diff options
Diffstat (limited to 'src')
51 files changed, 2920 insertions, 1283 deletions
diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index a7d33938..3f1f568a 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -3061,7 +3061,7 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params) case SOUND_PED_HELI_PLAYER_FOUND: { pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated; pedParams.m_fDistance = params.m_fDistance; - SetupPedComments(&pedParams, SOUND_PED_HELI_PLAYER_FOUND); + SetupPedComments(pedParams, SOUND_PED_HELI_PLAYER_FOUND); continue; } /* case SOUND_PED_BODYCAST_HIT: @@ -3075,7 +3075,7 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params) case SOUND_PED_VCPA_PLAYER_FOUND: { pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated; pedParams.m_fDistance = params.m_fDistance; - SetupPedComments(&pedParams, SOUND_PED_VCPA_PLAYER_FOUND); + SetupPedComments(pedParams, SOUND_PED_VCPA_PLAYER_FOUND); } case SOUND_WATER_FALL: { const float SOUND_INTENSITY = 40.0f; @@ -4171,40 +4171,41 @@ cAudioManager::ProcessPed(CPhysical *ped) //params.m_bDistanceCalculated = false; params.m_pPed = (CPed *)ped; params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos); - ProcessPedOneShots(¶ms); + ProcessPedOneShots(params); } void -cAudioManager::ProcessPedOneShots(cPedParams *params) +cAudioManager::ProcessPedOneShots(cPedParams ¶ms) { uint8 emittingVol; int32 sampleIndex; - CPed *ped = params->m_pPed; + CPed *ped = params.m_pPed; - bool stereo; + bool narrowSoundRange; int16 sound; - bool noReflection; + bool stereo; CWeapon *weapon; float maxDist = 0.f; // uninitialized variable static uint8 iSound = 21; + static uint32 iSplashFrame = 0; - weapon = params->m_pPed->GetWeapon(); + weapon = params.m_pPed->GetWeapon(); for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) { - noReflection = false; stereo = false; + narrowSoundRange = false; m_sQueueSample.m_bRequireReflection = false; sound = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]; switch (sound) { case SOUND_STEP_START: case SOUND_STEP_END: - if (!params->m_pPed->bIsLooking) { + if (!params.m_pPed->bIsLooking) { emittingVol = m_anRandomTable[3] % 15 + 45; if (FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity) emittingVol /= 2; maxDist = 400.f; - switch (params->m_pPed->m_nSurfaceTouched) { + switch (params.m_pPed->m_nSurfaceTouched) { case SURFACE_GRASS: sampleIndex = m_anRandomTable[1] % 5 + SFX_FOOTSTEP_GRASS_1; break; @@ -4245,10 +4246,10 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) } m_sQueueSample.m_nSampleIndex = sampleIndex; m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - 28; + m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - 32; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); - switch (params->m_pPed->m_nMoveState) { + switch (params.m_pPed->m_nMoveState) { case PEDMOVE_WALK: emittingVol /= 4; m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10; @@ -4306,229 +4307,83 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) case SOUND_FIGHT_37: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; m_sQueueSample.m_nFrequency = 18000; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_38: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; m_sQueueSample.m_nFrequency = 16500; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_39: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; m_sQueueSample.m_nFrequency = 20000; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_40: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; m_sQueueSample.m_nFrequency = 18000; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_41: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; m_sQueueSample.m_nFrequency = 16500; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_42: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2; m_sQueueSample.m_nFrequency = 20000; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_43: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; m_sQueueSample.m_nFrequency = 18000; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_44: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; m_sQueueSample.m_nFrequency = 16500; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_45: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4; m_sQueueSample.m_nFrequency = 20000; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_46: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; m_sQueueSample.m_nFrequency = 18000; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_47: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; m_sQueueSample.m_nFrequency = 16500; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = iSound; - stereo = true; - ++iSound; - m_sQueueSample.m_nReleasingVolumeModificator = 3; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - maxDist = SQR(30); - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 26 + 100; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; - break; + goto AddFightSound; case SOUND_FIGHT_48: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; m_sQueueSample.m_nFrequency = 20000; + AddFightSound: + { + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? stroring int as float + uint8 damagerType = soundParams & 0xFF; + uint32 weaponType = soundParams >> 8; + + if (damagerType == ENTITY_TYPE_PED) { + if (weaponType == WEAPONTYPE_BRASSKNUCKLE) { + CPed* ped = params.m_pPed; + uint32 fightMove = ped->m_curFightMove; + if (fightMove == FIGHTMOVE_BACKLEFT || fightMove == FIGHTMOVE_STDPUNCH || fightMove == FIGHTMOVE_PUNCH || + ped->m_nPedState == PED_ATTACK) { + CEntity* damageEntity = ped->m_pDamageEntity; + if (!damageEntity) + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1; + else if (damageEntity->GetType() != ENTITY_TYPE_PED) + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1; + else if (((CPed*)damageEntity)->m_curFightMove != FIGHTMOVE_HITHEAD) + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1; + else + m_sQueueSample.m_nSampleIndex = SFX_HAMMER_HIT_1; + } + } + } + else { + m_sQueueSample.m_nSampleIndex = m_anRandomTable[4] % 6 + SFX_COL_CAR_PANEL_1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + } + } m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound; - stereo = true; + narrowSoundRange = true; ++iSound; m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; @@ -4544,11 +4399,48 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) m_sQueueSample.m_bRequireReflection = true; break; case SOUND_WEAPON_BAT_ATTACK: - m_sQueueSample.m_nSampleIndex = SFX_BAT_HIT_LEFT; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; + case SOUND_WEAPON_KNIFE_ATTACK: + { + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? stroring int as float + uint8 damagerType = soundParams & 0xFF; + uint32 weaponType = soundParams >> 8; + if (damagerType == ENTITY_TYPE_PED) { + switch (weaponType) { + case WEAPONTYPE_SCREWDRIVER: + case WEAPONTYPE_KNIFE: + case WEAPONTYPE_CLEAVER: + case WEAPONTYPE_MACHETE: + case WEAPONTYPE_KATANA: + if (sound == SOUND_WEAPON_KNIFE_ATTACK) + m_sQueueSample.m_nSampleIndex = SFX_KNIFE_SLASH; + else + m_sQueueSample.m_nSampleIndex = SFX_KNIFE_STAB; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + break; + case WEAPONTYPE_HAMMER: + m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + break; + default: + m_sQueueSample.m_nSampleIndex = SFX_BAT_HIT_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 22000; + stereo = true; + break; + } + } + else { + m_sQueueSample.m_nSampleIndex = m_anRandomTable[4] % 6 + SFX_COL_CAR_PANEL_1; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + } m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 22000; + narrowSoundRange = true; m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; m_sQueueSample.m_fSoundIntensity = 30.0f; @@ -4560,25 +4452,112 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; + m_sQueueSample.m_bRequireReflection = true; + break; + } + // TODO: breaks the game right now, probably needs AudioManager.cpp to be done first + /* + case SOUND_WEAPON_CHAINSAW_ATTACK: + if (FindVehicleOfPlayer()) + continue; + m_sQueueSample.m_nSampleIndex = SFX_CAR_ACCEL_13; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW + m_sQueueSample.m_nCounter = 64; + m_sQueueSample.m_nFrequency = 27000; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 50.0f; + maxDist = SQR(50); + m_sQueueSample.m_nLoopCount = 0; + emittingVol = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_ACCEL_13); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_ACCEL_13); + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + break; + case SOUND_WEAPON_CHAINSAW_IDLE: + if (FindVehicleOfPlayer()) + continue; + m_sQueueSample.m_nSampleIndex = SFX_CAR_AFTER_ACCEL_13; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW + m_sQueueSample.m_nCounter = 68; + m_sQueueSample.m_nFrequency = 27000; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 0; + emittingVol = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; break; + case SOUND_WEAPON_CHAINSAW_MADECONTACT: + if (FindVehicleOfPlayer()) + continue; + if ((int32)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] != ENTITY_TYPE_PED) + ReportCollision(params.m_pPed, params.m_pPed, SURFACE_CAR, SURFACE_TARMAC, 0.0f, 0.09f); + m_sQueueSample.m_nSampleIndex = SFX_CAR_AFTER_ACCEL_13; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW + m_sQueueSample.m_nCounter = 68; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 22000; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 60.0f; + maxDist = SQR(60); + m_sQueueSample.m_nLoopCount = 0; + emittingVol = 100; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13); + m_sQueueSample.m_nEmittingVolume = 100; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 5; + break; + */ case SOUND_WEAPON_SHOT_FIRED: weapon = ped->GetWeapon(); + if (!weapon) + continue; switch (weapon->m_eWeaponType) { + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKETLAUNCHER: + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[0] % 20 + 80; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; + break; case WEAPONTYPE_COLT45: m_sQueueSample.m_nSampleIndex = SFX_COLT45_LEFT; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; - stereo = true; + narrowSoundRange = true; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COLT45_LEFT); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 50.0f; - maxDist = SQR(50); + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopStart = 0; m_sQueueSample.m_nLoopEnd = -1; @@ -4586,41 +4565,42 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; break; - case WEAPONTYPE_UZI: - m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; + case WEAPONTYPE_PYTHON: + m_sQueueSample.m_nSampleIndex = SFX_PYTHON_LEFT; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT); + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PYTHON_LEFT); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - maxDist = SQR(80); + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[3] % 15 + 70; m_sQueueSample.m_nLoopEnd = -1; + emittingVol = 127; m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; break; case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: m_sQueueSample.m_nSampleIndex = SFX_SHOTGUN_LEFT; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; - stereo = true; + narrowSoundRange = true; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHOTGUN_LEFT); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 60.0f; - maxDist = SQR(60); + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopStart = 0; m_sQueueSample.m_nLoopEnd = -1; @@ -4628,94 +4608,172 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; break; - case WEAPONTYPE_RUGER: - m_sQueueSample.m_nSampleIndex = SFX_AK47_LEFT; + case WEAPONTYPE_SPAS12_SHOTGUN: + m_sQueueSample.m_nSampleIndex = SFX_SPAS12_LEFT; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_LEFT); + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SPAS12_LEFT); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - maxDist = SQR(80); + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[1] % 15 + 70; m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[2] % 10 + 100; m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; break; - case WEAPONTYPE_M4: - m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT; + case WEAPONTYPE_TEC9: + m_sQueueSample.m_nSampleIndex = SFX_TEC_LEFT; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 17000; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M60_LEFT); + break; + case WEAPONTYPE_UZI: + case WEAPONTYPE_MINIGUN: + m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - maxDist = SQR(80); + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopStart = 0; - emittingVol = m_anRandomTable[4] % 15 + 70; + emittingVol = m_anRandomTable[3] % 15 + 70; m_sQueueSample.m_nLoopEnd = -1; m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = true; + stereo = true; break; - case WEAPONTYPE_SNIPERRIFLE: - m_sQueueSample.m_nSampleIndex = SFX_SNIPER_LEFT; + case WEAPONTYPE_SILENCED_INGRAM: + m_sQueueSample.m_nSampleIndex = SFX_TEC_LEFT; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 34000; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 70; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SNIPER_LEFT); + break; + case WEAPONTYPE_MP5: + m_sQueueSample.m_nSampleIndex = SFX_MP5_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_MP5_LEFT); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 60.0f; - maxDist = SQR(60); + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 70; m_sQueueSample.m_nLoopEnd = -1; - emittingVol = m_anRandomTable[4] % 10 + 110; m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; + stereo = true; break; - case WEAPONTYPE_ROCKETLAUNCHER: - m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT; + case WEAPONTYPE_M4: + m_sQueueSample.m_nSampleIndex = SFX_RUGER_LEFT; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 43150; + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 90; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_LEFT); + break; + case WEAPONTYPE_RUGER: + m_sQueueSample.m_nSampleIndex = SFX_RUGER_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RUGER_LEFT); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - m_sQueueSample.m_nReleasingVolumeModificator = 1; + m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 90.0f; - maxDist = SQR(90); + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopStart = 0; + emittingVol = m_anRandomTable[3] % 15 + 90; m_sQueueSample.m_nLoopEnd = -1; - emittingVol = m_anRandomTable[0] % 20 + 80; m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; + stereo = true; + break; + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + m_sQueueSample.m_nSampleIndex = SFX_SNIPER_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + if (weapon->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE) + m_sQueueSample.m_nFrequency = 25472; else - noReflection = true; + m_sQueueSample.m_nFrequency = 20182; + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = m_anRandomTable[4] % 10 + 110; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + stereo = true; break; case WEAPONTYPE_FLAMETHROWER: m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_LEFT; @@ -4734,53 +4792,73 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 6; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; + stereo = true; + break; + case WEAPONTYPE_M60: + case WEAPONTYPE_HELICANNON: + m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M60_LEFT); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = 127; + m_sQueueSample.m_nEmittingVolume = 127; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + stereo = true; break; default: continue; } - break; case SOUND_WEAPON_RELOAD: - weapon = &ped->m_weapons[ped->m_currentWeapon]; - switch (weapon->m_eWeaponType) { + switch ((int32)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]) { + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKETLAUNCHER: + m_sQueueSample.m_nSampleIndex = SFX_ROCKET_RELOAD; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_RELOAD); + break; case WEAPONTYPE_COLT45: + case WEAPONTYPE_PYTHON: m_sQueueSample.m_nSampleIndex = SFX_PISTOL_RELOAD; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PISTOL_RELOAD) + RandomDisplacement(300); break; - case WEAPONTYPE_UZI: - m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; - m_sQueueSample.m_nFrequency = 39243; - break; case WEAPONTYPE_SHOTGUN: - m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; - m_sQueueSample.m_nFrequency = 30290; - break; + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: case WEAPONTYPE_RUGER: m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_RELOAD); + m_sQueueSample.m_nFrequency = 30290; break; + case WEAPONTYPE_TEC9: + case WEAPONTYPE_UZI: + case WEAPONTYPE_SILENCED_INGRAM: + case WEAPONTYPE_MP5: case WEAPONTYPE_M4: + case WEAPONTYPE_M60: + case WEAPONTYPE_HELICANNON: m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_RELOAD); + m_sQueueSample.m_nFrequency = 39243; break; case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: m_sQueueSample.m_nSampleIndex = SFX_RIFLE_RELOAD; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RIFLE_RELOAD); break; - case WEAPONTYPE_ROCKETLAUNCHER: - m_sQueueSample.m_nSampleIndex = SFX_ROCKET_RELOAD; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_RELOAD); - break; default: continue; } emittingVol = 75; m_sQueueSample.m_nCounter = iSound++; - stereo = true; + narrowSoundRange = true; m_sQueueSample.m_nFrequency += RandomDisplacement(300); m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nReleasingVolumeModificator = 5; @@ -4796,28 +4874,71 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) m_sQueueSample.m_bRequireReflection = true; break; case SOUND_WEAPON_AK47_BULLET_ECHO: - m_sQueueSample.m_nSampleIndex = SFX_UZI_END_LEFT; + { + uint32 weaponType = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + switch (weaponType) { + case WEAPONTYPE_SPAS12_SHOTGUN: + m_sQueueSample.m_nSampleIndex = SFX_SPAS12_TAIL_LEFT; + break; + case WEAPONTYPE_TEC9: + case WEAPONTYPE_SILENCED_INGRAM: + m_sQueueSample.m_nSampleIndex = SFX_TEC_TAIL; + break; + case WEAPONTYPE_UZI: + case WEAPONTYPE_MP5: + m_sQueueSample.m_nSampleIndex = SFX_UZI_END_LEFT; + break; + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + m_sQueueSample.m_nSampleIndex = SFX_RUGER_TAIL; + break; + case WEAPONTYPE_M60: + case WEAPONTYPE_HELICANNON: + m_sQueueSample.m_nSampleIndex = SFX_M60_TAIL_LEFT; + break; + default: + continue; + } m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; - stereo = true; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_END_LEFT); + narrowSoundRange = true; + switch (weaponType) { + case WEAPONTYPE_TEC9: + m_sQueueSample.m_nFrequency = 13000; + break; + case WEAPONTYPE_SILENCED_INGRAM: + m_sQueueSample.m_nFrequency = 26000; + break; + case WEAPONTYPE_M4: + m_sQueueSample.m_nFrequency = 15600; + break; + case WEAPONTYPE_SNIPERRIFLE: + m_sQueueSample.m_nFrequency = 9959; + break; + case WEAPONTYPE_LASERSCOPE: + m_sQueueSample.m_nFrequency = 7904; + break; + default: + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + break; + } m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 80.0f; - maxDist = SQR(80); + m_sQueueSample.m_fSoundIntensity = 120.0f; + maxDist = SQR(120); m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopStart = 0; m_sQueueSample.m_nLoopEnd = -1; - emittingVol = m_anRandomTable[4] % 10 + 40; + emittingVol = m_anRandomTable[4] % 10 + 80; m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_bReleasingSoundFlag = true; - if (m_bDynamicAcousticModelingStatus) - m_sQueueSample.m_bRequireReflection = true; - else - noReflection = true; + m_sQueueSample.m_bRequireReflection = true; break; + } case SOUND_WEAPON_FLAMETHROWER_FIRE: m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_START_LEFT; m_sQueueSample.m_nBankIndex = SFX_BANK_0; @@ -4840,7 +4961,7 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) m_sQueueSample.m_nSampleIndex = SFX_BULLET_PED; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; - stereo = true; + narrowSoundRange = true; m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BULLET_PED); m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8); m_sQueueSample.m_nReleasingVolumeModificator = 7; @@ -4856,10 +4977,13 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) m_sQueueSample.m_bReleasingSoundFlag = true; break; case SOUND_SPLASH: + if (m_FrameCounter <= iSplashFrame) + continue; + iSplashFrame = m_FrameCounter + 6; m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nCounter = iSound++; - stereo = true; + narrowSoundRange = true; m_sQueueSample.m_nFrequency = RandomDisplacement(1400) + 20000; m_sQueueSample.m_nReleasingVolumeModificator = 1; m_sQueueSample.m_fSpeedMultiplier = 0.0f; @@ -4874,28 +4998,192 @@ cAudioManager::ProcessPedOneShots(cPedParams *params) m_sQueueSample.m_bReleasingSoundFlag = true; m_sQueueSample.m_bRequireReflection = true; break; + case SOUND_MELEE_ATTACK_START: + { + uint32 weaponType = ((uint32)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]) >> 8; + switch (weaponType) + { + case WEAPONTYPE_SCREWDRIVER: + case WEAPONTYPE_KNIFE: + case WEAPONTYPE_CLEAVER: + case WEAPONTYPE_MACHETE: + case WEAPONTYPE_KATANA: + m_sQueueSample.m_nSampleIndex = SFX_KNIFE_SWING; + break; + default: + m_sQueueSample.m_nSampleIndex = SFX_GOLF_CLUB_SWING; + break; + } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = iSound++; + narrowSoundRange = true; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + if (weaponType == WEAPONTYPE_UNARMED || weaponType == WEAPONTYPE_BRASSKNUCKLE) + emittingVol = m_anRandomTable[1] % 10 + 35; + else + emittingVol = m_anRandomTable[2] % 20 + 70; + maxDist = SQR(30); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_SKATING: + { + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + uint8 param1 = soundParams & 0xFF; + uint32 param2 = soundParams >> 8; + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 1) + SFX_SKATE_1; + m_sQueueSample.m_nBankIndex = 0; + m_sQueueSample.m_nCounter = iSound; + stereo = true; + ++iSound; + m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 1000 + 17000; + if (param2 == 0) + m_sQueueSample.m_nFrequency = (3 * m_sQueueSample.m_nFrequency) / 4; + m_sQueueSample.m_nReleasingVolumeModificator = 6; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 20.0f; + maxDist = SQR(20); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = (m_anRandomTable[2] % 20 + 70) * param1 / 127; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + } + case SOUND_WEAPON_MINIGUN_ATTACK: + m_sQueueSample.m_nSampleIndex = SFX_MINIGUN_FIRE_LEFT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 68; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_MINIGUN_FIRE_LEFT); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 150.0f; + emittingVol = 127; + maxDist = SQR(150); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_MINIGUN_FIRE_LEFT); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_MINIGUN_FIRE_LEFT); + m_sQueueSample.m_nEmittingVolume = 127; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + break; + case SOUND_WEAPON_MINIGUN_2: + m_sQueueSample.m_nSampleIndex = SFX_MINIGUN_FIRE_RIGHT; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 69; + m_sQueueSample.m_nFrequency = 18569; + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 150.0f; + emittingVol = 127.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + maxDist = SQR(150); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_MINIGUN_FIRE_RIGHT); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_MINIGUN_FIRE_RIGHT); + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + break; + case SOUND_WEAPON_MINIGUN_3: + m_sQueueSample.m_nSampleIndex = SFX_MINIGUN_STOP; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 69; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_MINIGUN_STOP); + m_sQueueSample.m_nReleasingVolumeModificator = 4; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 150.0f; + maxDist = SQR(150); + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + emittingVol = 127; + m_sQueueSample.m_nEmittingVolume = 127; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; + break; + case SOUND_SHIRT_WIND_FLAP: + if (params.m_pPed->IsPlayer()) { + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 0.0f) { + if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 1.0f) + m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] = 1.0f; + + emittingVol = 90.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; + + switch (params.m_pPed->m_pMyVehicle->GetModelIndex()) + { + case MI_ANGEL: + case MI_FREEWAY: + m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_17; + break; + case MI_PIZZABOY: + case MI_FAGGIO: + m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_18; + break; + case MI_PCJ600: + m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_20; + break; + case MI_SANCHEZ: + m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_19; + break; + default: + continue; + }; + + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 71; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nReleasingVolumeModificator = 3; + m_sQueueSample.m_fSpeedMultiplier = 3.0f; + m_sQueueSample.m_fSoundIntensity = 15.0f; + maxDist = SQR(15); + m_sQueueSample.m_nLoopCount = 0; + m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = false; + m_sQueueSample.m_nReleasingVolumeDivider = 3; + } + } + break; default: SetupPedComments(params, sound); continue; } - if (stereo && iSound > 60) + if (narrowSoundRange && iSound > 60) iSound = 21; - if (params->m_fDistance < maxDist) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + if (params.m_fDistance < maxDist) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); if (m_sQueueSample.m_nVolume != 0) { - if (noReflection) { + if (stereo) { if (m_sQueueSample.m_fDistance < 0.2f * m_sQueueSample.m_fSoundIntensity) { m_sQueueSample.m_bIs2D = true; m_sQueueSample.m_nOffset = 0; } else { - noReflection = false; + stereo = false; } } m_sQueueSample.m_bReverbFlag = true; AddSampleToRequestedQueue(); - if (noReflection) { + if (stereo) { m_sQueueSample.m_nOffset = 127; ++m_sQueueSample.m_nSampleIndex; if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] != SOUND_WEAPON_SHOT_FIRED || @@ -4933,9 +5221,9 @@ cAudioManager::SetPlayersMood(uint8 mood, uint32 time) } void -cAudioManager::SetupPedComments(cPedParams *params, uint32 sound) +cAudioManager::SetupPedComments(cPedParams ¶ms, uint16 sound) { - CPed *ped = params->m_pPed; + CPed *ped = params.m_pPed; uint8 emittingVol; float soundIntensity; tPedComment pedComment; @@ -4974,8 +5262,8 @@ cAudioManager::SetupPedComments(cPedParams *params, uint32 sound) } } - if(params->m_fDistance < SQR(soundIntensity)) { - CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); + if(params.m_fDistance < SQR(soundIntensity)) { + CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance); if(CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(), m_sQueueSample.m_vecPos, true, false, false, false, false, false)) emittingVol = MAX_VOLUME; else diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index c9bd6c17..fbfdb855 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -167,7 +167,7 @@ cAudioManager::SetEntityStatus(int32 id, uint8 status) } void -cAudioManager::PlayOneShot(int32 index, int16 sound, float vol) +cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol) { static const uint8 OneShotPriority[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 2, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1, 1, 1, 4, 4, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 3, 4, 2, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index 35bb877c..2e0af437 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -390,7 +390,7 @@ public: bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; //done void PlayLoadedMissionAudio(uint8 slot); // done - void PlayOneShot(int32 index, int16 sound, float vol); // done + void PlayOneShot(int32 index, uint16 sound, float vol); // done void PlaySuspectLastSeen(float x, float y, float z); // done void PlayerJustGotInCar() const; // done void PlayerJustLeftCar() const; // done @@ -435,7 +435,7 @@ public: void ProcessModelVehicle(cVehicleParams& params); // done void ProcessOneShotScriptObject(uint8 sound); // void ProcessPed(CPhysical *ped); // done - void ProcessPedOneShots(cPedParams *params); // + void ProcessPedOneShots(cPedParams ¶ms); // void ProcessPhysical(int32 id); // done void ProcessPlane(cVehicleParams& params); // done void ProcessPlayerMood(); // done @@ -500,7 +500,7 @@ public: bool SetupJumboRumbleSound(uint8 emittingVol); bool SetupJumboTaxiSound(uint8 vol); bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq); - void SetupPedComments(cPedParams *params, uint32 sound); // done + void SetupPedComments(cPedParams ¶ms, uint16 sound); // done void SetupSuspectLastSeenReport(); void Terminate(); //done diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h index ba2c8bec..0a1689bc 100644 --- a/src/audio/soundlist.h +++ b/src/audio/soundlist.h @@ -201,7 +201,7 @@ enum eSound : uint16 SOUND_FRONTEND_AUDIO_TEST, SOUND_INJURED_PED_MALE_OUCH, SOUND_INJURED_PED_FEMALE, - SOUND_SET_202, + SOUND_SHIRT_WIND_FLAP, SOUND_SET_203, SOUND_TOTAL_SOUNDS = 204, SOUND_NO_SOUND = 205, diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index 41dc735f..e10693eb 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -1766,10 +1766,18 @@ CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start) DoPathSearch(type, start, -1, target, pNodeList, &DummyResult, 32, nil, &dist, 999999.88f, -1); else DoPathSearch(type, start, -1, target, nil, &DummyResult2, 0, nil, &dist, 50.0f, -1); +#ifdef FIX_BUGS + // dist has GenerationDistMultiplier as a factor, so our reference dist should have it too + if(type == PATH_CAR) + return dist < 150.0f*TheCamera.GenerationDistMultiplier; + else + return dist < 100.0f*TheCamera.GenerationDistMultiplier; +#else if(type == PATH_CAR) return dist < 150.0f; else return dist < 100.0f; +#endif } void diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 4d325101..1ff4f8f6 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -619,11 +619,11 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) m_pObject->GetMatrix().UpdateRW(); m_pObject->UpdateRwFrame(); - if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0) && waterLevel >= m_pObject->GetPosition().z) + if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false) && waterLevel >= m_pObject->GetPosition().z) m_eType = PICKUP_FLOATINGPACKAGE_FLOATING; break; case PICKUP_FLOATINGPACKAGE_FLOATING: - if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0)) + if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false)) m_pObject->GetMatrix().GetPosition().z = waterLevel; m_pObject->GetMatrix().UpdateRW(); diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index e28bbf35..0c70d2f6 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -1,5 +1,5 @@ #include "common.h" - +#ifdef GTA_REPLAY #include "AnimBlendAssocGroup.h" #include "AnimBlendAssociation.h" #include "Bike.h" @@ -1887,3 +1887,4 @@ void CReplay::Display() if (Mode == MODE_PLAYBACK) CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY")); } +#endif diff --git a/src/control/Replay.h b/src/control/Replay.h index 319d8bd4..84a6bef0 100644 --- a/src/control/Replay.h +++ b/src/control/Replay.h @@ -66,6 +66,12 @@ struct CStoredDetailedAnimationState void PlayReplayFromHD(void); +#ifdef GTA_REPLAY +#define REPLAY_STUB +#else +#define REPLAY_STUB {} +#endif + class CReplay { enum { @@ -362,21 +368,25 @@ private: #endif public: - static void Init(void); - static void DisableReplays(void); - static void EnableReplays(void); - static void Update(void); - static void FinishPlayback(void); - static void EmptyReplayBuffer(void); - static void Display(void); - static void TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene); - static void StreamAllNecessaryCarsAndPeds(void); + static void Init(void) REPLAY_STUB; + static void DisableReplays(void) REPLAY_STUB; + static void EnableReplays(void) REPLAY_STUB; + static void Update(void) REPLAY_STUB; + static void FinishPlayback(void) REPLAY_STUB; + static void EmptyReplayBuffer(void) REPLAY_STUB; + static void Display(void) REPLAY_STUB; + static void TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene) REPLAY_STUB; + static void StreamAllNecessaryCarsAndPeds(void) REPLAY_STUB; + static void RecordParticle(tParticleType type, CVector const& vecPos, CVector const& vecDir, float fSize, RwRGBA const& color) REPLAY_STUB; + +#ifndef GTA_REPLAY + static bool ShouldStandardCameraBeProcessed(void) { return true; } + static bool IsPlayingBack() { return false; } + static bool IsPlayingBackFromFile() { return false; } +#else static bool ShouldStandardCameraBeProcessed(void); - static bool IsPlayingBack() { return Mode == MODE_PLAYBACK; } static bool IsPlayingBackFromFile() { return bPlayingBackFromFile; } - - static void RecordParticle(tParticleType type, CVector const& vecPos, CVector const& vecDir, float fSize, RwRGBA const& color); private: static void RecordThisFrame(void); static void StorePedUpdate(CPed *ped, int id); @@ -407,4 +417,5 @@ private: /* Absolute nonsense, but how could this function end up being outside of class? */ friend void PlayReplayFromHD(void); +#endif }; diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp index dee2cbe3..260978b3 100644 --- a/src/control/RoadBlocks.cpp +++ b/src/control/RoadBlocks.cpp @@ -97,11 +97,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType pCopPed->m_nRoadblockVeh->RegisterReference((CEntity**)&pCopPed->m_nRoadblockVeh); pCopPed->bCrouchWhenShooting = roadBlockType == 2 ? false : true; if (pEntityToAttack) { - if (pCopPed->m_pPointGunAt) - pCopPed->m_pPointGunAt->CleanUpOldReference(&pCopPed->m_pPointGunAt); - pCopPed->m_pPointGunAt = pEntityToAttack; - if (pEntityToAttack) - pEntityToAttack->RegisterReference(&pCopPed->m_pPointGunAt); + pCopPed->SetWeaponLockOnTarget(pEntityToAttack); pCopPed->SetAttack(pEntityToAttack); } pCopPed->m_pMyVehicle = pVehicle; diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 6c4e21d5..be0e9bf0 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -17,6 +17,9 @@ #include "FileMgr.h" #include "Frontend.h" #include "General.h" +#ifdef MISSION_REPLAY +#include "GenericGameStorage.h" +#endif #include "HandlingMgr.h" #include "Heli.h" #include "Hud.h" @@ -93,6 +96,10 @@ uint32 CTheScripts::LastMissionPassedTime; uint16 CTheScripts::NumberOfExclusiveMissionScripts; bool CTheScripts::bPlayerHasMetDebbieHarry; bool CTheScripts::bPlayerIsInTheStatium; +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) +int16 CTheScripts::CardStack[CARDS_IN_DECK * MAX_DECKS]; +int16 CTheScripts::CardStackPosition; +#endif #ifdef MISSION_REPLAY @@ -123,6 +130,9 @@ float oldTargetX; float oldTargetY; int missionRetryScriptIndex; bool doingMissionRetry; +bool gbTryingPorn4Again; +int IsInAmmunation; +int MissionSkipLevel; #endif @@ -1568,6 +1578,39 @@ const tScriptCommandData commands[] = { REGISTER_COMMAND(COMMAND_REGISTER_FIRE_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_IS_AUSTRALIAN_GAME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""), REGISTER_COMMAND(COMMAND_DISARM_CAR_BOMB, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), +#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT) + REGISTER_COMMAND(COMMAND_IS_JAPANESE_GAME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""), +#elif (!defined GTA_PS2) + REGISTER_COMMAND(COMMAND_SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), +#endif +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + REGISTER_COMMAND(COMMAND_SHUFFLE_CARD_DECKS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_FETCH_NEXT_CARD, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_GET_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_IS_DEBUG_CAMERA_ON, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""), + REGISTER_COMMAND(COMMAND_ADD_TO_OBJECT_ROTATION_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_SET_OBJECT_ROTATION_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_IS_OBJECT_STATIC, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""), + REGISTER_COMMAND(COMMAND_GET_ANGLE_BETWEEN_2D_VECTORS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_DO_2D_RECTANGLES_COLLIDE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), true, -1, ""), + REGISTER_COMMAND(COMMAND_GET_OBJECT_ROTATION_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_ADD_VELOCITY_RELATIVE_TO_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_GET_OBJECT_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""), +#endif +#if (defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT) + REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_START, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_END, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_CUTSCENE_SCROLL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), +#elif (defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + REGISTER_COMMAND(COMMAND_IS_MISSION_SKIP, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_SET_IN_AMMUNATION, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_DO_SAVE_GAME, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_IS_RETRY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""), + REGISTER_COMMAND(COMMAND_DUMMY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_START, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_END, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_CUTSCENE_SCROLL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), +#endif }; #undef REGISTER_COMMAND #undef INPUT_ARGUMENTS @@ -4802,7 +4845,7 @@ void RetryMission(int type, int unk) { if (type == 0) { doingMissionRetry = true; - FrontEndMenuManager.m_nCurrScreen = MENUPAGE_MISSION_RETRY; + FrontEndMenuManager.m_nCurrScreen = 57; // MENUPAGE_MISSION_RETRY FrontEndMenuManager.RequestFrontEndStartUp(); } else if (type == 2) { diff --git a/src/control/Script.h b/src/control/Script.h index f7613d18..983cf6e5 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -306,6 +306,15 @@ class CTheScripts static uint16 ScriptsUpdated; static uint32 LastMissionPassedTime; static uint16 NumberOfExclusiveMissionScripts; +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) +#define CARDS_IN_SUIT (13) +#define NUM_SUITS (4) +#define MAX_DECKS (6) +#define CARDS_IN_DECK (CARDS_IN_SUIT * NUM_SUITS) +#define CARDS_IN_STACK (CARDS_IN_DECK * MAX_DECKS) + static int16 CardStack[CARDS_IN_STACK]; + static int16 CardStackPosition; +#endif public: static bool bPlayerIsInTheStatium; static uint8 RiotIntensity; @@ -547,12 +556,16 @@ private: extern int scriptToLoad; #endif #ifdef MISSION_REPLAY +static_assert(false, "Mission replay is not supported"); extern int AllowMissionReplay; extern uint32 WaitForMissionActivate; extern uint32 WaitForSave; extern uint32 MissionStartTime; extern int missionRetryScriptIndex; extern bool doingMissionRetry; +extern bool gbTryingPorn4Again; +extern int IsInAmmunation; +extern int MissionSkipLevel; uint32 AddExtraDeathDelay(); void RetryMission(int, int); diff --git a/src/control/Script8.cpp b/src/control/Script8.cpp index 7af0ac8e..ddeaf64b 100644 --- a/src/control/Script8.cpp +++ b/src/control/Script8.cpp @@ -4,8 +4,18 @@ #include "ScriptCommands.h" #include "DMAudio.h" +#if ((defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT) && defined MORE_LANGUAGES) +#include "Frontend.h" +#endif #include "GameLogic.h" #include "Garages.h" +#ifdef MISSION_REPLAY +#include "GenericGameStorage.h" +#endif +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) +#include "General.h" +#include "maths.h" +#endif #include "Hud.h" #include "Pad.h" #include "PedAttractor.h" @@ -373,6 +383,228 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) } return 0; } +#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT) + case COMMAND_IS_JAPANESE_GAME: +#ifdef MORE_LANGUAGES + UpdateCompareFlag(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_JAPANESE); +#elif (defined GTAVC_JP_PATCH) + UpdateCompareFlag(true); +#else + UpdateCompareFlag(false); +#endif + return 0; +#elif (!defined GTA_PS2) + case COMMAND_SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED: + script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); + uint16 var = CTheScripts::Read2BytesFromScript(&m_nIp); + CollectParameters(&m_nIp, 1); + //CUserDisplay::OnscnTimer.SetCounterFlashWhenFirstDisplayed(var, ScriptParams[0]); + break; +#endif +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + case COMMAND_SHUFFLE_CARD_DECKS: + { + CollectParameters(&m_nIp, 1); + script_assert(ScriptParams[0] >= 0 && ScriptParams[0] <= 6); + for (int i = 0; i < CARDS_IN_STACK; i++) + CTheScripts::CardStack[i] = 0; + int16 seq[CARDS_IN_STACK]; + for (int i = 0; i < MAX_DECKS * CARDS_IN_DECK; i++) + seq[i] = i; + int cards_left = CARDS_IN_DECK * ScriptParams[0]; + for (int k = 1; k < CARDS_IN_DECK + 1; k++) { + for (int deck = 0; deck < ScriptParams[0]; deck++) { + int index = CGeneral::GetRandomNumberInRange(0, cards_left); + CTheScripts::CardStack[seq[index]] = k; + for (int l = index; l < cards_left; l++) { + if (l + 1 < CARDS_IN_STACK) + seq[l] = seq[l + 1]; + else + seq[l] = 0; + } + --cards_left; + } + } + CTheScripts::CardStackPosition = 0; + return 0; + } + case COMMAND_FETCH_NEXT_CARD: + { + if (CTheScripts::CardStack[CTheScripts::CardStackPosition] == 0) + CTheScripts::CardStackPosition = 0; + ScriptParams[0] = CTheScripts::CardStack[CTheScripts::CardStackPosition++]; + if (CTheScripts::CardStackPosition == CARDS_IN_DECK * MAX_DECKS) + CTheScripts::CardStackPosition = 0; + StoreParameters(&m_nIp, 1); + return 0; + } + case COMMAND_GET_OBJECT_VELOCITY: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + *(CVector*)ScriptParams[0] = GAME_SPEED_TO_METERS_PER_SECOND * pObject->GetMoveSpeed(); + StoreParameters(&m_nIp, 3); + return 0; + } + case COMMAND_IS_DEBUG_CAMERA_ON: + UpdateCompareFlag(TheCamera.WorldViewerBeingUsed); + return 0; + case COMMAND_ADD_TO_OBJECT_ROTATION_VELOCITY: + { + CollectParameters(&m_nIp, 4); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + CVector newSpeed = pObject->GetTurnSpeed() + *(CVector*)ScriptParams[1] / GAME_SPEED_TO_METERS_PER_SECOND; + if (pObject->bIsStatic) { + pObject->SetIsStatic(false); + pObject->AddToMovingList(); + } + pObject->SetTurnSpeed(newSpeed.x, newSpeed.y, newSpeed.z); + return 0; + } + case COMMAND_SET_OBJECT_ROTATION_VELOCITY: + { + CollectParameters(&m_nIp, 4); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + CVector newSpeed = *(CVector*)ScriptParams[1] / GAME_SPEED_TO_METERS_PER_SECOND; + if (pObject->bIsStatic) { + pObject->SetIsStatic(false); + pObject->AddToMovingList(); + } + pObject->SetTurnSpeed(newSpeed.x, newSpeed.y, newSpeed.z); + return 0; + } + case COMMAND_IS_OBJECT_STATIC: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + UpdateCompareFlag(pObject->GetIsStatic()); + return 0; + } + case COMMAND_GET_ANGLE_BETWEEN_2D_VECTORS: + { + CollectParameters(&m_nIp, 4); + CVector2D v1 = *(CVector2D*)ScriptParams[0]; + CVector2D v2 = *(CVector2D*)ScriptParams[2]; + float c = DotProduct2D(v1, v2) / (v1.Magnitude() * v2.Magnitude()); +#ifdef FIX_BUGS // command is a SA leftover where it was fixed to this + *(float*)ScriptParams[0] = RADTODEG(Acos(c)); +#else + *(float*)ScriptParams[0] = Acos(c); +#endif + return 0; + } + case COMMAND_DO_2D_RECTANGLES_COLLIDE: + { + CollectParameters(&m_nIp, 8); + float infX1 = *(float*)&ScriptParams[0] - *(float*)&ScriptParams[2] * 0.5; // NB: not float + float supX1 = *(float*)&ScriptParams[0] + *(float*)&ScriptParams[2] * 0.5; + float infX2 = *(float*)&ScriptParams[4] - *(float*)&ScriptParams[6] * 0.5; + float supX2 = *(float*)&ScriptParams[4] + *(float*)&ScriptParams[6] * 0.5; + float infY1 = *(float*)&ScriptParams[1] - *(float*)&ScriptParams[3] * 0.5; + float supY1 = *(float*)&ScriptParams[1] + *(float*)&ScriptParams[3] * 0.5; + float infY2 = *(float*)&ScriptParams[5] - *(float*)&ScriptParams[7] * 0.5; + float supY2 = *(float*)&ScriptParams[5] + *(float*)&ScriptParams[7] * 0.5; + bool collide = true; + if (infY2 > supY1) + collide = false; + if (infY1 > supY2) + collide = false; + if (infX2 > supX1) + collide = false; + if (infX1 > supX2) + collide = false; + UpdateCompareFlag(collide); + return 0; + } + case COMMAND_GET_OBJECT_ROTATION_VELOCITY: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + *(CVector*)ScriptParams[0] = pObject->GetTurnSpeed() * GAME_SPEED_TO_METERS_PER_SECOND; + StoreParameters(&m_nIp, 3); + return 0; + } + case COMMAND_ADD_VELOCITY_RELATIVE_TO_OBJECT_VELOCITY: + { + CollectParameters(&m_nIp, 4); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + CVector vecAddition = *(CVector*)&ScriptParams[1] * CTimer::GetTimeStep() / GAME_SPEED_TO_METERS_PER_SECOND; + if (!pObject->bIsStatic) { + CVector vecCurrSpeed = pObject->GetSpeed(); + vecCurrSpeed.Normalise(); + if (vecCurrSpeed.z != 1.0) { // NB: not float! + CVector vx = CrossProduct(vecCurrSpeed, CVector(0.0f, 0.0f, 1.0f)); + vx.Normalise(); + CVector vz = CrossProduct(vx, vecCurrSpeed); + vz.Normalise(); + CVector vecNewSpeed = pObject->GetSpeed() + vecAddition.x * vx + vecAddition.y * vecCurrSpeed + vecAddition.z * vecCurrSpeed; + if (pObject->bIsStatic) { + pObject->SetIsStatic(false); + pObject->AddToMovingList(); + } + pObject->SetMoveSpeed(vecNewSpeed); + } + } + return 0; + } + case COMMAND_GET_OBJECT_SPEED: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + *(float*)ScriptParams[0] = pObject->GetMoveSpeed().Magnitude() * GAME_SPEED_TO_METERS_PER_SECOND; + StoreParameters(&m_nIp, 1); + return 0; + } +#endif +#if (defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + case COMMAND_IS_MISSION_SKIP: +#ifdef MISSION_REPLAY + ScriptParams[0] = MissionSkipLevel; +#else + ScriptParams[0] = 0; +#endif + StoreParameters(&m_nIp, 1); + return 0; + case COMMAND_SET_IN_AMMUNATION: + CollectParameters(&m_nIp, 1); +#ifdef MISSION_REPLAY + IsInAmmunation = ScriptParams[0]; +#endif + return 0; + case COMMAND_DO_SAVE_GAME: + CollectParameters(&m_nIp, 1); +#ifdef MISSION_REPLAY + SaveGameForPause(ScriptParams[0]); +#endif + return 0; + case COMMAND_IS_RETRY: +#ifdef MISSION_REPLAY + if (strcmp(m_abScriptName, "porno4") != 0) + ScriptParams[0] = AllowMissionReplay; +#ifdef FIX_BUGS + else + ScriptParams[0] = gbTryingPorn4Again; +#else + else if (gbTryingPorn4Again) + ScriptParams[0] = 1; +#endif +#else + ScriptParams[0] = 0; +#endif + StoreParameters(&m_nIp, 1); + return 0; + case COMMAND_DUMMY: + return 0; +#endif +#if (defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + // it is unknown what these commands do but they don't take parameters + case COMMAND_MARK_CUTSCENE_START: + return 0; + case COMMAND_MARK_CUTSCENE_END: + return 0; + case COMMAND_CUTSCENE_SCROLL: + return 0; +#endif default: script_assert(0); } diff --git a/src/control/ScriptCommands.h b/src/control/ScriptCommands.h index 18fc9575..9863e852 100644 --- a/src/control/ScriptCommands.h +++ b/src/control/ScriptCommands.h @@ -1437,6 +1437,39 @@ enum { COMMAND_REGISTER_FIRE_LEVEL, COMMAND_IS_AUSTRALIAN_GAME, COMMAND_DISARM_CAR_BOMB, +#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT) + COMMAND_IS_JAPANESE_GAME, +#elif (!defined GTA_PS2) + COMMAND_SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED, +#endif +#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + COMMAND_SHUFFLE_CARD_DECKS, + COMMAND_FETCH_NEXT_CARD, + COMMAND_GET_OBJECT_VELOCITY, + COMMAND_IS_DEBUG_CAMERA_ON, + COMMAND_ADD_TO_OBJECT_ROTATION_VELOCITY, + COMMAND_SET_OBJECT_ROTATION_VELOCITY, + COMMAND_IS_OBJECT_STATIC, + COMMAND_GET_ANGLE_BETWEEN_2D_VECTORS, + COMMAND_DO_2D_RECTANGLES_COLLIDE, + COMMAND_GET_OBJECT_ROTATION_VELOCITY, + COMMAND_ADD_VELOCITY_RELATIVE_TO_OBJECT_VELOCITY, + COMMAND_GET_OBJECT_SPEED, +#endif +#if (defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT) + COMMAND_MARK_CUTSCENE_START, + COMMAND_MARK_CUTSCENE_END, + COMMAND_CUTSCENE_SCROLL, +#elif (defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT) + COMMAND_IS_MISSION_SKIP, + COMMAND_SET_IN_AMMUNATION, + COMMAND_DO_SAVE_GAME, + COMMAND_IS_RETRY, + COMMAND_DUMMY, + COMMAND_MARK_CUTSCENE_START, + COMMAND_MARK_CUTSCENE_END, + COMMAND_CUTSCENE_SCROLL, +#endif #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT LAST_SCRIPT_COMMAND #endif diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp index d39be754..8b798268 100644 --- a/src/core/AnimViewer.cpp +++ b/src/core/AnimViewer.cpp @@ -18,6 +18,7 @@ #include "World.h" #include "Renderer.h" #include "AnimManager.h" +#include "AnimBlendAssocGroup.h" #include "AnimViewer.h" #include "PlayerPed.h" #include "Pools.h" @@ -60,11 +61,14 @@ CAnimViewer::Render(void) { void CAnimViewer::Initialise(void) { - LoadingScreen("Loading the ModelViewer", "", GetRandomSplashScreen()); - animTxdSlot = CTxdStore::AddTxdSlot("generic"); - CTxdStore::Create(animTxdSlot); + + // we need messages, messages needs hud, hud needs those int hudSlot = CTxdStore::AddTxdSlot("hud"); CTxdStore::LoadTxd(hudSlot, "MODELS/HUD.TXD"); + CHud::m_Wants_To_Draw_Hud = false; + + animTxdSlot = CTxdStore::AddTxdSlot("generic"); + CTxdStore::Create(animTxdSlot); int particleSlot = CTxdStore::AddTxdSlot("particle"); CTxdStore::LoadTxd(particleSlot, "MODELS/PARTICLE.TXD"); CTxdStore::SetCurrentTxd(animTxdSlot); @@ -73,10 +77,6 @@ CAnimViewer::Initialise(void) { TheCamera.Init(); TheCamera.SetRwCamera(Scene.camera); TheCamera.Cams[TheCamera.ActiveCam].Distance = 5.0f; - - gbModelViewer = true; - CHud::m_Wants_To_Draw_Hud = false; - ThePaths.Init(); ThePaths.AllocatePathFindInfoMem(4500); CCollision::Init(); @@ -101,6 +101,9 @@ CAnimViewer::Initialise(void) { CStreaming::LoadAllRequestedModels(false); CRenderer::Init(); CVehicleModelInfo::LoadVehicleColours(); +#ifdef FIX_BUGS + CVehicleModelInfo::LoadEnvironmentMaps(); +#endif CAnimManager::LoadAnimFiles(); CWorld::PlayerInFocus = 0; CWeapon::InitialiseWeapons(); @@ -138,6 +141,25 @@ CAnimViewer::Initialise(void) { } else { // TODO? maybe request some special models here so the thing doesn't crash } + + // From LCS. idk if needed + int vanBlock = CAnimManager::GetAnimationBlockIndex("van"); + int bikesBlock = CAnimManager::GetAnimationBlockIndex("bikes"); + int bikevBlock = CAnimManager::GetAnimationBlockIndex("bikev"); + int bikehBlock = CAnimManager::GetAnimationBlockIndex("bikeh"); + int bikedBlock = CAnimManager::GetAnimationBlockIndex("biked"); + CStreaming::FlushRequestList(); + CStreaming::RequestAnim(vanBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::RequestAnim(bikesBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::RequestAnim(bikevBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::RequestAnim(bikehBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::RequestAnim(bikedBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::LoadAllRequestedModels(false); + CAnimManager::AddAnimBlockRef(vanBlock); + CAnimManager::AddAnimBlockRef(bikesBlock); + CAnimManager::AddAnimBlockRef(bikevBlock); + CAnimManager::AddAnimBlockRef(bikehBlock); + CAnimManager::AddAnimBlockRef(bikedBlock); } int @@ -215,8 +237,7 @@ CAnimViewer::Update(void) { static int modelId = 0; static int animId = 0; - // Please don't make this bool, static bool's are problematic on my side. - static int reloadIFP = 0; + static bool reloadIFP = false; AssocGroupId animGroup = ASSOCGRP_STD; int nextModelId = modelId; @@ -241,7 +262,7 @@ CAnimViewer::Update(void) CAnimManager::Initialise(); CAnimManager::LoadAnimFiles(); - reloadIFP = 0; + reloadIFP = false; } } else { animGroup = ASSOCGRP_STD; @@ -292,14 +313,19 @@ CAnimViewer::Update(void) if (pTarget->IsVehicle() || pTarget->IsPed() || pTarget->IsObject()) { ((CPhysical*)pTarget)->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); } +#ifdef FIX_BUGS + // so we don't end up in the water + pTarget->GetMatrix().GetPosition().z = 10.0f; +#else pTarget->GetMatrix().GetPosition().z = 0.0f; +#endif if (modelInfo->GetModelType() == MITYPE_PED) { ((CPed*)pTarget)->bKindaStayInSamePlace = true; // Triangle in mobile if (pad->GetSquareJustDown()) { - reloadIFP = 1; + reloadIFP = true; AsciiToUnicode("IFP reloaded", gUString); CMessages::AddMessage(gUString, 1000, 0); @@ -316,7 +342,7 @@ CAnimViewer::Update(void) } else if (pad->GetDPadUpJustDown()) { animId--; if (animId < 0) { - animId = NUM_ANIMS - 1; + animId = NUM_STD_ANIMS - 1; } PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId); @@ -325,7 +351,7 @@ CAnimViewer::Update(void) CMessages::AddMessage(gUString, 1000, 0); } else if (pad->GetDPadDownJustDown()) { - animId = (animId == (NUM_ANIMS - 1) ? 0 : animId + 1); + animId = (animId == (NUM_STD_ANIMS - 1) ? 0 : animId + 1); PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId); sprintf(gString, "Current anim: %d", animId); @@ -344,6 +370,11 @@ CAnimViewer::Update(void) AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString); CMessages::AddMessage(gUString, 100, 0); } + + // From LCS + if (CAnimManager::GetAnimAssocGroups()[animGroup].numAssociations <= animId) + animId = 0; + } else if (modelInfo->GetModelType() == MITYPE_VEHICLE) { if (pad->GetLeftShoulder1JustDown()) { diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 7560a86e..bc01b58e 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -4125,6 +4125,12 @@ CCam::Process_ModelView(const CVector &CameraTarget, float, float, float) Distance += CPad::GetPad(0)->GetLeftStickY()/1000.0f; else Distance += CPad::GetPad(0)->GetLeftStickY() * ((Distance - 10.0f)/20.0f + 1.0f) / 1000.0f; +#ifdef IMPROVED_CAMERA + if(CPad::GetPad(0)->GetLeftMouse()){ + Distance += DEGTORAD(CPad::GetPad(0)->GetMouseY()/2.0f); + Angle += DEGTORAD(CPad::GetPad(0)->GetMouseX()/2.0f); + } +#endif if(Distance < 1.5f) Distance = 1.5f; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 68771f64..a6cf71f1 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -612,7 +612,7 @@ CCamera::Process(void) // LOD dist if(!CCutsceneMgr::IsRunning() || CCutsceneMgr::UseLodMultiplier()){ - LODDistMultiplier = 70.0f/CDraw::GetFOV() * CDraw::GetAspectRatio()/(4.0f/3.0f); + LODDistMultiplier = 70.0f/CDraw::GetFOV(); if(GetPosition().z > 55.0f && FindPlayerVehicle() && FindPlayerVehicle()->pHandling->Flags & (HANDLING_IS_HELI|HANDLING_IS_PLANE) || FindPlayerPed()->m_attachedTo){ @@ -1011,14 +1011,15 @@ CCamera::CamControl(void) if((m_bLookingAtPlayer || m_bEnable1rstPersonCamCntrlsScript) && pTargetEntity->IsPed() && (!m_WideScreenOn || m_bEnable1rstPersonCamCntrlsScript) && !Cams[0].Using3rdPersonMouseCam() #ifdef FREE_CAM - && !CCamera::bFreeCam + && (!CCamera::bFreeCam || m_bEnable1rstPersonCamCntrlsScript) #endif ){ // See if we want to enter first person mode if(CPad::GetPad(0)->LookAroundLeftRight() || CPad::GetPad(0)->LookAroundUpDown()){ m_uiFirstPersonCamLastInputTime = CTimer::GetTimeInMilliseconds(); m_bFirstPersonBeingUsed = true; - }else if(m_bFirstPersonBeingUsed){ + } + if(m_bFirstPersonBeingUsed){ // Or if we want to go back to 3rd person if(CPad::GetPad(0)->GetPedWalkLeftRight() || CPad::GetPad(0)->GetPedWalkUpDown() || CPad::GetPad(0)->GetSquare() || CPad::GetPad(0)->GetTriangle() || @@ -1701,7 +1702,7 @@ CCamera::CamControl(void) StartTransitionWhenNotFinishedInter(ReqMode); pTargetEntity->RegisterReference(&pTargetEntity); Cams[ActiveCam].CamTargetEntity->RegisterReference(&Cams[ActiveCam].CamTargetEntity); - }else if(m_bStartInterScript && m_iTypeOfSwitch == JUMP_CUT){ + }else if(m_bStartInterScript && m_iTypeOfSwitch == JUMP_CUT || jumpCutTo1stPrs){ m_uiTransitionState = 0; m_vecDoingSpecialInterPolation = false; if(m_bEnable1rstPersonCamCntrlsScript && ReqMode == CCam::MODE_1STPERSON) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 04d7a8a2..2b458828 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -60,14 +60,6 @@ CRGBA INACTIVE_RADIO_COLOR(100, 100, 255, 100); #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result -#ifdef USE_PRECISE_MEASUREMENT_CONVERTION -#define MILES_IN_METER 0.000621371192f -#define FEET_IN_METER 3.28084f -#else -#define MILES_IN_METER 0.00059880241f -#define FEET_IN_METER 3.33f -#endif - #ifdef MAP_ENHANCEMENTS CVector2D mapCrosshair; #endif @@ -87,11 +79,6 @@ CVector2D mapCrosshair; bool CMenuManager::m_PrefsCutsceneBorders = true; #endif -const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); // TODO(Miami): is this still here? - -float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE; -float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE; - bool holdingScrollBar; // *(bool*)0x7039B9; // not original name CMenuManager FrontEndMenuManager; @@ -158,27 +145,43 @@ bool CMenuManager::m_bSaveWasSuccessful = false; wchar* CMenuManager::m_pDialogText = nil; #endif -#define PREPARE_MENU_HEADER \ +#define SET_FONT_FOR_MENU_HEADER \ CFont::SetRightJustifyOn(); \ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); \ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ CFont::SetDropShadowPosition(0); -#define ProcessSlider(value, y, increaseAction, decreaseAction, hoverStartX, hoverEndX) \ +#define RESET_FONT_FOR_NEW_PAGE \ + CFont::SetBackgroundOff(); \ + CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); \ + CFont::SetPropOn(); \ + CFont::SetCentreOff(); \ + CFont::SetJustifyOn(); \ + CFont::SetRightJustifyOff(); \ + CFont::SetBackGroundOnlyTextOn(); \ + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); \ + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + +#define ProcessSlider(value, y, increaseAction, decreaseAction, hoverEndX, onlyWhenHoveringRow) \ do { \ lastActiveBarX = DisplaySlider(MENU_X_LEFT_ALIGNED(MENUSLIDER_X), MENU_Y(y), MENU_Y(MENUSLIDER_SMALLEST_BAR), MENU_Y(MENUSLIDER_BIGGEST_BAR), MENU_X(MENUSLIDER_UNK), value, MENU_X(3.0f)); \ if (i != m_nCurrOption || !itemsAreSelectable) \ break; \ \ - if (CheckHover(hoverStartX, lastActiveBarX - MENU_X(3.0f), MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \ + if (CheckHover(0, lastActiveBarX - MENU_X(3.0f), MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) { \ m_nHoverOption = decreaseAction; \ - \ - if (!CheckHover(MENU_X(3.0f) + lastActiveBarX, hoverEndX, MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \ break; \ - \ + } \ + if (!CheckHover(MENU_X(3.0f) + lastActiveBarX, hoverEndX, MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) { \ + m_nHoverOption = HOVEROPTION_NOT_HOVERING; \ + break; \ + } \ m_nHoverOption = increaseAction; \ if (m_nMousePosX < MENU_X_LEFT_ALIGNED(MENUSLIDER_X)) \ m_nHoverOption = HOVEROPTION_NOT_HOVERING; \ + \ + if (onlyWhenHoveringRow && (m_nMousePosY < MENU_Y(y) || m_nMousePosY > MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \ + m_nHoverOption = HOVEROPTION_NOT_HOVERING; \ } while(0) // --- Functions not in the game/inlined starts @@ -275,7 +278,7 @@ CMenuManager::ThingsToDoBeforeLeavingPage() } } -int8 +inline int8 CMenuManager::GetPreviousPageOption() { return (!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry : @@ -410,7 +413,7 @@ CMenuManager::Initialise(void) DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); DoRWStuffEndOfFrame(); m_AllowNavigation = false; - m_menuTransitionProgress = -50; // to start from black + m_firstStartCounter = -50; // to start from black m_nMenuFadeAlpha = 0; m_nCurrOption = 0; m_nOptionHighlightTransitionBlend = 0; @@ -442,37 +445,6 @@ CMenuManager::Initialise(void) } void -CMenuManager::BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2) -{ - if (!text) - return; - -#ifdef MORE_LANGUAGES - if (CFont::IsJapanese() && stat2) - if (itsFloat) - sprintf(gString2, " %.2f/%.2f", *(float*)stat, *(float*)stat2); - else - sprintf(gString2, " %d/%d", *(int*)stat, *(int*)stat2); - else -#endif - if (stat2) { - if (itsFloat) - sprintf(gString2, " %.2f %s %.2f", *(float*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(float*)stat2); - else - sprintf(gString2, " %d %s %d", *(int*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(int*)stat2); - } else if (stat) { - if (itsFloat) - sprintf(gString2, " %.2f", *(float*)stat); - else - sprintf(gString2, " %d", *(int*)stat); - } else - gString2[0] = '\0'; - - UnicodeStrcpy(gUString, TheText.Get(text)); - AsciiToUnicode(gString2, gUString2); -} - -void CMenuManager::CentreMousePointer() { if (SCREEN_WIDTH * 0.5f != 0.0f && 0.0f != SCREEN_HEIGHT * 0.5f) { @@ -759,6 +731,7 @@ CMenuManager::DoSettingsBeforeStartingAGame() DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); } +// --MIAMI: Done void CMenuManager::DrawStandardMenus(bool activeScreen) { @@ -772,7 +745,11 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); +#ifdef ASPECT_RATIO_SCALE CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)); +#else + CFont::SetCentreSize(SCREEN_WIDTH); +#endif switch (m_nCurrScreen) { case MENUPAGE_CHOOSE_LOAD_SLOT: @@ -797,7 +774,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) // Page name if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') { - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); @@ -1168,9 +1145,11 @@ CMenuManager::DrawStandardMenus(bool activeScreen) if (CFont::Details.centre) { leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth / 2.f); rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth / 2.f + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X); + } else if (!CFont::Details.rightJustify) { leftXMax = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X; rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X); + } else { leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth); rightXMin = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X; @@ -1189,13 +1168,12 @@ CMenuManager::DrawStandardMenus(bool activeScreen) int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y; int topYMax = y; uint32 bottomYMin = y + 22; - int transition = m_nOptionHighlightTransitionBlend; // Actually bottomRight and bottomLeft should be exchanged here(although this is original code). // So this shows us either R* didn't use same struct for menu BG and highlight, or they just kept fields as x1,y1 etc. Yikes. - if (transition == 0) { - if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { + if (m_nOptionHighlightTransitionBlend == 0) { + if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(menuOptionHighlight.topLeft_x), MENU_Y(menuOptionHighlight.topLeft_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.topRight_x), MENU_Y(menuOptionHighlight.topRight_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomRight_x), MENU_Y(menuOptionHighlight.bottomRight_y), @@ -1212,9 +1190,10 @@ CMenuManager::DrawStandardMenus(bool activeScreen) menuOptionHighlight.bottomRight_y = bottomYMin + CGeneral::GetRandomNumber() % 7; menuOptionHighlight.UpdateMultipliers(); menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend); - } else if (transition < 255) { + + } else if (m_nOptionHighlightTransitionBlend < 255) { menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend); - if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { + if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(menuOptionHighlight.topLeft_x), MENU_Y(menuOptionHighlight.topLeft_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.topRight_x), MENU_Y(menuOptionHighlight.topRight_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomRight_x), MENU_Y(menuOptionHighlight.bottomRight_y), @@ -1223,7 +1202,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } else { m_nOptionHighlightTransitionBlend = 255; menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend); - if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { + if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(menuOptionHighlight.topLeft_x), MENU_Y(menuOptionHighlight.topLeft_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.topRight_x), MENU_Y(menuOptionHighlight.topRight_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomRight_x), MENU_Y(menuOptionHighlight.bottomRight_y), @@ -1247,8 +1226,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } } - if (section != 0) { - + if (section == 1) { if (leftText) { CFont::PrintString(MENU_X_LEFT_ALIGNED(aScreens[m_nCurrScreen].m_aEntries[i].m_X), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y), leftText); } @@ -1306,27 +1284,30 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } #endif - // TODO(Miami): check // Sliders int lastActiveBarX; switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { - case MENUACTION_BRIGHTNESS: - ProcessSlider(m_PrefsBrightness / 384.0f, 70.0f, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_DRAWDIST: - ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, 99.0f, HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_MUSICVOLUME: - if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) - ProcessSlider(m_PrefsMusicVolume / 64.0f, 70.0f, HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_SFXVOLUME: - if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) - ProcessSlider(m_PrefsSfxVolume / 64.0f, 99.0f, HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_MOUSESENS: - ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, 170.0f, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, MENU_X_LEFT_ALIGNED(200.0f), SCREEN_WIDTH); - break; + case MENUACTION_BRIGHTNESS: + ProcessSlider(m_PrefsBrightness / 384.0f, 70.0f, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, SCREEN_WIDTH, true); + break; + case MENUACTION_DRAWDIST: + ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, 99.0f, HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, SCREEN_WIDTH, true); + break; + case MENUACTION_MUSICVOLUME: + if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) + ProcessSlider(m_PrefsMusicVolume / 64.0f, 70.0f, HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, SCREEN_WIDTH, true); + break; + case MENUACTION_SFXVOLUME: + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) + ProcessSlider(m_PrefsSfxVolume / 64.0f, 99.0f, HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, SCREEN_WIDTH, true); + break; + case MENUACTION_MOUSESENS: + ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, 170.0f, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, SCREEN_WIDTH, false); + break; + case MENUACTION_MP3VOLUMEBOOST: + if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER && DMAudio.IsMP3RadioChannelAvailable()) + ProcessSlider(m_PrefsMP3BoostVolume / 64.f, 128.0f, HOVEROPTION_INCREASE_MP3BOOST, HOVEROPTION_DECREASE_MP3BOOST, SCREEN_WIDTH, true); + break; } // Not just unused, but also collides with the bug fix in Font.cpp. Yikes. @@ -1395,12 +1376,14 @@ CMenuManager::GetNumOptionsCntrlConfigScreens(void) return number; } +// --MIAMI: Done void CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 column) { int controllerAction = PED_FIREWEAPON; // GetStartOptionsCntrlConfigScreens(); int numOptions = GetNumOptionsCntrlConfigScreens(); + int nextY = MENU_Y(yStart); int bindingMargin = MENU_X(3.0f); float rowHeight; switch (m_ControlMethod) { @@ -1414,11 +1397,11 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 break; } - // MENU_Y(rowHeight * 0.0f + yStart); - for (int optionIdx = 0, nextY = MENU_Y(yStart); optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) { + for (int optionIdx = 0; optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) { int nextX = xStart; int bindingsForThisOpt = 0; - CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255))); + int contSetOrder = SETORDER_1; + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); if (column == CONTSETUP_PED_COLUMN) { switch (optionIdx) { @@ -1456,10 +1439,10 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 case 11: case 12: case 16: - case 18: - case 19: case 20: case 21: + case 22: + case 23: controllerAction = -1; break; case 13: @@ -1474,34 +1457,40 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 case 17: controllerAction = PED_LOCK_TARGET; break; - case 22: + case 18: + controllerAction = PED_DUCK; + break; + case 19: + controllerAction = PED_ANSWER_PHONE; + break; + case 24: controllerAction = PED_LOOKBEHIND; break; - case 23: + case 25: if (m_ControlMethod == CONTROL_STANDARD) controllerAction = -1; else controllerAction = PED_1RST_PERSON_LOOK_LEFT; break; - case 24: + case 26: if (m_ControlMethod == CONTROL_STANDARD) controllerAction = -1; else controllerAction = PED_1RST_PERSON_LOOK_RIGHT; break; - case 25: + case 27: controllerAction = PED_1RST_PERSON_LOOK_UP; break; - case 26: + case 28: controllerAction = PED_1RST_PERSON_LOOK_DOWN; break; - case 27: + case 29: controllerAction = PED_CYCLE_TARGET_LEFT; break; - case 28: + case 30: controllerAction = PED_CYCLE_TARGET_RIGHT; break; - case 29: + case 31: controllerAction = PED_CENTER_CAMERA_BEHIND_PLAYER; break; default: @@ -1523,11 +1512,13 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 case 14: case 15: case 17: - case 25: - case 26: + case 18: + case 19: case 27: case 28: case 29: + case 30: + case 31: controllerAction = -1; break; case 3: @@ -1560,32 +1551,31 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 case 16: controllerAction = VEHICLE_HANDBRAKE; break; - case 18: + case 20: controllerAction = VEHICLE_TURRETLEFT; break; - case 19: + case 21: controllerAction = VEHICLE_TURRETRIGHT; break; - case 20: + case 22: controllerAction = VEHICLE_TURRETUP; break; - case 21: + case 23: controllerAction = VEHICLE_TURRETDOWN; break; - case 22: + case 24: controllerAction = -2; break; - case 23: + case 25: controllerAction = VEHICLE_LOOKLEFT; break; - case 24: + case 26: controllerAction = VEHICLE_LOOKRIGHT; break; default: break; } } - int bindingWhite = 155; // Highlight selected column(and make its text black) if (m_nSelectedListRow == optionIdx) { @@ -1594,58 +1584,38 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 if (column == CONTSETUP_PED_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_PED_COLUMN) { #ifdef FIX_BUGS - if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); - } else { - CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); - } + CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); #else - if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), - MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); - } else { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), - MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); - } + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), + MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), + CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); #endif - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); - bindingWhite = 0; + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); } else if (column == CONTSETUP_VEHICLE_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_VEHICLE_COLUMN) { #ifdef FIX_BUGS - if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); - } else { - CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); - } + CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); #else - if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(235, 170, 50, FadeIn(150))); - } else { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(255, 217, 106, FadeIn(210))); - } + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), + CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); #endif - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); - bindingWhite = 0; + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); } } } // Print bindings, including seperator (-) between them CFont::SetScale(MENU_X(0.25f), MENU_Y(0.6f)); - for (int contSetOrder = SETORDER_1; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { + for (; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { wchar *settingText = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)controllerAction, (eContSetOrder)contSetOrder); if (settingText) { ++bindingsForThisOpt; if (bindingsForThisOpt > 1) { wchar *seperator = TheText.Get("FEC_IBT"); - CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80))); + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); CFont::PrintString(nextX, nextY, seperator); - CFont::SetColor(CRGBA(bindingWhite, bindingWhite, bindingWhite, FadeIn(255))); nextX += CFont::GetStringWidth(seperator, true) + bindingMargin; } CFont::PrintString(nextX, nextY, settingText); @@ -1658,23 +1628,27 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 } } if (controllerAction == -1) { - CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_NUS")); // not used + } else if (controllerAction == -2) { - CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_CMP")); // combo: l+r + } else if (bindingsForThisOpt == 0) { + m_NoEmptyBinding = false; if (m_nSelectedListRow != optionIdx) { - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound + } else if (m_bWaitingForNewKeyBind) { if (column != m_nSelectedContSetupColumn) { - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound } } else { if (column != m_nSelectedContSetupColumn) { - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); } CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound } @@ -1698,44 +1672,32 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 lastWaitingTextFlash = CTimer::GetTimeInMillisecondsPauseMode(); } if (showWaitingText) { - CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255))); + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_QUE")); // "???" } - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); - if (m_bKeyChangeNotProcessed) { - CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE - } else { - CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_RIG")); // SELECT A NEW CONTROL FOR THIS ACTION OR ESC TO CANCEL - } - + if (m_bKeyChangeNotProcessed) + DisplayHelperText("FET_CIG"); + else + DisplayHelperText("FET_RIG"); + CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); + CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); m_bKeyIsOK = true; } else { - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); - CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE + DisplayHelperText("FET_CIG"); CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); + CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + m_bKeyIsOK = false; m_bKeyChangeNotProcessed = false; } } else if (optionIdx == m_nSelectedListRow) { - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255))); - CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_EIG")); // CANNOT SET A CONTROL FOR THIS ACTION + DisplayHelperText("FET_EIG"); CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); + CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); } } @@ -1799,6 +1761,7 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig } } +// --MIAMI: Done void CMenuManager::DrawControllerSetupScreen() { @@ -1813,39 +1776,25 @@ CMenuManager::DrawControllerSetupScreen() default: break; } - CFont::SetBackgroundOff(); - CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); - PREPARE_MENU_HEADER + RESET_FONT_FOR_NEW_PAGE + SET_FONT_FOR_MENU_HEADER - switch (m_ControlMethod) { - case CONTROL_STANDARD: - CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), - TheText.Get("FET_STI")); + // Shadow + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); - CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), - TheText.Get("FET_STI")); - break; - case CONTROL_CLASSIC: - CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), - TheText.Get("FET_CTI")); + if (m_ControlMethod == CONTROL_STANDARD) + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_STI")); + else if (m_ControlMethod == CONTROL_CLASSIC) + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_CTI")); + + // Real header + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); + + if (m_ControlMethod == CONTROL_STANDARD) + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_STI")); + else if (m_ControlMethod == CONTROL_CLASSIC) + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_CTI")); - CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), - TheText.Get("FET_CTI")); - break; - default: - break; - } wchar *actionTexts[33]; actionTexts[0] = TheText.Get("FEC_FIR"); actionTexts[1] = TheText.Get("FEC_NWE"); @@ -1892,43 +1841,46 @@ CMenuManager::DrawControllerSetupScreen() actionTexts[27] = nil; } - // Gray panel background + // Blue panel background CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT), MENU_Y(CONTSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(CONTSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM)), - CRGBA(200, 200, 50, FadeIn(50))); + CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); if (m_nCurrExLayer == HOVEROPTION_LIST) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); else - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); // List header CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); CFont::SetRightJustifyOff(); - CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CAC")); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CFT")); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CCR")); + CFont::SetDropShadowPosition(0); CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X_LEFT_ALIGNED(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); + CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + int yStart; if (m_ControlMethod == CONTROL_CLASSIC) - yStart = CONTSETUP_LIST_HEADER_HEIGHT + 29; + yStart = CONTSETUP_LIST_TOP + 18; else - yStart = CONTSETUP_LIST_HEADER_HEIGHT + 34; + yStart = CONTSETUP_LIST_TOP + 21; + float optionYBottom = yStart + rowHeight; for (int i = 0; i < ARRAY_SIZE(actionTexts); ++i) { wchar *actionText = actionTexts[i]; if (!actionText) break; if (!m_bWaitingForNewKeyBind) { - if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) && + if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT - 10.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)) { - float curOptY = i * rowHeight + yStart; - if (m_nMousePosY > MENU_Y(curOptY) && m_nMousePosY < MENU_Y(rowHeight + curOptY)) { + if (m_nMousePosY > MENU_Y(i * rowHeight + yStart) && m_nMousePosY < MENU_Y(i * rowHeight + optionYBottom)) { m_nOptionMouseHovering = i; if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) { m_nCurrExLayer = HOVEROPTION_LIST; @@ -1968,10 +1920,10 @@ CMenuManager::DrawControllerSetupScreen() CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); CFont::SetRightJustifyOff(); - if (m_PrefsLanguage != LANGUAGE_GERMAN || i != 20 && i != 21) - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); + if (m_PrefsLanguage == LANGUAGE_GERMAN && (i == 20 || i == 21 || i == 22 || i == 23)) + CFont::SetScale(MENU_X(0.32f), MENU_Y(0.6f)); else - CFont::SetScale(MENU_X(0.32f), MENU_Y(SMALLESTTEXT_Y_SCALE)); + CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(i * rowHeight + yStart), actionText); } @@ -1979,15 +1931,15 @@ CMenuManager::DrawControllerSetupScreen() DrawControllerBound(yStart, MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), rowHeight, CONTSETUP_VEHICLE_COLUMN); if (!m_bWaitingForNewKeyBind) { - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y)); + CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); if ((m_nMousePosX > MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) - CFont::GetStringWidth(TheText.Get("FEDS_TB"), true) && m_nMousePosX < MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) && m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - CONTSETUP_BACK_HEIGHT)) || m_nCurrExLayer == HOVEROPTION_BACK) { m_nHoverOption = HOVEROPTION_BACK; - } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH) - && m_nMousePosY > MENU_Y(CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM + 5.0f)) { + } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT - 10.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH) + && m_nMousePosY > MENU_Y(CONTSETUP_LIST_TOP - 10.0f) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM)) { m_nHoverOption = HOVEROPTION_LIST; } else { @@ -1997,20 +1949,16 @@ CMenuManager::DrawControllerSetupScreen() // Back button and it's shadow CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y)); + CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); CFont::SetRightJustifyOn(); - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90))); - for (int i = 0; i < 2; i++) { - CFont::PrintString(MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT - 2.0f - i), - SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f - i), TheText.Get("FEDS_TB")); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); - if (m_nHoverOption == HOVEROPTION_BACK) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); - else - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); - } + CFont::PrintString(MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT - 2.0f), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f), TheText.Get("FEDS_TB")); } +// --MIAMI: Done void CMenuManager::DrawFrontEnd() { @@ -2031,13 +1979,13 @@ CMenuManager::DrawFrontEnd() if (m_nCurrOption == 0 && aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL) m_nCurrOption = 1; - if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255) + if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255) bMenuChangeOngoing = false; DrawBackground(false); } -// --MIAMI: Done except commented things +// --MIAMI: Done void CMenuManager::DrawBackground(bool transitionCall) { @@ -2046,7 +1994,7 @@ CMenuManager::DrawBackground(bool transitionCall) SetFrontEndRenderStates(); - if (m_menuTransitionProgress < 255) { + if (m_firstStartCounter < 255) { CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255)); } @@ -2077,7 +2025,7 @@ CMenuManager::DrawBackground(bool transitionCall) SCREEN_WIDTH, 0.0f, SCREEN_STRETCH_X(menuBg.topRight_x), SCREEN_STRETCH_Y(menuBg.topRight_y), CRGBA(0, 0, 0, 255)); } else { m_nMenuFadeAlpha = 255; - m_menuTransitionProgress = 255; + m_firstStartCounter = 255; m_aFrontEndSprites[MENUSPRITE_BACKGROUND].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, FadeIn(255))); if (m_nCurrScreen == MENUPAGE_MAP) PrintMap(); @@ -2161,30 +2109,30 @@ CMenuManager::DrawBackground(bool transitionCall) } menuBg.UpdateMultipliers(); - if (m_menuTransitionProgress == 255) + if (m_firstStartCounter == 255) m_nOptionHighlightTransitionBlend = 0; } static PauseModeTime LastFade = 0; - static uint8 forceFadeInCounter = 0; - if (m_nMenuFadeAlpha >= 255) { - if (m_nMenuFadeAlpha > 255) - m_nMenuFadeAlpha = 255; - } else { + if (m_nMenuFadeAlpha < 255) { + static uint8 forceFadeInCounter = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 30 #ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND // Dirty dirty hack || forceFadeInCounter > 30 #endif ) { m_nMenuFadeAlpha += 20; - m_menuTransitionProgress = Min(m_menuTransitionProgress + 20, 255); + if (m_firstStartCounter < 255) { + m_firstStartCounter = Min(m_firstStartCounter + 20, 255); + } LastFade = CTimer::GetTimeInMillisecondsPauseMode(); } forceFadeInCounter++; - } + } else if (m_nMenuFadeAlpha > 255) + m_nMenuFadeAlpha = 255; - if (!transitionCall && m_menuTransitionProgress == 255) { + if (!transitionCall && m_firstStartCounter == 255) { int actualAlpha = m_nMenuFadeAlpha; if (actualAlpha < 255) { int actualScreen = m_nCurrScreen; @@ -2218,7 +2166,7 @@ CMenuManager::DrawBackground(bool transitionCall) DrawControllerSetupScreen(); break; case MENUPAGE_OUTRO: - CMenuManager::DrawQuitGameScreen(); + DrawQuitGameScreen(); break; default: DrawStandardMenus(true); @@ -2229,7 +2177,7 @@ CMenuManager::DrawBackground(bool transitionCall) SetFrontEndRenderStates(); if (m_nCurrScreen != MENUPAGE_OUTRO) - if (m_menuTransitionProgress == 255) { + if (m_firstStartCounter == 255) { m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255)); } else { m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255))); @@ -2251,8 +2199,8 @@ CMenuManager::DrawBackground(bool transitionCall) } if (m_bShowMouse) { - CRect mouse(0.0f, 0.0f, MENU_X(40.0f), MENU_Y(40.0f)); - CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(55.0f), MENU_Y(43.0f)); + CRect mouse(0.0f, 0.0f, MENU_X(35.0f), MENU_Y(35.0f)); + CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(45.0f), MENU_Y(38.0f)); mouse.Translate(m_nMousePosX, m_nMousePosY); shad.Translate(m_nMousePosX, m_nMousePosY); @@ -2265,15 +2213,7 @@ CMenuManager::DrawBackground(bool transitionCall) void CMenuManager::DrawPlayerSetupScreen(bool activeScreen) { - CFont::SetBackgroundOff(); - CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + RESET_FONT_FOR_NEW_PAGE // lstrcpy's changed with strcpy if (!m_bSkinsEnumerated) { @@ -2360,7 +2300,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_PS")); @@ -2668,24 +2608,6 @@ CMenuManager::FadeIn(int alpha) return Min(m_nMenuFadeAlpha, alpha); } -void -CMenuManager::FilterOutColorMarkersFromString(wchar *str) -{ - int newIdx = 0; - wchar copy[256], *c; - UnicodeStrcpy(copy, str); - - for (c = copy; *c != '\0'; c++) { - if (*c == '~') { - c++; - while (*c != '~') c++; - } else { - str[newIdx++] = *c; - } - } - str[newIdx] = '\0'; -} - // --MIAMI: Done int CMenuManager::GetStartOptionsCntrlConfigScreens() @@ -3077,7 +2999,7 @@ CMenuManager::SmallMessageScreen(const char* text) CFont::PrintString(SCREEN_WIDTH / 2.f, y, TheText.Get(text)); } -// --MIAMI: Done, but FilterOutColorMarkersFromString is actually in CFont +// --MIAMI: Done void CMenuManager::PrintBriefs() { @@ -3101,7 +3023,7 @@ CMenuManager::PrintBriefs() brief.m_nNumber[4], brief.m_nNumber[5], gUString); CMessages::InsertStringInString(gUString, brief.m_pString); CMessages::InsertPlayerControlKeysInString(gUString); - FilterOutColorMarkersFromString(gUString); + CFont::FilterOutTokensFromString(gUString); nextY -= CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), nextY, gUString) * BRIEFS_LINE_HEIGHT + BRIEFS_LINE_SPACING; CFont::PrintString(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), MENU_Y(nextY), gUString); @@ -3116,7 +3038,7 @@ CMenuManager::PrintStats() static uint8 pirateCheck = 0; static float scrollY = 0; - int rowNum = ConstructStatLine(99999); + int rowNum = CStats::ConstructStatLine(99999); CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(142.0f), MENU_X_LEFT_ALIGNED(543.0f), MENU_Y(142.f), MENU_X_LEFT_ALIGNED(107.0f), MENU_Y(316.f), @@ -3170,7 +3092,7 @@ CMenuManager::PrintStats() // If it's still on screen if (y > MENU_Y(STATS_VISIBLE_START_Y) && y < MENU_Y(STATS_VISIBLE_END_Y)) { - ConstructStatLine(row); + CStats::ConstructStatLine(row); // But about to dim from bottom if (y < MENU_Y(STATS_BOTTOM_Y)) { @@ -3482,7 +3404,6 @@ CMenuManager::AdditionalOptionInput(bool &goBack) } } -// TODO(Miami): FrontEndMenuManager.ConstructStatLine -> CStats::ConstructStatLine // Not original name void CMenuManager::ExportStats() @@ -3494,7 +3415,7 @@ CMenuManager::ExportStats() FILE *txtFile = fopen("stats.txt", "w"); if (txtFile) { - int statLines = FrontEndMenuManager.ConstructStatLine(99999); + int statLines = CStats::ConstructStatLine(99999); fprintf(txtFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"); fprintf(txtFile, "\t\t\tGTA VICE CITY %s\n", UnicodeToAscii(TheText.Get("FEH_STA"))); fprintf(txtFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n\n"); @@ -3506,7 +3427,7 @@ CMenuManager::ExportStats() UnicodeStrcpy(gUString, CStats::FindCriminalRatingString()); fprintf(txtFile, "%s (%d)\n\n\n", UnicodeToAscii(gUString), CStats::FindCriminalRatingNumber()); for (int i = 0; i < statLines; ++i) { - FrontEndMenuManager.ConstructStatLine(i); + CStats::ConstructStatLine(i); char *statKey = UnicodeToAscii(gUString); if (statKey[0] != '\0') fprintf(txtFile, "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n%s\n", statKey); @@ -3514,7 +3435,7 @@ CMenuManager::ExportStats() char *statValue = UnicodeToAscii(gUString2); for (int j = 0; statValue[j] != '\0'; ++j) { if (statValue[j] == '_') - statValue[j] = 'º'; + statValue[j] = 0xBA; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation } if (statValue) fprintf(txtFile, "%s\n\n", statValue); @@ -3524,7 +3445,7 @@ CMenuManager::ExportStats() fclose(txtFile); FILE *htmlFile = fopen("stats.html", "w"); if (htmlFile) { - int statLines = FrontEndMenuManager.ConstructStatLine(99999); + int statLines = CStats::ConstructStatLine(99999); fprintf(htmlFile, "<title>Grand Theft Auto Vice City Stats</title>\n"); fprintf(htmlFile, "<body bgcolor=\"#FF00CC\" leftmargin=\"10\" topmargin=\"10\" marginwidth=\"10\" marginheight=\"10\">\n"); fprintf(htmlFile, "<table width=\"560\" align=\"center\" border=\"0\" cellpadding=\"5\" cellspacing=\"0\">\n"); @@ -3556,7 +3477,7 @@ CMenuManager::ExportStats() "2\"></td> </tr>\n", statKey, rating); for (int k = 0; k < statLines; ++k) { - FrontEndMenuManager.ConstructStatLine(k); + CStats::ConstructStatLine(k); statKey = UnicodeToAscii(gUString); if (statKey[0] != '\0') fprintf(htmlFile, "</font></strong></div></td> </tr> <tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> <td height=\"10" @@ -3576,7 +3497,7 @@ CMenuManager::ExportStats() char *statValue = UnicodeToAscii(gUString2); for (int l = 0; statValue[l] != '\0'; ++l) { if (statValue[l] == '_') - statValue[l] = 'º'; + statValue[l] = 0xBA; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation } if (statValue) fprintf(htmlFile, "%s", statValue); @@ -3704,15 +3625,6 @@ CMenuManager::PrintRadioSelector(void) m_aFrontEndSprites[second + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); - // Middle one(third) is colored differently whether on transition or not. - if (m_ScrollRadioBy != 0) { - m_aFrontEndSprites[third + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), - CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); - } else { - m_aFrontEndSprites[third + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2 - 10.f), MENU_Y(MENURADIO_ICON_Y - 10.f), MENU_X(MENURADIO_ICON_SIZE) + MENU_X(20.f), MENU_Y(MENURADIO_ICON_SIZE) + MENU_Y(20.f), - CRGBA(255, 255, 255, FadeIn(255))); - } - // Fourth m_aFrontEndSprites[fourth + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); @@ -3722,6 +3634,16 @@ CMenuManager::PrintRadioSelector(void) m_aFrontEndSprites[fifth + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); } + + // Middle one(third) is colored differently depending on if it's in transition. + // If not in transition then this icon indicates selected radio, and should be on top of all icons. thus drawn last + if (m_ScrollRadioBy != 0) { + m_aFrontEndSprites[third + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else { + m_aFrontEndSprites[third + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2 - 10.f), MENU_Y(MENURADIO_ICON_Y - 10.f), MENU_X(MENURADIO_ICON_SIZE) + MENU_X(20.f), MENU_Y(MENURADIO_ICON_SIZE) + MENU_Y(20.f), + CRGBA(255, 255, 255, FadeIn(255))); + } #endif static bool radioChangeRequested = false; @@ -3787,7 +3709,8 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack) m_nTotalListRow = m_nSkinsTotal; } if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { - m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25; + // GetNumOptionsCntrlConfigScreens would have been a better choice + m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 32 : 27; if (m_nSelectedListRow > m_nTotalListRow) m_nSelectedListRow = m_nTotalListRow - 1; } @@ -4015,7 +3938,7 @@ CMenuManager::UserInput(void) bool goDown = false; int8 changeValueBy; - if (!m_AllowNavigation && m_menuTransitionProgress == 255) + if (!m_AllowNavigation && m_firstStartCounter == 255) m_AllowNavigation = true; if (!m_bShowMouse && m_nCurrScreen != MENUPAGE_MAP && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) { m_bShowMouse = true; @@ -5434,162 +5357,6 @@ CMenuManager::PrintMap(void) DisplayHelperText("FEH_MPH"); } -// rowIdx 99999 returns total numbers of rows. otherwise it returns 0. -int -CMenuManager::ConstructStatLine(int rowIdx) -{ -#define STAT_LINE(str, left, isFloat, right) \ - do { \ - if(counter == rowIdx){ \ - BuildStatLine(str, left, isFloat, right); \ - return 0; \ - } counter++; \ - } while(0) - - int counter = 0, nTemp; - - STAT_LINE("PL_STAT", nil, false, nil); - - int percentCompleted = CStats::GetPercentageProgress(); - - STAT_LINE("PER_COM", &percentCompleted, false, nil); - STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil); - STAT_LINE("FEST_MP", &CStats::MissionsPassed, false, &CStats::TotalNumberMissions); - if (CGame::nastyGame) { - STAT_LINE("FEST_RP", &CStats::NumberKillFrenziesPassed, false, &CStats::TotalNumberKillFrenzies); - } - - CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus]; - float packagesPercent = 0.0f; - if (player.m_nTotalPackages != 0) - packagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages; - - int nPackagesPercent = packagesPercent; - STAT_LINE("PERPIC", &nPackagesPercent, false, &(nTemp = 100)); - STAT_LINE("NOUNIF", &CStats::NumberOfUniqueJumpsFound, false, &CStats::TotalNumberOfUniqueJumps); - STAT_LINE("DAYSPS", &CStats::DaysPassed, false, nil); - if (CGame::nastyGame) { - STAT_LINE("PE_WAST", &CStats::PeopleKilledByPlayer, false, nil); - STAT_LINE("PE_WSOT", &CStats::PeopleKilledByOthers, false, nil); - } - STAT_LINE("CAR_EXP", &CStats::CarsExploded, false, nil); - STAT_LINE("TM_BUST", &CStats::TimesArrested, false, nil); - STAT_LINE("TM_DED", &CStats::TimesDied, false, nil); - STAT_LINE("GNG_WST", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_GANG9] + CStats::PedsKilledOfThisType[PEDTYPE_GANG8] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG7] + CStats::PedsKilledOfThisType[PEDTYPE_GANG6] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG5] + CStats::PedsKilledOfThisType[PEDTYPE_GANG4] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG3] + CStats::PedsKilledOfThisType[PEDTYPE_GANG2] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG1]), false, nil); - STAT_LINE("DED_CRI", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]), false, nil); - STAT_LINE("HEL_DST", &CStats::HelisDestroyed, false, nil); - STAT_LINE("KGS_EXP", &CStats::KgsOfExplosivesUsed, false, nil); - - if (CStats::HighestScores[0] > 0) { - STAT_LINE("FEST_BB", nil, false, nil); - STAT_LINE("FEST_H0", &CStats::HighestScores[0], false, nil); - } - if (CStats::HighestScores[4] + CStats::HighestScores[3] + CStats::HighestScores[2] + CStats::HighestScores[1] > 0) { - STAT_LINE("FEST_GC", nil, false, nil); - } - if (CStats::HighestScores[1] > 0) { - STAT_LINE("FEST_H1", &CStats::HighestScores[1], false, nil); - } - if (CStats::HighestScores[2] > 0) { - STAT_LINE("FEST_H2", &CStats::HighestScores[2], false, nil); - } - if (CStats::HighestScores[3] > 0) { - STAT_LINE("FEST_H3", &CStats::HighestScores[3], false, nil); - } - if (CStats::HighestScores[4] > 0) { - STAT_LINE("FEST_H4", &CStats::HighestScores[4], false, nil); - } - - switch (m_PrefsLanguage) { - case LANGUAGE_AMERICAN: -#ifndef USE_MEASUREMENTS_IN_METERS - float fTemp; - STAT_LINE("FEST_DF", &(fTemp = CStats::DistanceTravelledOnFoot * MILES_IN_METER), true, nil); - STAT_LINE("FEST_DC", &(fTemp = CStats::DistanceTravelledByCar * MILES_IN_METER), true, nil); - STAT_LINE("DISTBIK", &(fTemp = CStats::DistanceTravelledByBike * MILES_IN_METER), true, nil); - STAT_LINE("DISTBOA", &(fTemp = CStats::DistanceTravelledByBoat * MILES_IN_METER), true, nil); - STAT_LINE("DISTGOL", &(fTemp = CStats::DistanceTravelledByGolfCart * MILES_IN_METER), true, nil); - STAT_LINE("DISTHEL", &(fTemp = CStats::DistanceTravelledByHelicoptor * MILES_IN_METER), true, nil); - STAT_LINE("MXCARD", &(fTemp = CStats::MaximumJumpDistance * FEET_IN_METER), true, nil); - STAT_LINE("MXCARJ", &(fTemp = CStats::MaximumJumpHeight * FEET_IN_METER), true, nil); - break; -#endif - case LANGUAGE_FRENCH: - case LANGUAGE_GERMAN: - case LANGUAGE_ITALIAN: - case LANGUAGE_SPANISH: -#ifdef MORE_LANGUAGES - case LANGUAGE_POLISH: - case LANGUAGE_RUSSIAN: - case LANGUAGE_JAPANESE: -#endif - STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, true, nil); - STAT_LINE("FESTDCM", &CStats::DistanceTravelledByCar, true, nil); - STAT_LINE("DISTBIM", &CStats::DistanceTravelledByBike, true, nil); - STAT_LINE("DISTBOM", &CStats::DistanceTravelledByBoat, true, nil); - STAT_LINE("DISTGOM", &CStats::DistanceTravelledByGolfCart, true, nil); - STAT_LINE("DISTHEM", &CStats::DistanceTravelledByHelicoptor, true, nil); - STAT_LINE("MXCARDM", &CStats::MaximumJumpDistance, true, nil); - STAT_LINE("MXCARJM", &CStats::MaximumJumpHeight, true, nil); - break; - default: - break; - } - - STAT_LINE("MXFLIP", &CStats::MaximumJumpFlips, false, nil); - STAT_LINE("MXJUMP", &CStats::MaximumJumpSpins, false, nil); - STAT_LINE("BSTSTU", nil, false, nil); - - if (counter == rowIdx) { - gUString[0] = '\0'; - switch (CStats::BestStuntJump) { - case 1: - UnicodeStrcpy(gUString2, TheText.Get("INSTUN")); - return 0; - case 2: - UnicodeStrcpy(gUString2, TheText.Get("PRINST")); - return 0; - case 3: - UnicodeStrcpy(gUString2, TheText.Get("DBINST")); - return 0; - case 4: - UnicodeStrcpy(gUString2, TheText.Get("DBPINS")); - return 0; - case 5: - UnicodeStrcpy(gUString2, TheText.Get("TRINST")); - return 0; - case 6: - UnicodeStrcpy(gUString2, TheText.Get("PRTRST")); - return 0; - case 7: - UnicodeStrcpy(gUString2, TheText.Get("QUINST")); - return 0; - case 8: - UnicodeStrcpy(gUString2, TheText.Get("PQUINS")); - return 0; - default: - UnicodeStrcpy(gUString2, TheText.Get("NOSTUC")); - return 0; - } - } - counter++; - STAT_LINE("PASDRO", &CStats::PassengersDroppedOffWithTaxi, false, nil); - STAT_LINE("MONTAX", &CStats::MoneyMadeWithTaxi, false, nil); - STAT_LINE("FEST_LS", &CStats::LivesSavedWithAmbulance, false, nil); - STAT_LINE("FEST_HA", &CStats::HighestLevelAmbulanceMission, false, nil); - STAT_LINE("FEST_CC", &CStats::CriminalsCaught, false, nil); - STAT_LINE("FEST_FE", &CStats::FiresExtinguished, false, nil); - STAT_LINE("DAYPLC", &(nTemp = CTimer::GetTimeInMilliseconds() + 100), false, nil); - //TODO(MIAMI): move this function to the CStats and add reading of Stat lines tied with "MEDIA" for the "CHASESTAT" cheatcode - return counter; - -#undef STAT_LINE -} - void CMenuManager::ChangeRadioStation(int8 increaseBy) { diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 0e898796..01eb1c2e 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -85,16 +85,15 @@ #define CONTSETUP_CLASSIC_ROW_HEIGHT 9.0f #define CONTSETUP_BOUND_HIGHLIGHT_HEIGHT 10 #define CONTSETUP_BOUND_COLUMN_WIDTH 190.0f -#define CONTSETUP_LIST_HEADER_HEIGHT 20.0f -#define CONTSETUP_LIST_TOP 28.0f +#define CONTSETUP_LIST_TOP 58.0f #define CONTSETUP_LIST_RIGHT 18.0f -#define CONTSETUP_LIST_BOTTOM 120.0f -#define CONTSETUP_LIST_LEFT 18.0f +#define CONTSETUP_LIST_BOTTOM 78.0f +#define CONTSETUP_LIST_LEFT 30.0f #define CONTSETUP_COLUMN_1_X 40.0f #define CONTSETUP_COLUMN_2_X 210.0f #define CONTSETUP_COLUMN_3_X (CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH + 10.0f) #define CONTSETUP_BACK_RIGHT 35.0f -#define CONTSETUP_BACK_BOTTOM 122.0f +#define CONTSETUP_BACK_BOTTOM 82.0f #define CONTSETUP_BACK_HEIGHT 25.0f enum @@ -310,21 +309,6 @@ enum eCheckHover HOVEROPTION_USESKIN, // also layer in controller setup and skin menu HOVEROPTION_NEXT_RADIO, HOVEROPTION_PREV_RADIO, - - // Below is TODO(Miami) - - // those are unused in VC - HOVEROPTION_RADIO_0 = HOVEROPTION_NEXT_RADIO, - HOVEROPTION_RADIO_1, - HOVEROPTION_RADIO_2, - HOVEROPTION_RADIO_3, - HOVEROPTION_RADIO_4, - HOVEROPTION_RADIO_5, - HOVEROPTION_RADIO_6, - HOVEROPTION_RADIO_7, - HOVEROPTION_RADIO_8, - HOVEROPTION_RADIO_9, - HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, HOVEROPTION_INCREASE_DRAWDIST, @@ -359,7 +343,7 @@ enum eControlMethod enum ControllerSetupColumn { CONTSETUP_PED_COLUMN = 0, - CONTSETUP_VEHICLE_COLUMN = 14, + CONTSETUP_VEHICLE_COLUMN = 16, }; struct tSkinInfo @@ -485,7 +469,7 @@ public: int8 m_PrefsShowSubtitles; int8 m_PrefsShowLegends; int8 m_PrefsUseWideScreen; - int8 m_PrefsVsync; // TODO(Miami): Are we sure? + int8 m_PrefsVsync; int8 m_PrefsVsyncDisp; int8 m_PrefsFrameLimiter; int8 m_nPrefsAudio3DProviderIndex; @@ -526,7 +510,7 @@ public: uint8 field_74[4]; int32 *pControlEdit; bool m_OnlySaveMenu; - int32 m_menuTransitionProgress; + int32 m_firstStartCounter; CSprite2d m_aFrontEndSprites[NUM_MENU_SPRITES]; bool m_bSpritesLoaded; int32 m_LeftMostRadioX; @@ -662,7 +646,6 @@ public: void Initialise(); void PrintMap(); void SetFrontEndRenderStates(); - static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2); static void CentreMousePointer(); void CheckCodesForControls(int); bool CheckHover(int x1, int x2, int y1, int y2); @@ -679,7 +662,6 @@ public: void DrawBackground(bool transitionCall); void DrawPlayerSetupScreen(bool); int FadeIn(int alpha); - void FilterOutColorMarkersFromString(wchar*); int GetStartOptionsCntrlConfigScreens(); void InitialiseChangedLanguageSettings(); void LoadAllTextures(); @@ -707,7 +689,6 @@ public: void UnloadTextures(); void WaitForUserCD(); int GetNumOptionsCntrlConfigScreens(); - int ConstructStatLine(int); void SwitchToNewScreen(int8); void AdditionalOptionInput(bool &goBack); void ExportStats(void); diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 6ac02103..f31ffa27 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -94,6 +94,9 @@ #include "postfx.h" #include "custompipes.h" #include "screendroplets.h" +#ifdef USE_TEXTURE_POOL +#include "TexturePools.h" +#endif eLevelName CGame::currLevel; int32 CGame::currArea; diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index e078e6d0..bd2351de 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -5,9 +5,21 @@ #include "World.h" #include "Pad.h" #include "DMAudio.h" +#include "main.h" +#include "Font.h" +#include "Frontend.h" +#include "audio_enums.h" #include <climits> +#ifdef USE_PRECISE_MEASUREMENT_CONVERTION +#define MILES_IN_METER 0.000621371192f +#define FEET_IN_METER 3.28084f +#else +#define MILES_IN_METER (1 / 1670.f) +#define FEET_IN_METER 3.33f +#endif + int32 CStats::SeagullsKilled; int32 CStats::BoatsExploded; int32 CStats::WantedStarsAttained; @@ -43,8 +55,8 @@ float CStats::GarbagePickups; float CStats::IceCreamSold; float CStats::TopShootingRangeScore; float CStats::ShootingRank; -int32 CStats::ProgressMade; -int32 CStats::TotalProgressInGame; +float CStats::ProgressMade; +float CStats::TotalProgressInGame; int32 CStats::CarsExploded; int32 CStats::PeopleKilledByPlayer; float CStats::MaximumJumpDistance; @@ -115,7 +127,7 @@ void CStats::Init() for (int i = 0; i < NUM_PEDTYPES; i++) PedsKilledOfThisType[i] = 0; HelisDestroyed = 0; - ProgressMade = 0; + ProgressMade = 0.0f; KgsOfExplosivesUsed = 0; BulletsThatHit = 0; TyresPopped = 0; @@ -346,27 +358,27 @@ wchar *CStats::FindCriminalRatingString() } wchar *CStats::FindChaseString(float fMediaLevel) { - if (fMediaLevel < 20.0f) return TheText.Get("MEDIA1"); - if (fMediaLevel < 50.0f) return TheText.Get("MEDIA2"); - if (fMediaLevel < 75.0f) return TheText.Get("MEDIA3"); - if (fMediaLevel < 100.0f) return TheText.Get("MEDIA4"); - if (fMediaLevel < 150.0f) return TheText.Get("MEDIA5"); - if (fMediaLevel < 200.0f) return TheText.Get("MEDIA6"); - if (fMediaLevel < 250.0f) return TheText.Get("MEDIA7"); - if (fMediaLevel < 300.0f) return TheText.Get("MEDIA8"); - if (fMediaLevel < 350.0f) return TheText.Get("MEDIA9"); - if (fMediaLevel < 400.0f) return TheText.Get("MEDIA10"); - if (fMediaLevel < 500.0f) return TheText.Get("MEDIA11"); - if (fMediaLevel < 600.0f) return TheText.Get("MEDIA12"); - if (fMediaLevel < 700.0f) return TheText.Get("MEDIA13"); - if (fMediaLevel < 800.0f) return TheText.Get("MEDIA14"); - if (fMediaLevel < 900.0f) return TheText.Get("MEDIA15"); - if (fMediaLevel < 1000.0f) return TheText.Get("MEDIA16"); - if (fMediaLevel < 1200.0f) return TheText.Get("MEDIA17"); - if (fMediaLevel < 1400.0f) return TheText.Get("MEDIA18"); - if (fMediaLevel < 1600.0f) return TheText.Get("MEDIA19"); - if (fMediaLevel < 1800.0f) return TheText.Get("MEDIA20"); - return TheText.Get("MEDIA21"); + if (fMediaLevel < 20.0f) return TheText.Get("CHASE1"); + if (fMediaLevel < 50.0f) return TheText.Get("CHASE2"); + if (fMediaLevel < 75.0f) return TheText.Get("CHASE3"); + if (fMediaLevel < 100.0f) return TheText.Get("CHASE4"); + if (fMediaLevel < 150.0f) return TheText.Get("CHASE5"); + if (fMediaLevel < 200.0f) return TheText.Get("CHASE6"); + if (fMediaLevel < 250.0f) return TheText.Get("CHASE7"); + if (fMediaLevel < 300.0f) return TheText.Get("CHASE8"); + if (fMediaLevel < 350.0f) return TheText.Get("CHASE9"); + if (fMediaLevel < 400.0f) return TheText.Get("CHASE10"); + if (fMediaLevel < 500.0f) return TheText.Get("CHASE11"); + if (fMediaLevel < 600.0f) return TheText.Get("CHASE12"); + if (fMediaLevel < 700.0f) return TheText.Get("CHASE13"); + if (fMediaLevel < 800.0f) return TheText.Get("CHASE14"); + if (fMediaLevel < 900.0f) return TheText.Get("CHASE15"); + if (fMediaLevel < 1000.0f) return TheText.Get("CHASE16"); + if (fMediaLevel < 1200.0f) return TheText.Get("CHASE17"); + if (fMediaLevel < 1400.0f) return TheText.Get("CHASE18"); + if (fMediaLevel < 1600.0f) return TheText.Get("CHASE19"); + if (fMediaLevel < 1800.0f) return TheText.Get("CHASE20"); + return TheText.Get("CHASE21"); } int32 CStats::FindCriminalRatingNumber() @@ -387,16 +399,16 @@ int32 CStats::FindCriminalRatingNumber() } if (RoundsFiredByPlayer > 100) - rating += (float)CStats::BulletsThatHit / (float)CStats::RoundsFiredByPlayer * 500.0f; + rating += (float)BulletsThatHit / (float)RoundsFiredByPlayer * 500.0f; if (TotalProgressInGame) - rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f; + rating += ProgressMade / TotalProgressInGame * 1000.0f; return rating; } float CStats::GetPercentageProgress() { - float percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : - CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1.0f)); + float percentCompleted = (TotalProgressInGame == 0.f ? 0.f : + 100.0f * ProgressMade / (CGame::nastyGame ? TotalProgressInGame : TotalProgressInGame - 1.0f)); return Min(percentCompleted, 100.0f); } @@ -773,4 +785,657 @@ CStats::PopulateFavoriteRadioStationList() float* pListenTimeArray = DMAudio.GetListenTimeArray(); for (int i = 0; i < NUM_RADIOS; i++) FavoriteRadioStationList[i] = pListenTimeArray[i]; -}
\ No newline at end of file +} + +void +CStats::BuildStatLine(Const char *text, void *stat, int displayType, void *stat2, int isTime) +{ +#define STAT_D *(int*)stat +#define STAT_F *(float*)stat +#define STAT2_D *(int*)stat2 +#define STAT2_F *(float*)stat2 + if (!text) + return; + + gString2[0] = '\0'; + if (isTime == 1) { + if (*((int*)stat2) >= 10) + sprintf(gString2, " %d:%d", STAT_D, STAT2_D); + else + sprintf(gString2, " %d:0%d", STAT_D, STAT2_D); + + } else if (stat2) { +#ifdef MORE_LANGUAGES + if (CFont::IsJapanese()) { + switch (displayType) { + case 0: + case 4: + sprintf(gString2, " %d/%d", STAT_D, STAT2_D); + break; + case 1: + sprintf(gString2, " %.2f/%.2f", STAT_F, STAT2_F); + break; + case 2: + sprintf(gString2, " %d%%/%d%%", STAT_D, STAT2_D); + break; + case 3: + sprintf(gString2, " $%.2f/$%.2f", STAT_F, STAT2_F); + break; + default: + break; + } + } else +#endif + { + switch (displayType) { + case 0: + sprintf(gString2, " %d %s %d", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D); + break; + case 1: + sprintf(gString2, " %.2f %s %.2f", STAT_F, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_F); + break; + case 2: + sprintf(gString2, " %d%% %s %d%%", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D); + break; + case 3: + sprintf(gString2, " $%.2f %s $%.2f", STAT_F, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_F); + break; + case 4: + sprintf(gString2, " %d_ %s %d_", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D); + break; + default: + break; + } + } + } else if (stat) { + switch (displayType) { + case 0: + sprintf(gString2, "%d", STAT_D); + break; + case 1: + sprintf(gString2, "%.2f", STAT_F); + break; + case 2: + sprintf(gString2, "%d%%", STAT_D); + break; + case 3: + sprintf(gString2, "$%.2f", STAT_F); + break; + case 4: +#ifdef MORE_LANGUAGES + if (CFont::IsJapanese()) + sprintf(gString2, "%d", STAT_D); + else +#endif + sprintf(gString2, "%d_", STAT_D); + break; + default: + break; + } + } + UnicodeStrcpy(gUString, TheText.Get(text)); + CFont::FilterOutTokensFromString(gUString); + AsciiToUnicode(gString2, gUString2); +#undef STAT_D +#undef STAT_F +#undef STAT2_D +#undef STAT2_F +} + +// rowIdx 99999 returns total numbers of rows. otherwise it returns 0. +int +CStats::ConstructStatLine(int rowIdx) +{ + +#define STAT_LINE_1(varType, left, right1, type) \ + do { \ + if(counter == rowIdx){ \ + varType a = right1; \ + BuildStatLine(left, &a, type, nil, 0); \ + return 0; \ + } counter++; \ + } while(0) + +#define STAT_LINE_2(varType, left, right1, type, right2, time) \ + do { \ + if(counter == rowIdx){ \ + varType a = right1; \ + varType b = right2; \ + BuildStatLine(left, &a, type, &b, time); \ + return 0; \ + } counter++; \ + } while(0) + +#define TEXT_ON_LEFT_GXT(name) \ + do { \ + if(counter == rowIdx){ \ + BuildStatLine(name, nil, 0, nil, 0); \ + return 0; \ + } counter++; \ + } while(0) + +#define TEXT_ON_RIGHT(text) \ + do { \ + if(counter == rowIdx){ \ + gUString[0] = '\0'; \ + UnicodeStrcpy(gUString2, text); \ + return 0; \ + } counter++; \ + } while(0) + +#define FASTEST_TIME(id, str) \ + do { \ + if(FastestTimes[id]) { \ + if(counter == rowIdx){ \ + int hour = 0, minute; \ + for (int i = FastestTimes[id]; i > 59; i -= 60) hour++; \ + for (minute = FastestTimes[id]; minute > 59; minute -= 60); \ + if (minute < 0) minute = -minute; \ + BuildStatLine(str, &hour, 0, &minute, 1); \ + return 0; \ + } \ + counter++; \ + } \ + } while(0) + + switch (rowIdx) { + case 0: { + int percentCompleted = GetPercentageProgress(); + BuildStatLine("PER_COM", &percentCompleted, 2, nil, 0); + return 0; + } + case 1: { + BuildStatLine("NMISON", &MissionsGiven, 0, nil, 0); + return 0; + } + case 2: { + int hour = (CTimer::GetTimeInMilliseconds() / 60000) / 60; + int minute = (CTimer::GetTimeInMilliseconds() / 60000) % 60; + BuildStatLine("ST_TIME", &hour, 0, &minute, 1); + return 0; + } + case 3: { + BuildStatLine("DAYSPS", &DaysPassed, 0, nil, 0); + return 0; + } + case 4: { + BuildStatLine("NUMSHV", &SafeHouseVisits, 0, nil, 0); + return 0; + } + } + int counter = 5; + + if (CGame::nastyGame) { + STAT_LINE_2(int, "FEST_RP", NumberKillFrenziesPassed, 0, TotalNumberKillFrenzies, 0); + } + + CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus]; + + // Hidden packages shouldn't be shown with percent +#ifdef FIX_BUGS + STAT_LINE_2(int, "PERPIC", player.m_nCollectedPackages, 0, player.m_nTotalPackages, 0); +#else + float fPackagesPercent = 0.0f; + if (player.m_nTotalPackages != 0) + fPackagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages; + + STAT_LINE_2(int, "PERPIC", fPackagesPercent, 0, 100, 0); +#endif + + if (CGame::nastyGame) { + STAT_LINE_1(int, "PE_WAST", PeopleKilledByPlayer, 0); + STAT_LINE_1(int, "PE_WSOT", PeopleKilledByOthers, 0); + } + STAT_LINE_1(int, "CAR_EXP", CarsExploded, 0); + STAT_LINE_1(int, "BOA_EXP", BoatsExploded, 0); + STAT_LINE_1(int, "HEL_DST", HelisDestroyed, 0); + STAT_LINE_1(int, "TYREPOP", TyresPopped, 0); + STAT_LINE_1(int, "ST_STAR", WantedStarsAttained, 0); + STAT_LINE_1(int, "ST_STGN", WantedStarsEvaded, 0); + STAT_LINE_1(int, "TM_BUST", TimesArrested, 0); + STAT_LINE_1(int, "TM_DED", TimesDied, 0); + +#ifdef MORE_LANGUAGES + // JP version removed it altogether actually + if (!CFont::IsJapanese()) +#endif + STAT_LINE_1(int, "ST_HEAD", HeadsPopped, 0); + + static uint32 lastProcessedDay = UINT32_MAX; + static uint32 lastPoliceSpending = 0; + + // What a random stat... + if (lastProcessedDay != DaysPassed) { + lastProcessedDay = DaysPassed; + lastPoliceSpending = (CTimer::GetTimeInMilliseconds() + 80) * 255.44f; + } + STAT_LINE_1(float, "DAYPLC", lastPoliceSpending, 3); + + int mostPatheticGang = 0; + int mostKill = 0; + for (int i = PEDTYPE_GANG1; i < PEDTYPE_GANG9; ++i) { + if (CStats::PedsKilledOfThisType[i] > mostKill) { + mostKill = CStats::PedsKilledOfThisType[i]; + mostPatheticGang = i; + } + } + if (mostPatheticGang > 0) { + TEXT_ON_LEFT_GXT("ST_GANG"); + + switch (mostPatheticGang) { + case PEDTYPE_GANG1: + TEXT_ON_RIGHT(TheText.Get("ST_GNG1")); + break; + case PEDTYPE_GANG2: + TEXT_ON_RIGHT(TheText.Get("ST_GNG2")); + break; + case PEDTYPE_GANG3: + TEXT_ON_RIGHT(TheText.Get("ST_GNG3")); + break; + case PEDTYPE_GANG4: + TEXT_ON_RIGHT(TheText.Get("ST_GNG4")); + break; + case PEDTYPE_GANG5: + TEXT_ON_RIGHT(TheText.Get("ST_GNG5")); + break; + case PEDTYPE_GANG6: + TEXT_ON_RIGHT(TheText.Get("ST_GNG6")); + break; + case PEDTYPE_GANG7: + TEXT_ON_RIGHT(TheText.Get("ST_GNG7")); + break; + case PEDTYPE_GANG8: + TEXT_ON_RIGHT(TheText.Get("ST_GNG8")); + break; + default: + break; + } + } + + STAT_LINE_1(int, "GNG_WST", PedsKilledOfThisType[PEDTYPE_GANG9] + PedsKilledOfThisType[PEDTYPE_GANG8] + + PedsKilledOfThisType[PEDTYPE_GANG7] + PedsKilledOfThisType[PEDTYPE_GANG6] + + PedsKilledOfThisType[PEDTYPE_GANG5] + PedsKilledOfThisType[PEDTYPE_GANG4] + + PedsKilledOfThisType[PEDTYPE_GANG3] + PedsKilledOfThisType[PEDTYPE_GANG2] + + PedsKilledOfThisType[PEDTYPE_GANG1], 0); + + STAT_LINE_1(int, "DED_CRI", PedsKilledOfThisType[PEDTYPE_CRIMINAL], 0); + STAT_LINE_1(int, "KGS_EXP", KgsOfExplosivesUsed, 0); + STAT_LINE_1(int, "BUL_FIR", RoundsFiredByPlayer, 0); + STAT_LINE_1(int, "BUL_HIT", BulletsThatHit, 0); +; + STAT_LINE_1(int, "ACCURA", RoundsFiredByPlayer == 0 ? 0 : (BulletsThatHit * 100.0f / (float)RoundsFiredByPlayer), 2); + + switch (FrontEndMenuManager.m_PrefsLanguage) { + case CMenuManager::LANGUAGE_AMERICAN: +#ifndef USE_MEASUREMENTS_IN_METERS + STAT_LINE_1(float, "FEST_DF", DistanceTravelledOnFoot * MILES_IN_METER, 1); + STAT_LINE_1(float, "FEST_DC", DistanceTravelledByCar * MILES_IN_METER, 1); + STAT_LINE_1(float, "DISTBIK", DistanceTravelledByBike * MILES_IN_METER, 1); + STAT_LINE_1(float, "DISTBOA", DistanceTravelledByBoat * MILES_IN_METER, 1); + STAT_LINE_1(float, "DISTGOL", DistanceTravelledByGolfCart * MILES_IN_METER, 1); + STAT_LINE_1(float, "DISTHEL", DistanceTravelledByHelicoptor * MILES_IN_METER, 1); +#ifdef FIX_BUGS + STAT_LINE_1(float, "TOT_DIS", (DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + DistanceTravelledByBike + + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor + DistanceTravelledByPlane) * MILES_IN_METER, 1); + STAT_LINE_1(float, "MXCARD", MaximumJumpDistance * FEET_IN_METER, 1); + STAT_LINE_1(float, "MXCARJ", MaximumJumpHeight * FEET_IN_METER, 1); +#else + STAT_LINE_1(float, "TOT_DIS", (DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + DistanceTravelledByBike + + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor) * MILES_IN_METER, 1); +#endif + break; +#endif + case CMenuManager::LANGUAGE_FRENCH: + case CMenuManager::LANGUAGE_GERMAN: + case CMenuManager::LANGUAGE_ITALIAN: + case CMenuManager::LANGUAGE_SPANISH: +#ifdef MORE_LANGUAGES + case CMenuManager::LANGUAGE_POLISH: + case CMenuManager::LANGUAGE_RUSSIAN: + case CMenuManager::LANGUAGE_JAPANESE: +#endif + STAT_LINE_1(float, "FESTDFM", DistanceTravelledOnFoot, 1); + STAT_LINE_1(float, "FESTDCM", DistanceTravelledByCar, 1); + STAT_LINE_1(float, "DISTBIM", DistanceTravelledByBike, 1); + STAT_LINE_1(float, "DISTBOM", DistanceTravelledByBoat, 1); + STAT_LINE_1(float, "DISTGOM", DistanceTravelledByGolfCart, 1); + STAT_LINE_1(float, "DISTHEM", DistanceTravelledByHelicoptor, 1); +#ifdef FIX_BUGS + STAT_LINE_1(float, "TOTDISM", DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + + DistanceTravelledByBike + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor + DistanceTravelledByPlane, 1); + STAT_LINE_1(float, "MXCARDM", MaximumJumpDistance, 1); + STAT_LINE_1(float, "MXCARJM", MaximumJumpHeight, 1); +#else + STAT_LINE_1(float, "TOTDISM", DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor, 1); +#endif + break; + default: + break; + } + + // They were selecting the unit according to language in III, but they deleted the feet code in VC. Weird +#ifndef FIX_BUGS + STAT_LINE_1(float, "MXCARDM", MaximumJumpDistance, 1); + STAT_LINE_1(float, "MXCARJM", MaximumJumpHeight, 1); +#endif + STAT_LINE_1(int, "MXFLIP", MaximumJumpFlips, 0); + STAT_LINE_2(int, "NOUNIF", NumberOfUniqueJumpsFound, 0, TotalNumberOfUniqueJumps, 0); + STAT_LINE_1(int, "MXJUMP", MaximumJumpSpins, 4); + + TEXT_ON_LEFT_GXT("BSTSTU"); + switch (BestStuntJump) { + case 1: + TEXT_ON_RIGHT(TheText.Get("INSTUN")); + break; + case 2: + TEXT_ON_RIGHT(TheText.Get("PRINST")); + break; + case 3: + TEXT_ON_RIGHT(TheText.Get("DBINST")); + break; + case 4: + TEXT_ON_RIGHT(TheText.Get("DBPINS")); + break; + case 5: + TEXT_ON_RIGHT(TheText.Get("TRINST")); + break; + case 6: + TEXT_ON_RIGHT(TheText.Get("PRTRST")); + break; + case 7: + TEXT_ON_RIGHT(TheText.Get("QUINST")); + break; + case 8: + TEXT_ON_RIGHT(TheText.Get("PQUINS")); + break; + default: + TEXT_ON_RIGHT(TheText.Get("NOSTUC")); + break; + } + STAT_LINE_1(int, "ST_WHEE", LongestWheelie, 0); + STAT_LINE_1(float, "ST_WHED", LongestWheelieDist, 1); + STAT_LINE_1(int, "ST_STOP", LongestStoppie, 0); + STAT_LINE_1(float, "ST_STOD", LongestStoppieDist, 1); + STAT_LINE_1(int, "ST_2WHE", Longest2Wheel, 0); + STAT_LINE_1(float, "ST_2WHD", Longest2WheelDist, 1); + + if (LoanSharks > 0.0f) + STAT_LINE_1(int, "ST_LOAN", LoanSharks, 0); + + STAT_LINE_1(int, "FEST_CC", CriminalsCaught, 0); + STAT_LINE_1(int, "FEST_HV", HighestLevelVigilanteMission, 0); + STAT_LINE_1(int, "PASDRO", PassengersDroppedOffWithTaxi, 0); + STAT_LINE_1(float, "MONTAX", MoneyMadeWithTaxi, 3); + STAT_LINE_1(int, "FEST_LS", LivesSavedWithAmbulance, 0); + STAT_LINE_1(int, "FEST_HA", HighestLevelAmbulanceMission, 0); + STAT_LINE_1(int, "FEST_FE", FiresExtinguished, 0); + STAT_LINE_1(int, "FIRELVL", HighestLevelFireMission, 0); + + STAT_LINE_2(int, "ST_STOR", StoresKnockedOff, 0, 15, 0); + + if (MovieStunts > 0.0f) + STAT_LINE_1(int, "ST_MOVI", MovieStunts, 0); + + STAT_LINE_2(int, "ST_ASSI", Assassinations, 0, 5, 0); + + if (PhotosTaken > 0) + STAT_LINE_1(int, "ST_PHOT", PhotosTaken, 0); + + if (PizzasDelivered > 0.0f) + STAT_LINE_1(int, "ST_PIZZ", PizzasDelivered, 0); + + if (GarbagePickups > 0.0f) + STAT_LINE_1(int, "ST_GARB", GarbagePickups, 0); + + if (IceCreamSold > 0.0f) + STAT_LINE_1(int, "ST_ICEC", IceCreamSold, 0); + + if (HighestScores[1]) + STAT_LINE_1(int, "STHC_02", HighestScores[1], 0); + + FASTEST_TIME(0, "STFT_01"); + FASTEST_TIME(1, "STFT_02"); + FASTEST_TIME(2, "STFT_03"); + FASTEST_TIME(3, "STFT_04"); + FASTEST_TIME(4, "STFT_05"); + FASTEST_TIME(5, "STFT_06"); + FASTEST_TIME(6, "STFT_07"); + FASTEST_TIME(7, "STFT_08"); + FASTEST_TIME(8, "STFT_09"); + FASTEST_TIME(9, "STFT_10"); + FASTEST_TIME(10, "STFT_11"); + FASTEST_TIME(11, "STFT_12"); + FASTEST_TIME(12, "STFT_13"); + FASTEST_TIME(13, "STFT_14"); + FASTEST_TIME(14, "STFT_15"); + FASTEST_TIME(15, "STFT_16"); + FASTEST_TIME(16, "STFT_17"); + FASTEST_TIME(17, "STFT_18"); + FASTEST_TIME(18, "STFT_19"); + FASTEST_TIME(19, "STFT_20"); + FASTEST_TIME(22, "STFT_23"); + + if (HighestScores[0]) + STAT_LINE_1(int, "STHC_01", HighestScores[0], 0); + + if (HighestScores[3]) + STAT_LINE_1(int, "STHC_04", HighestScores[3], 0); + + if (HighestScores[2]) + STAT_LINE_1(int, "STHC_03", HighestScores[2], 0); + + if (BestPositions[0] != INT_MAX) + STAT_LINE_1(int, "STHC_05", BestPositions[0], 0); + + FASTEST_TIME(20, "STFT_21"); + + if (FastestTimes[21]) + STAT_LINE_1(float, "STFT_22", FastestTimes[21] / 1000, 1); + + if (TopShootingRangeScore > 0.0f) + STAT_LINE_1(int, "TOP_SHO", TopShootingRangeScore, 0); + + if (ShootingRank > 0.0f) + STAT_LINE_1(int, "SHO_RAN", ShootingRank, 0); + + int flightMinute = (FlightTime / 60000) % 60; + int flightHour = (FlightTime / 60000) / 60; + STAT_LINE_2(int, "ST_FTIM", flightHour, 0, flightMinute, 1); + + // We always have pilot rank if we flew more then 5 minutes +#ifndef FIX_BUGS + if (flightHour != 0) + TEXT_ON_LEFT_GXT("ST_PRAN"); +#endif + +#ifdef FIX_BUGS +#define FL_TIME_MORE_THAN(hour, minute) (flightHour > hour || (flightHour == hour && flightMinute >= minute)) +#else +#define FL_TIME_MORE_THAN(hour, minute) (flightHour > hour || flightMinute >= minute) +#endif + + if (FL_TIME_MORE_THAN(0,5)) { + +#ifdef FIX_BUGS + TEXT_ON_LEFT_GXT("ST_PRAN"); +#endif + if (!FL_TIME_MORE_THAN(0,10)) TEXT_ON_RIGHT(TheText.Get("ST_PR01")); + else if (!FL_TIME_MORE_THAN(0,20)) TEXT_ON_RIGHT(TheText.Get("ST_PR02")); + else if (!FL_TIME_MORE_THAN(0,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR03")); + else if (!FL_TIME_MORE_THAN(1,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR04")); + else if (!FL_TIME_MORE_THAN(1,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR05")); + else if (!FL_TIME_MORE_THAN(2,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR06")); + else if (!FL_TIME_MORE_THAN(2,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR07")); + else if (!FL_TIME_MORE_THAN(3,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR08")); + else if (!FL_TIME_MORE_THAN(3,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR09")); + else if (!FL_TIME_MORE_THAN(4,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR10")); + else if (!FL_TIME_MORE_THAN(5,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR11")); + else if (!FL_TIME_MORE_THAN(10,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR12")); + else if (!FL_TIME_MORE_THAN(20,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR13")); + else if (!FL_TIME_MORE_THAN(25,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR14")); + else if (!FL_TIME_MORE_THAN(30,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR15")); + else if (!FL_TIME_MORE_THAN(49,2)) TEXT_ON_RIGHT(TheText.Get("ST_PR16")); + else if (!FL_TIME_MORE_THAN(50,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR17")); + else if (!FL_TIME_MORE_THAN(100,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR18")); + else TEXT_ON_RIGHT(TheText.Get("ST_PR19")); + } +#undef FL_TIME_MORE_THAN + + if (BloodRingKills > 0) + STAT_LINE_1(int, "ST_BRK", BloodRingKills, 0); + + if (BloodRingTime > 0) + STAT_LINE_1(int, "ST_LTBR", BloodRingTime, 0); + + STAT_LINE_1(int, "ST_DRWN", TimesDrowned, 0); + + if (SeagullsKilled > 0) + STAT_LINE_1(int, "SEAGULL", SeagullsKilled, 0); + + bool playerHatesRadio = true; + float* pListenTimeArray = DMAudio.GetListenTimeArray(); + for (int i = 0; i < NUM_RADIOS; i++) { + FavoriteRadioStationList[i] = pListenTimeArray[i]; + if (FavoriteRadioStationList[i] != 0.0) // double + playerHatesRadio = false; + } + + if (!playerHatesRadio) { + // Most listened + TEXT_ON_LEFT_GXT("FST_MFR"); + float mostListenTime = FavoriteRadioStationList[0]; + int mostListenedRadio = 0; + for (int i = 0; i < NUM_RADIOS; i++) { + if (FavoriteRadioStationList[i] > mostListenTime) { + mostListenTime = FavoriteRadioStationList[i]; + mostListenedRadio = i; + } + } + switch (mostListenedRadio) { + case WILDSTYLE: + TEXT_ON_RIGHT(TheText.Get("FEA_FM0")); + break; + case FLASH_FM: + TEXT_ON_RIGHT(TheText.Get("FEA_FM1")); + break; + case KCHAT: + TEXT_ON_RIGHT(TheText.Get("FEA_FM2")); + break; + case FEVER: + TEXT_ON_RIGHT(TheText.Get("FEA_FM3")); + break; + case V_ROCK: + TEXT_ON_RIGHT(TheText.Get("FEA_FM4")); + break; + case VCPR: + TEXT_ON_RIGHT(TheText.Get("FEA_FM5")); + break; + case RADIO_ESPANTOSO: + TEXT_ON_RIGHT(TheText.Get("FEA_FM6")); + break; + case EMOTION: + TEXT_ON_RIGHT(TheText.Get("FEA_FM7")); + break; + case WAVE: + TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); + break; + case USERTRACK: + TEXT_ON_RIGHT(TheText.Get("FEA_MP3")); + break; + default: + TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); // heh + break; + } + + // Least listened + TEXT_ON_LEFT_GXT("FST_LFR"); + float leastListenTime = FavoriteRadioStationList[0]; + int leastListenedRadio = 0; + for (int i = 0; i < NUM_RADIOS; i++) { +#ifdef FIX_BUGS + if (!DMAudio.IsMP3RadioChannelAvailable() && i == USERTRACK) + continue; +#endif + if (FavoriteRadioStationList[i] < leastListenTime) { + leastListenTime = FavoriteRadioStationList[i]; + leastListenedRadio = i; + } + } +#ifndef FIX_BUGS + if (!DMAudio.IsMP3RadioChannelAvailable() && leastListenedRadio == USERTRACK) + leastListenedRadio = WAVE; +#endif + + switch (leastListenedRadio) { + case WILDSTYLE: + TEXT_ON_RIGHT(TheText.Get("FEA_FM0")); + break; + case FLASH_FM: + TEXT_ON_RIGHT(TheText.Get("FEA_FM1")); + break; + case KCHAT: + TEXT_ON_RIGHT(TheText.Get("FEA_FM2")); + break; + case FEVER: + TEXT_ON_RIGHT(TheText.Get("FEA_FM3")); + break; + case V_ROCK: + TEXT_ON_RIGHT(TheText.Get("FEA_FM4")); + break; + case VCPR: + TEXT_ON_RIGHT(TheText.Get("FEA_FM5")); + break; + case RADIO_ESPANTOSO: + TEXT_ON_RIGHT(TheText.Get("FEA_FM6")); + break; + case EMOTION: + TEXT_ON_RIGHT(TheText.Get("FEA_FM7")); + break; + case WAVE: + TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); + break; + case USERTRACK: + TEXT_ON_RIGHT(TheText.Get("FEA_MP3")); + break; + default: + TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); // heh + break; + } + } + STAT_LINE_1(int, "SPRAYIN", Sprayings, 0); + STAT_LINE_1(float, "ST_WEAP", WeaponBudget, 3); + STAT_LINE_1(float, "ST_FASH", FashionBudget, 3); + STAT_LINE_1(float, "ST_PROP", PropertyBudget, 3); + STAT_LINE_1(float, "ST_AUTO", AutoPaintingBudget, 3); + STAT_LINE_1(float, "ST_DAMA", PropertyBudget, 3); + + if (NumPropertyOwned > 0) { + STAT_LINE_1(int, "PROPOWN", NumPropertyOwned, 0); + if (PropertyOwned[0]) TEXT_ON_RIGHT(TheText.Get("STPR_1")); + if (PropertyOwned[1]) TEXT_ON_RIGHT(TheText.Get("STPR_2")); + if (PropertyOwned[2]) TEXT_ON_RIGHT(TheText.Get("STPR_3")); + if (PropertyOwned[3]) TEXT_ON_RIGHT(TheText.Get("STPR_4")); + if (PropertyOwned[4]) TEXT_ON_RIGHT(TheText.Get("STPR_5")); + if (PropertyOwned[5]) TEXT_ON_RIGHT(TheText.Get("STPR_6")); + if (PropertyOwned[6]) TEXT_ON_RIGHT(TheText.Get("STPR_7")); + if (PropertyOwned[7]) TEXT_ON_RIGHT(TheText.Get("STPR_8")); + if (PropertyOwned[8]) TEXT_ON_RIGHT(TheText.Get("STPR_9")); + if (PropertyOwned[9]) TEXT_ON_RIGHT(TheText.Get("STPR_10")); + if (PropertyOwned[10]) TEXT_ON_RIGHT(TheText.Get("STPR_11")); + if (PropertyOwned[11]) TEXT_ON_RIGHT(TheText.Get("STPR_12")); + if (PropertyOwned[12]) TEXT_ON_RIGHT(TheText.Get("STPR_13")); + if (PropertyOwned[13]) TEXT_ON_RIGHT(TheText.Get("STPR_14")); + if (PropertyOwned[14]) TEXT_ON_RIGHT(TheText.Get("STPR_15")); + } + STAT_LINE_1(int, "CHASE", HighestChaseValue, 0); + TEXT_ON_RIGHT(FindChaseString(HighestChaseValue)); + + return counter; + +#undef STAT_LINE_1 +#undef STAT_LINE_2 +#undef TEXT_ON_LEFT_GXT +#undef TEXT_ON_RIGHT +#undef FASTEST_TIME +} diff --git a/src/core/Stats.h b/src/core/Stats.h index 49f84657..7fa69396 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -49,8 +49,8 @@ public: static int32 WantedStarsAttained; static int32 WantedStarsEvaded; static int32 PeopleKilledByPlayer; - static int32 ProgressMade; - static int32 TotalProgressInGame; + static float ProgressMade; + static float TotalProgressInGame; static float MaximumJumpDistance; static float MaximumJumpHeight; static int32 MaximumJumpFlips; @@ -147,4 +147,6 @@ public: static void AddPropertyAsOwned(int32); static void PopulateFavoriteRadioStationList(); static float GetFavoriteRadioStationList(int32); + static void BuildStatLine(Const char *, void *, int, void *, int); + static int ConstructStatLine(int); }; diff --git a/src/core/World.cpp b/src/core/World.cpp index 4c700f10..bc104fe9 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -942,26 +942,26 @@ CEntity * CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore, bool ignoreSomeObjects) { - static CColModel sphereCol; + static CColModel OurColModel; CColSphere sphere; - sphereCol.boundingSphere.center.x = 0.0f; - sphereCol.boundingSphere.center.y = 0.0f; - sphereCol.boundingSphere.center.z = 0.0f; - sphereCol.boundingSphere.radius = radius; - sphereCol.boundingBox.min.x = -radius; - sphereCol.boundingBox.min.y = -radius; - sphereCol.boundingBox.min.z = -radius; - sphereCol.boundingBox.max.x = radius; - sphereCol.boundingBox.max.y = radius; - sphereCol.boundingBox.max.z = radius; - sphereCol.numSpheres = 1; + OurColModel.boundingSphere.center.x = 0.0f; + OurColModel.boundingSphere.center.y = 0.0f; + OurColModel.boundingSphere.center.z = 0.0f; + OurColModel.boundingSphere.radius = radius; + OurColModel.boundingBox.min.x = -radius; + OurColModel.boundingBox.min.y = -radius; + OurColModel.boundingBox.min.z = -radius; + OurColModel.boundingBox.max.x = radius; + OurColModel.boundingBox.max.y = radius; + OurColModel.boundingBox.max.z = radius; + OurColModel.numSpheres = 1; sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f)); - sphereCol.spheres = &sphere; - sphereCol.numLines = 0; - sphereCol.numBoxes = 0; - sphereCol.numTriangles = 0; - sphereCol.ownsCollisionVolumes = false; + OurColModel.spheres = &sphere; + OurColModel.numLines = 0; + OurColModel.numBoxes = 0; + OurColModel.numTriangles = 0; + OurColModel.ownsCollisionVolumes = false; CMatrix sphereMat; sphereMat.SetTranslate(spherePos); @@ -980,7 +980,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad if(e->GetBoundRadius() + radius > distance) { CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); int collidedSpheres = - CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(), *eCol, + CCollision::ProcessColModels(sphereMat, OurColModel, e->GetMatrix(), *eCol, gaTempSphereColPoints, nil, nil); if(collidedSpheres != 0 || diff --git a/src/core/config.h b/src/core/config.h index e7b07576..6e4df00d 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -195,6 +195,7 @@ enum Config { # define RANDOMSPLASH // use random splash as on PS2 # define PS2_MATFX # endif +# define GTA_REPLAY #elif defined GTA_XBOX #endif @@ -240,6 +241,7 @@ enum Config { #define PS2_ALPHA_TEST // emulate ps2 alpha test #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number #define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time +#define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync //#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU //#define USE_TEXTURE_POOL //#define CUTSCENE_BORDERS_SWITCH @@ -308,6 +310,12 @@ enum Config { #define USE_DEBUG_SCRIPT_LOADER // Loads main.scm by default. Hold R for main_freeroam.scm and D for main_d.scm #define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script #define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely +#define SUPPORT_JAPANESE_SCRIPT +//#define SUPPORT_XBOX_SCRIPT +//#define SUPPORT_MOBILE_SCRIPT +#if (defined SUPPORT_XBOX_SCRIPT && defined SUPPORT_MOBILE_SCRIPT) +static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually exclusive"); +#endif //#define MISSION_REPLAY // mobile feature #endif //#define SIMPLIER_MISSIONS // apply simplifications from mobile diff --git a/src/core/main.cpp b/src/core/main.cpp index ef40777f..7fb07fff 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -599,8 +599,10 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) AsciiToUnicode(str1, tmpstr); CFont::PrintString(hpos, top, tmpstr); top += 22*yscale; - AsciiToUnicode(str2, tmpstr); - CFont::PrintString(hpos, top, tmpstr); + if (str2) { + AsciiToUnicode(str2, tmpstr); + CFont::PrintString(hpos, top, tmpstr); + } #endif } @@ -1424,15 +1426,6 @@ AppEventHandler(RsEvent event, void *param) return rsEVENTPROCESSED; } -#ifndef MASTER - case rsANIMVIEWER: - { - TheModelViewer(); - - return rsEVENTPROCESSED; - } -#endif - default: { return rsEVENTNOTPROCESSED; @@ -1448,22 +1441,27 @@ TheModelViewer(void) //TODO #else - CDraw::CalculateAspectRatio(); + // This is not original. Because; + // 1- We want 2D things to be initalized, whereas original AnimViewer doesn't use them. my additions marked with X + // 2- VC Mobile code run it like main function(as opposed to III and LCS), so it has it's own loop inside it, but our func. already called in a loop. + + CDraw::CalculateAspectRatio(); // X CAnimViewer::Update(); - CTimer::Update(); SetLightsWithTimeOfDayColour(Scene.world); CRenderer::ConstructRenderList(); DoRWStuffStartOfFrame(CTimeCycle::GetSkyTopRed()*0.5f, CTimeCycle::GetSkyTopGreen()*0.5f, CTimeCycle::GetSkyTopBlue()*0.5f, CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255); - CSprite2d::InitPerFrame(); - CFont::InitPerFrame(); + CSprite2d::SetRecipNearClip(); // X + CSprite2d::InitPerFrame(); // X + CFont::InitPerFrame(); // X DefinedState(); CVisibilityPlugins::InitAlphaEntityList(); CAnimViewer::Render(); - Render2dStuff(); + Render2dStuff(); // X DoRWStuffEndOfFrame(); + CTimer::Update(); #endif } #endif diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp index eb5551f9..b04f7c7e 100644 --- a/src/fakerw/fake.cpp +++ b/src/fakerw/fake.cpp @@ -578,6 +578,9 @@ void RwD3D8EngineSetRefreshRate(RwUInt32 refreshRate) {} RwBool RwD3D8DeviceSupportsDXTTexture(void) { return true; } +void RwD3D8EngineSetMultiSamplingLevels(RwUInt32 level) { Engine::setMultiSamplingLevels(level); } +RwUInt32 RwD3D8EngineGetMaxMultiSamplingLevels(void) { return Engine::getMaxMultiSamplingLevels(); } + RpMaterial *RpMaterialCreate(void) { return Material::create(); } RwBool RpMaterialDestroy(RpMaterial *material) { material->destroy(); return true; } diff --git a/src/fakerw/rwcore.h b/src/fakerw/rwcore.h index 31bc5541..e5d21865 100644 --- a/src/fakerw/rwcore.h +++ b/src/fakerw/rwcore.h @@ -411,3 +411,5 @@ RwFrame *RwCameraGetFrame(const RwCamera *camera); void RwD3D8EngineSetRefreshRate(RwUInt32 refreshRate); RwBool RwD3D8DeviceSupportsDXTTexture(void); +void RwD3D8EngineSetMultiSamplingLevels(RwUInt32 level); +RwUInt32 RwD3D8EngineGetMaxMultiSamplingLevels(void); diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp index bb7cfe76..a024b77a 100644 --- a/src/peds/CivilianPed.cpp +++ b/src/peds/CivilianPed.cpp @@ -18,7 +18,7 @@ #include <float.h> #endif -// --MIAMI: file done except TODOs +// --MIAMI: file done CCivilianPed::CCivilianPed(ePedType pedtype, uint32 mi) : CPed(pedtype) { @@ -228,7 +228,7 @@ CCivilianPed::CivilianAI(void) void CCivilianPed::ProcessControl(void) { - if (CharCreatedBy == TODO_CHAR) + if (CharCreatedBy == UNK_CHAR) return; CPed::ProcessControl(); diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp index 10490a69..33b44d3e 100644 --- a/src/peds/CopPed.cpp +++ b/src/peds/CopPed.cpp @@ -96,9 +96,7 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP) field_61C = 0; field_624 = 0; m_pStinger = new CStinger; - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); - m_pPointGunAt = nil; + SetWeaponLockOnTarget(nil); } CCopPed::~CCopPed() @@ -493,12 +491,7 @@ CCopPed::CopAI(void) false, true, false, false, true, false, false) || foundEnt && foundEnt == playerOrHisVeh) { - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference((CEntity**) &m_pPointGunAt); - m_pPointGunAt = playerOrHisVeh; - if (playerOrHisVeh) - playerOrHisVeh->RegisterReference((CEntity**) &m_pPointGunAt); - + SetWeaponLockOnTarget(playerOrHisVeh); SetAttack(playerOrHisVeh); SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000)); } @@ -880,4 +873,4 @@ CCopPed::ProcessStingerCop(void) } else { ClearPursuit(); } -}
\ No newline at end of file +} diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index acf219b4..b7623a33 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -39,8 +39,7 @@ #include "CutsceneShadow.h" #include "Clock.h" -// --MIAMI: file done except TODOs - +// --MIAMI: file done CPed *gapTempPedList[50]; uint16 gnNumTempPedList; @@ -4559,7 +4558,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) ped->bChangedSeat = true; } -// --MIAMI: Done, but what is TODO_CHAR?? +// --MIAMI: Done bool CPed::CanBeDeleted(void) { @@ -4571,7 +4570,7 @@ CPed::CanBeDeleted(void) return true; case MISSION_CHAR: return false; - case TODO_CHAR: + case UNK_CHAR: return false; default: return true; @@ -4587,7 +4586,7 @@ CPed::CanBeDeletedEvenInVehicle(void) return true; case MISSION_CHAR: return false; - case TODO_CHAR: + case UNK_CHAR: return false; default: return true; @@ -4887,7 +4886,7 @@ CPed::PreRender(void) fWindMult = DotProduct(m_pMyVehicle->m_vecMoveSpeed, GetForward()); if (fWindMult > 0.4f) { float volume = (fWindMult - 0.4f) / 0.6f; - DMAudio.PlayOneShot(m_audioEntityId, SOUND_SET_202, volume); //TODO(MIAMI): revise when audio is done + DMAudio.PlayOneShot(m_audioEntityId, SOUND_SHIRT_WIND_FLAP, volume); } } @@ -5522,7 +5521,7 @@ CPed::SetGetUp(void) if (m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) { m_headingRate = 0.0f; - // TODO(Miami): Looks like that should've been another getup anim but R* forgot it. Visit here later + // Seemingly they planned to use different getup anims for different conditions, but sadly in final game all getup anims(GETUP1, GETUP2, GETUP3) are same... if (bFleeWhenStanding && m_threatEx) animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f); else @@ -9770,6 +9769,17 @@ CPed::Say(uint16 audio, int32 time) } } +void +CPed::SetWeaponLockOnTarget(CEntity *target) +{ + if (m_pPointGunAt) + m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); + + m_pPointGunAt = (CPed*)target; + if (target) + ((CEntity*)target)->RegisterReference(&m_pPointGunAt); +} + #ifdef COMPATIBLE_SAVES #define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); #define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); diff --git a/src/peds/Ped.h b/src/peds/Ped.h index c6c4fcee..608bb710 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -254,7 +254,7 @@ enum eObjective : uint32 { enum { RANDOM_CHAR = 1, MISSION_CHAR, - TODO_CHAR, // TODO(Miami) + UNK_CHAR, }; enum PedLineUpPhase { @@ -866,6 +866,7 @@ public: void PositionAttachedPed(); bool CanUseTorsoWhenLooking(); void ScanForDelayedResponseThreats(); + void SetWeaponLockOnTarget(CEntity*); // Static methods static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset); @@ -1067,6 +1068,13 @@ public: else return (AnimationId)0; } + + static AnimationId GetMeleeStartAnim(CWeaponInfo* weapon) { + if (!!weapon->m_bPartialAttack) + return ANIM_MELEE_ATTACK_START; + else + return (AnimationId)0; + } // -- // My additions, because there were many, many instances of that. @@ -1147,10 +1155,7 @@ void FinishTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg); void StartTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg); void PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount); -// TODO(Miami): Change those when Ped struct is done -#ifndef PED_SKIN -VALIDATE_SIZE(CPed, 0x53C); -#endif +VALIDATE_SIZE(CPed, 0x5F4); bool IsPedPointerValid(CPed*); bool IsPedPointerValid_NotInWorld(CPed*); diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index 8c7847a7..1f61118f 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -324,11 +324,7 @@ CPed::SetObjective(eObjective newObj, void *entity) break; case OBJECTIVE_DESTROY_OBJECT: - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); - m_pPointGunAt = (CPed*)entity; - if (entity) - ((CEntity*)entity)->RegisterReference((CEntity**) &m_pPointGunAt); + SetWeaponLockOnTarget((CEntity*)entity); break; case OBJECTIVE_ENTER_CAR_AS_PASSENGER: case OBJECTIVE_ENTER_CAR_AS_DRIVER: @@ -698,11 +694,7 @@ CPed::UpdateFromLeader(void) m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget); TurnBody(); if (m_attackTimer < CTimer::GetTimeInMilliseconds() && !GetWeapon()->IsTypeMelee()) { - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); - m_pPointGunAt = m_threatEntity; - if (m_threatEntity) - m_threatEntity->RegisterReference((CEntity **) &m_pPointGunAt); + SetWeaponLockOnTarget(m_threatEntity); SetAttack(m_threatEntity); } } @@ -1353,12 +1345,7 @@ CPed::ProcessObjective(void) CWorld::bIncludeDeadPeds = false; if (foundEnt == m_carInObjective) { SetAttack(m_carInObjective); - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt); - m_pPointGunAt = m_carInObjective; - if (m_pPointGunAt) - m_pPointGunAt->RegisterReference((CEntity **) &m_pPointGunAt); - + SetWeaponLockOnTarget(m_carInObjective); SetShootTimer(CGeneral::GetRandomNumberInRange(500, 2000)); if (distWithTargetSc > 10.0f && !bKindaStayInSamePlace) { SetAttackTimer(CGeneral::GetRandomNumberInRange(2000, 5000)); @@ -6477,13 +6464,7 @@ CPed::KillCharOnFootArmed(CVector &ourPos, CVector &targetPos, CVector &distWith if (m_attackTimer < CTimer::GetTimeInMilliseconds() && distWithTargetSc < wepRange && distWithTargetSc > 3.0f) { SetAttack(vehOfTarget); - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); - - m_pPointGunAt = vehOfTarget; - if (vehOfTarget) - vehOfTarget->RegisterReference((CEntity **) &m_pPointGunAt); - + SetWeaponLockOnTarget(vehOfTarget); SetShootTimer(CGeneral::GetRandomNumberInRange(500, 2000)); CVector2D dirVehGoing = vehOfTarget->m_vecMoveSpeed; @@ -6620,13 +6601,7 @@ CPed::KillCharOnFootArmed(CVector &ourPos, CVector &targetPos, CVector &distWith } bObstacleShowedUpDuringKillObjective = false; SetAttack(m_pedInObjective); - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); - - m_pPointGunAt = m_pedInObjective; - if (m_pedInObjective) - m_pedInObjective->RegisterReference((CEntity**)&m_pPointGunAt); - + SetWeaponLockOnTarget(m_pedInObjective); SetShootTimer(CGeneral::GetRandomNumberInRange(600.0f, 1500.0f)); int time; @@ -6756,34 +6731,34 @@ CPed::KillCharOnFootMelee(CVector &ourPos, CVector &targetPos, CVector &distWith // Already calculated at the start // float distWithTargetSc = distWithTarget.Magnitude(); - float wepRange = 0.3f; - float wepRangeAdjusted = wepInfo->m_fRange / 2.f; + float maxDistToKeep = 0.3f; + float wepRange = wepInfo->m_fRange / 2.f; if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED && !IsPlayer() && !(m_pedStats->m_flags & STAT_CAN_KICK)) - wepRangeAdjusted -= 0.3f; + wepRange -= 0.3f; - if (distWithTargetSc <= 5.f && victimPlayer && !victimPlayer->m_bDrunkVisualsWearOff) { - - if (m_pedInObjective->EnteringCar() && wepRangeAdjusted > 2.f) { + if (distWithTargetSc <= 5.f && victimPlayer && !victimPlayer->m_bNoPosForMeleeAttack) { + + if (m_pedInObjective->EnteringCar() && wepRange > 2.f) { m_vecSeekPos = m_pedInObjective->GetPosition(); - wepRangeAdjusted = 1.0f; - wepRange = 0.5f; + wepRange = 1.0f; + maxDistToKeep = 0.5f; } else { int8 attackDir = victimPlayer->FindMeleeAttackPoint(this, distWithTarget, endOfAttack); if (attackDir == -1) { m_vecSeekPos = victimPlayer->GetPosition(); - wepRange = 4.0f; + maxDistToKeep = 4.0f; } else { - victimPlayer->GetMeleeAttackCoords(m_vecSeekPos, attackDir, wepRangeAdjusted); + victimPlayer->GetMeleeAttackCoords(m_vecSeekPos, attackDir, wepRange); distWithTargetSc = (m_vecSeekPos - GetPosition()).Magnitude(); canReachVictim = true; } } } else { m_vecSeekPos = m_pedInObjective->GetPosition(); - wepRange = Max(0.8f, 0.9f * wepRangeAdjusted); - wepRangeAdjusted = 1.1f * wepRangeAdjusted; - if (victimPlayer && victimPlayer->m_bDrunkVisualsWearOff) + maxDistToKeep = Max(0.8f, 0.9f * wepRange); + wepRange *= 1.1f; + if (victimPlayer && victimPlayer->m_bNoPosForMeleeAttack) victimPlayer = nil; } @@ -6851,7 +6826,7 @@ CPed::KillCharOnFootMelee(CVector &ourPos, CVector &targetPos, CVector &distWith } } - if (distWithTargetSc > wepRange && !bKindaStayInSamePlace && m_nPedState != PED_ATTACK && + if (distWithTargetSc > maxDistToKeep && !bKindaStayInSamePlace && m_nPedState != PED_ATTACK && (m_nPedState != PED_FIGHT || m_curFightMove == FIGHTMOVE_IDLE) && !killPlayerInNoPoliceZone) { bool goForward = false; @@ -6859,10 +6834,10 @@ CPed::KillCharOnFootMelee(CVector &ourPos, CVector &targetPos, CVector &distWith if (m_nPedState == PED_FIGHT) { if (canReachVictim) { CVector attackAndVictimDist = m_vecSeekPos - m_pedInObjective->GetPosition(); - CVector victimFarness = attackAndVictimDist / wepRangeAdjusted; + CVector victimFarness = attackAndVictimDist / wepRange; CVector distVec = GetPosition() - m_pedInObjective->GetPosition(); float distSqr = distVec.MagnitudeSqr(); - if (sq(wepRangeAdjusted) > distSqr && distSqr > 0.05f) { + if (sq(wepRange) > distSqr && distSqr > 0.05f) { distVec.Normalise(); if (DotProduct2D(victimFarness, distVec) > Cos(DEGTORAD(30.f))) goForward = true; @@ -6888,15 +6863,15 @@ CPed::KillCharOnFootMelee(CVector &ourPos, CVector &targetPos, CVector &distWith SetSeek(m_vecSeekPos, m_distanceToCountSeekDone); } else { if (canReachVictim) - SetSeek(m_vecSeekPos, wepRange); + SetSeek(m_vecSeekPos, maxDistToKeep); else - SetSeek(m_pedInObjective, wepRange); + SetSeek(m_pedInObjective, maxDistToKeep); } return ATTACK_IN_PROGRESS; } if (m_attackTimer < CTimer::GetTimeInMilliseconds() - && distWithTargetSc < wepRangeAdjusted && m_pedInObjective->m_nPedState != PED_GETUP && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) { + && distWithTargetSc < wepRange && m_pedInObjective->m_nPedState != PED_GETUP && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) { if (bIsDucking) { CAnimBlendAssociation* duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_DOWN); @@ -6951,4 +6926,4 @@ bool CPed::CanBeDamagedByThisGangMember(CPed* who) { return m_gangFlags & (1 << (who->m_nPedType - PEDTYPE_GANG1)); -}
\ No newline at end of file +} diff --git a/src/peds/PedFight.cpp b/src/peds/PedFight.cpp index 4d4850e7..0367ef4c 100644 --- a/src/peds/PedFight.cpp +++ b/src/peds/PedFight.cpp @@ -26,10 +26,7 @@ #include "Glass.h" #include "SpecialFX.h" -//--MIAMI: file done except TODOs - -// TODO(Miami) -#define AUDIO_NOT_READY +//--MIAMI: file done uint16 nPlayerInComboMove; RpClump* flyingClumpTemp; @@ -875,23 +872,14 @@ CPed::Attack(void) } switch (ourWeapon->m_AnimToPlay) { case ASSOCGRP_UNARMED: - if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) { -#ifdef AUDIO_NOT_READY - DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, 0.0f); -#else + if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, (damagerType | (ourWeaponType << 8))); -#endif - } break; case ASSOCGRP_KNIFE: case ASSOCGRP_BASEBALLBAT: case ASSOCGRP_GOLFCLUB: case ASSOCGRP_CHAINSAW: -#ifdef AUDIO_NOT_READY - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f); -#else DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8))); -#endif break; default: break; @@ -1003,11 +991,7 @@ CPed::Attack(void) bIsAttacking = false; bIsPointingGunAt = false; m_shootTimer = CTimer::GetTimeInMilliseconds(); -#ifdef AUDIO_NOT_READY - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f); -#else DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType); -#endif return; } } @@ -1052,14 +1036,8 @@ CPed::Attack(void) ClearAimFlag(); // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading) - if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < animLoopEnd) { - -#ifdef AUDIO_NOT_READY - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f); -#else + if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < animLoopEnd) DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, ourWeaponType); -#endif - } // Fun fact: removing this part leds to reloading flamethrower if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) { @@ -4242,4 +4220,4 @@ CPed::RemoveWeaponAnims(int unused, float animDelta) else CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, -animDelta); } -}
\ No newline at end of file +} diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 76599777..101d342e 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -18,9 +18,15 @@ #include "CarCtrl.h" #include "MBlur.h" #include "Streaming.h" +#include "Population.h" +#include "Script.h" +#include "Replay.h" +#include "PedPlacement.h" #define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f +bool CPlayerPed::bDontAllowWeaponChange; + const uint32 CPlayerPed::nSaveStructSize = #ifdef COMPATIBLE_SAVES 1752; @@ -30,6 +36,12 @@ const uint32 CPlayerPed::nSaveStructSize = int32 idleAnimBlockIndex; +CPad* +GetPadFromPlayer(CPlayerPed*) +{ + return CPad::GetPad(0); +} + CPlayerPed::~CPlayerPed() { delete m_pWanted; @@ -52,10 +64,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) m_nSelectedWepSlot = 0; m_nSpeedTimer = 0; m_bSpeedTimerFlag = false; - - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); - m_pPointGunAt = nil; + SetWeaponLockOnTarget(nil); SetPedState(PED_IDLE); #ifndef FIX_BUGS m_fCurrentStamina = m_fMaxStamina = 150.0f; @@ -68,7 +77,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) m_bHaveTargetSelected = false; m_bHasLockOnTarget = false; m_bCanBeDamaged = true; - m_bDrunkVisualsWearOff = false; + m_bNoPosForMeleeAttack = false; m_fWalkAngle = 0.0f; m_fFPSMoveHeading = 0.0f; m_pMinigunTopAtomic = nil; @@ -76,13 +85,13 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) m_fGunSpinAngle = 0.0; m_nPadDownPressedInMilliseconds = 0; m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1; - unused1 = false; + unk1 = false; for (int i = 0; i < 6; i++) { m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f); m_pPedAtSafePos[i] = nil; m_pMeleeList[i] = nil; } - m_nCheckPlayersIndex = 0; + m_nAttackDirToCheck = 0; m_nLastBusFareCollected = 0; idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles"); } @@ -92,28 +101,28 @@ void CPlayerPed::ClearWeaponTarget() { if (m_nPedType == PEDTYPE_PLAYER1) { - if (m_pPointGunAt) - m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt); - - m_pPointGunAt = nil; + SetWeaponLockOnTarget(nil); TheCamera.ClearPlayerWeaponMode(); CWeaponEffects::ClearCrossHair(); } ClearPointGunAt(); } +// --MIAMI: Done void CPlayerPed::SetWantedLevel(int32 level) { m_pWanted->SetWantedLevel(level); } +// --MIAMI: Done void CPlayerPed::SetWantedLevelNoDrop(int32 level) { m_pWanted->SetWantedLevelNoDrop(level); } +// --MIAMI: Done void CPlayerPed::MakeObjectTargettable(int32 handle) { @@ -125,23 +134,21 @@ CPlayerPed::MakeObjectTargettable(int32 handle) } } +// --MIAMI: Done // I don't know the actual purpose of parameter void CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity) { if (m_pedStats->m_temper < 52) { m_pedStats->m_temper++; - } else { - if (annoyedByPassingEntity) { - if (m_pedStats->m_temper < 55) { - m_pedStats->m_temper++; - } else { - m_pedStats->m_temper = 46; - } - } + } else if (annoyedByPassingEntity && m_pedStats->m_temper < 55) { + m_pedStats->m_temper++; + } else if (annoyedByPassingEntity) { + m_pedStats->m_temper = 46; } } +// --MIAMI: Done void CPlayerPed::ClearAdrenaline(void) { @@ -151,6 +158,7 @@ CPlayerPed::ClearAdrenaline(void) } } +// --MIAMI: Done CPlayerInfo * CPlayerPed::GetPlayerInfoForThisPlayerPed() { @@ -160,6 +168,7 @@ CPlayerPed::GetPlayerInfoForThisPlayerPed() return nil; } +// --MIAMI: Done void CPlayerPed::SetupPlayerPed(int32 index) { @@ -175,18 +184,21 @@ CPlayerPed::SetupPlayerPed(int32 index) player->m_wepAccuracy = 100; } +// --MIAMI: Done void CPlayerPed::DeactivatePlayerPed(int32 index) { CWorld::Remove(CWorld::Players[index].m_pPed); } +// --MIAMI: Done void CPlayerPed::ReactivatePlayerPed(int32 index) { CWorld::Add(CWorld::Players[index].m_pPed); } +// --MIAMI: Done void CPlayerPed::UseSprintEnergy(void) { @@ -203,7 +215,7 @@ CPlayerPed::UseSprintEnergy(void) } } -// --MIAMI: Use that on everywhere except ProcessPlayerWeapon +// --MIAMI: Done void CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon) { @@ -228,7 +240,7 @@ CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon) TheCamera.ClearPlayerWeaponMode(); } -// --MIAMI: Done, but this should be only called from ProcessPlayerWeapon +// --MIAMI: Done void CPlayerPed::MakeChangesForNewWeapon(int32 slot) { @@ -236,6 +248,7 @@ CPlayerPed::MakeChangesForNewWeapon(int32 slot) MakeChangesForNewWeapon(m_weapons[slot].m_eWeaponType); } +// --MIAMI: Done void CPlayerPed::ReApplyMoveAnims(void) { @@ -244,7 +257,7 @@ CPlayerPed::ReApplyMoveAnims(void) for(int i = 0; i < ARRAY_SIZE(moveAnims); i++) { CAnimBlendAssociation *curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), moveAnims[i]); if (curMoveAssoc) { - if (strcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) { + if (CGeneral::faststrcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name)) { CAnimBlendAssociation *newMoveAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, moveAnims[i]); newMoveAssoc->blendDelta = curMoveAssoc->blendDelta; newMoveAssoc->blendAmount = curMoveAssoc->blendAmount; @@ -278,7 +291,6 @@ CPlayerPed::SetInitialState(void) ClearLookFlag(); bIsPointingGunAt = false; bRenderPedInCar = true; - if (m_pFire) m_pFire->Extinguish(); @@ -303,6 +315,7 @@ CPlayerPed::SetInitialState(void) m_attachWepAmmo = 0; } +// --MIAMI: Done void CPlayerPed::SetRealMoveAnim(void) { @@ -330,7 +343,7 @@ CPlayerPed::SetRealMoveAnim(void) if (!curIdleAssoc) curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); - if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) { + if (!((curRunStopAssoc && curRunStopAssoc->IsRunning()) || (curRunStopRAssoc && curRunStopRAssoc->IsRunning()))) { if (curRunStopAssoc && curRunStopAssoc->blendDelta >= 0.0f || curRunStopRAssoc && curRunStopRAssoc->blendDelta >= 0.0f) { if (curRunStopAssoc) { @@ -382,8 +395,8 @@ CPlayerPed::SetRealMoveAnim(void) CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f); } } - m_nMoveState = PEDMOVE_STILL; + } else { if (curIdleAssoc) { if (curWalkStartAssoc) { @@ -439,6 +452,7 @@ CPlayerPed::SetRealMoveAnim(void) } if (curSprintAssoc && (m_nMoveState != PEDMOVE_SPRINT || m_fMoveSpeed < 0.4f)) { + // Stop sprinting in various conditions if (curSprintAssoc->blendAmount == 0.0f) { curSprintAssoc->blendDelta = -1000.0f; curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT; @@ -462,8 +476,8 @@ CPlayerPed::SetRealMoveAnim(void) curRunAssoc->flags &= ~ASSOC_RUNNING; curRunAssoc->blendAmount = 0.0f; curRunAssoc->blendDelta = 0.0f; - } else if (curSprintAssoc->blendDelta >= 0.0f) { + } else if (curSprintAssoc->blendDelta >= 0.0f) { // Stop sprinting when tired curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT; curSprintAssoc->blendDelta = -1.0f; @@ -473,7 +487,9 @@ CPlayerPed::SetRealMoveAnim(void) curSprintAssoc->blendDelta = -8.0f; curRunAssoc->blendDelta = 8.0f; } + } else if (curWalkStartAssoc) { + // Walk start and walk/run shouldn't run at the same time curWalkAssoc->flags &= ~ASSOC_RUNNING; curRunAssoc->flags &= ~ASSOC_RUNNING; curWalkAssoc->blendAmount = 0.0f; @@ -481,11 +497,13 @@ CPlayerPed::SetRealMoveAnim(void) } else if (m_nMoveState == PEDMOVE_SPRINT) { if (curSprintAssoc) { + // We have anim, do it if (curSprintAssoc->blendDelta < 0.0f) { curSprintAssoc->blendDelta = 2.0f; curRunAssoc->blendDelta = -2.0f; } } else { + // Transition between run-sprint curWalkAssoc->blendAmount = 0.0f; curRunAssoc->blendAmount = 1.0f; curSprintAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_SPRINT, 2.0f); @@ -505,6 +523,8 @@ CPlayerPed::SetRealMoveAnim(void) curRunAssoc->blendAmount = 1.0f; m_nMoveState = PEDMOVE_RUN; } + curWalkAssoc->blendDelta = 0.0f; + curRunAssoc->blendDelta = 0.0f; } } } @@ -531,9 +551,15 @@ CPlayerPed::SetRealMoveAnim(void) if (curSprintAssoc) curSprintAssoc->speed = 2.0f; } + } else if (curSprintAssoc) { + if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIXED) { + curSprintAssoc->speed = 0.7f; + } else + curSprintAssoc->speed = 1.0f; } } +// --MIAMI: Done void CPlayerPed::RestoreSprintEnergy(float restoreSpeed) { @@ -541,21 +567,57 @@ CPlayerPed::RestoreSprintEnergy(float restoreSpeed) m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f; } - -// TODO(Miami) -bool +// --MIAMI: Done +float CPlayerPed::DoWeaponSmoothSpray(void) { if (m_nPedState == PED_ATTACK && !m_pPointGunAt) { - eWeaponType weapon = GetWeapon()->m_eWeaponType; - if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || - weapon == WEAPONTYPE_TEC9 || weapon == WEAPONTYPE_SILENCED_INGRAM || weapon == WEAPONTYPE_MP5 || - weapon == WEAPONTYPE_SHOTGUN || weapon == WEAPONTYPE_RUGER || weapon == WEAPONTYPE_M4 || weapon == WEAPONTYPE_HELICANNON) - return true; - } - return false; + CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + switch (GetWeapon()->m_eWeaponType) { + case WEAPONTYPE_GOLFCLUB: + case WEAPONTYPE_NIGHTSTICK: + case WEAPONTYPE_BASEBALLBAT: + if (GetFireAnimGround(weaponInfo, false) && RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(weaponInfo, false))) + return PI / 176.f; + else + return -1.0f; + + case WEAPONTYPE_CHAINSAW: + if (GetMeleeStartAnim(weaponInfo) && RpAnimBlendClumpGetAssociation(GetClump(), GetMeleeStartAnim(weaponInfo))) + return PI / 128.0f; + else if (GetFireAnimGround(weaponInfo, false) && RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(weaponInfo, false))) + return PI / 176.f; + else + return PI / 80.f; + + case WEAPONTYPE_PYTHON: + return PI / 112.f; + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + return PI / 112.f; + case WEAPONTYPE_UZI: + case WEAPONTYPE_MP5: + return PI / 112.f; + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + return PI / 112.f; + case WEAPONTYPE_FLAMETHROWER: + return PI / 80.f; + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: + case WEAPONTYPE_HELICANNON: + return PI / 176.f; + default: + return -1.0f; + } + } else if (bIsDucking) + return PI / 112.f; + else + return -1.0f; } +// --MIAMI: Done void CPlayerPed::DoStuffToGoOnFire(void) { @@ -563,6 +625,7 @@ CPlayerPed::DoStuffToGoOnFire(void) TheCamera.ClearPlayerWeaponMode(); } +// --MIAMI: Done bool CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed) { @@ -571,18 +634,10 @@ CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed) if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange) return true; -/* - if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_RUGER) - return false; - - distVec.Normalise(); - - if (DotProduct(distVec,GetForward()) < 0.4f) - return true; -*/ return false; } +// --MIAMI: Done // Cancels landing anim while running & jumping? I think void CPlayerPed::RunningLand(CPad *padUsed) @@ -601,9 +656,13 @@ CPlayerPed::RunningLand(CPad *padUsed) } } +// --MIAMI: Done bool -CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect) +CPlayerPed::IsThisPedAnAimingPriority(CPed *suspect) { + if (!suspect->bIsPlayerFriend) + return true; + if (suspect->m_pPointGunAt == this) return true; @@ -617,7 +676,7 @@ CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect) default: break; } - return false; + return suspect->m_nPedState == PED_ABSEIL; } // --MIAMI: Done @@ -638,6 +697,7 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed) if (!padUsed->GetTarget() && !m_attachedTo) { RestorePreviousState(); TheCamera.ClearPlayerWeaponMode(); + return; } int firingRate = GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE ? 333 : 266; @@ -656,7 +716,7 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed) GetWeapon()->Update(m_audioEntityId, nil); } -// --MIAMI: Done except commented thing +// --MIAMI: Done // I think R* also used goto in here. void CPlayerPed::ProcessWeaponSwitch(CPad *padUsed) @@ -664,8 +724,7 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed) if (CDarkel::FrenzyOnGoing() || m_attachedTo) goto switchDetectDone; - // TODO(Miami): byte_A10B57 - if (!m_pPointGunAt && /* !byte_A10B57 && */ GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR) { + if (!m_pPointGunAt && !bDontAllowWeaponChange && GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR) { if (padUsed->CycleWeaponRightJustDown()) { if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON @@ -759,7 +818,7 @@ CPlayerPed::PlayerControlM16(CPad *padUsed) bCrouchWhenShooting = false; } - if (!padUsed->GetTarget()) { + if (!padUsed->GetTarget() && !m_attachedTo) { RestorePreviousState(); TheCamera.ClearPlayerWeaponMode(); } @@ -816,14 +875,7 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) float padMove = CVector2D(leftRight, upDown).Magnitude(); float padMoveInGameUnit = padMove / PAD_MOVE_TO_GAME_WORLD_MOVE; if (padMoveInGameUnit > 0.0f) { -#ifdef FREE_CAM - if (!CCamera::bFreeCam) - m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation); - else - m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation; -#else m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation); -#endif m_fMoveSpeed = Min(padMoveInGameUnit, 0.07f * CTimer::GetTimeStep() + m_fMoveSpeed); } else { m_fMoveSpeed = 0.0f; @@ -831,8 +883,7 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) if (m_nPedState == PED_JUMP) { if (bIsInTheAir) { - if (bUsesCollision && !bHitSteepSlope && - (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f) + if (bUsesCollision && !bHitSteepSlope && (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f) && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) { float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O @@ -849,15 +900,15 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) return; } - if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) - && padUsed->GetSprint()) { + if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && padUsed->GetSprint()) { m_nMoveState = PEDMOVE_SPRINT; } if (m_nPedState != PED_FIGHT) SetRealMoveAnim(); - if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) - && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) { + if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && + padUsed->JumpJustDown() && m_nPedState != PED_JUMP) { + ClearAttack(); ClearWeaponTarget(); if (m_nEvadeAmount != 0 && m_pEvadingFrom) { @@ -868,15 +919,22 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) SetJump(); } } + + // FIX: Fact that PlayIdleAnimations only called through PlayerControlZelda was making it visible to only Classic control players. This isn't fair! +#ifdef FIX_BUGS + if (m_nPedState != PED_FIGHT) + PlayIdleAnimations(padUsed); +#endif } +// --MIAMI: Done void CPlayerPed::KeepAreaAroundPlayerClear(void) { BuildPedLists(); for (int i = 0; i < m_numNearPeds; ++i) { CPed *nearPed = m_nearPeds[i]; - if (nearPed->CharCreatedBy == RANDOM_CHAR && !nearPed->DyingOrDead()) { + if (nearPed->CharCreatedBy == RANDOM_CHAR && nearPed->m_nPedState != PED_DRIVING && !nearPed->DyingOrDead()) { if (nearPed->GetIsOnScreen()) { if (nearPed->m_objective == OBJECTIVE_NONE) { nearPed->SetFindPathAndFlee(this, 5000, true); @@ -919,18 +977,17 @@ CPlayerPed::KeepAreaAroundPlayerClear(void) } } +// --MIAMI: Done void -CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool lookToLeft) +CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool lookToLeft, bool priority) { + // priority param is unused CVector distVec = candidate->GetPosition() - GetPosition(); if (distVec.Magnitude2D() <= distLimit) { if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) { -#ifdef VC_PED_PORTS float angleBetweenUs = CGeneral::GetATanOfXY(candidate->GetPosition().x - TheCamera.GetPosition().x, - candidate->GetPosition().y - TheCamera.GetPosition().y); -#else - float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y); -#endif + candidate->GetPosition().y - TheCamera.GetPosition().y); + angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset); float closeness; if (lookToLeft) { @@ -947,6 +1004,7 @@ CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, } } +// --MIAMI: Done void CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool priority) { @@ -959,7 +1017,7 @@ CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastC float closeness = -dist - 5.0f * Abs(angleBetweenUs); if (priority) { - closeness += 5.0f; + closeness += 30.0f; } if (closeness > *lastCloseness) { @@ -971,45 +1029,80 @@ CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastC } bool +CPlayerPed::CanIKReachThisTarget(CVector target, CWeapon* weapon, bool zRotImportant) +{ + float angleToFace = CGeneral::GetRadianAngleBetweenPoints(target.x, target.y, GetPosition().x, GetPosition().y); + float angleDiff = CGeneral::LimitRadianAngle(angleToFace - m_fRotationCur); + + return (!zRotImportant || CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_bCanAimWithArm || Abs(angleDiff) <= HALFPI) && + (CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_bCanAimWithArm || Abs(target.z - GetPosition().z) <= (target - GetPosition()).Magnitude2D()); +} + +void +CPlayerPed::RotatePlayerToTrackTarget(void) +{ + if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm) + return; + + float angleToFace = CGeneral::GetRadianAngleBetweenPoints( + m_pPointGunAt->GetPosition().x, m_pPointGunAt->GetPosition().y, + GetPosition().x, GetPosition().y); + + float angleDiff = CGeneral::LimitRadianAngle(m_fRotationCur - angleToFace); + if (angleDiff < -DEGTORAD(25.0f)) { + m_fRotationCur -= angleDiff + DEGTORAD(25.0f); + m_fRotationDest -= angleDiff + DEGTORAD(25.0f); + + } else if (angleDiff > DEGTORAD(25.0f)) { + m_fRotationCur -= angleDiff - DEGTORAD(25.0f); + m_fRotationDest -= angleDiff - DEGTORAD(25.0f); + } +} + +// --MIAMI: Done +bool CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft) { CEntity *nextTarget = nil; float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange; - // nextTarget = nil; + // nextTarget = nil; // duplicate float lastCloseness = -10000.0f; - // unused - // CGeneral::GetATanOfXY(GetForward().x, GetForward().y); + // CGeneral::GetATanOfXY(GetForward().x, GetForward().y); // unused CVector distVec = previousTarget->GetPosition() - GetPosition(); float referenceBeta = CGeneral::GetATanOfXY(distVec.x, distVec.y); for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) { CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h); if (pedToCheck) { - if (pedToCheck != FindPlayerPed() && pedToCheck != previousTarget) { - if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle - && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) { + if (pedToCheck != this && pedToCheck != previousTarget) { + if (!pedToCheck->DyingOrDead() +#ifndef AIMING_VEHICLE_OCCUPANTS // Mobile thing + && (!pedToCheck->bInVehicle || (pedToCheck->m_pMyVehicle && pedToCheck->m_pMyVehicle->IsBike())) +#endif + && pedToCheck->m_leader != this && !pedToCheck->bNeverEverTargetThisPed + && OurPedCanSeeThisOne(pedToCheck) && CanIKReachThisTarget(pedToCheck->GetPosition(), GetWeapon(), true)) { EvaluateNeighbouringTarget(pedToCheck, &nextTarget, &lastCloseness, - weaponRange, referenceBeta, lookToLeft); + weaponRange, referenceBeta, lookToLeft, IsThisPedAnAimingPriority(pedToCheck)); } } } } for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) { CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]); - if (obj) - EvaluateNeighbouringTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, lookToLeft); + if (obj && !obj->bHasBeenDamaged && CanIKReachThisTarget(obj->GetPosition(), GetWeapon(), true)) + EvaluateNeighbouringTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, lookToLeft, true); } if (!nextTarget) return false; - m_pPointGunAt = nextTarget; - if (nextTarget) - nextTarget->RegisterReference((CEntity**)&m_pPointGunAt); + SetWeaponLockOnTarget(nextTarget); + bDontAllowWeaponChange = true; SetPointGunAt(nextTarget); return true; } +// --MIAMI: Done bool CPlayerPed::FindWeaponLockOnTarget(void) { @@ -1019,40 +1112,43 @@ CPlayerPed::FindWeaponLockOnTarget(void) if (m_pPointGunAt) { CVector distVec = m_pPointGunAt->GetPosition() - GetPosition(); if (distVec.Magnitude2D() > weaponRange) { - m_pPointGunAt = nil; + SetWeaponLockOnTarget(nil); return false; } else { return true; } } - // nextTarget = nil; + // nextTarget = nil; // duplicate float lastCloseness = -10000.0f; float referenceBeta = CGeneral::GetATanOfXY(GetForward().x, GetForward().y); for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) { CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h); if (pedToCheck) { - if (pedToCheck != FindPlayerPed()) { - if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle - && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) { + if (pedToCheck != this) { + if (!pedToCheck->DyingOrDead() +#ifndef AIMING_VEHICLE_OCCUPANTS // Mobile thing + && (!pedToCheck->bInVehicle || (pedToCheck->m_pMyVehicle && pedToCheck->m_pMyVehicle->IsBike())) +#endif + && pedToCheck->m_leader != this && !pedToCheck->bNeverEverTargetThisPed + && OurPedCanSeeThisOne(pedToCheck) && CanIKReachThisTarget(pedToCheck->GetPosition(), GetWeapon(), true)) { EvaluateTarget(pedToCheck, &nextTarget, &lastCloseness, - weaponRange, referenceBeta, IsThisPedAttackingPlayer(pedToCheck)); + weaponRange, referenceBeta, IsThisPedAnAimingPriority(pedToCheck)); } } } } for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) { CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]); - if (obj) - EvaluateTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, false); + if (obj && !obj->bHasBeenDamaged && CanIKReachThisTarget(obj->GetPosition(), GetWeapon(), true)) + EvaluateTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, true); } if (!nextTarget) return false; - m_pPointGunAt = nextTarget; - if (nextTarget) - nextTarget->RegisterReference((CEntity**)&m_pPointGunAt); + SetWeaponLockOnTarget(nextTarget); + bDontAllowWeaponChange = true; SetPointGunAt(nextTarget); Say(SOUND_PED_AIMING); return true; @@ -1131,7 +1227,6 @@ CPlayerPed::ProcessAnimGroups(void) } } -// TODO(Miami) void CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) { @@ -1199,12 +1294,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) } else { m_fAttackButtonCounter = 0.0f; } -#ifdef FREE_CAM - if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f) - StartFightAttack(padUsed->GetWeapon()); - else -#endif - SetAttack(m_pPointGunAt); + SetAttack(m_pPointGunAt); } else { if (m_nPedState == PED_ATTACK) { if (padUsed->WeaponJustDown()) { @@ -1221,8 +1311,8 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR && GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE || padUsed->WeaponJustDown()) - SetAttack(nil); + } else if (padUsed->WeaponJustDown()) { if (m_fMoveSpeed < 1.0f || m_nPedState == PED_FIGHT) StartFightAttack(padUsed->GetWeapon()); @@ -1255,15 +1345,14 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) // On this one we can rotate arm. if (weaponInfo->m_bCanAimWithArm) { if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately! - SetPointGunAt(nil); + SetWeaponLockOnTarget(nil); bIsPointingGunAt = false; // to not stop after attack } SetLookFlag(limitedCam, true); SetAimFlag(limitedCam); -#ifdef VC_PED_PORTS SetLookTimer(INT32_MAX); // removing this makes head move for real, but I experinced some bugs. -#endif + } else { m_fRotationDest = limitedCam; changedHeadingRate = 2; @@ -1283,7 +1372,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2; } } - } else if (weaponInfo->m_bCanAimWithArm) + } else if (weaponInfo->m_bCanAimWithArm && m_nPedState != PED_ATTACK) ClearPointGunAt(); } } @@ -1307,19 +1396,23 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) return; } - CPed *gunPointed = (CPed*)m_pPointGunAt; - if (gunPointed && gunPointed->IsPed() && - ((gunPointed->bInVehicle && (!gunPointed->m_pMyVehicle || !gunPointed->m_pMyVehicle->IsBike())) || !CGame::nastyGame && gunPointed->DyingOrDead())) { + if (m_pPointGunAt->IsPed() && ( +#ifndef AIMING_VEHICLE_OCCUPANTS + (((CPed*)m_pPointGunAt)->bInVehicle && (!((CPed*)m_pPointGunAt)->m_pMyVehicle || !((CPed*)m_pPointGunAt)->m_pMyVehicle->IsBike())) || +#endif + !CGame::nastyGame && ((CPed*)m_pPointGunAt)->DyingOrDead())) { ClearWeaponTarget(); return; } if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon()) || - (!bCanPointGunAtTarget && !weaponInfo->m_bCanAimWithArm)) { + (!bCanPointGunAtTarget && !weaponInfo->m_bCanAimWithArm)) { // this line isn't on Mobile, idk why ClearWeaponTarget(); return; } - // TODO(Miami): RotatePlayerToTrackTarget + if (m_pPointGunAt) { + RotatePlayerToTrackTarget(); + } if (m_pPointGunAt) { if (padUsed->ShiftTargetLeftJustDown()) @@ -1329,12 +1422,8 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) } TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SYPHON, 0, 0); TheCamera.UpdateAimingCoors(m_pPointGunAt->GetPosition()); - } -#ifdef FREE_CAM - else if ((CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE) || !CCamera::m_bUseMouse3rdPerson) { -#else - else if (!CCamera::m_bUseMouse3rdPerson) { -#endif + + } else if (!CCamera::m_bUseMouse3rdPerson) { if (padUsed->TargetJustDown() || TheCamera.m_bJustJumpedOutOf1stPersonBecauseOfTarget) FindWeaponLockOnTarget(); } @@ -1343,16 +1432,12 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) } if (m_pPointGunAt) { -#ifndef VC_PED_PORTS - CVector markPos = m_pPointGunAt->GetPosition(); -#else CVector markPos; if (m_pPointGunAt->IsPed()) { ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition(*(RwV3d *)&markPos, PED_MID); } else { markPos = m_pPointGunAt->GetPosition(); } -#endif if (bCanPointGunAtTarget) { CWeaponEffects::MarkTarget(markPos, 64, 0, 0, 255, 0.8f); } else { @@ -1362,17 +1447,29 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) m_bHasLockOnTarget = m_pPointGunAt != nil; } +bool +CPlayerPed::MovementDisabledBecauseOfTargeting(void) +{ + return m_pPointGunAt && !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm; +} + +// --MIAMI: Done void CPlayerPed::PlayerControlZelda(CPad *padUsed) { - bool doSmoothSpray = DoWeaponSmoothSpray(); + float smoothSprayRate = DoWeaponSmoothSpray(); float camOrientation = TheCamera.Orientation; float leftRight = padUsed->GetPedWalkLeftRight(); float upDown = padUsed->GetPedWalkUpDown(); float padMoveInGameUnit; bool smoothSprayWithoutMove = false; - if (doSmoothSpray && upDown > 0.0f) { + if (MovementDisabledBecauseOfTargeting()) { + upDown = 0.0f; + leftRight = 0.0f; + } + + if (smoothSprayRate > 0.0f && upDown > 0.0f) { padMoveInGameUnit = 0.0f; smoothSprayWithoutMove = true; } else { @@ -1382,12 +1479,8 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed) if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) { float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown); float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation); - if (doSmoothSpray) { - if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || GetWeapon()->m_eWeaponType == WEAPONTYPE_COLT45 - || CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nWeaponSlot == 5) - m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 80.0f) * CTimer::GetTimeStep(); - else - m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 128.0f) * CTimer::GetTimeStep(); + if (smoothSprayRate > 0.0f) { + m_fRotationDest = m_fRotationCur - leftRight / 128.0f * smoothSprayRate * CTimer::GetTimeStep(); } else { m_fRotationDest = neededTurn; } @@ -1419,12 +1512,11 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed) return; } - if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) - && padUsed->GetSprint()) { - - if (!m_pCurrentPhysSurface || !m_pCurrentPhysSurface->bInfiniteMass || m_pCurrentPhysSurface->m_phy_flagA08) + if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && padUsed->GetSprint()) { + if (!m_pCurrentPhysSurface || (!m_pCurrentPhysSurface->bInfiniteMass || m_pCurrentPhysSurface->m_phy_flagA08)) m_nMoveState = PEDMOVE_SPRINT; } + if (m_nPedState != PED_FIGHT) SetRealMoveAnim(); @@ -1443,32 +1535,165 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed) PlayIdleAnimations(padUsed); } +// Finds nice positions for peds to duck and shoot player. And it's inside PlayerPed, this is treachery! +void +CPlayerPed::FindNewAttackPoints(void) +{ + for (int i=0; i<ARRAY_SIZE(m_pPedAtSafePos); i++) { + CPed *safeNeighbour = m_pPedAtSafePos[i]; + if (safeNeighbour) { + if (safeNeighbour->m_nPedState == PED_DEAD || safeNeighbour->m_pedInObjective != this) { + m_vecSafePos[i].x = 0.0f; + m_vecSafePos[i].y = 0.0f; + m_vecSafePos[i].z = 0.0f; + m_pPedAtSafePos[i] = nil; + } + } else { + m_vecSafePos[i].x = 0.0f; + m_vecSafePos[i].y = 0.0f; + m_vecSafePos[i].z = 0.0f; + } + } + CEntity *entities[6]; + int16 numEnts; + float rightMult, fwdMult; + CWorld::FindObjectsInRange(GetPosition(), 18.0f, true, &numEnts, 6, entities, true, false, false, true, false); + for (int i = 0; i < numEnts; ++i) { + CEntity *ent = entities[i]; + int16 mi = ent->GetModelIndex(); + if (!ent->IsObject() || ((CObject*)ent)->m_nSpecialCollisionResponseCases == COLLRESPONSE_FENCEPART) + if (!IsTreeModel(mi)) + continue; + + if (mi == MI_TRAFFICLIGHTS) { + rightMult = 2.957f; + fwdMult = 0.147f; + + } else if (mi == MI_SINGLESTREETLIGHTS1) { + rightMult = 0.744f; + fwdMult = 0.0f; + + } else if (mi == MI_SINGLESTREETLIGHTS2) { + rightMult = 0.043f; + fwdMult = 0.0f; + + } else if (mi == MI_SINGLESTREETLIGHTS3) { + rightMult = 1.143f; + fwdMult = 0.145f; + + } else if (mi == MI_DOUBLESTREETLIGHTS) { + rightMult = 0.744f; + fwdMult = 0.0f; + + } else if (mi == MI_LAMPPOST1) { + rightMult = 0.744f; + fwdMult = 0.0f; + + } else if (mi == MI_TRAFFICLIGHT01) { + rightMult = 2.957f; + fwdMult = 0.147f; + + } else if (mi == MI_LITTLEHA_POLICE) { + rightMult = 0.0f; + fwdMult = 0.0f; + + } else if (mi == MI_PARKBENCH) { + rightMult = 0.0f; + fwdMult = 0.0f; + + } else if (IsTreeModel(mi)) { + rightMult = 0.0f; + fwdMult = 0.0f; + } else + continue; + + CVector entAttackPoint(rightMult * ent->GetRight().x + fwdMult * ent->GetForward().x + ent->GetPosition().x, + rightMult * ent->GetRight().y + fwdMult * ent->GetForward().y + ent->GetPosition().y, + ent->GetPosition().z); + CVector attackerPos = GetPosition() - entAttackPoint; // for now it's dist, not attackerPos + CVector dirTowardsUs = attackerPos; + dirTowardsUs.Normalise(); + dirTowardsUs *= 2.0f; + attackerPos = entAttackPoint - dirTowardsUs; // to make cop farther from us + CPedPlacement::FindZCoorForPed(&attackerPos); + if (CPedPlacement::IsPositionClearForPed(attackerPos)) + m_vecSafePos[i] = attackerPos; + } +} + void CPlayerPed::ProcessControl(void) { + // Mobile has some debug/abandoned cheat thing in here: "gbFrankenTommy" + if (m_nEvadeAmount != 0) --m_nEvadeAmount; if (m_nEvadeAmount == 0) m_pEvadingFrom = nil; + if (m_pWanted->m_nWantedLevel > 0) + FindNewAttackPoints(); + + UpdateMeleeAttackers(); + if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat()) { bTryingToReachDryLand = true; + } else if (!(((uint8)CTimer::GetFrameCounter() + m_randomSeed) & 0xF)) { - CVehicle *nearVeh = (CVehicle*)CWorld::TestSphereAgainstWorld(GetPosition(), 7.0f, nil, - false, true, false, false, false, false); + CVehicle *nearVeh = (CVehicle*)CWorld::TestSphereAgainstWorld(GetPosition(), 7.0f, nil, false, true, false, false, false, false); if (nearVeh && nearVeh->IsBoat()) bTryingToReachDryLand = true; else bTryingToReachDryLand = false; } + + if (m_nFadeDrunkenness) { + if (m_nDrunkenness - 1 > 0) { + --m_nDrunkenness; + } else { + m_nDrunkenness = 0; + CMBlur::ClearDrunkBlur(); + m_nFadeDrunkenness = 0; + } + } + if (m_nDrunkenness != 0) { + CMBlur::SetDrunkBlur(m_nDrunkenness / 255.f); + } CPed::ProcessControl(); + SetNearbyPedsToInteractWithPlayer(); if (bWasPostponed) return; - CPad *padUsed = CPad::GetPad(0); + CPad *padUsed = GetPadFromPlayer(this); m_pWanted->Update(); - CEntity::PruneReferences(); + PruneReferences(); + + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN) { + CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + CAnimBlendAssociation *fireAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(weaponInfo)); + if (fireAnim && fireAnim->currentTime - fireAnim->timeStep < weaponInfo->m_fAnimLoopEnd && m_nPedState == PED_ATTACK) { + if (m_fGunSpinSpeed < 0.45f) { + m_fGunSpinSpeed = Min(0.45f, m_fGunSpinSpeed + CTimer::GetTimeStep() * 0.013f); + } + + if (padUsed->GetWeapon() && GetWeapon()->m_nAmmoTotal > 0 && fireAnim->currentTime >= weaponInfo->m_fAnimLoopStart) { + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_MINIGUN_ATTACK, 0.0f); + } else { + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_MINIGUN_2, m_fGunSpinSpeed * (20.f / 9)); + } + } else { + if (m_fGunSpinSpeed > 0.0f) { + if (m_fGunSpinSpeed >= 0.45f) { + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_MINIGUN_3, 0.0f); + } + m_fGunSpinSpeed = Max(0.0f, m_fGunSpinSpeed - CTimer::GetTimeStep() * 0.003f); + } + } + } + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW && m_nPedState != PED_ATTACK && !bInVehicle) { + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_CHAINSAW_ATTACK, 0.0f); + } if (m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT) RestoreSprintEnergy(1.0f); @@ -1486,27 +1711,30 @@ CPlayerPed::ProcessControl(void) return; } if (m_nPedState == PED_DRIVING && m_objective != OBJECTIVE_LEAVE_CAR) { - if (m_pMyVehicle->IsCar() && ((CAutomobile*)m_pMyVehicle)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING) { - CAnimBlendAssociation *rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR); - if (!rollDoorAssoc) { - rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW); - } + if (!CReplay::IsPlayingBack() || m_pMyVehicle) { + if (m_pMyVehicle->IsCar() && ((CAutomobile*)m_pMyVehicle)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING) { + CAnimBlendAssociation *rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR); - // These comparisons are wrong, they return uint16 - if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || padUsed - && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f - || padUsed->GetBrake() != 0.0f)) { + if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || (rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW))) { + if (rollDoorAssoc) + m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime); - if (rollDoorAssoc) - m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime); - } else { - m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF; - if (m_pMyVehicle->bLowVehicle) - rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW); - else - rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR); + } else { + // These comparisons are wrong, they return uint16 + if (padUsed && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f || padUsed->GetBrake() != 0.0f)) { + if (rollDoorAssoc) + m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime); + + } else { + m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF; + if (m_pMyVehicle->bLowVehicle) + rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW); + else + rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR); - rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this); + rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this); + } + } } } return; @@ -1515,8 +1743,8 @@ CPlayerPed::ProcessControl(void) m_nMoveState = PEDMOVE_STILL; if (bIsLanding) RunningLand(padUsed); - if (padUsed && padUsed->WeaponJustDown() && !TheCamera.Using1stPersonWeaponMode()) { + if (padUsed && padUsed->WeaponJustDown() && !TheCamera.Using1stPersonWeaponMode()) { // ...Really? eWeaponType playerWeapon = FindPlayerPed()->GetWeapon()->m_eWeaponType; if (playerWeapon == WEAPONTYPE_SNIPERRIFLE || playerWeapon == WEAPONTYPE_LASERSCOPE) { @@ -1539,12 +1767,19 @@ CPlayerPed::ProcessControl(void) if (TheCamera.Using1stPersonWeaponMode()) { if (padUsed) PlayerControlFighter(padUsed); - } else if (TheCamera.Cams[0].Using3rdPersonMouseCam()) { + + } else if (TheCamera.Cams[0].Using3rdPersonMouseCam() +#ifdef FREE_CAM + && !CCamera::bFreeCam +#endif + ) { if (padUsed) PlayerControl1stPersonRunAround(padUsed); + } else if (m_nPedState == PED_FIGHT) { if (padUsed) PlayerControlFighter(padUsed); + } else if (padUsed) { PlayerControlZelda(padUsed); } @@ -1621,6 +1856,7 @@ CPlayerPed::ProcessControl(void) if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE) { if (padUsed) PlayerControlSniper(padUsed); + } else if (padUsed) { PlayerControlM16(padUsed); } @@ -1683,20 +1919,18 @@ CPlayerPed::ProcessControl(void) m_lookTimer = 0; float camAngle = CGeneral::LimitRadianAngle(TheCamera.Cams[TheCamera.ActiveCam].Front.Heading()); float angleBetweenPlayerAndCam = Abs(camAngle - m_fRotationCur); - if (m_nPedState != PED_ATTACK - && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) { + if (m_nPedState != PED_ATTACK && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) { if (angleBetweenPlayerAndCam > DEGTORAD(150.0f) && angleBetweenPlayerAndCam < DEGTORAD(210.0f)) { float rightTurnAngle = CGeneral::LimitRadianAngle(m_fRotationCur - DEGTORAD(150.0f)); float leftTurnAngle = CGeneral::LimitRadianAngle(DEGTORAD(150.0f) + m_fRotationCur); - if (m_fLookDirection != 999999.0f) { - if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection)) - camAngle = rightTurnAngle; - else - camAngle = leftTurnAngle; - } else { + + if (m_fLookDirection == 999999.0f || bIsDucking) camAngle = rightTurnAngle; - } + else if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection)) + camAngle = rightTurnAngle; + else + camAngle = leftTurnAngle; } SetLookFlag(camAngle, true); SetLookTimer(CTimer::GetTimeStepInMilliseconds() * 5.0f); @@ -1722,18 +1956,23 @@ CPlayerPed::ProcessControl(void) m_bSpeedTimerFlag = false; } + if (bDontAllowWeaponChange && FindPlayerPed() == this) { + if (!CPad::GetPad(0)->GetTarget()) + bDontAllowWeaponChange = false; + } + if (m_nPedState != PED_SNIPER_MODE && (GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING || m_nPedState == PED_ATTACK)) m_nPadDownPressedInMilliseconds = CTimer::GetTimeInMilliseconds(); -#ifdef PED_SKIN - if (!bIsVisible && IsClumpSkinned(GetClump())) + if (!bIsVisible) UpdateRpHAnim(); -#endif } +// --MIAMI: Done bool CPlayerPed::DoesPlayerWantNewWeapon(eWeaponType weapon, bool onlyIfSlotIsEmpty) { + // GetPadFromPlayer(); // unused uint32 slot = CWeaponInfo::GetWeaponInfo(weapon)->m_nWeaponSlot; if (!HasWeaponSlot(slot) || GetWeapon(slot).m_eWeaponType == weapon) @@ -1746,7 +1985,6 @@ CPlayerPed::DoesPlayerWantNewWeapon(eWeaponType weapon, bool onlyIfSlotIsEmpty) return m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN || slot != m_currentWeapon; } -// TODO(Miami): This only works on gamepad cam! This isn't fair void CPlayerPed::PlayIdleAnimations(CPad *padUsed) { @@ -1816,6 +2054,84 @@ CPlayerPed::PlayIdleAnimations(CPad *padUsed) // --MIAMI: Done void +CPlayerPed::SetNearbyPedsToInteractWithPlayer(void) +{ + if (CGame::noProstitutes) + return; + + for (int i = 0; i < m_numNearPeds; ++i) { + CPed *nearPed = m_nearPeds[i]; + if (nearPed && nearPed->m_objectiveTimer < CTimer::GetTimeInMilliseconds() && !CTheScripts::IsPlayerOnAMission()) { + int mi = nearPed->GetModelIndex(); + if (CPopulation::CanSolicitPlayerOnFoot(mi)) { + CVector distToMe = nearPed->GetPosition() - GetPosition(); + CVector dirToMe = GetPosition() - nearPed->GetPosition(); + dirToMe.Normalise(); + if (DotProduct(dirToMe, nearPed->GetForward()) > 0.707 && DotProduct(GetForward(), nearPed->GetForward()) < -0.707 // those are double + && distToMe.MagnitudeSqr() < 9.0f && nearPed->m_objective == OBJECTIVE_NONE) { + nearPed->SetObjective(OBJECTIVE_SOLICIT_FOOT, this); + nearPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 10000; + nearPed->Say(SOUND_PED_SOLICIT); + } + } else if (CPopulation::CanSolicitPlayerInCar(mi)) { + if (InVehicle() && m_pMyVehicle->IsVehicleNormal()) { + if (m_pMyVehicle->IsCar()) { + CVector distToVeh = nearPed->GetPosition() - m_pMyVehicle->GetPosition(); + if (distToVeh.MagnitudeSqr() < 25.0f && m_pMyVehicle->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil) && nearPed->m_objective == OBJECTIVE_NONE) { + nearPed->SetObjective(OBJECTIVE_SOLICIT_VEHICLE, m_pMyVehicle); + } + } + } + } + } + } +} + +// --MIAMI: Done +void +CPlayerPed::UpdateMeleeAttackers(void) +{ + CVector attackCoord; + if (((CTimer::GetFrameCounter() + m_randomSeed + 7) & 3) == 0) { + GetMeleeAttackCoords(attackCoord, m_nAttackDirToCheck, 2.0f); + + // Check if there is any vehicle/building inbetween us and m_nAttackDirToCheck. Peds will be able to attack us from those available directions. + if (CWorld::GetIsLineOfSightClear(GetPosition(), attackCoord, true, true, false, true, false, false, false) + && !CWorld::TestSphereAgainstWorld(attackCoord, 0.4f, m_pMeleeList[m_nAttackDirToCheck], true, true, false, true, false, false)) { + if (m_pMeleeList[m_nAttackDirToCheck] == this) + m_pMeleeList[m_nAttackDirToCheck] = nil; // mark it as available + } else { + m_pMeleeList[m_nAttackDirToCheck] = this; // slot not available. useful for m_bNoPosForMeleeAttack + } + if (++m_nAttackDirToCheck >= ARRAY_SIZE(m_pMeleeList)) + m_nAttackDirToCheck = 0; + } + // 6 directions + for (int i = 0; i < ARRAY_SIZE(m_pMeleeList); ++i) { + CPed *victim = m_pMeleeList[i]; + if (victim && victim != this) { + if (victim->m_nPedState != PED_DEAD && victim->m_pedInObjective == this) { + if (victim->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || victim->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS || victim->m_objective == OBJECTIVE_KILL_CHAR_ON_BOAT) { + GetMeleeAttackCoords(attackCoord, i, 2.0f); + if ((attackCoord - GetPosition()).MagnitudeSqr() > 12.25f) + m_pMeleeList[i] = nil; + } else { + m_pMeleeList[i] = nil; + } + } else { + m_pMeleeList[i] = nil; + } + } + } + m_bNoPosForMeleeAttack = m_pMeleeList[0] == this && m_pMeleeList[1] == this && m_pMeleeList[2] == this +#ifdef FIX_BUGS + && m_pMeleeList[3] == this +#endif + && m_pMeleeList[4] == this && m_pMeleeList[5] == this; +} + +// --MIAMI: Done +void CPlayerPed::RemovePedFromMeleeList(CPed *ped) { int i = 0; diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index 8a6e7576..e09a67f0 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -31,12 +31,12 @@ public: bool m_bAdrenalineActive; bool m_bHasLockOnTarget; bool m_bCanBeDamaged; - bool m_bDrunkVisualsWearOff; // TODO(Miami): That may be something else + bool m_bNoPosForMeleeAttack; + bool unk1; CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree CPed *m_pPedAtSafePos[6]; CPed *m_pMeleeList[6]; // reachable peds at each direction(6) - char unused1; - int16 m_nCheckPlayersIndex; + int16 m_nAttackDirToCheck; float m_fWalkAngle; //angle between heading and walking direction float m_fFPSMoveHeading; RpAtomic* m_pMinigunTopAtomic; //atomic for the spinning part of the minigun model @@ -45,6 +45,8 @@ public: unsigned int m_nPadDownPressedInMilliseconds; unsigned int m_nLastBusFareCollected; + static bool bDontAllowWeaponChange; + CPlayerPed(); ~CPlayerPed(); void SetMoveAnim() { }; @@ -64,18 +66,18 @@ public: class CPlayerInfo *GetPlayerInfoForThisPlayerPed(); void SetRealMoveAnim(void); void RestoreSprintEnergy(float); - bool DoWeaponSmoothSpray(void); + float DoWeaponSmoothSpray(void); void DoStuffToGoOnFire(void); bool DoesTargetHaveToBeBroken(CVector, CWeapon*); void RunningLand(CPad*); - bool IsThisPedAttackingPlayer(CPed*); + bool IsThisPedAnAimingPriority(CPed*); void PlayerControlSniper(CPad*); void PlayerControlM16(CPad*); void PlayerControlFighter(CPad*); void ProcessWeaponSwitch(CPad*); void MakeObjectTargettable(int32); void PlayerControl1stPersonRunAround(CPad *padUsed); - void EvaluateNeighbouringTarget(CEntity*, CEntity**, float*, float, float, bool); + void EvaluateNeighbouringTarget(CEntity*, CEntity**, float*, float, float, bool, bool); void EvaluateTarget(CEntity*, CEntity**, float*, float, float, bool); bool FindNextWeaponLockOnTarget(CEntity*, bool); bool FindWeaponLockOnTarget(void); @@ -87,6 +89,12 @@ public: void RemovePedFromMeleeList(CPed*); void GetMeleeAttackCoords(CVector&, int8, float); int32 FindMeleeAttackPoint(CPed*, CVector&, uint32&); + bool CanIKReachThisTarget(CVector, CWeapon*, bool); + void RotatePlayerToTrackTarget(void); + bool MovementDisabledBecauseOfTargeting(void); + void FindNewAttackPoints(void); + void SetNearbyPedsToInteractWithPlayer(void); + void UpdateMeleeAttackers(void); static void SetupPlayerPed(int32); static void DeactivatePlayerPed(int32); diff --git a/src/render/Font.cpp b/src/render/Font.cpp index 78a8599e..9b022394 100644 --- a/src/render/Font.cpp +++ b/src/render/Font.cpp @@ -390,9 +390,9 @@ CFont::PrintChar(float x, float y, wchar c) x + 32.0f * RenderState.scaleX * 1.0f, y + 33.0f * RenderState.scaleY * 0.5f), RenderState.color, - xoff / 16.0f, yoff / 12.8f, - (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f - 0.017f, - xoff / 16.0f, (yoff + 1.0f) / 12.8f, + xoff / 16.0f, yoff / 12.8f + 0.0021f, + (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f, + xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.017f, (xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.017f); } } else @@ -1437,3 +1437,21 @@ CFont::SetDropColor(CRGBA col) if (Details.alphaFade < 255.0f) Details.dropColor.a *= Details.alphaFade / 255.0f; } + +void +CFont::FilterOutTokensFromString(wchar *str) +{ + int newIdx = 0; + wchar copy[256], *c; + UnicodeStrcpy(copy, str); + + for (c = copy; *c != '\0'; c++) { + if (*c == '~') { + c++; + while (*c != '~') c++; + } else { + str[newIdx++] = *c; + } + } + str[newIdx] = '\0'; +} diff --git a/src/render/Font.h b/src/render/Font.h index 47a39f73..8942bcc6 100644 --- a/src/render/Font.h +++ b/src/render/Font.h @@ -200,6 +200,7 @@ public: static void SetColor(CRGBA col); static void SetDropColor(CRGBA col); static wchar FindNewCharacter(wchar c); + static void FilterOutTokensFromString(wchar*); #ifdef MORE_LANGUAGES static void ReloadFonts(uint8 set); diff --git a/src/render/Occlusion.cpp b/src/render/Occlusion.cpp index 79ce0461..5fef6e21 100644 --- a/src/render/Occlusion.cpp +++ b/src/render/Occlusion.cpp @@ -292,6 +292,11 @@ COcclusion::ProcessBeforeRendering(void) { NumActiveOccluders = 0; +#ifndef MASTER + if (gbModelViewer) + return; +#endif + if (CGame::currArea != AREA_MAIN_MAP) return; diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 4c4fc434..7d62a01c 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -727,13 +727,6 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer) return (nil); } -#ifdef USE_TEXTURE_POOL -WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x6271E0); } -WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x627080); } -WRAPPER void _TexturePoolsFinalShutdown() { EAXJMP(0x626F80); } -WRAPPER void _TexturePoolsUnknown(bool) { EAXJMP(0x626F70); } -#endif - #ifdef LIBRW #include <rpmatfx.h> #include "VehicleModelInfo.h" diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h index cbcbb2e0..cf086e5a 100644 --- a/src/rw/RwHelper.h +++ b/src/rw/RwHelper.h @@ -54,8 +54,6 @@ RwCamera *CameraCreate(RwInt32 width, RwBool zBuffer); -void _TexturePoolsInitialise(); -void _TexturePoolsShutdown(); RpAtomic *ConvertPlatformAtomic(RpAtomic *atomic, void *data); diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp index 069152a2..c5252f77 100644 --- a/src/rw/TexRead.cpp +++ b/src/rw/TexRead.cpp @@ -24,6 +24,7 @@ #include "Sprite2d.h" #include "Text.h" #include "RwHelper.h" +#include "Frontend.h" #endif //GTA_PC float texLoadTime; @@ -390,6 +391,15 @@ CreateTxdImageForVideoCard() // so let's hope that is the case for all rw::gl3::needToReadBackTextures = true; #endif + +#ifdef DISABLE_VSYNC_ON_TEXTURE_CONVERSION + // let's disable vsync and frame limiter to speed up texture conversion + // (actually we probably don't need to disable frame limiter in here, but let's do it just in case =P) + int8 vsyncState = FrontEndMenuManager.m_PrefsVsync; + int8 frameLimiterState = FrontEndMenuManager.m_PrefsFrameLimiter; + FrontEndMenuManager.m_PrefsVsync = 0; + FrontEndMenuManager.m_PrefsFrameLimiter = 0; +#endif int32 i; for (i = 0; i < TXDSTORESIZE; i++) { @@ -444,6 +454,12 @@ CreateTxdImageForVideoCard() } } +#ifdef DISABLE_VSYNC_ON_TEXTURE_CONVERSION + // restore vsync and frame limiter states + FrontEndMenuManager.m_PrefsVsync = vsyncState; + FrontEndMenuManager.m_PrefsFrameLimiter = frameLimiterState; +#endif + RwStreamClose(img, nil); delete []buf; diff --git a/src/rw/TexturePools.cpp b/src/rw/TexturePools.cpp new file mode 100644 index 00000000..c2ba6cf9 --- /dev/null +++ b/src/rw/TexturePools.cpp @@ -0,0 +1,221 @@ +#ifndef LIBRW + +#include <d3d8.h> +#define WITHD3D +#include "common.h" +#include "TexturePools.h" + +// TODO: this needs to be integrated into RW + +extern "C" LPDIRECT3DDEVICE8 _RwD3DDevice; + +CTexturePool aTexturePools[12]; +CPaletteList PaletteList; +int numTexturePools; +int MaxPaletteIndex; +bool bUsePaletteIndex = true; + + +void +CTexturePool::Create(D3DFORMAT _Format, int _size, uint32 mipmapLevels, int32 numTextures) +{ + Format = _Format; + size = _size; + levels = mipmapLevels; + pTextures = new IDirect3DTexture8 *[numTextures]; + texturesMax = numTextures; + texturesNum = 0; + texturesUsed = 0; +} + +void +CTexturePool::Release() +{ + int i = 0; + while (i < texturesNum) { + pTextures[i]->Release(); + i++; + } + + delete[] pTextures; + + pTextures = nil; + texturesNum = 0; + texturesUsed = 0; +} + +IDirect3DTexture8 * +CTexturePool::FindTexture() +{ + if (texturesNum == 0) + return nil; + texturesUsed--; + return pTextures[--texturesNum]; +} + +bool +CTexturePool::AddTexture(IDirect3DTexture8 *texture) +{ + ++texturesUsed; + if (texturesNum >= texturesMax) + return false; + pTextures[texturesNum] = texture; + ++texturesNum; + return true; +} + +void +CTexturePool::Resize(int numTextures) +{ + if (numTextures == texturesMax) + return; + + IDirect3DTexture8 **newTextures = new IDirect3DTexture8 *[numTextures]; + + for (int i = 0; i < texturesNum && i < numTextures; i++) + newTextures[i] = pTextures[i]; + + if (numTextures < texturesNum) { + for (int i = numTextures; i < texturesNum; i++) + pTextures[i]->Release(); + } + delete[] pTextures; + pTextures = newTextures; + texturesMax = numTextures; +} + +void +CPaletteList::Alloc(int max) +{ + Data = new int[max]; + Max = max; + Num = 0; +} + +void +CPaletteList::Free() +{ + delete[] Data; + Data = nil; + Num = 0; +} + +int +CPaletteList::Find() +{ + if (Num == 0) + return -1; + return Data[--Num]; +} + +void +CPaletteList::Add(int item) +{ + if (Num < Max) + Data[Num++] = item; + else { + Resize(2 * Max); + Add(item); + } +} + +void +CPaletteList::Resize(int max) +{ + if (max == Max) + return; + + int *newData = new int[4 * max]; + for (int i = 0; i < Num && i < max; i++) + newData[i] = Data[i]; + delete[] Data; + Data = newData; + Max = max; +} + +HRESULT +CreateTexture(int width, int height, int levels, D3DFORMAT Format, IDirect3DTexture8 **texture) +{ + if (width == height) { + for (int i = 0; i < numTexturePools; i++) { + if (width != aTexturePools[i].GetSize() && levels == aTexturePools[i].levels && Format == aTexturePools[i].Format) + *texture = aTexturePools[i].FindTexture(); + } + } + if (*texture) + return D3D_OK; + else + return _RwD3DDevice->CreateTexture(width, height, levels, 0, Format, D3DPOOL_MANAGED, texture); +} + +void +ReleaseTexture(IDirect3DTexture8 *texture) +{ + int levels = 1; + if (texture->GetLevelCount() > 1) + levels = 0; + + D3DSURFACE_DESC SURFACE_DESC; + + texture->GetLevelDesc(0, &SURFACE_DESC); + + if (SURFACE_DESC.Width == SURFACE_DESC.Height) { + for (int i = 0; i < numTexturePools; i++) { + if (SURFACE_DESC.Width == aTexturePools[i].GetSize() && SURFACE_DESC.Format == aTexturePools[i].Format && levels == aTexturePools[i].levels) { + if (!aTexturePools[i].AddTexture(texture)) { + if (aTexturePools[i].texturesUsed > 3 * aTexturePools[i].texturesMax / 2) { + aTexturePools[i].Resize(2 * aTexturePools[i].texturesMax); + aTexturePools[i].texturesUsed--; + aTexturePools[i].AddTexture(texture); + } else { + texture->Release(); + } + } + return; + } + } + } + if (numTexturePools < 12 && bUsePaletteIndex && levels != 0 && SURFACE_DESC.Width == SURFACE_DESC.Height && + (SURFACE_DESC.Width == 64 || SURFACE_DESC.Width == 128 || SURFACE_DESC.Width == 256)) { + aTexturePools[numTexturePools].Create(SURFACE_DESC.Format, SURFACE_DESC.Width, 1, 16); + aTexturePools[numTexturePools].AddTexture(texture); + numTexturePools++; + } else + texture->Release(); +} + +int +FindAvailablePaletteIndex() +{ + int index = PaletteList.Find(); + if (index == -1) + index = MaxPaletteIndex++; + return index; +} + +void +AddAvailablePaletteIndex(int index) +{ + if (bUsePaletteIndex) + PaletteList.Add(index); +} + +void +_TexturePoolsInitialise() +{ + PaletteList.Alloc(100); + MaxPaletteIndex = 0; +} + +void +_TexturePoolsShutdown() +{ + for (int i = 0; i < numTexturePools; i++) + aTexturePools[i].Release(); + + numTexturePools = 0; + bUsePaletteIndex = false; + PaletteList.Free(); +} + +#endif // !LIBRW
\ No newline at end of file diff --git a/src/rw/TexturePools.h b/src/rw/TexturePools.h new file mode 100644 index 00000000..75187432 --- /dev/null +++ b/src/rw/TexturePools.h @@ -0,0 +1,42 @@ +#pragma once + +class CTexturePool +{ +public: + D3DFORMAT Format; + int size; + uint32 levels; + int32 texturesMax; + int32 texturesUsed; + int32 texturesNum; + IDirect3DTexture8 **pTextures; + +public: + CTexturePool() {} + void Create(D3DFORMAT _Format, int size, uint32 mipmapLevels, int32 numTextures); + void Release(); + IDirect3DTexture8 *FindTexture(); + bool AddTexture(IDirect3DTexture8 *texture); + void Resize(int numTextures); +#ifdef FIX_BUGS + int GetSize() { return size; } +#else + float GetSize() { return size; } +#endif +}; + +class CPaletteList +{ + int Max; + int Num; + int *Data; +public: + void Alloc(int max); + void Free(); + int Find(); + void Add(int item); + void Resize(int max); +}; + +void _TexturePoolsInitialise(); +void _TexturePoolsShutdown();
\ No newline at end of file diff --git a/src/skel/crossplatform.h b/src/skel/crossplatform.h index fe1f22fd..bfc03913 100644 --- a/src/skel/crossplatform.h +++ b/src/skel/crossplatform.h @@ -87,9 +87,6 @@ enum eGameState GS_FRONTEND, GS_INIT_PLAYING_GAME, GS_PLAYING_GAME, -#ifndef MASTER - GS_ANIMVIEWER, -#endif }; extern RwUInt32 gGameState; diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index cac487b1..c219e711 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -841,7 +841,10 @@ psSelectDevice() PSGLOBAL(fullScreen) = !FrontEndMenuManager.m_nPrefsWindowed; #endif - + +#ifdef MULTISAMPLING + RwD3D8EngineSetMultiSamplingLevels(1 << FrontEndMenuManager.m_nPrefsMSAALevel); +#endif return TRUE; } @@ -1256,17 +1259,11 @@ void resizeCB(GLFWwindow* window, int width, int height) { * memory things don't work. */ /* 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 if (RwInitialised && height > 0 && width > 0) { RwRect r; @@ -1479,12 +1476,14 @@ WinMain(HINSTANCE instance, RwChar** argv; SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE); -#if 1 - // TODO: make this an option somewhere - AllocConsole(); - freopen("CONIN$", "r", stdin); - freopen("CONOUT$", "w", stdout); - freopen("CONOUT$", "w", stderr); +#ifndef MASTER + if (strstr(cmdLine, "-console")) + { + AllocConsole(); + freopen("CONIN$", "r", stdin); + freopen("CONOUT$", "w", stdout); + freopen("CONOUT$", "w", stderr); + } #endif #else @@ -1639,18 +1638,6 @@ main(int argc, char *argv[]) FrontEndMenuManager.DrawMemoryCardStartUpMenus(); } #endif - - if (TurnOnAnimViewer) - { -#ifndef MASTER - CAnimViewer::Initialise(); -#ifndef PS2_MENU - FrontEndMenuManager.m_bGameNotLoaded = false; -#endif - gGameState = GS_ANIMVIEWER; - TurnOnAnimViewer = false; -#endif - } initkeymap(); @@ -1670,6 +1657,18 @@ main(int argc, char *argv[]) * Enter the message processing loop... */ +#ifndef MASTER + if (gbModelViewer) { + // This is TheModelViewer in LCS + LoadingScreen("Loading the ModelViewer", NULL, GetRandomSplashScreen()); + CAnimViewer::Initialise(); + CTimer::Update(); +#ifndef PS2_MENU + FrontEndMenuManager.m_bGameNotLoaded = false; +#endif + } +#endif + #ifdef PS2_MENU if (TheMemoryCard.m_bWantToLoad) LoadSplash(GetLevelSplashScreen(CGame::currLevel)); @@ -1684,7 +1683,13 @@ main(int argc, char *argv[]) #endif { glfwPollEvents(); - if( ForegroundApp ) +#ifndef MASTER + if (gbModelViewer) { + // This is TheModelViewerCore in LCS + TheModelViewer(); + } else +#endif + if ( ForegroundApp ) { switch ( gGameState ) { @@ -1888,18 +1893,6 @@ main(int argc, char *argv[]) } break; } -#ifndef MASTER - case GS_ANIMVIEWER: - { - float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond(); - if (RwInitialised) - { - if (!FrontEndMenuManager.m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) - RsEventHandler(rsANIMVIEWER, (void*)TRUE); - } - break; - } -#endif } } else @@ -1971,12 +1964,13 @@ main(int argc, char *argv[]) } else { - if ( gGameState == GS_PLAYING_GAME ) - CGame::ShutDown(); #ifndef MASTER - else if ( gGameState == GS_ANIMVIEWER ) + if ( gbModelViewer ) CAnimViewer::Shutdown(); + else #endif + if ( gGameState == GS_PLAYING_GAME ) + CGame::ShutDown(); CTimer::Stop(); @@ -1997,13 +1991,13 @@ main(int argc, char *argv[]) #endif } - - if ( gGameState == GS_PLAYING_GAME ) - CGame::ShutDown(); #ifndef MASTER - else if ( gGameState == GS_ANIMVIEWER ) + if ( gbModelViewer ) CAnimViewer::Shutdown(); + else #endif + if ( gGameState == GS_PLAYING_GAME ) + CGame::ShutDown(); DMAudio.Terminate(); diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp index e21abb17..a21d5674 100644 --- a/src/skel/skeleton.cpp +++ b/src/skel/skeleton.cpp @@ -10,13 +10,12 @@ #include "skeleton.h" #include "platform.h" +#include "main.h" // --MIAMI: file done static RwBool DefaultVideoMode = TRUE; -bool TurnOnAnimViewer = false; - RsGlobalType RsGlobal; #ifdef _WIN32 @@ -161,7 +160,7 @@ rsPreInitCommandLine(RwChar *arg) #ifndef MASTER if (!strcmp(arg, RWSTRING("-animviewer"))) { - TurnOnAnimViewer = TRUE; + gbModelViewer = TRUE; return TRUE; } diff --git a/src/skel/skeleton.h b/src/skel/skeleton.h index 1c468179..380b6c05 100644 --- a/src/skel/skeleton.h +++ b/src/skel/skeleton.h @@ -79,11 +79,8 @@ enum RsEvent rsPADANALOGUERIGHTRESET, rsPREINITCOMMANDLINE, rsACTIVATE, - rsANIMVIEWER, }; -extern bool TurnOnAnimViewer; - typedef enum RsEvent RsEvent; typedef RsEventStatus (*RsInputEventHandler)(RsEvent event, void *param); diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index a10a1a92..a437a3b4 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -1008,17 +1008,11 @@ 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; @@ -2005,11 +1999,15 @@ WinMain(HINSTANCE instance, RwChar **argv; SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE); - // TODO: make this an option somewhere - AllocConsole(); - freopen("CONIN$", "r", stdin); - freopen("CONOUT$", "w", stdout); - freopen("CONOUT$", "w", stderr); +#ifndef MASTER + if (strstr(cmdLine, "-console")) + { + AllocConsole(); + freopen("CONIN$", "r", stdin); + freopen("CONOUT$", "w", stdout); + freopen("CONOUT$", "w", stderr); + } +#endif /* * Initialize the platform independent data. @@ -2169,17 +2167,17 @@ WinMain(HINSTANCE instance, } #endif - if (TurnOnAnimViewer) - { #ifndef MASTER + if (gbModelViewer) { + // This is TheModelViewer in LCS + LoadingScreen("Loading the ModelViewer", NULL, GetRandomSplashScreen()); CAnimViewer::Initialise(); + CTimer::Update(); #ifndef PS2_MENU FrontEndMenuManager.m_bGameNotLoaded = false; #endif - gGameState = GS_ANIMVIEWER; - TurnOnAnimViewer = false; -#endif } +#endif while ( TRUE ) { @@ -2224,6 +2222,12 @@ WinMain(HINSTANCE instance, DispatchMessage(&message); } } +#ifndef MASTER + else if (gbModelViewer) { + // This is TheModelViewerCore in LCS + TheModelViewer(); + } +#endif else if( ForegroundApp ) { switch ( gGameState ) @@ -2443,18 +2447,6 @@ WinMain(HINSTANCE instance, } break; } -#ifndef MASTER - case GS_ANIMVIEWER: - { - float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond(); - if (RwInitialised) - { - if (!FrontEndMenuManager.m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) - RsEventHandler(rsANIMVIEWER, (void*)TRUE); - } - break; - } -#endif } } else @@ -2526,12 +2518,13 @@ WinMain(HINSTANCE instance, } else { - if ( gGameState == GS_PLAYING_GAME ) - CGame::ShutDown(); #ifndef MASTER - else if ( gGameState == GS_ANIMVIEWER ) + if ( gbModelViewer ) CAnimViewer::Shutdown(); + else #endif + if ( gGameState == GS_PLAYING_GAME ) + CGame::ShutDown(); CTimer::Stop(); @@ -2553,12 +2546,13 @@ WinMain(HINSTANCE instance, } - if ( gGameState == GS_PLAYING_GAME ) - CGame::ShutDown(); #ifndef MASTER - else if ( gGameState == GS_ANIMVIEWER ) + if ( gbModelViewer ) CAnimViewer::Shutdown(); + else #endif + if ( gGameState == GS_PLAYING_GAME ) + CGame::ShutDown(); DMAudio.Terminate(); diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 14abbfc6..feaa80de 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -26,6 +26,7 @@ #include "AnimBlendAssociation.h" #include "RpAnimBlend.h" #include "Record.h" +#include "Shadows.h" //--MIAMI: file done @@ -1006,7 +1007,7 @@ CBoat::PreRender(void) if(atomic) SetComponentAtomicAlpha(atomic, Max(150-alpha, 0)); } - //CShadows::StoreShadowForVehicle(this); + CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_SEAPLANE); }else if(GetModelIndex() == MI_COASTG || GetModelIndex() == MI_DINGHY || GetModelIndex() == MI_RIO || GetModelIndex() == MI_SQUALO || GetModelIndex() == MI_MARQUIS){ if(m_aBoatNodes[BOAT_RUDDER]){ diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp index 716ce8d0..620a04fb 100644 --- a/src/vehicles/Plane.cpp +++ b/src/vehicles/Plane.cpp @@ -566,7 +566,7 @@ CPlane::ProcessControl(void) if(mi->m_planeLodId != -1){ m_rwObject = CModelInfo::GetModelInfo(mi->m_planeLodId)->CreateInstance(); if(m_rwObject) - m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject))); + m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject))); } } }else if(CStreaming::HasModelLoaded(GetModelIndex())){ diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 20ada534..d1f9490d 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -36,9 +36,6 @@ #include "Sprite.h" #include "Pickups.h" -// TODO(Miami) -#define AUDIO_NOT_READY - float fReloadAnimSampleFraction[5] = { 0.5f, 0.7f, 0.75f, 0.75f, 0.7f }; float fSeaSparrowAimingAngle = 10.0f; float fHunterAimingAngle = 30.0f; @@ -2899,26 +2896,15 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound) default: break; } - if (reloadAssoc->GetProgress() >= soundStart && (reloadAssoc->currentTime - reloadAssoc->timeStep) / reloadAssoc->hierarchy->totalLength < soundStart) { -#ifdef AUDIO_NOT_READY - DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f); -#else + if (reloadAssoc->GetProgress() >= soundStart && (reloadAssoc->currentTime - reloadAssoc->timeStep) / reloadAssoc->hierarchy->totalLength < soundStart) DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType); -#endif - } if (CTimer::GetTimeInMilliseconds() > m_nTimer && reloadAssoc->GetProgress() < 0.9f) { m_nTimer = CTimer::GetTimeInMilliseconds(); } } else { uint32 timePassed = m_nTimer - CWeaponInfo::ms_aReloadSampleTime[m_eWeaponType]; if (CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed) - { -#ifdef AUDIO_NOT_READY - DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f); -#else DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType); -#endif - } } } diff --git a/src/weapons/WeaponEffects.cpp b/src/weapons/WeaponEffects.cpp index 42d4f52c..b0df610f 100644 --- a/src/weapons/WeaponEffects.cpp +++ b/src/weapons/WeaponEffects.cpp @@ -8,7 +8,6 @@ #include "WeaponType.h" RwTexture *gpCrossHairTex; -RwRaster *gpCrossHairRaster; CWeaponEffects gCrossHair; @@ -40,7 +39,6 @@ CWeaponEffects::Init(void) CTxdStore::SetCurrentTxd(slot); gpCrossHairTex = RwTextureRead("target256", "target256m"); - gpCrossHairRaster = RwTextureGetRaster(gpCrossHairTex); CTxdStore::PopCurrentTxd(); } @@ -99,7 +97,7 @@ CWeaponEffects::Render(void) #else RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVDESTALPHA); #endif - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpCrossHairRaster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)RwTextureGetRaster(gpCrossHairTex)); RwV3d pos; float w, h; |