From 9fed0c040c482bac8cba688e7564c8e8dfe23b30 Mon Sep 17 00:00:00 2001 From: _AG Date: Thu, 4 Jul 2019 22:31:21 +0200 Subject: [PATCH 01/30] Darkel/Wanted update. --- src/Camera.cpp | 9 + src/Camera.h | 1 + src/Stats.cpp | 9 +- src/Stats.h | 4 + src/Wanted.cpp | 93 +++++++++++ src/Wanted.h | 12 +- src/control/Darkel.cpp | 314 ++++++++++++++++++++++++++++++++++- src/control/Darkel.h | 39 ++++- src/entities/Ped.cpp | 9 +- src/entities/Ped.h | 3 +- src/entities/PlayerPed.cpp | 16 +- src/entities/PlayerPed.h | 1 + src/render/WeaponEffects.cpp | 7 + src/render/WeaponEffects.h | 14 ++ src/weapons/Weapon.h | 18 +- src/weapons/WeaponInfo.cpp | 6 +- 16 files changed, 531 insertions(+), 24 deletions(-) diff --git a/src/Camera.cpp b/src/Camera.cpp index d7ee398b..735ff4a2 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -136,6 +136,15 @@ CCamera::RenderMotionBlur(void) m_motionBlur, m_BlurType, m_imotionBlurAddAlpha); } +void +CCamera::ClearPlayerWeaponMode() +{ + PlayerWeaponMode.Mode = 0; + PlayerWeaponMode.MaxZoom = 1; + PlayerWeaponMode.MinZoom = -1; + PlayerWeaponMode.Duration = 0.0f; +} + /* * diff --git a/src/Camera.h b/src/Camera.h index 84c3060b..db5fff46 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -457,6 +457,7 @@ int m_iModeObbeCamIsInForCar; void SetMotionBlur(int r, int g, int b, int a, int type); void SetMotionBlurAlpha(int a); void RenderMotionBlur(void); + void ClearPlayerWeaponMode(); void CalculateDerivedValues(void); void DrawBordersForWideScreen(void); diff --git a/src/Stats.cpp b/src/Stats.cpp index 5256b0cf..7db6e795 100644 --- a/src/Stats.cpp +++ b/src/Stats.cpp @@ -2,4 +2,11 @@ #include "Stats.h" int32 &CStats::DaysPassed = *(int32*)0x8F2BB8; -int32 &CStats::HeadShots = *(int32*)0x8F647C; \ No newline at end of file +int32 &CStats::HeadShots = *(int32*)0x8F647C; +int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C; +int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50; + +void CStats::AnotherKillFrenzyPassed() +{ + ++NumberKillFrenziesPassed; +} diff --git a/src/Stats.h b/src/Stats.h index 4508e8a8..eff4af1d 100644 --- a/src/Stats.h +++ b/src/Stats.h @@ -5,4 +5,8 @@ class CStats public: static int32 &DaysPassed; static int32 &HeadShots; + static int32 &NumberKillFrenziesPassed; + static int32 &PeopleKilledByOthers; + + static void AnotherKillFrenzyPassed(); }; \ No newline at end of file diff --git a/src/Wanted.cpp b/src/Wanted.cpp index ece68e64..21853308 100644 --- a/src/Wanted.cpp +++ b/src/Wanted.cpp @@ -2,6 +2,8 @@ #include "patcher.h" #include "Wanted.h" +int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714; + bool CWanted::AreSwatRequired() { return m_nWantedLevel >= 4; @@ -33,4 +35,95 @@ int CWanted::NumOfHelisRequired() default: return 0; }; +} + +void CWanted::SetWantedLevel(int32 level) +{ + ClearQdCrimes(); + switch (level) { + case NOTWANTED: + m_nChaos = 0; + break; + case WANTEDLEVEL_1: + m_nChaos = 60; + break; + case WANTEDLEVEL_2: + m_nChaos = 220; + break; + case WANTEDLEVEL_3: + m_nChaos = 420; + break; + case WANTEDLEVEL_4: + m_nChaos = 820; + break; + case WANTEDLEVEL_5: + m_nChaos = 1620; + break; + case WANTEDLEVEL_6: + m_nChaos = 3220; + break; + default: + if (level > MaximumWantedLevel) + m_nChaos = MaximumWantedLevel; + break; + } + UpdateWantedLevel(); +} + +void CWanted::ClearQdCrimes() +{ + for (int i = 0; i < 16; i++) { + m_sCrimes[i].m_eCrimeType = CRIME_NONE; + }; +} + +void CWanted::UpdateWantedLevel() +{ + int32 CurrWantedLevel = m_nWantedLevel; + + if (m_nChaos >= 0 && m_nChaos < 40) { + m_nWantedLevel = NOTWANTED; + m_MaximumLawEnforcerVehicles = 0; + m_MaxCops = 0; + m_RoadblockDensity = 0; + } + else if (m_nChaos >= 40 && m_nChaos < 200) { + m_nWantedLevel = WANTEDLEVEL_1; + m_MaximumLawEnforcerVehicles = 1; + m_MaxCops = 1; + m_RoadblockDensity = 0; + } + else if (m_nChaos >= 200 && m_nChaos < 400) { + m_nWantedLevel = WANTEDLEVEL_2; + m_MaximumLawEnforcerVehicles = 2; + m_MaxCops = 3; + m_RoadblockDensity = 0; + } + else if (m_nChaos >= 400 && m_nChaos < 800) { + m_nWantedLevel = WANTEDLEVEL_3; + m_MaximumLawEnforcerVehicles = 2; + m_MaxCops = 4; + m_RoadblockDensity = 4; + } + else if (m_nChaos >= 800 && m_nChaos < 1600) { + m_nWantedLevel = WANTEDLEVEL_4; + m_MaximumLawEnforcerVehicles = 2; + m_MaxCops = 6; + m_RoadblockDensity = 8; + } + else if (m_nChaos >= 1600 && m_nChaos < 3200) { + m_nWantedLevel = WANTEDLEVEL_5; + m_MaximumLawEnforcerVehicles = 3; + m_MaxCops = 8; + m_RoadblockDensity = 10; + } + else if (m_nChaos >= 3200) { + m_nWantedLevel = WANTEDLEVEL_6; + m_MaximumLawEnforcerVehicles = 3; + m_MaxCops = 10; + m_RoadblockDensity = 12; + } + + if (CurrWantedLevel != m_nWantedLevel) + m_nLastWantedLevelChange = CTimer::GetTimeInMilliseconds(); } \ No newline at end of file diff --git a/src/Wanted.h b/src/Wanted.h index aafa9ac0..d14bb905 100644 --- a/src/Wanted.h +++ b/src/Wanted.h @@ -20,11 +20,11 @@ public: int32 m_nLastUpdateTime; int32 m_nLastWantedLevelChange; float m_fCrimeSensitivity; - uint8 m_bCurrentCops; - uint8 m_bMaxCops; - uint8 m_bMaximumLawEnforcerVehicles; + uint8 m_CurrentCops; + uint8 m_MaxCops; + uint8 m_MaximumLawEnforcerVehicles; int8 field_19; - int16 m_wRoadblockDensity; + int16 m_RoadblockDensity; uint8 m_IsIgnoredByCops : 1; uint8 m_IsIgnoredByEveryOne : 1; uint8 m_IsSwatRequired : 1; @@ -34,12 +34,16 @@ public: int32 m_nWantedLevel; CCrime m_sCrimes[16]; CCopPed *m_pCops[10]; + static int32 &MaximumWantedLevel; public: bool AreSwatRequired(); bool AreFbiRequired(); bool AreArmyRequired(); int NumOfHelisRequired(); + void SetWantedLevel(int32); + void ClearQdCrimes(); + void UpdateWantedLevel(); }; static_assert(sizeof(CWanted) == 0x204, "CWanted: error"); diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index 32d975e0..931884fc 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -1,12 +1,320 @@ #include "common.h" #include "patcher.h" +#include "main.h" #include "Darkel.h" +#include "Timer.h" +#include "DMAudio.h" +#include "Population.h" +#include "Weapon.h" +#include "World.h" +#include "PlayerPed.h" +#include "Stats.h" +#include "Font.h" +#include "Text.h" +int32 &CDarkel::TimeLimit = *(int32*)0x885BAC; +int32 &CDarkel::PreviousTime = *(int32*)0x885B00; +int32 &CDarkel::TimeOfFrenzyStart = *(int32*)0x9430D8; +int32 &CDarkel::WeaponType = *(int32*)0x9430F0; +int32 &CDarkel::AmmoInterruptedWeapon = *(int32*)0x8E29C8; +int32 &CDarkel::KillsNeeded = *(int32*)0x8F1AB8; +int8 &CDarkel::InterruptedWeapon = *(int8*)0x95CD60; +int8 &CDarkel::bStandardSoundAndMessages = *(int8*)0x95CDB6; +int8 &CDarkel::bNeedHeadShot = *(int8*)0x95CDCA; +int8 &CDarkel::bProperKillFrenzy = *(int8*)0x95CD98; +eKillFrenzyStatus &CDarkel::Status = *(eKillFrenzyStatus*)0x95CCB4; +int16 *CDarkel::RegisteredKills = (int16*)0x6EDBE0; +int32 &CDarkel::ModelToKill = *(int32*)0x8F2C78; +int32 &CDarkel::ModelToKill2 = *(int32*)0x885B40; +int32 &CDarkel::ModelToKill3 = *(int32*)0x885B3C; +int32 &CDarkel::ModelToKill4 = *(int32*)0x885B34; +wchar *CDarkel::pStartMessage = (wchar*)0x8F2C08; + +int32 CDarkel::CalcFade(uint32 time, int32 min, uint32 max) { + if (time >= min && time <= max) { + if (time >= min + 500) { + if (time <= max - 500) + return -1; + else + return 255 * (max - time) / 500; + } + else + return 255 * (time - min) / 500; + } + else + return 0; +} + + +#if 0 WRAPPER void CDarkel::DrawMessages(void) { EAXJMP(0x420920); } +#else +void CDarkel::DrawMessages() +{ + bool DisplayTimers = false; + + switch (Status) { + case KILLFRENZY_ONGOING: + DisplayTimers = true; + break; + case KILLFRENZY_PASSED: + case KILLFRENZY_FAILED: + DisplayTimers = false; + break; + }; + + if (DisplayTimers) { + CFont::SetPropOn(); + CFont::SetBackgroundOff(); + CFont::SetBackGroundOnlyTextOn(); + CFont::SetAlignment(ALIGN_RIGHT); + CFont::SetRightJustifyWrap(-SCREEN_WIDTH); + CFont::SetFontStyle(FONT_HEADING); + CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); + + float AlignToHUD = SCREEN_SCALE_X(-10.0f); + int32 a = (TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart)); + if (CTimer::GetFrameCounter() & 8 || a > 4000) { + sprintf(gString, "%d:%02d", a / 60000, a % 60000 / 1000); + AsciiToUnicode(gString, gUString); + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(25.0f) + AlignToHUD, SCREEN_SCALE_Y(112.0f), gUString); + + CFont::SetColor(CRGBA(150, 100, 255, 255)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(27.0f) + AlignToHUD, SCREEN_SCALE_Y(110.0f), gUString); + } + + if (KillsNeeded <= 0) + KillsNeeded = 0; + + sprintf((char *)gString, "%d", KillsNeeded); + AsciiToUnicode(gString, gUString); + + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(25.0f) + AlignToHUD, SCREEN_SCALE_Y(134.0f), gUString); + + CFont::SetColor(CRGBA(255, 128, 128, 255)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(27.0f) + AlignToHUD, SCREEN_SCALE_Y(132.0f), gUString); + } +} +#endif + +void CDarkel::Init() +{ + Status = KILLFRENZY_INIT; +} + +int16 CDarkel::QueryModelsKilledByPlayer(int32 modelId) +{ + return RegisteredKills[modelId]; +} -bool CDarkel::Status = *(bool*)0x95CCB4; bool CDarkel::FrenzyOnGoing() { - return Status == 1; -} \ No newline at end of file + return Status == KILLFRENZY_ONGOING; +} + + +eKillFrenzyStatus CDarkel::ReadStatus() +{ + return Status; +} + +int32 CDarkel::RegisterCarBlownUpByPlayer(eKillFrenzyStatus status) +{ + return 0; +} + +void CDarkel::RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag) +{ + + +} + +void CDarkel::RegisterKillNotByPlayer() +{ + ++CStats::NumberKillFrenziesPassed; +} + +void CDarkel::ResetModelsKilledByPlayer() +{ + for (int i = 0; i < 200; i++) { + for (int j = 0; j < 8; j++) + RegisteredKills[i + j] = 0; + }; +} + +void CDarkel::ResetOnPlayerDeath() +{ + eWeaponType &EWeaponType = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + int32 &CurrentWeapon = CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId; + int32 &CurrentDarkelWeapon = CDarkel::WeaponType; + uint32 &TotalAmmo = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; + + if (Status == KILLFRENZY_ONGOING) { + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_FAILED; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + CurrentDarkelWeapon = WEAPONTYPE_UZI; + + if (CurrentDarkelWeapon < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; + TotalAmmo = AmmoInterruptedWeapon; + } + + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponModel(CurrentWeapon); + FindPlayerPed()->m_currentWeapon = EWeaponType; + FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); + } + } +} + +#if 0 +WRAPPER void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) { EAXJMP(0x4210E0); } +#else +void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) +{ + eWeaponType &EWeaponType = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + uint32 &TotalAmmo = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; + uint32 &AmmoInClip = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip; + + if (weaponType == WEAPONTYPE_UZI_DRIVEBY) + weaponType = WEAPONTYPE_UZI; + + WeaponType = weaponType; + Status = KILLFRENZY_ONGOING; + KillsNeeded = kill; + ModelToKill = modelId0; + ModelToKill2 = modelId2; + ModelToKill3 = modelId3; + ModelToKill4 = modelId4; + pStartMessage = text; + + if (text == TheText.Get("PAGE_00")) { + CDarkel::bProperKillFrenzy = 1; + CDarkel::pStartMessage = 0; + } + else + bProperKillFrenzy = 0; + + bStandardSoundAndMessages = standardSound; + bNeedHeadShot = needHeadShot; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + TimeLimit = time; + PreviousTime = time / 1000; + + if (weaponType < WEAPONTYPE_TOTALWEAPONS) { + InterruptedWeapon = FindPlayerPed()->m_currentWeapon; + FindPlayerPed()->GiveWeapon(weaponType, 0); + AmmoInterruptedWeapon = TotalAmmo; + FindPlayerPed()->GiveWeapon(weaponType, 30000); + FindPlayerPed()->m_bWeaponSlot = EWeaponType; + FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_bWeaponSlot); + + if (FindPlayerVehicle()) { + FindPlayerPed()->m_currentWeapon = EWeaponType; + if (TotalAmmo <= AmmoInClip) + AmmoInClip = TotalAmmo; + + FindPlayerPed()->ClearWeaponTarget(); + } + } + if (CDarkel::bStandardSoundAndMessages) + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_START, 0); +} +#endif + +void CDarkel::Update() +{ + eWeaponType &EWeaponType = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + int32 &CurrentWeapon = CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId; + int32 &CurrentDarkelWeapon = CDarkel::WeaponType; + uint32 &TotalAmmo = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; + + if (Status == KILLFRENZY_ONGOING) { + int32 FrameTime = TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart); + if ((TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart)) > 0 || TimeLimit < 0) { + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_ONGOING, FrameTime); + + int32 PrevTime = FrameTime / 1000; + + if (PrevTime != PreviousTime) { + if (PreviousTime < 12) + DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, PrevTime); + PreviousTime = PrevTime; + } + + } + else { + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_FAILED; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + CurrentDarkelWeapon = WEAPONTYPE_UZI; + + if (CurrentDarkelWeapon < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; + TotalAmmo = AmmoInterruptedWeapon; + } + + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponModel(CurrentWeapon); + FindPlayerPed()->m_currentWeapon = EWeaponType; + FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); + } + + if (bStandardSoundAndMessages) + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_FAILED, 0); + } + + if (KillsNeeded <= 0) { + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_PASSED; + + if (bProperKillFrenzy) + CStats::AnotherKillFrenzyPassed(); + + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + + FindPlayerPed()->m_pWanted->SetWantedLevel(NOTWANTED); + + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + CurrentDarkelWeapon = WEAPONTYPE_UZI; + + if (CurrentDarkelWeapon < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; + TotalAmmo = AmmoInterruptedWeapon; + } + + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponModel(CurrentWeapon); + FindPlayerPed()->m_currentWeapon = EWeaponType; + FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); + } + + if (bStandardSoundAndMessages) + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0); + } + } +} + +STARTPATCHES + /*InjectHook(0x421380, CDarkel::CalcFade, PATCH_JUMP); + InjectHook(0x420920, CDarkel::DrawMessages, PATCH_JUMP); + InjectHook(0x420E60, CDarkel::FrenzyOnGoing, PATCH_JUMP); + InjectHook(0x420650, CDarkel::Init, PATCH_JUMP); + InjectHook(0x421370, CDarkel::QueryModelsKilledByPlayer, PATCH_JUMP); + InjectHook(0x420E50, CDarkel::ReadStatus, PATCH_JUMP); + InjectHook(0x421070, CDarkel::RegisterCarBlownUpByPlayer, PATCH_JUMP); + InjectHook(0x420F60, CDarkel::RegisterKillByPlayer, PATCH_JUMP); + InjectHook(0x421060, CDarkel::RegisterKillNotByPlayer, PATCH_JUMP); + InjectHook(0x421310, CDarkel::ResetModelsKilledByPlayer, PATCH_JUMP); + InjectHook(0x420E70, CDarkel::ResetOnPlayerDeath, PATCH_JUMP); + InjectHook(0x4210E0, CDarkel::StartFrenzy, PATCH_JUMP); + InjectHook(0x420660, CDarkel::Update, PATCH_JUMP);*/ +ENDPATCHES \ No newline at end of file diff --git a/src/control/Darkel.h b/src/control/Darkel.h index ed78d4e1..905f5497 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -1,11 +1,48 @@ #pragma once +#include "Weapon.h" + +enum eKillFrenzyStatus +{ + KILLFRENZY_INIT, + KILLFRENZY_ONGOING, + KILLFRENZY_PASSED, + KILLFRENZY_FAILED, +}; class CDarkel { private: - static bool Status; + static int32 &TimeLimit; + static int32 &PreviousTime; + static int32 &TimeOfFrenzyStart; + static int32 &WeaponType; + static int32 &AmmoInterruptedWeapon; + static int32 &KillsNeeded; + static int8 &InterruptedWeapon; + static int8 &bStandardSoundAndMessages; + static int8 &bNeedHeadShot; + static int8 &bProperKillFrenzy; + static eKillFrenzyStatus &Status; + static int16 *RegisteredKills; + static int32 &ModelToKill; + static int32 &ModelToKill2; + static int32 &ModelToKill3; + static int32 &ModelToKill4; + static wchar *pStartMessage; public: + static int32 CalcFade(uint32 time, int32 min, uint32 max); static void DrawMessages(void); static bool FrenzyOnGoing(); + static void Init(); + static int16 QueryModelsKilledByPlayer(int32 modelId); + static eKillFrenzyStatus ReadStatus(); + static int32 RegisterCarBlownUpByPlayer(eKillFrenzyStatus status); + static void RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag); + static void RegisterKillNotByPlayer(); + static void ResetModelsKilledByPlayer(); + static void ResetOnPlayerDeath(); + static void StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot); + static void Update(); + }; diff --git a/src/entities/Ped.cpp b/src/entities/Ped.cpp index 9e1836c2..2e51a5c1 100644 --- a/src/entities/Ped.cpp +++ b/src/entities/Ped.cpp @@ -39,6 +39,7 @@ WRAPPER void CPed::PreRender(void) { EAXJMP(0x4CFDD0); } WRAPPER void CPed::Render(void) { EAXJMP(0x4D03F0); } WRAPPER int32 CPed::ProcessEntityCollision(CEntity*, CColPoint*) { EAXJMP(0x4CBB30); } WRAPPER void CPed::SetMoveAnim(void) { EAXJMP(0x4C5A40); } +WRAPPER void CPed::MakeChangesForNewWeapon(int8) { EAXJMP(0x4F2560); } bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44; bool &CPed::bPedCheat2 = *(bool*)0x95CD5A; @@ -461,9 +462,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) } m_maxWeaponTypeAllowed = 0; m_currentWeapon = 0; - m_storedWeapon = NO_STORED_WEAPON; + m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; - for(int i = 0; i < NUM_PED_WEAPONTYPES; i++) + for(int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) { CWeapon &weapon = GetWeapon(i); weapon.m_eWeaponType = WEAPONTYPE_UNARMED; @@ -1445,9 +1446,9 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg) // Only uzi can be used on cars, so previous weapon was stored if (ped->IsPlayer() && weaponType == WEAPONTYPE_UZI) { - if (ped->m_storedWeapon != NO_STORED_WEAPON) { + if (ped->m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) { ped->SetCurrentWeapon(ped->m_storedWeapon); - ped->m_storedWeapon = NO_STORED_WEAPON; + ped->m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; } } else { ped->AddWeaponModel(CWeaponInfo::GetWeaponInfo(weaponType)->m_nModelId); diff --git a/src/entities/Ped.h b/src/entities/Ped.h index 558ec9c1..4367dc61 100644 --- a/src/entities/Ped.h +++ b/src/entities/Ped.h @@ -324,7 +324,7 @@ public: uint8 pad_351[3]; uint32 m_timerUnused; CEntity *m_targetUnused; - CWeapon m_weapons[NUM_PED_WEAPONTYPES]; + CWeapon m_weapons[WEAPONTYPE_TOTAL_INVENTORY_WEAPONS]; eWeaponType m_storedWeapon; uint8 m_currentWeapon; // eWeaponType uint8 m_maxWeaponTypeAllowed; // eWeaponType @@ -427,6 +427,7 @@ public: bool CanSeeEntity(CEntity*, float); void RestorePreviousObjective(void); void SetObjective(eObjective, void*); + void MakeChangesForNewWeapon(int8); // Static methods static void GetLocalPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enterType, float offset); diff --git a/src/entities/PlayerPed.cpp b/src/entities/PlayerPed.cpp index 2d67d5b2..7eb01db0 100644 --- a/src/entities/PlayerPed.cpp +++ b/src/entities/PlayerPed.cpp @@ -1,6 +1,8 @@ #include "common.h" #include "patcher.h" #include "PlayerPed.h" +#include "Camera.h" +#include "WeaponEffects.h" CPlayerPed::~CPlayerPed() { @@ -9,6 +11,18 @@ CPlayerPed::~CPlayerPed() WRAPPER void CPlayerPed::ReApplyMoveAnims(void) { EAXJMP(0x4F07C0); } +void CPlayerPed::ClearWeaponTarget() +{ + if (!m_nPedType) { + m_pPointGunAt = 0; + TheCamera.ClearPlayerWeaponMode(); + CWeaponEffects::ClearCrosshair(); + } + ClearPointGunAt(); +} + STARTPATCHES - InjectHook(0x4EFB30, &CPlayerPed::dtor, PATCH_JUMP); +InjectHook(0x4EFB30, &CPlayerPed::dtor, PATCH_JUMP); +InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP); + ENDPATCHES \ No newline at end of file diff --git a/src/entities/PlayerPed.h b/src/entities/PlayerPed.h index 15ad74a6..4f325da3 100644 --- a/src/entities/PlayerPed.h +++ b/src/entities/PlayerPed.h @@ -43,6 +43,7 @@ public: void dtor(void) { this->CPlayerPed::~CPlayerPed(); } void ReApplyMoveAnims(void); + void ClearWeaponTarget(); }; static_assert(sizeof(CPlayerPed) == 0x5F0, "CPlayerPed: error"); diff --git a/src/render/WeaponEffects.cpp b/src/render/WeaponEffects.cpp index a1a6d25a..e062da07 100644 --- a/src/render/WeaponEffects.cpp +++ b/src/render/WeaponEffects.cpp @@ -3,3 +3,10 @@ #include "WeaponEffects.h" WRAPPER void CWeaponEffects::Render(void) { EAXJMP(0x564D70); } + +CWeaponEffects &gCrossHair = *(CWeaponEffects*)0x6503BC; + +void CWeaponEffects::ClearCrosshair() +{ + gCrossHair.m_bCrosshair = false; +} diff --git a/src/render/WeaponEffects.h b/src/render/WeaponEffects.h index 63c8fd7d..7176c26d 100644 --- a/src/render/WeaponEffects.h +++ b/src/render/WeaponEffects.h @@ -2,6 +2,20 @@ class CWeaponEffects { +public: + bool m_bCrosshair; + int8 gap_1[3]; + CVector m_vecPos; + int8 field_16; + int8 field_17; + int8 field_18; + int8 field_19; + float field_20; + int32 field_24; + RwTexture *m_pTexture; + RwRaster *m_pRaster; + public: static void Render(void); + static void ClearCrosshair(); }; diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h index 8cb435ce..a8a5d9b3 100644 --- a/src/weapons/Weapon.h +++ b/src/weapons/Weapon.h @@ -1,9 +1,9 @@ #pragma once #include "Entity.h" -enum eWeaponType : uint32 +enum eWeaponType { - WEAPONTYPE_UNARMED = 0, + WEAPONTYPE_UNARMED, WEAPONTYPE_BASEBALLBAT, WEAPONTYPE_COLT45, WEAPONTYPE_UZI, @@ -16,10 +16,16 @@ enum eWeaponType : uint32 WEAPONTYPE_MOLOTOV, WEAPONTYPE_GRENADE, WEAPONTYPE_DETONATOR, - NUM_PED_WEAPONTYPES = 13, - WEAPONTYPE_HELICANNON = 13, - NUM_WEAPONTYPES, - NO_STORED_WEAPON = 22 + WEAPONTYPE_TOTAL_INVENTORY_WEAPONS, + WEAPONTYPE_TOTALWEAPONS, + WEAPONTYPE_ARMOUR, + WEAPONTYPE_RAMMEDBYCAR, + WEAPONTYPE_RUNOVERBYCAR, + WEAPONTYPE_EXPLOSION, + WEAPONTYPE_UZI_DRIVEBY, + WEAPONTYPE_WATER, + WEAPONTYPE_FALL_DAMAGE, + WEAPONTYPE_UNIDENTIFIED, }; enum eWeaponFire { diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp index 5be18c3c..6884d347 100644 --- a/src/weapons/WeaponInfo.cpp +++ b/src/weapons/WeaponInfo.cpp @@ -6,7 +6,7 @@ #include "AnimBlendAssociation.h" //CWeaponInfo (&CWeaponInfo::ms_apWeaponInfos)[14] = * (CWeaponInfo(*)[14]) * (uintptr*)0x6503EC; -CWeaponInfo CWeaponInfo::ms_apWeaponInfos[NUM_WEAPONTYPES]; +CWeaponInfo CWeaponInfo::ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS]; static char ms_aWeaponNames[][32] = { "Unarmed", @@ -34,7 +34,7 @@ void CWeaponInfo::Initialise(void) { debug("Initialising CWeaponInfo...\n"); - for (int i = 0; i < NUM_WEAPONTYPES; i++) { + for (int i = 0; i < WEAPONTYPE_TOTALWEAPONS; i++) { ms_apWeaponInfos[i].m_eWeaponFire = WEAPON_FIRE_INSTANT_HIT; ms_apWeaponInfos[i].m_AnimToPlay = ANIM_PUNCH_R; ms_apWeaponInfos[i].m_Anim2ToPlay = NUM_ANIMS; @@ -176,7 +176,7 @@ CWeaponInfo::LoadWeaponData(void) eWeaponType CWeaponInfo::FindWeaponType(char *name) { - for (int i = 0; i < NUM_WEAPONTYPES; i++) { + for (int i = 0; i < WEAPONTYPE_TOTALWEAPONS; i++) { if (strcmp(ms_aWeaponNames[i], name) == 0) { return static_cast(i); } From 29767c19645d88827b799908f4595123e6c27ede Mon Sep 17 00:00:00 2001 From: _AG Date: Sun, 7 Jul 2019 09:13:04 +0200 Subject: [PATCH 02/30] Lil update. --- src/Stats.h | 1 + src/control/Darkel.cpp | 223 ++++++++++++++++++++++------------------- src/control/Darkel.h | 2 +- 3 files changed, 122 insertions(+), 104 deletions(-) diff --git a/src/Stats.h b/src/Stats.h index eff4af1d..38e8d5be 100644 --- a/src/Stats.h +++ b/src/Stats.h @@ -8,5 +8,6 @@ public: static int32 &NumberKillFrenziesPassed; static int32 &PeopleKilledByOthers; +public: static void AnotherKillFrenzyPassed(); }; \ No newline at end of file diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index 931884fc..ab55c4d4 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -30,22 +30,22 @@ int32 &CDarkel::ModelToKill3 = *(int32*)0x885B3C; int32 &CDarkel::ModelToKill4 = *(int32*)0x885B34; wchar *CDarkel::pStartMessage = (wchar*)0x8F2C08; -int32 CDarkel::CalcFade(uint32 time, int32 min, uint32 max) { - if (time >= min && time <= max) { - if (time >= min + 500) { - if (time <= max - 500) - return -1; +int32 CDarkel::CalcFade(uint32 time, int32 start, uint32 end) { + if (time >= start && time <= end) { + if (time >= start + 500) { + if (time <= end - 500) + return 0; else - return 255 * (max - time) / 500; + return 255 * (end - time) / 500; } else - return 255 * (time - min) / 500; + return 255 * (time - start) / 500; } else return 0; } - +// This function has been cleaned up from unused stuff. #if 0 WRAPPER void CDarkel::DrawMessages(void) { EAXJMP(0x420920); } #else @@ -101,7 +101,7 @@ void CDarkel::DrawMessages() void CDarkel::Init() { - Status = KILLFRENZY_INIT; + Status = KILLFRENZY_NONE; } int16 CDarkel::QueryModelsKilledByPlayer(int32 modelId) @@ -121,16 +121,24 @@ eKillFrenzyStatus CDarkel::ReadStatus() return Status; } +#if 1 +WRAPPER int32 CDarkel::RegisterCarBlownUpByPlayer(eKillFrenzyStatus status) { EAXJMP(0x421070); } +#else int32 CDarkel::RegisterCarBlownUpByPlayer(eKillFrenzyStatus status) { return 0; } +#endif +#if 1 +WRAPPER void CDarkel::RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag) { EAXJMP(0x420F60); } +#else void CDarkel::RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag) { } +#endif void CDarkel::RegisterKillNotByPlayer() { @@ -139,49 +147,62 @@ void CDarkel::RegisterKillNotByPlayer() void CDarkel::ResetModelsKilledByPlayer() { - for (int i = 0; i < 200; i++) { - for (int j = 0; j < 8; j++) - RegisteredKills[i + j] = 0; - }; + for (int i = 0; i < 200; i++) + RegisteredKills[i] = 0; } +#if 0 +WRAPPER void CDarkel::ResetOnPlayerDeath() { EAXJMP(0x420E70); } +#else void CDarkel::ResetOnPlayerDeath() { - eWeaponType &EWeaponType = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; - int32 &CurrentWeapon = CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId; - int32 &CurrentDarkelWeapon = CDarkel::WeaponType; - uint32 &TotalAmmo = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; + if (Status != KILLFRENZY_ONGOING) + return; - if (Status == KILLFRENZY_ONGOING) { - CPopulation::m_AllRandomPedsThisType = -1; - Status = KILLFRENZY_FAILED; - TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_FAILED; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - CurrentDarkelWeapon = WEAPONTYPE_UZI; + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + WeaponType = WEAPONTYPE_UZI; - if (CurrentDarkelWeapon < WEAPONTYPE_TOTALWEAPONS) { - FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; - TotalAmmo = AmmoInterruptedWeapon; - } + if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; + CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon; + } - if (FindPlayerVehicle()) { - FindPlayerPed()->RemoveWeaponModel(CurrentWeapon); - FindPlayerPed()->m_currentWeapon = EWeaponType; - FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); - } + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId); + FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); + } + + + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_FAILED; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + WeaponType = WEAPONTYPE_UZI; + + if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; + CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon; + } + + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId); + FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); } } +#endif #if 0 WRAPPER void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) { EAXJMP(0x4210E0); } #else void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) { - eWeaponType &EWeaponType = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; - uint32 &TotalAmmo = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; - uint32 &AmmoInClip = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip; - if (weaponType == WEAPONTYPE_UZI_DRIVEBY) weaponType = WEAPONTYPE_UZI; @@ -210,15 +231,15 @@ void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 if (weaponType < WEAPONTYPE_TOTALWEAPONS) { InterruptedWeapon = FindPlayerPed()->m_currentWeapon; FindPlayerPed()->GiveWeapon(weaponType, 0); - AmmoInterruptedWeapon = TotalAmmo; + AmmoInterruptedWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; FindPlayerPed()->GiveWeapon(weaponType, 30000); - FindPlayerPed()->m_bWeaponSlot = EWeaponType; + FindPlayerPed()->m_bWeaponSlot = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_bWeaponSlot); if (FindPlayerVehicle()) { - FindPlayerPed()->m_currentWeapon = EWeaponType; - if (TotalAmmo <= AmmoInClip) - AmmoInClip = TotalAmmo; + FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal <= CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip) + CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; FindPlayerPed()->ClearWeaponTarget(); } @@ -230,76 +251,72 @@ void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 void CDarkel::Update() { - eWeaponType &EWeaponType = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; - int32 &CurrentWeapon = CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId; - int32 &CurrentDarkelWeapon = CDarkel::WeaponType; - uint32 &TotalAmmo = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; + if (Status != KILLFRENZY_ONGOING) + return; - if (Status == KILLFRENZY_ONGOING) { - int32 FrameTime = TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart); - if ((TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart)) > 0 || TimeLimit < 0) { - DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_ONGOING, FrameTime); + int32 FrameTime = TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart); + if ((TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart)) > 0 || TimeLimit < 0) { + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_ONGOING, FrameTime); - int32 PrevTime = FrameTime / 1000; + int32 PrevTime = FrameTime / 1000; - if (PrevTime != PreviousTime) { - if (PreviousTime < 12) - DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, PrevTime); - PreviousTime = PrevTime; - } - - } - else { - CPopulation::m_AllRandomPedsThisType = -1; - Status = KILLFRENZY_FAILED; - TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - CurrentDarkelWeapon = WEAPONTYPE_UZI; - - if (CurrentDarkelWeapon < WEAPONTYPE_TOTALWEAPONS) { - FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; - TotalAmmo = AmmoInterruptedWeapon; - } - - if (FindPlayerVehicle()) { - FindPlayerPed()->RemoveWeaponModel(CurrentWeapon); - FindPlayerPed()->m_currentWeapon = EWeaponType; - FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); - } - - if (bStandardSoundAndMessages) - DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_FAILED, 0); + if (PrevTime != PreviousTime) { + if (PreviousTime < 12) + DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, PrevTime); + PreviousTime = PrevTime; } - if (KillsNeeded <= 0) { - CPopulation::m_AllRandomPedsThisType = -1; - Status = KILLFRENZY_PASSED; + } + else { + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_FAILED; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - if (bProperKillFrenzy) - CStats::AnotherKillFrenzyPassed(); + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + WeaponType = WEAPONTYPE_UZI; - TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - - FindPlayerPed()->m_pWanted->SetWantedLevel(NOTWANTED); - - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - CurrentDarkelWeapon = WEAPONTYPE_UZI; - - if (CurrentDarkelWeapon < WEAPONTYPE_TOTALWEAPONS) { - FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; - TotalAmmo = AmmoInterruptedWeapon; - } - - if (FindPlayerVehicle()) { - FindPlayerPed()->RemoveWeaponModel(CurrentWeapon); - FindPlayerPed()->m_currentWeapon = EWeaponType; - FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); - } - - if (bStandardSoundAndMessages) - DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0); + if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; + CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon; } + + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId); + FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); + } + + if (bStandardSoundAndMessages) + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_FAILED, 0); + } + + if (KillsNeeded <= 0) { + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_PASSED; + + if (bProperKillFrenzy) + CStats::AnotherKillFrenzyPassed(); + + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + + FindPlayerPed()->m_pWanted->SetWantedLevel(NOTWANTED); + + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + WeaponType = WEAPONTYPE_UZI; + + if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon; + CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon; + } + + if (FindPlayerVehicle()) { + FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId); + FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); + } + + if (bStandardSoundAndMessages) + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0); } } diff --git a/src/control/Darkel.h b/src/control/Darkel.h index 905f5497..da1df24a 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -3,7 +3,7 @@ enum eKillFrenzyStatus { - KILLFRENZY_INIT, + KILLFRENZY_NONE, KILLFRENZY_ONGOING, KILLFRENZY_PASSED, KILLFRENZY_FAILED, From 0c34fb1bb2239b1433719bb410b71e0c28840c85 Mon Sep 17 00:00:00 2001 From: _AG Date: Sun, 7 Jul 2019 15:26:55 +0200 Subject: [PATCH 03/30] blah --- src/core/Stats.h | 2 +- src/peds/Ped.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/Stats.h b/src/core/Stats.h index a5670020..30058a59 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -5,7 +5,7 @@ class CStats public: static int32 &DaysPassed; static int32 &HeadShots; - static bool& CommercialPassed; + static bool& CommercialPassed; static int32 &NumberKillFrenziesPassed; static int32 &PeopleKilledByOthers; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index e4cc848e..016fea2f 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -2702,9 +2702,9 @@ CPed::QuitEnteringCar(void) bUsesCollision = true; if (IsPlayer() && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) { - if (IsPlayer() && m_storedWeapon != NO_STORED_WEAPON) { + if (IsPlayer() && m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) { SetCurrentWeapon(m_storedWeapon); - m_storedWeapon = NO_STORED_WEAPON; + m_storedWeapon = WEAPONTYPE_UNIDENTIFIED; } } else { CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); From 9062f958a40b7812438592872372077e2e2136e4 Mon Sep 17 00:00:00 2001 From: Filip Gawin Date: Fri, 5 Jul 2019 20:38:06 +0200 Subject: [PATCH 04/30] cleanup AudioManager --- src/audio/AudioManager.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 76ef8244..a48a3838 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -313,13 +313,9 @@ cAudioManager::ResetPoliceRadio() void cAudioManager::InterrogateAudioEntities() { - int32 i = 0; - int32 next; - - while(i < m_nAudioEntitiesTotal) { + for(uint32 i = 0; i < m_nAudioEntitiesTotal; i++) { ProcessEntity(m_anAudioEntityIndices[i]); - next = m_anAudioEntityIndices[i++]; - m_asAudioEntities[next].field_24 = 0; + m_asAudioEntities[m_anAudioEntityIndices[i]].field_24 = 0; } } @@ -436,7 +432,7 @@ cAudioManager::RandomDisplacement(uint32 seed) int32 value; static bool bIsEven = true; - static uint8 base = 0; + static uint32 base = 0; if(!seed) return 0; From d6944ec570d10f23867a925e5438192b314eb936 Mon Sep 17 00:00:00 2001 From: Filip Gawin Date: Fri, 5 Jul 2019 21:15:32 +0200 Subject: [PATCH 05/30] cAudioManager::Initialise --- src/audio/AudioManager.cpp | 108 +++++++++++++++++++++++++++++++++++- src/audio/AudioManager.h | 13 ++++- src/audio/MusicManager.cpp | 14 +++++ src/audio/MusicManager.h | 3 + src/audio/SampleManager.cpp | 28 ++++++++++ src/audio/SampleManager.h | 7 +++ 6 files changed, 167 insertions(+), 6 deletions(-) diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index a48a3838..6df4c052 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -94,6 +94,102 @@ constexpr int totalAudioEntitiesSlots = 200; char &g_nMissionAudioPlayingStatus = *(char *)0x60ED88; +void +cAudioManager::Initialise() +{ + if(!m_bIsInitialised) { + PreInitialiseGameSpecificSetup(); + m_bIsInitialised = cSampleManager.Initialise(); + if(m_bIsInitialised) { + m_bActiveSamples = cSampleManager.GetActiveSamples(); + if(m_bActiveSamples <= 1u) { + Terminate(); + } else { + --m_bActiveSamples; + PostInitialiseGameSpecificSetup(); + InitialisePoliceRadioZones(); + InitialisePoliceRadio(); + MusicManager.Initialise(); + } + } + } +} + +void +cAudioManager::PostInitialiseGameSpecificSetup() +{ + m_nFireAudioEntity = CreateEntity( + AUDIOTYPE_FIRE, (CPhysical *)0x8F31D0); // last is addr of firemanager @todo change + if(m_nFireAudioEntity >= 0) cAudioManager::SetEntityStatus(m_nFireAudioEntity, 1); + + m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (CPhysical *)1); + if(m_nCollisionEntity >= 0) cAudioManager::SetEntityStatus(m_nCollisionEntity, 1); + + m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (CPhysical *)1); + if(m_nFrontEndEntity >= 0) cAudioManager::SetEntityStatus(m_nFrontEndEntity, 1); + + m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (CPhysical *)1); + if(m_nProjectileEntity >= 0) cAudioManager::SetEntityStatus(m_nProjectileEntity, 1); + + m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATER_CANNON, (CPhysical *)1); + if(m_nWaterCannonEntity >= 0) cAudioManager::SetEntityStatus(m_nWaterCannonEntity, 1); + + m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_D, (CPhysical *)1); + if(m_nPoliceChannelEntity >= 0) cAudioManager::SetEntityStatus(m_nPoliceChannelEntity, 1); + + m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (CPhysical *)1); + if(m_nBridgeEntity >= 0) cAudioManager::SetEntityStatus(m_nBridgeEntity, 1); + + m_sMissionAudio.m_nSampleIndex = NO_SAMPLE; + m_sMissionAudio.m_bLoadingStatus = 0; + m_sMissionAudio.m_bPlayStatus = 0; + m_sMissionAudio.field_22 = 0; + m_sMissionAudio.m_bIsPlayed = 0; + m_sMissionAudio.field_12 = 1; + m_sMissionAudio.field_24 = 0; + ResetAudioLogicTimers((int32)CTimer::GetTimeInMilliseconds); +} + +WRAPPER +void +cAudioManager::InitialisePoliceRadioZones() +{ + EAXJMP(0x57EAC0); +} + +WRAPPER +void +cAudioManager::ResetAudioLogicTimers(int32 timer) +{ + EAXJMP(0x569650); +} + +void +cAudioManager::Terminate() +{ + if(m_bIsInitialised) { + MusicManager.Terminate(); + + for(uint32 i = 0; i < totalAudioEntitiesSlots; i++) { + m_asAudioEntities[i].m_bIsUsed = 0; + m_anAudioEntityIndices[i] = 200; + } + + m_nAudioEntitiesTotal = 0; + m_nScriptObjectEntityTotal = 0; + PreTerminateGameSpecificShutdown(); + + for(uint32 i = 0; i < 2; i++) { + if(cSampleManager.IsSampleBankLoaded(i)) cSampleManager.UnloadSampleBank(i); + } + + cSampleManager.Terminate(); + + m_bIsInitialised = 0; + PostTerminateGameSpecificShutdown(); + } +} + char cAudioManager::GetMissionScriptPoliceAudioPlayingStatus() { @@ -469,17 +565,17 @@ cAudioManager::IsAudioInitialised() const } int32 -cAudioManager::CreateEntity(int32 type, CPhysical *memory) +cAudioManager::CreateEntity(int32 type, CPhysical *entity) { if(!m_bIsInitialised) return -4; - if(!memory) return -2; + if(!entity) return -2; if(type >= TOTAL_AUDIO_TYPES) return -1; for(uint32 i = 0; i < 200; i++) { if(!m_asAudioEntities[i].m_bIsUsed) { m_asAudioEntities[i].m_bIsUsed = true; m_asAudioEntities[i].m_bStatus = 0; m_asAudioEntities[i].m_nType = (eAudioType)type; - m_asAudioEntities[i].m_pEntity = memory; + m_asAudioEntities[i].m_pEntity = entity; m_asAudioEntities[i].m_awAudioEvent[0] = SOUND_TOTAL_PED_SOUNDS; m_asAudioEntities[i].m_awAudioEvent[1] = SOUND_TOTAL_PED_SOUNDS; m_asAudioEntities[i].m_awAudioEvent[2] = SOUND_TOTAL_PED_SOUNDS; @@ -2720,6 +2816,12 @@ cAudioManager::Service() } STARTPATCHES +InjectHook(0x57A0E0, &cAudioManager::Initialise, PATCH_JUMP); +InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP); +//InjectHook(0x57EAC0, &cAudioManager::InitialisePoliceRadioZones, PATCH_JUMP); +//InjectHook(0x569650, &cAudioManager::ResetAudioLogicTimers, PATCH_JUMP); +InjectHook(0x57A150, &cAudioManager::Terminate, PATCH_JUMP); + InjectHook(0x57F050, &cAudioManager::GetMissionScriptPoliceAudioPlayingStatus, PATCH_JUMP); InjectHook(0x5795D0, &cAudioManager::GetMissionAudioLoadingStatus, PATCH_JUMP); diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index 24dae2ce..9796c1c8 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -218,6 +218,15 @@ public: char field_19195; int m_nTimeOfRecentCrime; + void Initialise(); + void PostInitialiseGameSpecificSetup(); + void InitialisePoliceRadioZones(); // @todo + void ResetAudioLogicTimers(int32 timer); // @todo + + void Terminate(); + + // done + char GetMissionScriptPoliceAudioPlayingStatus(); bool GetMissionAudioLoadingStatus(); @@ -282,8 +291,6 @@ public: void InitialisePoliceRadio(); - // done - int32 RandomDisplacement(uint32 seed); void ReleaseDigitalHandle(); @@ -292,7 +299,7 @@ public: bool IsAudioInitialised() const; - int32 CreateEntity(int32 type, CPhysical *memory); + int32 CreateEntity(int32 type, CPhysical *entity); void DestroyEntity(int32 id); void SetEntityStatus(int32 id, bool status); diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp index 7b7c1182..dcd4ae93 100644 --- a/src/audio/MusicManager.cpp +++ b/src/audio/MusicManager.cpp @@ -174,3 +174,17 @@ void cMusicManager::DisplayRadioStationName() } } #endif + +WRAPPER +void +cMusicManager::Initialise() +{ + EAXJMP(0x57CF70); +} + +WRAPPER +void +cMusicManager::Terminate() +{ + EAXJMP(0x57D140); +} diff --git a/src/audio/MusicManager.h b/src/audio/MusicManager.h index dcb34daf..944fd16e 100644 --- a/src/audio/MusicManager.h +++ b/src/audio/MusicManager.h @@ -264,6 +264,9 @@ public: uint8 field_2395; public: + void Initialise(); + void Terminate(); + char *Get3DProviderName(char); bool PlayerInCar(); void DisplayRadioStationName(); diff --git a/src/audio/SampleManager.cpp b/src/audio/SampleManager.cpp index 7af3446b..fbeb49ed 100644 --- a/src/audio/SampleManager.cpp +++ b/src/audio/SampleManager.cpp @@ -12,6 +12,33 @@ bool CSampleManager::IsMP3RadioChannelAvailable() { return nNumOfMp3Files != 0; } +WRAPPER +bool CSampleManager::IsSampleBankLoaded(uint8) { EAXJMP(0x567130); } + +WRAPPER +void CSampleManager::UnloadSampleBank(uint8) { EAXJMP(0x567110); } + +WRAPPER +void +CSampleManager::Terminate() +{ + EAXJMP(0x566DC0); +} + +WRAPPER +bool +CSampleManager::Initialise() +{ + EAXJMP(0x566530); +} + +WRAPPER +int32 +CSampleManager::GetActiveSamples() +{ + EAXJMP(0x565970); +} + WRAPPER void CSampleManager::ReleaseDigitalHandle() { @@ -87,6 +114,7 @@ CSampleManager::StopChannel(int32 id) { EAXJMP(0x567BE0); } + STARTPATCHES InjectHook(0x566490, CSampleManager::IsMP3RadioChannelAvailable, PATCH_JUMP); ENDPATCHES \ No newline at end of file diff --git a/src/audio/SampleManager.h b/src/audio/SampleManager.h index 1bee1775..f0245d4e 100644 --- a/src/audio/SampleManager.h +++ b/src/audio/SampleManager.h @@ -11,6 +11,13 @@ struct tSample { class CSampleManager { public: + bool IsSampleBankLoaded(uint8); + void UnloadSampleBank(uint8); + void Terminate(); + + bool Initialise(); + int32 GetActiveSamples(); + void ReleaseDigitalHandle(); void RequireDigitalHandle(); From 567937a8cdcce8271b7242e41d4b716443b00be2 Mon Sep 17 00:00:00 2001 From: Filip Gawin Date: Sun, 7 Jul 2019 16:32:28 +0200 Subject: [PATCH 06/30] Fix reverse warn and air brakes --- src/audio/AudioManager.cpp | 159 +++++++++++++++++++++++++++++++++++-- src/audio/AudioManager.h | 17 ++-- 2 files changed, 165 insertions(+), 11 deletions(-) diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 6df4c052..9e86aef0 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -91,9 +91,153 @@ enum eVehicleModel cAudioManager &AudioManager = *(cAudioManager *)0x880FC0; constexpr int totalAudioEntitiesSlots = 200; +constexpr int maxVolume = 127; char &g_nMissionAudioPlayingStatus = *(char *)0x60ED88; +void +cAudioManager::AddSampleToRequestedQueue() +{ + int32 calculatedVolume; + tActiveSample *sample; + int32 unknown1; + uint8 unknown2; + bool bReflections; + + if(m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) { + calculatedVolume = m_sQueueSample.field_16 * (maxVolume - m_sQueueSample.m_bVolume); + unknown2 = m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; + if(unknown2 >= m_bActiveSamples) { + unknown1 = 27 * m_bActiveSampleQueue; + unknown2 = *(&m_asSamples[53].field_91 + m_bActiveSamples + unknown1); + if(m_asSamples[unknown1 + unknown2].calculatedVolume <= calculatedVolume) + return; + } else { + ++m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; + } + m_sQueueSample.calculatedVolume = calculatedVolume; + m_sQueueSample.m_bLoopEnded = 0; + if(m_sQueueSample.m_bIsDistant) { + m_sQueueSample.m_bRequireReflection = 0; + m_sQueueSample.m_bLoopsRemaining = 0; + } + if(m_bDynamicAcousticModelingStatus && m_sQueueSample.m_nLoopCount) { + bReflections = m_sQueueSample.m_bRequireReflection; + } else { + bReflections = false; + m_sQueueSample.m_bLoopsRemaining = 0; + } + m_sQueueSample.m_bRequireReflection = 0; + + if(!m_bDynamicAcousticModelingStatus) m_sQueueSample.m_bReverbFlag = 0; + + sample = &m_asSamples[27 * m_bActiveSampleQueue + unknown2]; + sample->m_nEntityIndex = m_sQueueSample.m_nEntityIndex; + sample->field_4 = m_sQueueSample.field_4; + sample->m_nSampleIndex = m_sQueueSample.m_nSampleIndex; + sample->m_bBankIndex = m_sQueueSample.m_bBankIndex; + sample->m_bIsDistant = m_sQueueSample.m_bIsDistant; + sample->field_16 = m_sQueueSample.field_16; + sample->m_nFrequency = m_sQueueSample.m_nFrequency; + sample->m_bVolume = m_sQueueSample.m_bVolume; + sample->m_fDistance = m_sQueueSample.m_fDistance; + sample->m_nLoopCount = m_sQueueSample.m_nLoopCount; + sample->m_nLoopStart = m_sQueueSample.m_nLoopStart; + sample->m_nLoopEnd = m_sQueueSample.m_nLoopEnd; + sample->m_bEmittingVolume = m_sQueueSample.m_bEmittingVolume; + sample->field_48 = m_sQueueSample.field_48; + sample->m_fSoundIntensity = m_sQueueSample.m_fSoundIntensity; + sample->field_56 = m_sQueueSample.field_56; + sample->m_vecPos = m_sQueueSample.m_vecPos; + sample->m_bReverbFlag = m_sQueueSample.m_bReverbFlag; + sample->m_bLoopsRemaining = m_sQueueSample.m_bLoopsRemaining; + sample->m_bRequireReflection = m_sQueueSample.m_bRequireReflection; + sample->m_bOffset = m_sQueueSample.m_bOffset; + sample->field_76 = m_sQueueSample.field_76; + sample->m_bIsProcessed = m_sQueueSample.m_bIsProcessed; + sample->m_bLoopEnded = m_sQueueSample.m_bLoopEnded; + sample->calculatedVolume = m_sQueueSample.calculatedVolume; + sample->field_88 = m_sQueueSample.field_88; + + AddDetailsToRequestedOrderList(unknown2); + if(bReflections) AddReflectionsToRequestedQueue(); + } +} + +void +cAudioManager::AddDetailsToRequestedOrderList(uint8 sample) +{ + int32 offset; + uint32 i = 0; + if(sample != 0) { + for(; i < sample; i++) { + offset = 27 * m_bActiveSampleQueue; + if(m_asSamples[offset + m_abSampleQueueIndexTable[i + offset]] + .calculatedVolume > m_asSamples[offset + sample].calculatedVolume) + break; + } + if(i < sample) { + memmove(&m_abSampleQueueIndexTable[offset + 1 + i], + &m_abSampleQueueIndexTable[offset + i], m_bActiveSamples - i - 1); + } + } + m_abSampleQueueIndexTable[27 * m_bActiveSampleQueue + i] = sample; +} + +void +cAudioManager::AddReflectionsToRequestedQueue() +{ + float reflectionDistance; + int32 noise; + uint8 emittingVolume = emittingVolume = + (m_sQueueSample.m_bVolume >> 1) + (m_sQueueSample.m_bVolume >> 3); + + for(uint32 i = 0; i < 5u; i++) { + reflectionDistance = m_afReflectionsDistances[i]; + if(reflectionDistance > 0.0f && reflectionDistance < 100.f && + reflectionDistance < m_sQueueSample.m_fSoundIntensity) { + m_sQueueSample.m_bLoopsRemaining = (reflectionDistance * 0.38873f); // @todo assert value + if(m_sQueueSample.m_bLoopsRemaining > 5u) { + m_sQueueSample.m_fDistance = m_afReflectionsDistances[i]; + m_sQueueSample.m_bEmittingVolume = emittingVolume; + m_sQueueSample.m_bVolume = + ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, + m_sQueueSample.m_fDistance); + if(m_sQueueSample.m_bVolume > emittingVolume >> 4) { + m_sQueueSample.field_4 += ((i + 1) << 8); + if(m_sQueueSample.m_nLoopCount) { + noise = RandomDisplacement( + m_sQueueSample.m_nFrequency >> 5); + if(noise <= 0) + m_sQueueSample.m_nFrequency += noise; + else + m_sQueueSample.m_nFrequency -= noise; + } + m_sQueueSample.field_16 += 20; + m_sQueueSample.m_vecPos.x = m_avecReflectionsPos[i].x; + m_sQueueSample.m_vecPos.y = m_avecReflectionsPos[i].y; + m_sQueueSample.m_vecPos.z = m_avecReflectionsPos[i].z; + AddSampleToRequestedQueue(); + } + } + } + } +} + +uint32 +cAudioManager::ComputeVolume(int emittingVolume, float soundIntensity, float distance) +{ + float newSoundIntensity; + if(soundIntensity <= 0.0f) return 0; + if((soundIntensity * 0.2f) <= distance) { + newSoundIntensity = soundIntensity * 0.2f; + emittingVolume = + sq((soundIntensity - distance) / (soundIntensity - newSoundIntensity)) * + emittingVolume; + } + return emittingVolume; +} + void cAudioManager::Initialise() { @@ -409,7 +553,7 @@ cAudioManager::ResetPoliceRadio() void cAudioManager::InterrogateAudioEntities() { - for(uint32 i = 0; i < m_nAudioEntitiesTotal; i++) { + for(int32 i = 0; i < m_nAudioEntitiesTotal; i++) { ProcessEntity(m_anAudioEntityIndices[i]); m_asAudioEntities[m_anAudioEntityIndices[i]].field_24 = 0; } @@ -418,7 +562,7 @@ cAudioManager::InterrogateAudioEntities() void cAudioManager::ClearRequestedQueue() { - for(uint32 i = 0; i < m_bActiveSamples; i++) { + for(int32 i = 0; i < m_bActiveSamples; i++) { m_abSampleQueueIndexTable[i + 27 * m_bActiveSampleQueue] = m_bActiveSamples; } m_bSampleRequestQueuesStatus[m_bActiveSampleQueue] = 0; @@ -432,14 +576,14 @@ cAudioManager::ClearRequestedQueue() bool cAudioManager::UsesReverseWarning(int32 model) { - return model == LINERUN || fabs(model - FIRETRUK) <= 1 || model == BUS || + return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH; // fix } bool cAudioManager::HasAirBrakes(int32 model) { - return model == LINERUN || fabs(model - FIRETRUK) <= 1 || model == BUS || + return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH; // fix } @@ -594,7 +738,7 @@ cAudioManager::DestroyEntity(int32 id) if(m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots && m_asAudioEntities[id].m_bIsUsed) { m_asAudioEntities[id].m_bIsUsed = 0; - for(uint32 i = 0; i < m_nAudioEntitiesTotal; ++i) { + for(int32 i = 0; i < m_nAudioEntitiesTotal; ++i) { if(id == m_anAudioEntityIndices[i]) { if(i < totalAudioEntitiesSlots - 1) memmove(&m_anAudioEntityIndices[i], @@ -2816,6 +2960,11 @@ cAudioManager::Service() } STARTPATCHES +InjectHook(0x57B070, &cAudioManager::AddSampleToRequestedQueue, PATCH_JUMP); +InjectHook(0x57B210, &cAudioManager::AddDetailsToRequestedOrderList, PATCH_JUMP); +InjectHook(0x57B300, &cAudioManager::AddReflectionsToRequestedQueue, PATCH_JUMP); +InjectHook(0x57ABB0, &cAudioManager::ComputeVolume, PATCH_JUMP); + InjectHook(0x57A0E0, &cAudioManager::Initialise, PATCH_JUMP); InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP); //InjectHook(0x57EAC0, &cAudioManager::InitialisePoliceRadioZones, PATCH_JUMP); diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index 9796c1c8..7a2dc9c5 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -44,7 +44,7 @@ public: char m_bLoopEnded; char field_82; char field_83; - int field_84; + int calculatedVolume; char field_88; char field_89; char field_90; @@ -218,15 +218,20 @@ public: char field_19195; int m_nTimeOfRecentCrime; + void AddSampleToRequestedQueue(); + + void AddDetailsToRequestedOrderList(uint8 sample); + void AddReflectionsToRequestedQueue(); + + uint32 ComputeVolume(int emittingVolume, float soundIntensity, float distance); + void Initialise(); void PostInitialiseGameSpecificSetup(); - void InitialisePoliceRadioZones(); // @todo + void InitialisePoliceRadioZones(); // @todo void ResetAudioLogicTimers(int32 timer); // @todo void Terminate(); - // done - char GetMissionScriptPoliceAudioPlayingStatus(); bool GetMissionAudioLoadingStatus(); @@ -270,7 +275,7 @@ public: void InterrogateAudioEntities(); void ClearRequestedQueue(); -// void AgeCrimes(); + // void AgeCrimes(); //todo bool UsesReverseWarning(int32 model); bool HasAirBrakes(int32 model); @@ -283,7 +288,7 @@ public: void ProcessPlane(void *); // todo void ClearMissionAudio(); -// void ProcessReverb(); + // void ProcessReverb(); // todo bool IsMissionAudioSampleFinished(); From ee0494b2d86aef799177cc0b80383a29ceee441b Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sun, 7 Jul 2019 19:00:02 +0300 Subject: [PATCH 07/30] IntoTheScripts! --- src/control/Script.cpp | 305 +++++++++++++++++++++++++++++++++++++++-- src/control/Script.h | 182 +++++++++++++++++++++--- src/core/config.h | 1 + src/core/re3.cpp | 23 +--- src/render/Hud.cpp | 10 +- 5 files changed, 466 insertions(+), 55 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 5e7f4936..d2e27487 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -6,6 +6,7 @@ #include "Camera.h" #include "CarCtrl.h" #include "DMAudio.h" +#include "FileMgr.h" #include "Hud.h" #include "ModelIndices.h" #include "PlayerInfo.h" @@ -17,18 +18,44 @@ #include "Weather.h" #include "World.h" -uint8 (&CTheScripts::ScriptSpace)[160 * 1024] = *(uint8(*)[160 * 1024])*(uintptr*)0x74B248; -CTextLine (&CTheScripts::IntroTextLines)[2] = *(CTextLine (*)[2])*(uintptr*)0x70EA74; -CScriptRectangle (&CTheScripts::IntroRectangles)[16] = *(CScriptRectangle (*)[16])*(uintptr*)0x72D108; -CSprite2d (&CTheScripts::ScriptSprites)[16] = *(CSprite2d(*)[16])*(uintptr*)0x72B090; +uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SPACE])*(uintptr*)0x74B248; +CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08; +int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200; +int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0; +CTextLine (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(CTextLine (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68; +CScriptRectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(CScriptRectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108; +CSprite2d (&CTheScripts::ScriptSprites)[MAX_NUM_SCRIPT_SRPITES] = *(CSprite2d(*)[MAX_NUM_SCRIPT_SRPITES])*(uintptr*)0x72B090; +CScriptSphere(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(CScriptSphere(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60; +tCollectiveData(&CTheScripts::CollectiveArray)[MAX_NUM_COLLECTIVES] = *(tCollectiveData(*)[MAX_NUM_COLLECTIVES])*(uintptr*)0x6FA008; +tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject(*)[MAX_NUM_USED_OBJECTS])*(uintptr*)0x6E69C8; +int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558; +tBuildingSwap(&CTheScripts::BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS] = *(tBuildingSwap(*)[MAX_NUM_BUILDING_SWAPS])*(uintptr*)0x880E30; +CEntity*(&CTheScripts::InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS] = *(CEntity*(*)[MAX_NUM_INVISIBILITY_SETTINGS])*(uintptr*)0x8620F0; bool &CTheScripts::DbgFlag = *(bool*)0x95CD87; uint32 &CTheScripts::OnAMissionFlag = *(uint32*)0x8F2A24; int32 &CTheScripts::StoreVehicleIndex = *(int32*)0x8F5F3C; bool &CTheScripts::StoreVehicleWasRandom = *(bool*)0x95CDBC; - -CMissionCleanup(&CTheScripts::MissionCleanup) = *(CMissionCleanup*)0x8F2AD8; -CUpsideDownCarCheck(&CTheScripts::UpsideDownCars) = *(CUpsideDownCarCheck*)0x6EE450; -CStuckCarCheck(&CTheScripts::StuckCars) = *(CStuckCarCheck*)0x87C588; +CRunningScript *&CTheScripts::pIdleScripts = *(CRunningScript**)0x9430D4; +CRunningScript *&CTheScripts::pActiveScripts = *(CRunningScript**)0x8E2BF4; +uint32 &CTheScripts::NextFreeCollectiveIndex = *(uint32*)0x942F98; +int32 &CTheScripts::LastRandomPedId = *(int32*)0x8F251C; +uint16 &CTheScripts::NumberOfUsedObjects = *(uint16*)0x95CC72; +bool &CTheScripts::bAlreadyRunningAMissionScript = *(bool*)0x95CDB3; +bool &CTheScripts::bUsingAMultiScriptFile = *(bool*)0x95CD55; +uint16 &CTheScripts::NumberOfMissionScripts = *(uint16*)0x95CC9A; +uint32 &CTheScripts::LargestMissionScriptSize = *(uint32*)0x9414C8; +uint32 &CTheScripts::MainScriptSize = *(uint32*)0x9405A4; +uint8 &CTheScripts::FailCurrentMission = *(uint8*)0x95CD41; +uint8 &CTheScripts::CountdownToMakePlayerUnsafe = *(uint8*)0x95CD51; +uint8 &CTheScripts::DelayMakingPlayerUnsafeThisTime = *(uint8*)0x95CD88; +uint16 &CTheScripts::NumScriptDebugLines = *(uint16*)0x95CC42; +uint16 &CTheScripts::NumberOfIntroRectanglesThisFrame = *(uint16*)0x95CC88; +uint16 &CTheScripts::NumberOfIntroTextLinesThisFrame = *(uint16*)0x95CC32; +bool &CTheScripts::UseTextCommands = *(bool*)0x95CD57; +CMissionCleanup (&CTheScripts::MissionCleanup) = *(CMissionCleanup*)0x8F2A24; +CUpsideDownCarCheck (&CTheScripts::UpsideDownCars) = *(CUpsideDownCarCheck*)0x6EE450; +CStuckCarCheck (&CTheScripts::StuckCars) = *(CStuckCarCheck*)0x87C588; +int32(&ScriptParams)[32] = *(int32(*)[32])*(uintptr*)0x6ED460; CMissionCleanup::CMissionCleanup() { @@ -277,11 +304,263 @@ bool CStuckCarCheck::HasCarBeenStuckForAWhile(int32 id) return false; } +void CRunningScript::CollectParameters(uint32* pIp, int16 total) +{ + for (int16 i = 0; i < total; i++){ + float tmp; + switch (CTheScripts::Read1ByteFromScript(pIp)) + { + case ARGUMENT_INT32: + ScriptParams[i] = CTheScripts::Read4BytesFromScript(pIp); + break; + case ARGUMENT_GLOBALVAR: + ScriptParams[i] = *((int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)]); + break; + case ARGUMENT_LOCALVAR: + ScriptParams[i] = m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)]; + break; + case ARGUMENT_INT8: + ScriptParams[i] = CTheScripts::Read1ByteFromScript(pIp); + break; + case ARGUMENT_INT16: + ScriptParams[i] = CTheScripts::Read2BytesFromScript(pIp); + break; + case ARGUMENT_FLOAT: + tmp = CTheScripts::ReadFloatFromScript(pIp); + ScriptParams[i] = *(int32*)&tmp; + break; + default: + assert(0); + break; + } + } +} + +int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip) +{ + uint32* pIp = &ip; + float tmp; + switch (CTheScripts::Read1ByteFromScript(pIp)) + { + case ARGUMENT_INT32: + return CTheScripts::Read4BytesFromScript(pIp); + case ARGUMENT_GLOBALVAR: + return *((int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)]); + case ARGUMENT_LOCALVAR: + return m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)]; + case ARGUMENT_INT8: + return CTheScripts::Read1ByteFromScript(pIp); + case ARGUMENT_INT16: + return CTheScripts::Read2BytesFromScript(pIp); + case ARGUMENT_FLOAT: + tmp = CTheScripts::ReadFloatFromScript(pIp); + return *(int32*)&tmp; + default: + assert(0); + } + return -1; +} + +void CRunningScript::StoreParameters(uint32* pIp, int16 number) +{ + for (int16 i = 0; i < number; i++){ + switch (CTheScripts::Read1ByteFromScript(pIp)) { + case ARGUMENT_GLOBALVAR: + *(int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i]; + break; + case ARGUMENT_LOCALVAR: + m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i]; + break; + default: + assert(0); + } + } +} + +int32 *CRunningScript::GetPointerToScriptVariable(uint32* pIp, int16 type) +{ + switch (CTheScripts::Read1ByteFromScript(pIp)) + { + case ARGUMENT_GLOBALVAR: + assert(type == VAR_GLOBAL); + return (int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)]; + case ARGUMENT_LOCALVAR: + assert(type == VAR_LOCAL); + return &m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)]; + default: + assert(0); + } + return nil; +} + +void CRunningScript::Init() +{ + strcpy(m_abScriptName, "noname"); + next = prev = nil; + m_nIp = 0; + for (int i = 0; i < MAX_STACK_DEPTH; i++) + m_anStack[i] = 0; + m_nStackPointer = 0; + m_nWakeTime = 0; + m_bCondResult = false; + m_bIsMissionThread = false; + m_bSkipWakeTime = false; + for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) + m_anLocalVariables[i] = 0; + m_nAndOrState = 0; + m_bNotFlag = false; + m_bWBCheckEnabled = true; + m_bWBChecked = false; + m_bMissionFlag = false; +} + +#ifdef USE_DEBUG_SCRIPT_LOADER +int open_script() +{ + static int scriptToLoad = 1; + + if (GetAsyncKeyState('G') & 0x8000) + scriptToLoad = 0; + if (GetAsyncKeyState('R') & 0x8000) + scriptToLoad = 1; + if (GetAsyncKeyState('D') & 0x8000) + scriptToLoad = 2; + + switch (scriptToLoad) { + case 0: return CFileMgr::OpenFile("main.scm", "rb"); + case 1: return CFileMgr::OpenFile("main_freeroam.scm", "rb"); + case 2: return CFileMgr::OpenFile("main_d.scm", "rb"); + } + return CFileMgr::OpenFile("main.scm", "rb"); +} +#endif + +void CTheScripts::Init() +{ + for (int i = 0; i < SIZE_SCRIPT_SPACE; i++) + ScriptSpace[i] = 0; + pActiveScripts = pIdleScripts = nil; + for (int i = 0; i < MAX_NUM_SCRIPTS; i++){ + ScriptsArray[i].Init(); + ScriptsArray[i].AddScriptToList(&pIdleScripts); + } + MissionCleanup.Init(); + UpsideDownCars.Init(); + StuckCars.Init(); + CFileMgr::SetDir("data"); +#ifdef USE_DEBUG_SCRIPT_LOADER + int mainf = open_script(); +#else + int mainf = CFileMgr::OpenFile("main.scm", "rb"); +#endif + CFileMgr::Read(mainf, (char*)ScriptSpace, SIZE_MAIN_SCRIPT); + CFileMgr::CloseFile(mainf); + CFileMgr::SetDir(""); + StoreVehicleIndex = -1; + StoreVehicleWasRandom = true; + OnAMissionFlag = 0; + for (int i = 0; i < MAX_NUM_CONTACTS; i++){ + BaseBriefIdForContact[i] = 0; + OnAMissionForContactFlag[i] = 0; + } + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++){ + CollectiveArray[i].index = -1; + CollectiveArray[i].unk_data = 0; + } + NextFreeCollectiveIndex = 0; + LastRandomPedId = -1; + for (int i = 0; i < MAX_NUM_USED_OBJECTS; i++){ + memset(&UsedObjectArray[i].name, 0, sizeof(UsedObjectArray[i].name)); + UsedObjectArray[i].index = 0; + } + NumberOfUsedObjects = 0; + ReadObjectNamesFromScript(); + UpdateObjectIndices(); + bAlreadyRunningAMissionScript = false; + bUsingAMultiScriptFile = true; + for (int i = 0; i < MAX_NUM_MISSION_SCRIPTS; i++) + MultiScriptArray[i] = 0; + NumberOfMissionScripts = 0; + LargestMissionScriptSize = 0; + MainScriptSize = 0; + ReadMultiScriptFileOffsetsFromScript(); + FailCurrentMission = 0; + CountdownToMakePlayerUnsafe = 0; + DbgFlag = 0; + DelayMakingPlayerUnsafeThisTime = 0; + NumScriptDebugLines = 0; + for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++){ + ScriptSphereArray[i].m_bInUse = false; + ScriptSphereArray[i].m_Index = 1; + ScriptSphereArray[i].m_Id = 0; + ScriptSphereArray[i].m_vecCenter = CVector(0.0f, 0.0f, 0.0f); + ScriptSphereArray[i].m_fRadius = 0.0f; + } + for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++){ + IntroTextLines[i].m_fScaleX = 0.48f; + IntroTextLines[i].m_fScaleY = 1.12f; + IntroTextLines[i].m_sColor = CRGBA(225, 225, 225, 255); + IntroTextLines[i].m_bJustify = false; + IntroTextLines[i].m_bRightJustify = false; + IntroTextLines[i].m_bCentered = false; + IntroTextLines[i].m_bBackground = false; + IntroTextLines[i].m_bBackgroundOnly = false; + IntroTextLines[i].m_fWrapX = 182.0f; /* TODO: scaling as bugfix */ + IntroTextLines[i].m_fCenterSize = 640.0f; /* --||-- */ + IntroTextLines[i].m_sBackgroundColor = CRGBA(128, 128, 128, 128); + IntroTextLines[i].m_bTextProportional = true; + IntroTextLines[i].m_bTextBeforeFade = false; + IntroTextLines[i].m_nFont = 2; /* enum? */ + IntroTextLines[i].m_fAtX = 0.0f; + IntroTextLines[i].m_fAtY = 0.0f; + memset(&IntroTextLines[i].m_Text, 0, sizeof(IntroTextLines[i].m_Text)); + } + NumberOfIntroTextLinesThisFrame = 0; + UseTextCommands = false; + for (int i = 0; i < MAX_NUM_INTRO_RECTANGLES; i++){ + IntroRectangles[i].m_bIsUsed = false; + IntroRectangles[i].m_bIsAntialiased = false; + IntroRectangles[i].m_nTextureId = -1; + IntroRectangles[i].m_sRect = CRect(0.0f, 0.0f, 0.0f, 0.0f); + IntroRectangles[i].m_sColor = CRGBA(255, 255, 255, 255); + } + NumberOfIntroRectanglesThisFrame = 0; + for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++){ + BuildingSwapArray[i].m_pBuilding = nil; + BuildingSwapArray[i].m_nNewModel = -1; + BuildingSwapArray[i].m_nOldModel = -1; + } + for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) + InvisibilitySettingArray[i] = nil; +} + +void CRunningScript::RemoveScriptFromList(CRunningScript** ppScript) +{ + if (prev) + prev->next = next; + else + *ppScript = next; + if (next) + next->prev = prev; +} + +void CRunningScript::AddScriptToList(CRunningScript** ppScript) +{ + next = *ppScript; + prev = nil; + if (*ppScript) + (*ppScript)->prev = this; + *ppScript = this; +} + +WRAPPER bool CTheScripts::IsPlayerOnAMission() { EAXJMP(0x439410); } +WRAPPER void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2) { EAXJMP(0x4534E0); } WRAPPER void CTheScripts::CleanUpThisVehicle(CVehicle*) { EAXJMP(0x4548D0); } WRAPPER void CTheScripts::CleanUpThisPed(CPed*) { EAXJMP(0x4547A0); } WRAPPER void CTheScripts::CleanUpThisObject(CObject*) { EAXJMP(0x454910); } -WRAPPER bool CTheScripts::IsPlayerOnAMission() { EAXJMP(0x439410); } -WRAPPER void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2) { EAXJMP(0x4534E0); } +WRAPPER void CTheScripts::ReadObjectNamesFromScript() { EAXJMP(0x454960); } +WRAPPER void CTheScripts::UpdateObjectIndices() { EAXJMP(0x454AD0); } +WRAPPER void CTheScripts::ReadMultiScriptFileOffsetsFromScript() { EAXJMP(0x454BC0); } STARTPATCHES InjectHook(0x437AE0, &CMissionCleanup::Init, PATCH_JUMP); @@ -299,4 +578,10 @@ InjectHook(0x4380A0, &CStuckCarCheck::Process, PATCH_JUMP); InjectHook(0x4381C0, &CStuckCarCheck::AddCarToCheck, PATCH_JUMP); InjectHook(0x438240, &CStuckCarCheck::RemoveCarFromCheck, PATCH_JUMP); InjectHook(0x4382A0, &CStuckCarCheck::HasCarBeenStuckForAWhile, PATCH_JUMP); +InjectHook(0x4382E0, &CRunningScript::CollectParameters, PATCH_JUMP); +InjectHook(0x438460, &CRunningScript::CollectNextParameterWithoutIncreasingPC, PATCH_JUMP); +InjectHook(0x4385A0, &CRunningScript::StoreParameters, PATCH_JUMP); +InjectHook(0x438640, &CRunningScript::GetPointerToScriptVariable, PATCH_JUMP); +InjectHook(0x4386C0, &CRunningScript::Init, PATCH_JUMP); +InjectHook(0x438790, &CTheScripts::Init, PATCH_JUMP); ENDPATCHES \ No newline at end of file diff --git a/src/control/Script.h b/src/control/Script.h index 42e41c70..5759cf82 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -1,4 +1,6 @@ #pragma once +#include "common.h" +#include "Collision.h" #include "Ped.h" #include "Object.h" #include "Sprite2d.h" @@ -8,11 +10,17 @@ struct CScriptRectangle { bool m_bIsUsed; bool m_bIsAntialiased; - uint16 m_wTextureId; + int16 m_nTextureId; CRect m_sRect; CRGBA m_sColor; }; +static_assert(sizeof(CScriptRectangle) == 0x18, "Script.h: error"); + +enum { + SCRIPT_TEXT_MAX_LENGTH = 500 +}; + struct CTextLine { float m_fScaleX; @@ -26,33 +34,58 @@ struct CTextLine float m_fCenterSize; CRGBA m_sBackgroundColor; bool m_bTextProportional; - int32 field_29; + bool m_bTextBeforeFade; bool m_bRightJustify; - int32 field_31; int32 m_nFont; - float field_36; - float field_40; - wchar m_awText[500]; + float m_fAtX; + float m_fAtY; + wchar m_Text[SCRIPT_TEXT_MAX_LENGTH]; }; -struct CRunningScript +static_assert(sizeof(CTextLine) == 0x414, "Script.h: error"); + +struct CScriptSphere +{ + bool m_bInUse; + uint16 m_Index; + uint32 m_Id; + CVector m_vecCenter; + float m_fRadius; +}; + +enum { + MAX_STACK_DEPTH = 6, + NUM_LOCAL_VARS = 16, + NUM_TIMERS = 2 +}; + +class CRunningScript { CRunningScript *next; CRunningScript *prev; - uint8 m_abScriptName[8]; + char m_abScriptName[8]; uint32 m_nIp; - uint32 m_anStack[6]; + uint32 m_anStack[MAX_STACK_DEPTH]; uint16 m_nStackPointer; - void* m_anLocalVariables[18]; + int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS]; bool m_bCondResult; bool m_bIsMissionThread; bool m_bSkipWakeTime; uint32 m_nWakeTime; - uint16 m_wIfOp; + uint16 m_nAndOrState; bool m_bNotFlag; - bool m_bWBCheck; - bool m_bWastedOrBusted; + bool m_bWBCheckEnabled; + bool m_bWBChecked; bool m_bMissionFlag; + +public: + void CollectParameters(uint32*, int16); + int32 CollectNextParameterWithoutIncreasingPC(uint32); + int32* GetPointerToScriptVariable(uint32*, int16); + void StoreParameters(uint32*, int16); + void Init(); + void RemoveScriptFromList(CRunningScript**); + void AddScriptToList(CRunningScript**); }; enum { @@ -133,13 +166,80 @@ public: bool HasCarBeenStuckForAWhile(int32); }; +enum { + ARGUMENT_INT32 = 1, + ARGUMENT_GLOBALVAR, + ARGUMENT_LOCALVAR, + ARGUMENT_INT8, + ARGUMENT_INT16, + ARGUMENT_FLOAT +}; + +struct tCollectiveData +{ + int32 index; + uint32 unk_data; +}; + +enum { + USED_OBJECT_NAME_LENGTH = 24 +}; + +struct tUsedObject +{ + char name[USED_OBJECT_NAME_LENGTH]; + int32 index; +}; + +struct tBuildingSwap +{ + CBuilding* m_pBuilding; + int32 m_nNewModel; + int32 m_nOldModel; +}; + + +enum { + VAR_LOCAL = 1, + VAR_GLOBAL = 2, +}; + +enum { + SIZE_MAIN_SCRIPT = 128 * 1024, + SIZE_MISSION_SCRIPT = 32 * 1024, + SIZE_SCRIPT_SPACE = SIZE_MAIN_SCRIPT + SIZE_MISSION_SCRIPT +}; + +enum { + MAX_NUM_SCRIPTS = 128, + MAX_NUM_CONTACTS = 16, + MAX_NUM_INTRO_TEXT_LINES = 2, + MAX_NUM_INTRO_RECTANGLES = 16, + MAX_NUM_SCRIPT_SRPITES = 16, + MAX_NUM_SCRIPT_SPHERES = 16, + MAX_NUM_COLLECTIVES = 32, + MAX_NUM_USED_OBJECTS = 200, + MAX_NUM_MISSION_SCRIPTS = 120, + MAX_NUM_BUILDING_SWAPS = 25, + MAX_NUM_INVISIBILITY_SETTINGS = 20 +}; + class CTheScripts { public: - static uint8(&ScriptSpace)[160 * 1024]; - static CTextLine(&IntroTextLines)[2]; - static CScriptRectangle(&IntroRectangles)[16]; - static CSprite2d(&ScriptSprites)[16]; + static uint8(&ScriptSpace)[SIZE_SCRIPT_SPACE]; + static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS]; + static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS]; + static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS]; + static CTextLine(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES]; + static CScriptRectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES]; + static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES]; + static CScriptSphere(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES]; + static tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES]; + static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS]; + static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS]; + static tBuildingSwap(&BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS]; + static CEntity*(&InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS]; static bool &DbgFlag; static uint32 &OnAMissionFlag; static CMissionCleanup &MissionCleanup; @@ -147,11 +247,57 @@ public: static CUpsideDownCarCheck &UpsideDownCars; static int32 &StoreVehicleIndex; static bool &StoreVehicleWasRandom; - + static CRunningScript *&pIdleScripts; + static CRunningScript *&pActiveScripts; + static uint32 &NextFreeCollectiveIndex; + static int32 &LastRandomPedId; + static uint16 &NumberOfUsedObjects; + static bool &bAlreadyRunningAMissionScript; + static bool &bUsingAMultiScriptFile; + static uint16 &NumberOfMissionScripts; + static uint32 &LargestMissionScriptSize; + static uint32 &MainScriptSize; + static uint8 &FailCurrentMission; + static uint8 &CountdownToMakePlayerUnsafe; + static uint8 &DelayMakingPlayerUnsafeThisTime; + static uint16 &NumScriptDebugLines; + static uint16 &NumberOfIntroRectanglesThisFrame; + static uint16 &NumberOfIntroTextLinesThisFrame; + static bool &UseTextCommands; public: static bool IsPlayerOnAMission(); static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2); static void CleanUpThisVehicle(CVehicle*); static void CleanUpThisPed(CPed*); static void CleanUpThisObject(CObject*); + static void Init(); + + static void ReadObjectNamesFromScript(); + static void UpdateObjectIndices(); + static void ReadMultiScriptFileOffsetsFromScript(); + + static int32 Read4BytesFromScript(uint32* pIp){ + int32 retval = 0; + for (int i = 0; i < 4; i++){ + retval |= ScriptSpace[(*pIp)++] << (8 * i); + } + return retval; + } + static int16 Read2BytesFromScript(uint32* pIp){ + int16 retval = 0; + for (int i = 0; i < 2; i++){ + retval |= ScriptSpace[(*pIp)++] << (8 * i); + } + return retval; + } + static int8 Read1ByteFromScript(uint32* pIp){ + int8 retval = 0; + for (int i = 0; i < 1; i++){ + retval |= ScriptSpace[(*pIp)++] << (8 * i); + } + return retval; + } + static float ReadFloatFromScript(uint32* pIp){ + return Read2BytesFromScript(pIp) / 16.0f; + } }; diff --git a/src/core/config.h b/src/core/config.h index 8cb02190..c3b66ff7 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -114,3 +114,4 @@ enum Config { #define FIX_BUGS // fix bugs in the game, TODO: use this more #define KANGAROO_CHEAT #define ASPECT_RATIO_SCALE +#define USE_DEBUG_SCRIPT_LOADER \ No newline at end of file diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 9dc39d46..d6e81214 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -57,27 +57,6 @@ mysrand(unsigned int seed) myrand_seed = seed; } -int (*open_script_orig)(const char *path, const char *mode); -int -open_script(const char *path, const char *mode) -{ - static int scriptToLoad = 1; - - if(GetAsyncKeyState('G') & 0x8000) - scriptToLoad = 0; - if(GetAsyncKeyState('R') & 0x8000) - scriptToLoad = 1; - if(GetAsyncKeyState('D') & 0x8000) - scriptToLoad = 2; - - switch(scriptToLoad){ - case 0: return open_script_orig(path, mode); - case 1: return open_script_orig("main_freeroam.scm", mode); - case 2: return open_script_orig("main_d.scm", mode); - } - return open_script_orig(path, mode); -} - int gDbgSurf; void (*DebugMenuProcess)(void); @@ -356,7 +335,7 @@ patch() Patch(0x5382BF, 0x0EEB); InjectHook(0x5382EC, HeadlightsFix, PATCH_JUMP); - InterceptCall(&open_script_orig, open_script, 0x438869); +// InterceptCall(&open_script_orig, open_script, 0x438869); // InterceptCall(&RsEventHandler_orig, delayedPatches10, 0x58275E); } diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index 680720e0..754f4b85 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -814,8 +814,8 @@ void CHud::Draw() if (!CTimer::GetIsUserPaused()) { CTextLine* IntroText = CTheScripts::IntroTextLines; - for (int i = 0; i < 2; i++) { - if (CTheScripts::IntroTextLines[i].m_awText[0] && CTheScripts::IntroTextLines[i].field_29) { + for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) { + if (CTheScripts::IntroTextLines[i].m_Text[0] && CTheScripts::IntroTextLines[i].m_bTextBeforeFade) { CFont::SetScale(SCREEN_SCALE_X(CTheScripts::IntroTextLines[i].m_fScaleX), SCREEN_SCALE_Y(CTheScripts::IntroTextLines[i].m_fScaleY * 0.5f)); CFont::SetColor(CTheScripts::IntroTextLines[i].m_sColor); @@ -855,7 +855,7 @@ void CHud::Draw() CFont::SetPropOff(); CFont::SetFontStyle(CTheScripts::IntroTextLines[i].m_nFont); - CFont::PrintString(SCREEN_SCALE_X(640.0f - CTheScripts::IntroTextLines[i].field_36), SCREEN_SCALE_Y(448.0f - CTheScripts::IntroTextLines[i].field_40), IntroText->m_awText); + CFont::PrintString(SCREEN_SCALE_X(640.0f - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_SCALE_Y(448.0f - CTheScripts::IntroTextLines[i].m_fAtY), IntroText->m_Text); } } @@ -863,14 +863,14 @@ void CHud::Draw() for (int i = 0; i < 16; i++) { if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bIsAntialiased) { - if (CTheScripts::IntroRectangles[i].m_wTextureId >= 0) { + if (CTheScripts::IntroRectangles[i].m_nTextureId >= 0) { CRect rect = { CTheScripts::IntroRectangles[i].m_sRect.left, CTheScripts::IntroRectangles[i].m_sRect.bottom, CTheScripts::IntroRectangles[i].m_sRect.right, CTheScripts::IntroRectangles[i].m_sRect.bottom }; - CTheScripts::ScriptSprites[CTheScripts::IntroRectangles[i].m_wTextureId].Draw(rect, IntroRect->m_sColor); + CTheScripts::ScriptSprites[CTheScripts::IntroRectangles[i].m_nTextureId].Draw(rect, IntroRect->m_sColor); } else { CRect rect = { From c1f3ce8cceb675a9c76b4dc4e7cdfb18b17c4f2f Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 7 Jul 2019 18:36:55 +0200 Subject: [PATCH 08/30] implemented CDoor --- src/control/Replay.cpp | 4 +- src/math/Matrix.h | 9 +++ src/vehicles/Automobile.cpp | 4 +- src/vehicles/Automobile.h | 17 +---- src/vehicles/Door.cpp | 126 ++++++++++++++++++++++++++++++++++++ src/vehicles/Door.h | 36 +++++++++++ 6 files changed, 177 insertions(+), 19 deletions(-) create mode 100644 src/vehicles/Door.cpp create mode 100644 src/vehicles/Door.h diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 06995663..d0264415 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -686,8 +686,8 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI car->m_aSuspensionSpringRatio[i] = vp->wheel_susp_dist[i] / 50.0f; car->m_aWheelRotation[i] = vp->wheel_rotation[i] * M_PI / 128.0f; } - car->Doors[2].m_fAngle = car->Doors[2].m_fPreviousAngle = vp->door_angles[0] * M_PI / 127.0f; - car->Doors[3].m_fAngle = car->Doors[3].m_fPreviousAngle = vp->door_angles[1] * M_PI / 127.0f; + car->Doors[2].m_fAngle = car->Doors[2].m_fPrevAngle = vp->door_angles[0] * M_PI / 127.0f; + car->Doors[3].m_fAngle = car->Doors[3].m_fPrevAngle = vp->door_angles[1] * M_PI / 127.0f; if (vp->door_angles[0]) car->Damage.SetDoorStatus(2, 2); if (vp->door_angles[1]) diff --git a/src/math/Matrix.h b/src/math/Matrix.h index 6e1001cb..5cc7d12f 100644 --- a/src/math/Matrix.h +++ b/src/math/Matrix.h @@ -306,6 +306,15 @@ Multiply3x3(const CMatrix &mat, const CVector &vec) mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z); } +inline CVector +Multiply3x3(const CVector &vec, const CMatrix &mat) +{ + return CVector( + mat.m_matrix.right.x * vec.x + mat.m_matrix.right.y * vec.y + mat.m_matrix.right.z * vec.z, + mat.m_matrix.up.x * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.up.z * vec.z, + mat.m_matrix.at.x * vec.x + mat.m_matrix.at.y * vec.y + mat.m_matrix.at.z * vec.z); +} + class CCompressedMatrixNotAligned { CVector m_vecPos; diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 54eed17a..80131179 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -14,5 +14,5 @@ WRAPPER void CAutomobile::SetPanelDamage(int32, uint32, bool) { EAXJMP(0x5301A0) WRAPPER void CAutomobile::SetBumperDamage(int32, uint32, bool) { EAXJMP(0x530120); } STARTPATCHES -InjectHook(0x52D170, &CAutomobile::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x52D170, &CAutomobile::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 630635c7..c20d078b 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -1,21 +1,8 @@ #pragma once -#include "DamageManager.h" #include "Vehicle.h" - -struct CDoor -{ - float m_fAngleWhenOpened; - float m_fAngleWhenClosed; - char field_8; - char field_9; - char field_10; - char field_11; - float m_fAngle; - float m_fPreviousAngle; - float m_fAngularVelocity; - CVector m_vecVelocity; -}; +#include "DamageManager.h" +#include "Door.h" class CAutomobile : public CVehicle { diff --git a/src/vehicles/Door.cpp b/src/vehicles/Door.cpp new file mode 100644 index 00000000..ec5eb223 --- /dev/null +++ b/src/vehicles/Door.cpp @@ -0,0 +1,126 @@ +#include "common.h" +#include "patcher.h" +#include "Vehicle.h" +#include "Door.h" + +CDoor::CDoor(void) +{ + memset(this, 0, sizeof(*this)); +} + +void +CDoor::Open(float ratio) +{ + float open; + + m_fPrevAngle = m_fAngle; + open = RetAngleWhenOpen(); + if(ratio < 1.0f){ + m_fAngle = open*ratio; + if(m_fAngle == 0.0f) + m_fAngVel = 0.0f; + }else{ + m_nDoorState = DOORST_OPEN; + m_fAngle = open; + } +} + +void +CDoor::Process(CVehicle *vehicle) +{ + static CVector vecOffset(1.0f, 0.0f, 0.0f); + CVector speed = vehicle->GetSpeed(vecOffset); + CVector vecSpeedDiff = speed - m_vecSpeed; + vecSpeedDiff = Multiply3x3(vecSpeedDiff, vehicle->GetMatrix()); + + // air resistance + float fSpeedDiff = 0.0f; // uninitialized in game + switch(m_nAxis){ + case 0: // x-axis + if(m_nDirn) + fSpeedDiff = vecSpeedDiff.y + vecSpeedDiff.z; + else + fSpeedDiff = -(vecSpeedDiff.y + vecSpeedDiff.z); + break; + + // we don't support y axis apparently? + + case 2: // z-axis + if(m_nDirn) + fSpeedDiff = -(vecSpeedDiff.x + vecSpeedDiff.y); + else + fSpeedDiff = vecSpeedDiff.x + vecSpeedDiff.y; + break; + } + fSpeedDiff = clamp(fSpeedDiff, -0.2f, 0.2f); + if(fabs(fSpeedDiff) > 0.002f) + m_fAngVel += fSpeedDiff; + m_fAngVel *= 0.945f; + m_fAngVel = clamp(m_fAngVel, -0.3f, 0.3f); + + m_fAngle += m_fAngVel; + m_nDoorState = DOORST_SWINGING; + if(m_fAngle > m_fMaxAngle){ + m_fAngle = m_fMaxAngle; + m_fAngVel *= -0.8f; + m_nDoorState = DOORST_OPEN; + } + if(m_fAngle < m_fMinAngle){ + m_fAngle = m_fMinAngle; + m_fAngVel *= -0.8f; + m_nDoorState = DOORST_CLOSED; + } + m_vecSpeed = speed; +} + +float +CDoor::RetAngleWhenClosed(void) +{ + if(fabs(m_fMaxAngle) < fabs(m_fMinAngle)) + return m_fMaxAngle; + else + return m_fMinAngle; +} + +float +CDoor::RetAngleWhenOpen(void) +{ + if(fabs(m_fMaxAngle) < fabs(m_fMinAngle)) + return m_fMinAngle; + else + return m_fMaxAngle; +} + +float +CDoor::GetAngleOpenRatio(void) +{ + float open = RetAngleWhenOpen(); + if(open == 0.0f) + return 0.0f; + return m_fAngle/open; +} + +bool +CDoor::IsFullyOpen(void) +{ + // why -0.5? that's around 28 deg less than fully open + if(fabs(m_fAngle) < fabs(RetAngleWhenOpen()) - 0.5f) + return false; + return true; +} + +bool +CDoor::IsClosed(void) +{ + return m_fAngle == RetAngleWhenClosed(); +} + +STARTPATCHES + InjectHook(0x545EF0, &CDoor::Open, PATCH_JUMP); + InjectHook(0x545BD0, &CDoor::Process, PATCH_JUMP); + InjectHook(0x545FE0, &CDoor::RetAngleWhenClosed, PATCH_JUMP); + InjectHook(0x546020, &CDoor::RetAngleWhenOpen, PATCH_JUMP); + InjectHook(0x545F80, &CDoor::GetAngleOpenRatio, PATCH_JUMP); + InjectHook(0x546090, &CDoor::IsFullyOpen, PATCH_JUMP); + InjectHook(0x546060, &CDoor::IsClosed, PATCH_JUMP); +ENDPATCHES diff --git a/src/vehicles/Door.h b/src/vehicles/Door.h new file mode 100644 index 00000000..fc771a40 --- /dev/null +++ b/src/vehicles/Door.h @@ -0,0 +1,36 @@ +#pragma once + +class CVehicle; + +enum eDoorState +{ + DOORST_SWINGING, + // actually wrong though, + // OPEN is really MAX_ANGLE and CLOSED is MIN_ANGLE + DOORST_OPEN, + DOORST_CLOSED +}; + +struct CDoor +{ + float m_fMaxAngle; + float m_fMinAngle; + // direction of rotation for air resistance + int8 m_nDirn; + // axis in which this door rotates + int8 m_nAxis; + int8 m_nDoorState; + float m_fAngle; + float m_fPrevAngle; + float m_fAngVel; + CVector m_vecSpeed; + + CDoor(void); + void Open(float ratio); + void Process(CVehicle *veh); + float RetAngleWhenClosed(void); + float RetAngleWhenOpen(void); + float GetAngleOpenRatio(void); + bool IsFullyOpen(void); + bool IsClosed(void); +}; From a4e6930bb629dadfcfddd7b730b1542827574c1e Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sun, 7 Jul 2019 20:57:00 +0300 Subject: [PATCH 09/30] More scripts --- src/control/Script.cpp | 116 +++++++++++++++++++++++++++++++++-------- src/control/Script.h | 22 ++++++-- src/render/Hud.cpp | 2 +- 3 files changed, 114 insertions(+), 26 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index d2e27487..ca04af5e 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -13,6 +13,7 @@ #include "PlayerPed.h" #include "Pools.h" #include "Population.h" +#include "Replay.h" #include "Streaming.h" #include "User.h" #include "Weather.h" @@ -32,7 +33,7 @@ int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_ tBuildingSwap(&CTheScripts::BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS] = *(tBuildingSwap(*)[MAX_NUM_BUILDING_SWAPS])*(uintptr*)0x880E30; CEntity*(&CTheScripts::InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS] = *(CEntity*(*)[MAX_NUM_INVISIBILITY_SETTINGS])*(uintptr*)0x8620F0; bool &CTheScripts::DbgFlag = *(bool*)0x95CD87; -uint32 &CTheScripts::OnAMissionFlag = *(uint32*)0x8F2A24; +uint32 &CTheScripts::OnAMissionFlag = *(uint32*)0x8F1B64; int32 &CTheScripts::StoreVehicleIndex = *(int32*)0x8F5F3C; bool &CTheScripts::StoreVehicleWasRandom = *(bool*)0x95CDBC; CRunningScript *&CTheScripts::pIdleScripts = *(CRunningScript**)0x9430D4; @@ -55,6 +56,8 @@ bool &CTheScripts::UseTextCommands = *(bool*)0x95CD57; CMissionCleanup (&CTheScripts::MissionCleanup) = *(CMissionCleanup*)0x8F2A24; CUpsideDownCarCheck (&CTheScripts::UpsideDownCars) = *(CUpsideDownCarCheck*)0x6EE450; CStuckCarCheck (&CTheScripts::StuckCars) = *(CStuckCarCheck*)0x87C588; +uint16 &CTheScripts::CommandsExecuted = *(uint16*)0x95CCA6; +uint16 &CTheScripts::ScriptsUpdated = *(uint16*)0x95CC5E; int32(&ScriptParams)[32] = *(int32(*)[32])*(uintptr*)0x6ED460; CMissionCleanup::CMissionCleanup() @@ -435,6 +438,27 @@ int open_script() } #endif +void CTextLine::Reset() +{ + m_fScaleX = 0.48f; + m_fScaleY = 1.12f; + m_sColor = CRGBA(225, 225, 225, 255); + m_bJustify = false; + m_bRightJustify = false; + m_bCentered = false; + m_bBackground = false; + m_bBackgroundOnly = false; + m_fWrapX = 182.0f; /* TODO: scaling as bugfix */ + m_fCenterSize = 640.0f; /* --||-- */ + m_sBackgroundColor = CRGBA(128, 128, 128, 128); + m_bTextProportional = true; + m_bTextBeforeFade = false; + m_nFont = 2; /* enum? */ + m_fAtX = 0.0f; + m_fAtY = 0.0f; + memset(&m_Text, 0, sizeof(m_Text)); +} + void CTheScripts::Init() { for (int i = 0; i < SIZE_SCRIPT_SPACE; i++) @@ -497,29 +521,13 @@ void CTheScripts::Init() ScriptSphereArray[i].m_fRadius = 0.0f; } for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++){ - IntroTextLines[i].m_fScaleX = 0.48f; - IntroTextLines[i].m_fScaleY = 1.12f; - IntroTextLines[i].m_sColor = CRGBA(225, 225, 225, 255); - IntroTextLines[i].m_bJustify = false; - IntroTextLines[i].m_bRightJustify = false; - IntroTextLines[i].m_bCentered = false; - IntroTextLines[i].m_bBackground = false; - IntroTextLines[i].m_bBackgroundOnly = false; - IntroTextLines[i].m_fWrapX = 182.0f; /* TODO: scaling as bugfix */ - IntroTextLines[i].m_fCenterSize = 640.0f; /* --||-- */ - IntroTextLines[i].m_sBackgroundColor = CRGBA(128, 128, 128, 128); - IntroTextLines[i].m_bTextProportional = true; - IntroTextLines[i].m_bTextBeforeFade = false; - IntroTextLines[i].m_nFont = 2; /* enum? */ - IntroTextLines[i].m_fAtX = 0.0f; - IntroTextLines[i].m_fAtY = 0.0f; - memset(&IntroTextLines[i].m_Text, 0, sizeof(IntroTextLines[i].m_Text)); + IntroTextLines[i].Reset(); } NumberOfIntroTextLinesThisFrame = 0; UseTextCommands = false; for (int i = 0; i < MAX_NUM_INTRO_RECTANGLES; i++){ - IntroRectangles[i].m_bIsUsed = false; - IntroRectangles[i].m_bIsAntialiased = false; + IntroRectangles[i].m_Type = 0; + IntroRectangles[i].m_bBeforeFade = false; IntroRectangles[i].m_nTextureId = -1; IntroRectangles[i].m_sRect = CRect(0.0f, 0.0f, 0.0f, 0.0f); IntroRectangles[i].m_sColor = CRGBA(255, 255, 255, 255); @@ -553,7 +561,68 @@ void CRunningScript::AddScriptToList(CRunningScript** ppScript) *ppScript = this; } -WRAPPER bool CTheScripts::IsPlayerOnAMission() { EAXJMP(0x439410); } +CRunningScript* CTheScripts::StartNewScript(uint32 ip) +{ + CRunningScript* pNew = pIdleScripts; + assert(pNew); + pNew->RemoveScriptFromList(&pIdleScripts); + pNew->Init(); + pNew->SetIP(ip); + pNew->AddScriptToList(&pActiveScripts); + return pNew; +} + +void CTheScripts::Process() +{ + if (CReplay::IsPlayingBack()) + return; + CommandsExecuted = 0; + ScriptsUpdated = 0; + float timeStep = CTimer::GetTimeStepInMilliseconds(); + UpsideDownCars.UpdateTimers(); + StuckCars.Process(); + DrawScriptSpheres(); + if (FailCurrentMission) + --FailCurrentMission; + if (CountdownToMakePlayerUnsafe){ + if (--CountdownToMakePlayerUnsafe == 0) + CWorld::Players[0].MakePlayerSafe(false); + } + if (UseTextCommands){ + for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) + IntroTextLines[i].Reset(); + NumberOfIntroRectanglesThisFrame = 0; + for (int i = 0; i < MAX_NUM_INTRO_RECTANGLES; i++){ + IntroRectangles[i].m_Type = 0; + IntroRectangles[i].m_bBeforeFade = false; + } + NumberOfIntroRectanglesThisFrame = 0; + if (UseTextCommands == 1) + UseTextCommands = 0; + } + CRunningScript* script = pActiveScripts; + while (script != nil){ + CRunningScript* next = script->GetNext(); + ++ScriptsUpdated; + script->UpdateTimers(timeStep); + script->Process(); + script = next; + } + DbgFlag = false; +} + +CRunningScript* CTheScripts::StartTestScript() +{ + return StartNewScript(0); +} + +bool CTheScripts::IsPlayerOnAMission() +{ + return OnAMissionFlag && *(int32*)&ScriptSpace[OnAMissionFlag] == 1; +} + +WRAPPER void CRunningScript::Process() { EAXJMP(0x439440); } +WRAPPER void CTheScripts::DrawScriptSpheres() { EAXJMP(0x44FAC0); } WRAPPER void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2) { EAXJMP(0x4534E0); } WRAPPER void CTheScripts::CleanUpThisVehicle(CVehicle*) { EAXJMP(0x4548D0); } WRAPPER void CTheScripts::CleanUpThisPed(CPed*) { EAXJMP(0x4547A0); } @@ -582,6 +651,9 @@ InjectHook(0x4382E0, &CRunningScript::CollectParameters, PATCH_JUMP); InjectHook(0x438460, &CRunningScript::CollectNextParameterWithoutIncreasingPC, PATCH_JUMP); InjectHook(0x4385A0, &CRunningScript::StoreParameters, PATCH_JUMP); InjectHook(0x438640, &CRunningScript::GetPointerToScriptVariable, PATCH_JUMP); -InjectHook(0x4386C0, &CRunningScript::Init, PATCH_JUMP); InjectHook(0x438790, &CTheScripts::Init, PATCH_JUMP); +InjectHook(0x439000, &CTheScripts::StartNewScript, PATCH_JUMP); +InjectHook(0x439040, &CTheScripts::Process, PATCH_JUMP); +InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP); +InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP); ENDPATCHES \ No newline at end of file diff --git a/src/control/Script.h b/src/control/Script.h index 5759cf82..392f4b40 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -8,8 +8,8 @@ struct CScriptRectangle { - bool m_bIsUsed; - bool m_bIsAntialiased; + int8 m_Type; + bool m_bBeforeFade; int16 m_nTextureId; CRect m_sRect; CRGBA m_sColor; @@ -40,6 +40,8 @@ struct CTextLine float m_fAtX; float m_fAtY; wchar m_Text[SCRIPT_TEXT_MAX_LENGTH]; + + void Reset(); }; static_assert(sizeof(CTextLine) == 0x414, "Script.h: error"); @@ -79,6 +81,13 @@ class CRunningScript bool m_bMissionFlag; public: + void SetIP(uint32 ip) { m_nIp = ip; } + CRunningScript* GetNext() { return next; } + void UpdateTimers(float timeStep){ + m_anLocalVariables[NUM_LOCAL_VARS] += timeStep; + m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep; + } + void CollectParameters(uint32*, int16); int32 CollectNextParameterWithoutIncreasingPC(uint32); int32* GetPointerToScriptVariable(uint32*, int16); @@ -86,6 +95,7 @@ public: void Init(); void RemoveScriptFromList(CRunningScript**); void AddScriptToList(CRunningScript**); + void Process(); }; enum { @@ -264,17 +274,23 @@ public: static uint16 &NumberOfIntroRectanglesThisFrame; static uint16 &NumberOfIntroTextLinesThisFrame; static bool &UseTextCommands; + static uint16 &CommandsExecuted; + static uint16 &ScriptsUpdated; public: - static bool IsPlayerOnAMission(); static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2); static void CleanUpThisVehicle(CVehicle*); static void CleanUpThisPed(CPed*); static void CleanUpThisObject(CObject*); static void Init(); + static CRunningScript* StartNewScript(uint32); + static void Process(); + static CRunningScript* StartTestScript(); + static bool IsPlayerOnAMission(); static void ReadObjectNamesFromScript(); static void UpdateObjectIndices(); static void ReadMultiScriptFileOffsetsFromScript(); + static void DrawScriptSpheres(); static int32 Read4BytesFromScript(uint32* pIp){ int32 retval = 0; diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index 754f4b85..b9ae3e8d 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -862,7 +862,7 @@ void CHud::Draw() CScriptRectangle* IntroRect = CTheScripts::IntroRectangles; for (int i = 0; i < 16; i++) { - if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bIsAntialiased) { + if (CTheScripts::IntroRectangles[i].m_Type && CTheScripts::IntroRectangles[i].m_bBeforeFade) { if (CTheScripts::IntroRectangles[i].m_nTextureId >= 0) { CRect rect = { CTheScripts::IntroRectangles[i].m_sRect.left, From 439f371fc346ca797faf013b4098b52c92a1481e Mon Sep 17 00:00:00 2001 From: _AG Date: Sun, 7 Jul 2019 20:59:49 +0200 Subject: [PATCH 10/30] Darkel is bored. --- src/control/Darkel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index ab55c4d4..f050a540 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -34,7 +34,7 @@ int32 CDarkel::CalcFade(uint32 time, int32 start, uint32 end) { if (time >= start && time <= end) { if (time >= start + 500) { if (time <= end - 500) - return 0; + return 255; else return 255 * (end - time) / 500; } @@ -55,6 +55,7 @@ void CDarkel::DrawMessages() switch (Status) { case KILLFRENZY_ONGOING: + assert(pStartMessage != nil); DisplayTimers = true; break; case KILLFRENZY_PASSED: From 4f3d17a81c5be7112b9adff89bc621a770bf1ffa Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Mon, 8 Jul 2019 00:05:24 +0300 Subject: [PATCH 11/30] More script --- src/control/Script.cpp | 80 +++++++++++++++++++++++++++++++++++++++--- src/control/Script.h | 18 ++++++++-- src/render/Hud.cpp | 2 +- 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index ca04af5e..2846d33d 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -8,7 +8,9 @@ #include "DMAudio.h" #include "FileMgr.h" #include "Hud.h" +#include "Messages.h" #include "ModelIndices.h" +#include "Pad.h" #include "PlayerInfo.h" #include "PlayerPed.h" #include "Pools.h" @@ -406,7 +408,7 @@ void CRunningScript::Init() m_nStackPointer = 0; m_nWakeTime = 0; m_bCondResult = false; - m_bIsMissionThread = false; + m_bIsMissionScript = false; m_bSkipWakeTime = false; for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) m_anLocalVariables[i] = 0; @@ -526,7 +528,7 @@ void CTheScripts::Init() NumberOfIntroTextLinesThisFrame = 0; UseTextCommands = false; for (int i = 0; i < MAX_NUM_INTRO_RECTANGLES; i++){ - IntroRectangles[i].m_Type = 0; + IntroRectangles[i].m_bIsUsed = false; IntroRectangles[i].m_bBeforeFade = false; IntroRectangles[i].m_nTextureId = -1; IntroRectangles[i].m_sRect = CRect(0.0f, 0.0f, 0.0f, 0.0f); @@ -593,7 +595,7 @@ void CTheScripts::Process() IntroTextLines[i].Reset(); NumberOfIntroRectanglesThisFrame = 0; for (int i = 0; i < MAX_NUM_INTRO_RECTANGLES; i++){ - IntroRectangles[i].m_Type = 0; + IntroRectangles[i].m_bIsUsed = false; IntroRectangles[i].m_bBeforeFade = false; } NumberOfIntroRectanglesThisFrame = 0; @@ -621,8 +623,78 @@ bool CTheScripts::IsPlayerOnAMission() return OnAMissionFlag && *(int32*)&ScriptSpace[OnAMissionFlag] == 1; } -WRAPPER void CRunningScript::Process() { EAXJMP(0x439440); } +void CRunningScript::Process() +{ + if (m_bIsMissionScript) + DoDeatharrestCheck(); + if (m_bMissionFlag && CTheScripts::FailCurrentMission == 1 && m_nStackPointer == 1) + m_nIp = m_anStack[--m_nStackPointer]; + if (CTimer::GetTimeInMilliseconds() >= m_nWakeTime){ + while (!ProcessOneCommand()) + ; + return; + } + if (!m_bSkipWakeTime) + return; + if (!CPad::GetPad(0)->GetCrossJustDown()) + return; + m_nWakeTime = 0; + for (int i = 0; i < 6; i++){ /* TODO: add constant for number of messages */ + if (CMessages::BIGMessages[i].m_Current.m_pText) + CMessages::BIGMessages[i].m_Current.m_nStartTime = 0; + if (CMessages::BriefMessages[0].m_pText) + CMessages::BriefMessages[0].m_nStartTime = 0; + } +} + +int8 CRunningScript::ProcessOneCommand() +{ + ++CTheScripts::CommandsExecuted; + int32 command = CTheScripts::Read2BytesFromScript(&m_nIp); + m_bNotFlag = (command & 0x8000); + command &= 0x7FFF; + if (command < 100) + return ProcessCommandsFrom0To99(command); + if (command < 200) + return ProcessCommandsFrom100To199(command); + if (command < 300) + return ProcessCommandsFrom200To299(command); + if (command < 400) + return ProcessCommandsFrom300To399(command); + if (command < 500) + return ProcessCommandsFrom400To499(command); + if (command < 600) + return ProcessCommandsFrom500To599(command); + if (command < 700) + return ProcessCommandsFrom600To699(command); + if (command < 800) + return ProcessCommandsFrom700To799(command); + if (command < 900) + return ProcessCommandsFrom800To899(command); + if (command < 1000) + return ProcessCommandsFrom900To999(command); + if (command < 1100) + return ProcessCommandsFrom1000To1099(command); + if (command < 1200) + return ProcessCommandsFrom1100To1199(command); + return -1; +} + +WRAPPER int8 CRunningScript::ProcessCommandsFrom0To99(int32 command) { EAXJMP(0x439650); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) { EAXJMP(0x43AEA0); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom200To299(int32 command) { EAXJMP(0x43D530); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom300To399(int32 command) { EAXJMP(0x43ED30); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom400To499(int32 command) { EAXJMP(0x440CB0); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom500To599(int32 command) { EAXJMP(0x4429C0); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom600To699(int32 command) { EAXJMP(0x444B20); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom700To799(int32 command) { EAXJMP(0x4458A0); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom800To899(int32 command) { EAXJMP(0x448240); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom900To999(int32 command) { EAXJMP(0x44CB80); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom1000To1099(int32 command) { EAXJMP(0x588490); } +WRAPPER int8 CRunningScript::ProcessCommandsFrom1100To1199(int32 command) { EAXJMP(0x589D00); } + WRAPPER void CTheScripts::DrawScriptSpheres() { EAXJMP(0x44FAC0); } +WRAPPER void CRunningScript::DoDeatharrestCheck() { EAXJMP(0x452A30); } WRAPPER void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2) { EAXJMP(0x4534E0); } WRAPPER void CTheScripts::CleanUpThisVehicle(CVehicle*) { EAXJMP(0x4548D0); } WRAPPER void CTheScripts::CleanUpThisPed(CPed*) { EAXJMP(0x4547A0); } diff --git a/src/control/Script.h b/src/control/Script.h index 392f4b40..d4624ad4 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -8,7 +8,7 @@ struct CScriptRectangle { - int8 m_Type; + int8 m_bIsUsed; bool m_bBeforeFade; int16 m_nTextureId; CRect m_sRect; @@ -71,7 +71,7 @@ class CRunningScript uint16 m_nStackPointer; int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS]; bool m_bCondResult; - bool m_bIsMissionThread; + bool m_bIsMissionScript; bool m_bSkipWakeTime; uint32 m_nWakeTime; uint16 m_nAndOrState; @@ -96,6 +96,20 @@ public: void RemoveScriptFromList(CRunningScript**); void AddScriptToList(CRunningScript**); void Process(); + int8 ProcessOneCommand(); + void DoDeatharrestCheck(); + int8 ProcessCommandsFrom0To99(int32); + int8 ProcessCommandsFrom100To199(int32); + int8 ProcessCommandsFrom200To299(int32); + int8 ProcessCommandsFrom300To399(int32); + int8 ProcessCommandsFrom400To499(int32); + int8 ProcessCommandsFrom500To599(int32); + int8 ProcessCommandsFrom600To699(int32); + int8 ProcessCommandsFrom700To799(int32); + int8 ProcessCommandsFrom800To899(int32); + int8 ProcessCommandsFrom900To999(int32); + int8 ProcessCommandsFrom1000To1099(int32); + int8 ProcessCommandsFrom1100To1199(int32); }; enum { diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index b9ae3e8d..b3264dc7 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -862,7 +862,7 @@ void CHud::Draw() CScriptRectangle* IntroRect = CTheScripts::IntroRectangles; for (int i = 0; i < 16; i++) { - if (CTheScripts::IntroRectangles[i].m_Type && CTheScripts::IntroRectangles[i].m_bBeforeFade) { + if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bBeforeFade) { if (CTheScripts::IntroRectangles[i].m_nTextureId >= 0) { CRect rect = { CTheScripts::IntroRectangles[i].m_sRect.left, From b1d1d6f7016e803d956310c92be376ad55000172 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Mon, 8 Jul 2019 00:32:54 +0300 Subject: [PATCH 12/30] Added script commands --- src/control/Script.cpp | 1 + src/control/ScriptCommands.h | 1158 ++++++++++++++++++++++++++++++++++ 2 files changed, 1159 insertions(+) create mode 100644 src/control/ScriptCommands.h diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 2846d33d..ae2a45aa 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -2,6 +2,7 @@ #include "patcher.h" #include "Script.h" +#include "ScriptCommands.h" #include "Camera.h" #include "CarCtrl.h" diff --git a/src/control/ScriptCommands.h b/src/control/ScriptCommands.h new file mode 100644 index 00000000..55ac4439 --- /dev/null +++ b/src/control/ScriptCommands.h @@ -0,0 +1,1158 @@ +#pragma once + +enum { + COMMAND_NOP = 0, + COMMAND_WAIT, + COMMAND_GOTO, + COMMAND_SHAKE_CAM, + COMMAND_SET_VAR_INT, + COMMAND_SET_VAR_FLOAT, + COMMAND_SET_LVAR_INT, + COMMAND_SET_LVAR_FLOAT, + COMMAND_ADD_VAL_TO_INT_VAR, + COMMAND_ADD_VAL_TO_FLOAT_VAR, + COMMAND_ADD_VAL_TO_INT_LVAR, + COMMAND_ADD_VAL_TO_FLOAT_LVAR, + COMMAND_SUB_VAL_FROM_INT_VAR, + COMMAND_SUB_VAL_FROM_FLOAT_VAR, + COMMAND_SUB_VAL_FROM_INT_LVAR, + COMMAND_SUB_VAL_FROM_FLOAT_LVAR, + COMMAND_MULT_INT_VAR_BY_VAL, + COMMAND_MULT_FLOAT_VAR_BY_VAL, + COMMAND_MULT_INT_LVAR_BY_VAL, + COMMAND_MULT_FLOAT_LVAR_BY_VAL, + COMMAND_DIV_INT_VAR_BY_VAL, + COMMAND_DIV_FLOAT_VAR_BY_VAL, + COMMAND_DIV_INT_LVAR_BY_VAL, + COMMAND_DIV_FLOAT_LVAR_BY_VAL, + COMMAND_IS_INT_VAR_GREATER_THAN_NUMBER, + COMMAND_IS_INT_LVAR_GREATER_THAN_NUMBER, + COMMAND_IS_NUMBER_GREATER_THAN_INT_VAR, + COMMAND_IS_NUMBER_GREATER_THAN_INT_LVAR, + COMMAND_IS_INT_VAR_GREATER_THAN_INT_VAR, + COMMAND_IS_INT_LVAR_GREATER_THAN_INT_LVAR, + COMMAND_IS_INT_VAR_GREATER_THAN_INT_LVAR, + COMMAND_IS_INT_LVAR_GREATER_THAN_INT_VAR, + COMMAND_IS_FLOAT_VAR_GREATER_THAN_NUMBER, + COMMAND_IS_FLOAT_LVAR_GREATER_THAN_NUMBER, + COMMAND_IS_NUMBER_GREATER_THAN_FLOAT_VAR, + COMMAND_IS_NUMBER_GREATER_THAN_FLOAT_LVAR, + COMMAND_IS_FLOAT_VAR_GREATER_THAN_FLOAT_VAR, + COMMAND_IS_FLOAT_LVAR_GREATER_THAN_FLOAT_LVAR, + COMMAND_IS_FLOAT_VAR_GREATER_THAN_FLOAT_LVAR, + COMMAND_IS_FLOAT_LVAR_GREATER_THAN_FLOAT_VAR, + COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_NUMBER, + COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_NUMBER, + COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_INT_VAR, + COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_INT_LVAR, + COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_VAR, + COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_LVAR, + COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_LVAR, + COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_VAR, + COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_NUMBER, + COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_NUMBER, + COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_VAR, + COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_LVAR, + COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_VAR, + COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR, + COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR, + COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_VAR, + COMMAND_IS_INT_VAR_EQUAL_TO_NUMBER, + COMMAND_IS_INT_LVAR_EQUAL_TO_NUMBER, + COMMAND_IS_INT_VAR_EQUAL_TO_INT_VAR, + COMMAND_IS_INT_LVAR_EQUAL_TO_INT_LVAR, + COMMAND_IS_INT_VAR_EQUAL_TO_INT_LVAR, + COMMAND_IS_INT_VAR_NOT_EQUAL_TO_NUMBER, + COMMAND_IS_INT_LVAR_NOT_EQUAL_TO_NUMBER, + COMMAND_IS_INT_VAR_NOT_EQUAL_TO_INT_VAR, + COMMAND_IS_INT_LVAR_NOT_EQUAL_TO_INT_LVAR, + COMMAND_IS_INT_VAR_NOT_EQUAL_TO_INT_LVAR, + COMMAND_IS_FLOAT_VAR_EQUAL_TO_NUMBER, + COMMAND_IS_FLOAT_LVAR_EQUAL_TO_NUMBER, + COMMAND_IS_FLOAT_VAR_EQUAL_TO_FLOAT_VAR, + COMMAND_IS_FLOAT_LVAR_EQUAL_TO_FLOAT_LVAR, + COMMAND_IS_FLOAT_VAR_EQUAL_TO_FLOAT_LVAR, + COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_NUMBER, + COMMAND_IS_FLOAT_LVAR_NOT_EQUAL_TO_NUMBER, + COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_VAR, + COMMAND_IS_FLOAT_LVAR_NOT_EQUAL_TO_FLOAT_LVAR, + COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_LVAR, + COMMAND_GOTO_IF_TRUE, + COMMAND_GOTO_IF_FALSE, + COMMAND_TERMINATE_THIS_SCRIPT, + COMMAND_START_NEW_SCRIPT, + COMMAND_GOSUB, + COMMAND_RETURN, + COMMAND_LINE, + COMMAND_CREATE_PLAYER, + COMMAND_GET_PLAYER_COORDINATES, + COMMAND_SET_PLAYER_COORDINATES, + COMMAND_IS_PLAYER_IN_AREA_2D, + COMMAND_IS_PLAYER_IN_AREA_3D, + COMMAND_ADD_INT_VAR_TO_INT_VAR, + COMMAND_ADD_FLOAT_VAR_TO_FLOAT_VAR, + COMMAND_ADD_INT_LVAR_TO_INT_LVAR, + COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_LVAR, + COMMAND_ADD_INT_VAR_TO_INT_LVAR, + COMMAND_ADD_FLOAT_VAR_TO_FLOAT_LVAR, + COMMAND_ADD_INT_LVAR_TO_INT_VAR, + COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_VAR, + COMMAND_SUB_INT_VAR_FROM_INT_VAR, + COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_VAR, + COMMAND_SUB_INT_LVAR_FROM_INT_LVAR, + COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_LVAR, + COMMAND_SUB_INT_VAR_FROM_INT_LVAR, + COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_LVAR, + COMMAND_SUB_INT_LVAR_FROM_INT_VAR, + COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_VAR, + COMMAND_MULT_INT_VAR_BY_INT_VAR, + COMMAND_MULT_FLOAT_VAR_BY_FLOAT_VAR, + COMMAND_MULT_INT_LVAR_BY_INT_LVAR, + COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_LVAR, + COMMAND_MULT_INT_VAR_BY_INT_LVAR, + COMMAND_MULT_FLOAT_VAR_BY_FLOAT_LVAR, + COMMAND_MULT_INT_LVAR_BY_INT_VAR, + COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_VAR, + COMMAND_DIV_INT_VAR_BY_INT_VAR, + COMMAND_DIV_FLOAT_VAR_BY_FLOAT_VAR, + COMMAND_DIV_INT_LVAR_BY_INT_LVAR, + COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_LVAR, + COMMAND_DIV_INT_VAR_BY_INT_LVAR, + COMMAND_DIV_FLOAT_VAR_BY_FLOAT_LVAR, + COMMAND_DIV_INT_LVAR_BY_INT_VAR, + COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_VAR, + COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR, + COMMAND_ADD_TIMED_VAL_TO_FLOAT_LVAR, + COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR, + COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR, + COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR, + COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR, + COMMAND_SUB_TIMED_VAL_FROM_FLOAT_VAR, + COMMAND_SUB_TIMED_VAL_FROM_FLOAT_LVAR, + COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR, + COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_LVAR, + COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_VAR, + COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_LVAR, + COMMAND_SET_VAR_INT_TO_VAR_INT, + COMMAND_SET_LVAR_INT_TO_LVAR_INT, + COMMAND_SET_VAR_FLOAT_TO_VAR_FLOAT, + COMMAND_SET_LVAR_FLOAT_TO_LVAR_FLOAT, + COMMAND_SET_VAR_FLOAT_TO_LVAR_FLOAT, + COMMAND_SET_LVAR_FLOAT_TO_VAR_FLOAT, + COMMAND_SET_VAR_INT_TO_LVAR_INT, + COMMAND_SET_LVAR_INT_TO_VAR_INT, + COMMAND_CSET_VAR_INT_TO_VAR_FLOAT, + COMMAND_CSET_VAR_FLOAT_TO_VAR_INT, + COMMAND_CSET_LVAR_INT_TO_VAR_FLOAT, + COMMAND_CSET_LVAR_FLOAT_TO_VAR_INT, + COMMAND_CSET_VAR_INT_TO_LVAR_FLOAT, + COMMAND_CSET_VAR_FLOAT_TO_LVAR_INT, + COMMAND_CSET_LVAR_INT_TO_LVAR_FLOAT, + COMMAND_CSET_LVAR_FLOAT_TO_LVAR_INT, + COMMAND_ABS_VAR_INT, + COMMAND_ABS_LVAR_INT, + COMMAND_ABS_VAR_FLOAT, + COMMAND_ABS_LVAR_FLOAT, + COMMAND_GENERATE_RANDOM_FLOAT, + COMMAND_GENERATE_RANDOM_INT, + COMMAND_CREATE_CHAR, + COMMAND_DELETE_CHAR, + COMMAND_CHAR_WANDER_DIR, + COMMAND_CHAR_WANDER_RANGE, + COMMAND_CHAR_FOLLOW_PATH, + COMMAND_CHAR_SET_IDLE, + COMMAND_GET_CHAR_COORDINATES, + COMMAND_SET_CHAR_COORDINATES, + COMMAND_IS_CHAR_STILL_ALIVE, + COMMAND_IS_CHAR_IN_AREA_2D, + COMMAND_IS_CHAR_IN_AREA_3D, + COMMAND_CREATE_CAR, + COMMAND_DELETE_CAR, + COMMAND_CAR_GOTO_COORDINATES, + COMMAND_CAR_WANDER_RANDOMLY, + COMMAND_CAR_SET_IDLE, + COMMAND_GET_CAR_COORDINATES, + COMMAND_SET_CAR_COORDINATES, + COMMAND_IS_CAR_STILL_ALIVE, + COMMAND_SET_CAR_CRUISE_SPEED, + COMMAND_SET_CAR_DRIVING_STYLE, + COMMAND_SET_CAR_MISSION, + COMMAND_IS_CAR_IN_AREA_2D, + COMMAND_IS_CAR_IN_AREA_3D, + COMMAND_SPECIAL_0, + COMMAND_SPECIAL_1, + COMMAND_SPECIAL_2, + COMMAND_SPECIAL_3, + COMMAND_SPECIAL_4, + COMMAND_SPECIAL_5, + COMMAND_SPECIAL_6, + COMMAND_SPECIAL_7, + COMMAND_PRINT_BIG, + COMMAND_PRINT, + COMMAND_PRINT_NOW, + COMMAND_PRINT_SOON, + COMMAND_CLEAR_PRINTS, + COMMAND_GET_TIME_OF_DAY, + COMMAND_SET_TIME_OF_DAY, + COMMAND_GET_MINUTES_TO_TIME_OF_DAY, + COMMAND_IS_POINT_ON_SCREEN, + COMMAND_DEBUG_ON, + COMMAND_DEBUG_OFF, + COMMAND_RETURN_TRUE, + COMMAND_RETURN_FALSE, + COMMAND_VAR_INT, + COMMAND_VAR_FLOAT, + COMMAND_LVAR_INT, + COMMAND_LVAR_FLOAT, + COMMAND_LBRACKET, + COMMAND_RBRACKET, + COMMAND_REPEAT, + COMMAND_ENDREPEAT, + COMMAND_IF_, + COMMAND_IFNOT, + COMMAND_ELSE, + COMMAND_ENDIF, + COMMAND_WHILE, + COMMAND_WHILENOT, + COMMAND_ENDWHILE, + COMMAND_ANDOR, + COMMAND_LAUNCH_MISSION, + COMMAND_MISSION_HAS_FINISHED, + COMMAND_STORE_CAR_CHAR_IS_IN, + COMMAND_STORE_CAR_PLAYER_IS_IN, + COMMAND_IS_CHAR_IN_CAR, + COMMAND_IS_PLAYER_IN_CAR, + COMMAND_IS_CHAR_IN_MODEL, + COMMAND_IS_PLAYER_IN_MODEL, + COMMAND_IS_CHAR_IN_ANY_CAR, + COMMAND_IS_PLAYER_IN_ANY_CAR, + COMMAND_IS_BUTTON_PRESSED, + COMMAND_GET_PAD_STATE, + COMMAND_LOCATE_PLAYER_ANY_MEANS_2D, + COMMAND_LOCATE_PLAYER_ON_FOOT_2D, + COMMAND_LOCATE_PLAYER_IN_CAR_2D, + COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D, + COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D, + COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D, + COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_2D, + COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_2D, + COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D, + COMMAND_LOCATE_CHAR_ANY_MEANS_2D, + COMMAND_LOCATE_CHAR_ON_FOOT_2D, + COMMAND_LOCATE_CHAR_IN_CAR_2D, + COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D, + COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D, + COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D, + COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_2D, + COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_2D, + COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D, + COMMAND_LOCATE_PLAYER_ANY_MEANS_3D, + COMMAND_LOCATE_PLAYER_ON_FOOT_3D, + COMMAND_LOCATE_PLAYER_IN_CAR_3D, + COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D, + COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D, + COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D, + COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_3D, + COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_3D, + COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D, + COMMAND_LOCATE_CHAR_ANY_MEANS_3D, + COMMAND_LOCATE_CHAR_ON_FOOT_3D, + COMMAND_LOCATE_CHAR_IN_CAR_3D, + COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D, + COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D, + COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D, + COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_3D, + COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_3D, + COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D, + COMMAND_CREATE_OBJECT, + COMMAND_DELETE_OBJECT, + COMMAND_ADD_SCORE, + COMMAND_IS_SCORE_GREATER, + COMMAND_STORE_SCORE, + COMMAND_GIVE_REMOTE_CONTROLLED_CAR_TO_PLAYER, + COMMAND_ALTER_WANTED_LEVEL, + COMMAND_ALTER_WANTED_LEVEL_NO_DROP, + COMMAND_IS_WANTED_LEVEL_GREATER, + COMMAND_CLEAR_WANTED_LEVEL, + COMMAND_SET_DEATHARREST_STATE, + COMMAND_HAS_DEATHARREST_BEEN_EXECUTED, + COMMAND_ADD_AMMO_TO_PLAYER, + COMMAND_ADD_AMMO_TO_CHAR, + COMMAND_ADD_AMMO_TO_CAR, + COMMAND_IS_PLAYER_STILL_ALIVE, + COMMAND_IS_PLAYER_DEAD, + COMMAND_IS_CHAR_DEAD, + COMMAND_IS_CAR_DEAD, + COMMAND_SET_CHAR_THREAT_SEARCH, + COMMAND_SET_CHAR_THREAT_REACTION, + COMMAND_SET_CHAR_OBJ_NO_OBJ, + COMMAND_ORDER_DRIVER_OUT_OF_CAR, + COMMAND_ORDER_CHAR_TO_DRIVE_CAR, + COMMAND_ADD_PATROL_POINT, + COMMAND_IS_PLAYER_IN_GANGZONE, + COMMAND_IS_PLAYER_IN_ZONE, + COMMAND_IS_PLAYER_PRESSING_HORN, + COMMAND_HAS_CHAR_SPOTTED_PLAYER, + COMMAND_ORDER_CHAR_TO_BACKDOOR, + COMMAND_ADD_CHAR_TO_GANG, + COMMAND_IS_CHAR_OBJECTIVE_PASSED, + COMMAND_SET_CHAR_DRIVE_AGGRESSION, + COMMAND_SET_CHAR_MAX_DRIVESPEED, + COMMAND_CREATE_CHAR_INSIDE_CAR, + COMMAND_WARP_PLAYER_FROM_CAR_TO_COORD, + COMMAND_MAKE_CHAR_DO_NOTHING, + COMMAND_SET_CHAR_INVINCIBLE, + COMMAND_SET_PLAYER_INVINCIBLE, + COMMAND_SET_CHAR_GRAPHIC_TYPE, + COMMAND_SET_PLAYER_GRAPHIC_TYPE, + COMMAND_HAS_PLAYER_BEEN_ARRESTED, + COMMAND_STOP_CHAR_DRIVING, + COMMAND_KILL_CHAR, + COMMAND_SET_FAVOURITE_CAR_MODEL_FOR_CHAR, + COMMAND_SET_CHAR_OCCUPATION, + COMMAND_CHANGE_CAR_LOCK, + COMMAND_SHAKE_CAM_WITH_POINT, + COMMAND_IS_CAR_MODEL, + COMMAND_IS_CAR_REMAP, + COMMAND_HAS_CAR_JUST_SUNK, + COMMAND_SET_CAR_NO_COLLIDE, + COMMAND_IS_CAR_DEAD_IN_AREA_2D, + COMMAND_IS_CAR_DEAD_IN_AREA_3D, + COMMAND_IS_TRAILER_ATTACHED, + COMMAND_IS_CAR_ON_TRAILER, + COMMAND_HAS_CAR_GOT_WEAPON, + COMMAND_PARK, + COMMAND_HAS_PARK_FINISHED, + COMMAND_KILL_ALL_PASSENGERS, + COMMAND_SET_CAR_BULLETPROOF, + COMMAND_SET_CAR_FLAMEPROOF, + COMMAND_SET_CAR_ROCKETPROOF, + COMMAND_IS_CARBOMB_ACTIVE, + COMMAND_GIVE_CAR_ALARM, + COMMAND_PUT_CAR_ON_TRAILER, + COMMAND_IS_CAR_CRUSHED, + COMMAND_CREATE_GANG_CAR, + COMMAND_CREATE_CAR_GENERATOR, + COMMAND_SWITCH_CAR_GENERATOR, + COMMAND_ADD_PAGER_MESSAGE, + COMMAND_DISPLAY_ONSCREEN_TIMER, + COMMAND_CLEAR_ONSCREEN_TIMER, + COMMAND_DISPLAY_ONSCREEN_COUNTER, + COMMAND_CLEAR_ONSCREEN_COUNTER, + COMMAND_SET_ZONE_CAR_INFO, + COMMAND_IS_CHAR_IN_GANG_ZONE, + COMMAND_IS_CHAR_IN_ZONE, + COMMAND_SET_CAR_DENSITY, + COMMAND_SET_PED_DENSITY, + COMMAND_POINT_CAMERA_AT_PLAYER, + COMMAND_POINT_CAMERA_AT_CAR, + COMMAND_POINT_CAMERA_AT_CHAR, + COMMAND_RESTORE_CAMERA, + COMMAND_SHAKE_PAD, + COMMAND_SET_ZONE_PED_INFO, + COMMAND_SET_TIME_SCALE, + COMMAND_IS_CAR_IN_AIR, + COMMAND_SET_FIXED_CAMERA_POSITION, + COMMAND_POINT_CAMERA_AT_POINT, + COMMAND_ADD_BLIP_FOR_CAR_OLD, + COMMAND_ADD_BLIP_FOR_CHAR_OLD, + COMMAND_ADD_BLIP_FOR_OBJECT_OLD, + COMMAND_REMOVE_BLIP, + COMMAND_CHANGE_BLIP_COLOUR, + COMMAND_DIM_BLIP, + COMMAND_ADD_BLIP_FOR_COORD_OLD, + COMMAND_CHANGE_BLIP_SCALE, + COMMAND_SET_FADING_COLOUR, + COMMAND_DO_FADE, + COMMAND_GET_FADING_STATUS, + COMMAND_ADD_HOSPITAL_RESTART, + COMMAND_ADD_POLICE_RESTART, + COMMAND_OVERRIDE_NEXT_RESTART, + COMMAND_DRAW_SHADOW, + COMMAND_GET_PLAYER_HEADING, + COMMAND_SET_PLAYER_HEADING, + COMMAND_GET_CHAR_HEADING, + COMMAND_SET_CHAR_HEADING, + COMMAND_GET_CAR_HEADING, + COMMAND_SET_CAR_HEADING, + COMMAND_GET_OBJECT_HEADING, + COMMAND_SET_OBJECT_HEADING, + COMMAND_IS_PLAYER_TOUCHING_OBJECT, + COMMAND_IS_CHAR_TOUCHING_OBJECT, + COMMAND_SET_PLAYER_AMMO, + COMMAND_SET_CHAR_AMMO, + COMMAND_SET_CAR_AMMO, + COMMAND_LOAD_CAMERA_SPLINE, + COMMAND_MOVE_CAMERA_ALONG_SPLINE, + COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE, + COMMAND_DECLARE_MISSION_FLAG, + COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT, + COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT, + COMMAND_IS_PLAYER_HEALTH_GREATER, + COMMAND_IS_CHAR_HEALTH_GREATER, + COMMAND_IS_CAR_HEALTH_GREATER, + COMMAND_ADD_BLIP_FOR_CAR, + COMMAND_ADD_BLIP_FOR_CHAR, + COMMAND_ADD_BLIP_FOR_OBJECT, + COMMAND_ADD_BLIP_FOR_CONTACT_POINT, + COMMAND_ADD_BLIP_FOR_COORD, + COMMAND_CHANGE_BLIP_DISPLAY, + COMMAND_ADD_ONE_OFF_SOUND, + COMMAND_ADD_CONTINUOUS_SOUND, + COMMAND_REMOVE_SOUND, + COMMAND_IS_CAR_STUCK_ON_ROOF, + COMMAND_ADD_UPSIDEDOWN_CAR_CHECK, + COMMAND_REMOVE_UPSIDEDOWN_CAR_CHECK, + COMMAND_SET_CHAR_OBJ_WAIT_ON_FOOT, + COMMAND_SET_CHAR_OBJ_FLEE_ON_FOOT_TILL_SAFE, + COMMAND_SET_CHAR_OBJ_GUARD_SPOT, + COMMAND_SET_CHAR_OBJ_GUARD_AREA, + COMMAND_SET_CHAR_OBJ_WAIT_IN_CAR, + COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_2D, + COMMAND_IS_PLAYER_IN_AREA_IN_CAR_2D, + COMMAND_IS_PLAYER_STOPPED_IN_AREA_2D, + COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D, + COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D, + COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D, + COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D, + COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D, + COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D, + COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D, + COMMAND_IS_CHAR_IN_AREA_ON_FOOT_2D, + COMMAND_IS_CHAR_IN_AREA_IN_CAR_2D, + COMMAND_IS_CHAR_STOPPED_IN_AREA_2D, + COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D, + COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D, + COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D, + COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D, + COMMAND_IS_CHAR_STOPPED_IN_AREA_3D, + COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D, + COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D, + COMMAND_IS_CAR_STOPPED_IN_AREA_2D, + COMMAND_IS_CAR_STOPPED_IN_AREA_3D, + COMMAND_LOCATE_CAR_2D, + COMMAND_LOCATE_STOPPED_CAR_2D, + COMMAND_LOCATE_CAR_3D, + COMMAND_LOCATE_STOPPED_CAR_3D, + COMMAND_GIVE_WEAPON_TO_PLAYER, + COMMAND_GIVE_WEAPON_TO_CHAR, + COMMAND_GIVE_WEAPON_TO_CAR, + COMMAND_SET_PLAYER_CONTROL, + COMMAND_FORCE_WEATHER, + COMMAND_FORCE_WEATHER_NOW, + COMMAND_RELEASE_WEATHER, + COMMAND_SET_CURRENT_PLAYER_WEAPON, + COMMAND_SET_CURRENT_CHAR_WEAPON, + COMMAND_SET_CURRENT_CAR_WEAPON, + COMMAND_GET_OBJECT_COORDINATES, + COMMAND_SET_OBJECT_COORDINATES, + COMMAND_GET_GAME_TIMER, + COMMAND_TURN_CHAR_TO_FACE_COORD, + COMMAND_TURN_PLAYER_TO_FACE_COORD, + COMMAND_STORE_WANTED_LEVEL, + COMMAND_IS_CAR_STOPPED, + COMMAND_MARK_CHAR_AS_NO_LONGER_NEEDED, + COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED, + COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED, + COMMAND_DONT_REMOVE_CHAR, + COMMAND_DONT_REMOVE_CAR, + COMMAND_DONT_REMOVE_OBJECT, + COMMAND_CREATE_CHAR_AS_PASSENGER, + COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT, + COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ON_FOOT, + COMMAND_SET_CHAR_OBJ_KILL_CHAR_ANY_MEANS, + COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ANY_MEANS, + COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE, + COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE, + COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS, + COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS, + COMMAND_SET_CHAR_OBJ_GOTO_CHAR_ON_FOOT, + COMMAND_SET_CHAR_OBJ_GOTO_PLAYER_ON_FOOT, + COMMAND_SET_CHAR_OBJ_LEAVE_CAR, + COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_PASSENGER, + COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_DRIVER, + COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_IN_CAR, + COMMAND_SET_CHAR_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE, + COMMAND_SET_CHAR_OBJ_DESTROY_OBJECT, + COMMAND_SET_CHAR_OBJ_DESTROY_CAR, + COMMAND_SET_CHAR_OBJ_GOTO_AREA_ON_FOOT, + COMMAND_SET_CHAR_OBJ_GOTO_AREA_IN_CAR, + COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET, + COMMAND_SET_CHAR_OBJ_GUARD_ATTACK, + COMMAND_SET_CHAR_AS_LEADER, + COMMAND_SET_PLAYER_AS_LEADER, + COMMAND_LEAVE_GROUP, + COMMAND_SET_CHAR_OBJ_FOLLOW_ROUTE, + COMMAND_ADD_ROUTE_POINT, + COMMAND_PRINT_WITH_NUMBER_BIG, + COMMAND_PRINT_WITH_NUMBER, + COMMAND_PRINT_WITH_NUMBER_NOW, + COMMAND_PRINT_WITH_NUMBER_SOON, + COMMAND_SWITCH_ROADS_ON, + COMMAND_SWITCH_ROADS_OFF, + COMMAND_GET_NUMBER_OF_PASSENGERS, + COMMAND_GET_MAXIMUM_NUMBER_OF_PASSENGERS, + COMMAND_SET_CAR_DENSITY_MULTIPLIER, + COMMAND_SET_CAR_HEAVY, + COMMAND_CLEAR_CHAR_THREAT_SEARCH, + COMMAND_ACTIVATE_CRANE, + COMMAND_DEACTIVATE_CRANE, + COMMAND_SET_MAX_WANTED_LEVEL, + COMMAND_SAVE_VAR_INT, + COMMAND_SAVE_VAR_FLOAT, + COMMAND_IS_CAR_IN_AIR_PROPER, + COMMAND_IS_CAR_UPSIDEDOWN, + COMMAND_GET_PLAYER_CHAR, + COMMAND_CANCEL_OVERRIDE_RESTART, + COMMAND_SET_POLICE_IGNORE_PLAYER, + COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER, + COMMAND_START_KILL_FRENZY, + COMMAND_READ_KILL_FRENZY_STATUS, + COMMAND_SQRT, + COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_2D, + COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_2D, + COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D, + COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D, + COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D, + COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D, + COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_2D, + COMMAND_LOCATE_CHAR_ON_FOOT_CAR_2D, + COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D, + COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D, + COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D, + COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D, + COMMAND_GENERATE_RANDOM_FLOAT_IN_RANGE, + COMMAND_GENERATE_RANDOM_INT_IN_RANGE, + COMMAND_LOCK_CAR_DOORS, + COMMAND_EXPLODE_CAR, + COMMAND_ADD_EXPLOSION, + COMMAND_IS_CAR_UPRIGHT, + COMMAND_TURN_CHAR_TO_FACE_CHAR, + COMMAND_TURN_CHAR_TO_FACE_PLAYER, + COMMAND_TURN_PLAYER_TO_FACE_CHAR, + COMMAND_SET_CHAR_OBJ_GOTO_COORD_ON_FOOT, + COMMAND_SET_CHAR_OBJ_GOTO_COORD_IN_CAR, + COMMAND_CREATE_PICKUP, + COMMAND_HAS_PICKUP_BEEN_COLLECTED, + COMMAND_REMOVE_PICKUP, + COMMAND_SET_TAXI_LIGHTS, + COMMAND_PRINT_BIG_Q, + COMMAND_PRINT_WITH_NUMBER_BIG_Q, + COMMAND_SET_GARAGE, + COMMAND_SET_GARAGE_WITH_CAR_MODEL, + COMMAND_SET_TARGET_CAR_FOR_MISSION_GARAGE, + COMMAND_IS_CAR_IN_MISSION_GARAGE, + COMMAND_SET_FREE_BOMBS, + COMMAND_SET_POWERPOINT, + COMMAND_SET_ALL_TAXI_LIGHTS, + COMMAND_IS_CAR_ARMED_WITH_ANY_BOMB, + COMMAND_APPLY_BRAKES_TO_PLAYERS_CAR, + COMMAND_SET_PLAYER_HEALTH, + COMMAND_SET_CHAR_HEALTH, + COMMAND_SET_CAR_HEALTH, + COMMAND_GET_PLAYER_HEALTH, + COMMAND_GET_CHAR_HEALTH, + COMMAND_GET_CAR_HEALTH, + COMMAND_IS_CAR_ARMED_WITH_BOMB, + COMMAND_CHANGE_CAR_COLOUR, + COMMAND_SWITCH_PED_ROADS_ON, + COMMAND_SWITCH_PED_ROADS_OFF, + COMMAND_CHAR_LOOK_AT_CHAR_ALWAYS, + COMMAND_CHAR_LOOK_AT_PLAYER_ALWAYS, + COMMAND_PLAYER_LOOK_AT_CHAR_ALWAYS, + COMMAND_STOP_CHAR_LOOKING, + COMMAND_STOP_PLAYER_LOOKING, + COMMAND_SWITCH_HELICOPTER, + COMMAND_SET_GANG_ATTITUDE, + COMMAND_SET_GANG_GANG_ATTITUDE, + COMMAND_SET_GANG_PLAYER_ATTITUDE, + COMMAND_SET_GANG_PED_MODELS, + COMMAND_SET_GANG_CAR_MODEL, + COMMAND_SET_GANG_WEAPONS, + COMMAND_SET_CHAR_OBJ_RUN_TO_AREA, + COMMAND_SET_CHAR_OBJ_RUN_TO_COORD, + COMMAND_IS_PLAYER_TOUCHING_OBJECT_ON_FOOT, + COMMAND_IS_CHAR_TOUCHING_OBJECT_ON_FOOT, + COMMAND_LOAD_SPECIAL_CHARACTER, + COMMAND_HAS_SPECIAL_CHARACTER_LOADED, + COMMAND_FLASH_CAR, + COMMAND_FLASH_CHAR, + COMMAND_FLASH_OBJECT, + COMMAND_IS_PLAYER_IN_REMOTE_MODE, + COMMAND_ARM_CAR_WITH_BOMB, + COMMAND_SET_CHAR_PERSONALITY, + COMMAND_SET_CUTSCENE_OFFSET, + COMMAND_SET_ANIM_GROUP_FOR_CHAR, + COMMAND_SET_ANIM_GROUP_FOR_PLAYER, + COMMAND_REQUEST_MODEL, + COMMAND_HAS_MODEL_LOADED, + COMMAND_MARK_MODEL_AS_NO_LONGER_NEEDED, + COMMAND_GRAB_PHONE, + COMMAND_SET_REPEATED_PHONE_MESSAGE, + COMMAND_SET_PHONE_MESSAGE, + COMMAND_HAS_PHONE_DISPLAYED_MESSAGE, + COMMAND_TURN_PHONE_OFF, + COMMAND_DRAW_CORONA, + COMMAND_DRAW_LIGHT, + COMMAND_STORE_WEATHER, + COMMAND_RESTORE_WEATHER, + COMMAND_STORE_CLOCK, + COMMAND_RESTORE_CLOCK, + COMMAND_RESTART_CRITICAL_MISSION, + COMMAND_IS_PLAYER_PLAYING, + COMMAND_SET_COLL_OBJ_NO_OBJ, + COMMAND_SET_COLL_OBJ_WAIT_ON_FOOT, + COMMAND_SET_COLL_OBJ_FLEE_ON_FOOT_TILL_SAFE, + COMMAND_SET_COLL_OBJ_GUARD_SPOT, + COMMAND_SET_COLL_OBJ_GUARD_AREA, + COMMAND_SET_COLL_OBJ_WAIT_IN_CAR, + COMMAND_SET_COLL_OBJ_KILL_CHAR_ON_FOOT, + COMMAND_SET_COLL_OBJ_KILL_PLAYER_ON_FOOT, + COMMAND_SET_COLL_OBJ_KILL_CHAR_ANY_MEANS, + COMMAND_SET_COLL_OBJ_KILL_PLAYER_ANY_MEANS, + COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE, + COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE, + COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS, + COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS, + COMMAND_SET_COLL_OBJ_GOTO_CHAR_ON_FOOT, + COMMAND_SET_COLL_OBJ_GOTO_PLAYER_ON_FOOT, + COMMAND_SET_COLL_OBJ_LEAVE_CAR, + COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_PASSENGER, + COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_DRIVER, + COMMAND_SET_COLL_OBJ_FOLLOW_CAR_IN_CAR, + COMMAND_SET_COLL_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE, + COMMAND_SET_COLL_OBJ_DESTROY_OBJECT, + COMMAND_SET_COLL_OBJ_DESTROY_CAR, + COMMAND_SET_COLL_OBJ_GOTO_AREA_ON_FOOT, + COMMAND_SET_COLL_OBJ_GOTO_AREA_IN_CAR, + COMMAND_SET_COLL_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET, + COMMAND_SET_COLL_OBJ_GUARD_ATTACK, + COMMAND_SET_COLL_OBJ_FOLLOW_ROUTE, + COMMAND_SET_COLL_OBJ_GOTO_COORD_ON_FOOT, + COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR, + COMMAND_SET_COLL_OBJ_RUN_TO_AREA, + COMMAND_SET_COLL_OBJ_RUN_TO_COORD, + COMMAND_ADD_PEDS_IN_AREA_TO_COLL, + COMMAND_ADD_PEDS_IN_VEHICLE_TO_COLL, + COMMAND_CLEAR_COLL, + COMMAND_IS_COLL_IN_CARS, + COMMAND_LOCATE_COLL_ANY_MEANS_2D, + COMMAND_LOCATE_COLL_ON_FOOT_2D, + COMMAND_LOCATE_COLL_IN_CAR_2D, + COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D, + COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D, + COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D, + COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D, + COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D, + COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D, + COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D, + COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D, + COMMAND_LOCATE_COLL_IN_CAR_CAR_2D, + COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D, + COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D, + COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D, + COMMAND_IS_COLL_IN_AREA_2D, + COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D, + COMMAND_IS_COLL_IN_AREA_IN_CAR_2D, + COMMAND_IS_COLL_STOPPED_IN_AREA_2D, + COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D, + COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D, + COMMAND_GET_NUMBER_OF_PEDS_IN_COLL, + COMMAND_SET_CHAR_HEED_THREATS, + COMMAND_SET_PLAYER_HEED_THREATS, + COMMAND_GET_CONTROLLER_MODE, + COMMAND_SET_CAN_RESPRAY_CAR, + COMMAND_IS_TAXI, + COMMAND_UNLOAD_SPECIAL_CHARACTER, + COMMAND_RESET_NUM_OF_MODELS_KILLED_BY_PLAYER, + COMMAND_GET_NUM_OF_MODELS_KILLED_BY_PLAYER, + COMMAND_ACTIVATE_GARAGE, + COMMAND_SWITCH_TAXI_TIMER, + COMMAND_CREATE_OBJECT_NO_OFFSET, + COMMAND_IS_BOAT, + COMMAND_SET_CHAR_OBJ_GOTO_AREA_ANY_MEANS, + COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS, + COMMAND_IS_PLAYER_STOPPED, + COMMAND_IS_CHAR_STOPPED, + COMMAND_MESSAGE_WAIT, + COMMAND_ADD_PARTICLE_EFFECT, + COMMAND_SWITCH_WIDESCREEN, + COMMAND_ADD_SPRITE_BLIP_FOR_CAR, + COMMAND_ADD_SPRITE_BLIP_FOR_CHAR, + COMMAND_ADD_SPRITE_BLIP_FOR_OBJECT, + COMMAND_ADD_SPRITE_BLIP_FOR_CONTACT_POINT, + COMMAND_ADD_SPRITE_BLIP_FOR_COORD, + COMMAND_SET_CHAR_ONLY_DAMAGED_BY_PLAYER, + COMMAND_SET_CAR_ONLY_DAMAGED_BY_PLAYER, + COMMAND_SET_CHAR_PROOFS, + COMMAND_SET_CAR_PROOFS, + COMMAND_IS_PLAYER_IN_ANGLED_AREA_2D, + COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_2D, + COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_2D, + COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D, + COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D, + COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D, + COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D, + COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D, + COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D, + COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D, + COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D, + COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D, + COMMAND_DEACTIVATE_GARAGE, + COMMAND_GET_NUMBER_OF_CARS_COLLECTED_BY_GARAGE, + COMMAND_HAS_CAR_BEEN_TAKEN_TO_GARAGE, + COMMAND_SET_SWAT_REQUIRED, + COMMAND_SET_FBI_REQUIRED, + COMMAND_SET_ARMY_REQUIRED, + COMMAND_IS_CAR_IN_WATER, + COMMAND_GET_CLOSEST_CHAR_NODE, + COMMAND_GET_CLOSEST_CAR_NODE, + COMMAND_CAR_GOTO_COORDINATES_ACCURATE, + COMMAND_START_PACMAN_RACE, + COMMAND_START_PACMAN_RECORD, + COMMAND_GET_NUMBER_OF_POWER_PILLS_EATEN, + COMMAND_CLEAR_PACMAN, + COMMAND_START_PACMAN_SCRAMBLE, + COMMAND_GET_NUMBER_OF_POWER_PILLS_CARRIED, + COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_CARRIED, + COMMAND_IS_CAR_ON_SCREEN, + COMMAND_IS_CHAR_ON_SCREEN, + COMMAND_IS_OBJECT_ON_SCREEN, + COMMAND_GOSUB_FILE, + COMMAND_GET_GROUND_Z_FOR_3D_COORD, + COMMAND_START_SCRIPT_FIRE, + COMMAND_IS_SCRIPT_FIRE_EXTINGUISHED, + COMMAND_REMOVE_SCRIPT_FIRE, + COMMAND_SET_COMEDY_CONTROLS, + COMMAND_BOAT_GOTO_COORDS, + COMMAND_BOAT_STOP, + COMMAND_IS_PLAYER_SHOOTING_IN_AREA, + COMMAND_IS_CHAR_SHOOTING_IN_AREA, + COMMAND_IS_CURRENT_PLAYER_WEAPON, + COMMAND_IS_CURRENT_CHAR_WEAPON, + COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_EATEN, + COMMAND_ADD_POWER_PILL, + COMMAND_SET_BOAT_CRUISE_SPEED, + COMMAND_GET_RANDOM_CHAR_IN_AREA, + COMMAND_GET_RANDOM_CHAR_IN_ZONE, + COMMAND_IS_PLAYER_IN_TAXI, + COMMAND_IS_PLAYER_SHOOTING, + COMMAND_IS_CHAR_SHOOTING, + COMMAND_CREATE_MONEY_PICKUP, + COMMAND_SET_CHAR_ACCURACY, + COMMAND_GET_CAR_SPEED, + COMMAND_LOAD_CUTSCENE, + COMMAND_CREATE_CUTSCENE_OBJECT, + COMMAND_SET_CUTSCENE_ANIM, + COMMAND_START_CUTSCENE, + COMMAND_GET_CUTSCENE_TIME, + COMMAND_HAS_CUTSCENE_FINISHED, + COMMAND_CLEAR_CUTSCENE, + COMMAND_RESTORE_CAMERA_JUMPCUT, + COMMAND_CREATE_COLLECTABLE1, + COMMAND_SET_COLLECTABLE1_TOTAL, + COMMAND_IS_PROJECTILE_IN_AREA, + COMMAND_DESTROY_PROJECTILES_IN_AREA, + COMMAND_DROP_MINE, + COMMAND_DROP_NAUTICAL_MINE, + COMMAND_IS_CHAR_MODEL, + COMMAND_LOAD_SPECIAL_MODEL, + COMMAND_CREATE_CUTSCENE_HEAD, + COMMAND_SET_CUTSCENE_HEAD_ANIM, + COMMAND_SIN, + COMMAND_COS, + COMMAND_GET_CAR_FORWARD_X, + COMMAND_GET_CAR_FORWARD_Y, + COMMAND_CHANGE_GARAGE_TYPE, + COMMAND_ACTIVATE_CRUSHER_CRANE, + COMMAND_PRINT_WITH_2_NUMBERS, + COMMAND_PRINT_WITH_2_NUMBERS_NOW, + COMMAND_PRINT_WITH_2_NUMBERS_SOON, + COMMAND_PRINT_WITH_3_NUMBERS, + COMMAND_PRINT_WITH_3_NUMBERS_NOW, + COMMAND_PRINT_WITH_3_NUMBERS_SOON, + COMMAND_PRINT_WITH_4_NUMBERS, + COMMAND_PRINT_WITH_4_NUMBERS_NOW, + COMMAND_PRINT_WITH_4_NUMBERS_SOON, + COMMAND_PRINT_WITH_5_NUMBERS, + COMMAND_PRINT_WITH_5_NUMBERS_NOW, + COMMAND_PRINT_WITH_5_NUMBERS_SOON, + COMMAND_PRINT_WITH_6_NUMBERS, + COMMAND_PRINT_WITH_6_NUMBERS_NOW, + COMMAND_PRINT_WITH_6_NUMBERS_SOON, + COMMAND_SET_CHAR_OBJ_FOLLOW_CHAR_IN_FORMATION, + COMMAND_PLAYER_MADE_PROGRESS, + COMMAND_SET_PROGRESS_TOTAL, + COMMAND_REGISTER_JUMP_DISTANCE, + COMMAND_REGISTER_JUMP_HEIGHT, + COMMAND_REGISTER_JUMP_FLIPS, + COMMAND_REGISTER_JUMP_SPINS, + COMMAND_REGISTER_JUMP_STUNT, + COMMAND_REGISTER_UNIQUE_JUMP_FOUND, + COMMAND_SET_UNIQUE_JUMPS_TOTAL, + COMMAND_REGISTER_PASSENGER_DROPPED_OFF_TAXI, + COMMAND_REGISTER_MONEY_MADE_TAXI, + COMMAND_REGISTER_MISSION_GIVEN, + COMMAND_REGISTER_MISSION_PASSED, + COMMAND_SET_CHAR_RUNNING, + COMMAND_REMOVE_ALL_SCRIPT_FIRES, + COMMAND_IS_FIRST_CAR_COLOUR, + COMMAND_IS_SECOND_CAR_COLOUR, + COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_WEAPON, + COMMAND_HAS_CAR_BEEN_DAMAGED_BY_WEAPON, + COMMAND_IS_CHAR_IN_CHARS_GROUP, + COMMAND_IS_CHAR_IN_PLAYERS_GROUP, + COMMAND_EXPLODE_CHAR_HEAD, + COMMAND_EXPLODE_PLAYER_HEAD, + COMMAND_ANCHOR_BOAT, + COMMAND_SET_ZONE_GROUP, + COMMAND_START_CAR_FIRE, + COMMAND_START_CHAR_FIRE, + COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_AREA, + COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_ZONE, + COMMAND_HAS_RESPRAY_HAPPENED, + COMMAND_SET_CAMERA_ZOOM, + COMMAND_CREATE_PICKUP_WITH_AMMO, + COMMAND_SET_CAR_RAM_CAR, + COMMAND_SET_CAR_BLOCK_CAR, + COMMAND_SET_CHAR_OBJ_CATCH_TRAIN, + COMMAND_SET_COLL_OBJ_CATCH_TRAIN, + COMMAND_SET_PLAYER_NEVER_GETS_TIRED, + COMMAND_SET_PLAYER_FAST_RELOAD, + COMMAND_SET_CHAR_BLEEDING, + COMMAND_SET_CAR_FUNNY_SUSPENSION, + COMMAND_SET_CAR_BIG_WHEELS, + COMMAND_SET_FREE_RESPRAYS, + COMMAND_SET_PLAYER_VISIBLE, + COMMAND_SET_CHAR_VISIBLE, + COMMAND_SET_CAR_VISIBLE, + COMMAND_IS_AREA_OCCUPIED, + COMMAND_START_DRUG_RUN, + COMMAND_HAS_DRUG_RUN_BEEN_COMPLETED, + COMMAND_HAS_DRUG_PLANE_BEEN_SHOT_DOWN, + COMMAND_SAVE_PLAYER_FROM_FIRES, + COMMAND_DISPLAY_TEXT, + COMMAND_SET_TEXT_SCALE, + COMMAND_SET_TEXT_COLOUR, + COMMAND_SET_TEXT_JUSTIFY, + COMMAND_SET_TEXT_CENTRE, + COMMAND_SET_TEXT_WRAPX, + COMMAND_SET_TEXT_CENTRE_SIZE, + COMMAND_SET_TEXT_BACKGROUND, + COMMAND_SET_TEXT_BACKGROUND_COLOUR, + COMMAND_SET_TEXT_BACKGROUND_ONLY_TEXT, + COMMAND_SET_TEXT_PROPORTIONAL, + COMMAND_SET_TEXT_FONT, + COMMAND_INDUSTRIAL_PASSED, + COMMAND_COMMERCIAL_PASSED, + COMMAND_SUBURBAN_PASSED, + COMMAND_ROTATE_OBJECT, + COMMAND_SLIDE_OBJECT, + COMMAND_REMOVE_CHAR_ELEGANTLY, + COMMAND_SET_CHAR_STAY_IN_SAME_PLACE, + COMMAND_IS_NASTY_GAME, + COMMAND_UNDRESS_CHAR, + COMMAND_DRESS_CHAR, + COMMAND_START_CHASE_SCENE, + COMMAND_STOP_CHASE_SCENE, + COMMAND_IS_EXPLOSION_IN_AREA, + COMMAND_IS_EXPLOSION_IN_ZONE, + COMMAND_START_DRUG_DROP_OFF, + COMMAND_HAS_DROP_OFF_PLANE_BEEN_SHOT_DOWN, + COMMAND_FIND_DROP_OFF_PLANE_COORDINATES, + COMMAND_CREATE_FLOATING_PACKAGE, + COMMAND_PLACE_OBJECT_RELATIVE_TO_CAR, + COMMAND_MAKE_OBJECT_TARGETTABLE, + COMMAND_ADD_ARMOUR_TO_PLAYER, + COMMAND_ADD_ARMOUR_TO_CHAR, + COMMAND_OPEN_GARAGE, + COMMAND_CLOSE_GARAGE, + COMMAND_WARP_CHAR_FROM_CAR_TO_COORD, + COMMAND_SET_VISIBILITY_OF_CLOSEST_OBJECT_OF_TYPE, + COMMAND_HAS_CHAR_SPOTTED_CHAR, + COMMAND_SET_CHAR_OBJ_HAIL_TAXI, + COMMAND_HAS_OBJECT_BEEN_DAMAGED, + COMMAND_START_KILL_FRENZY_HEADSHOT, + COMMAND_ACTIVATE_MILITARY_CRANE, + COMMAND_WARP_PLAYER_INTO_CAR, + COMMAND_WARP_CHAR_INTO_CAR, + COMMAND_SWITCH_CAR_RADIO, + COMMAND_SET_AUDIO_STREAM, + COMMAND_PRINT_WITH_2_NUMBERS_BIG, + COMMAND_PRINT_WITH_3_NUMBERS_BIG, + COMMAND_PRINT_WITH_4_NUMBERS_BIG, + COMMAND_PRINT_WITH_5_NUMBERS_BIG, + COMMAND_PRINT_WITH_6_NUMBERS_BIG, + COMMAND_SET_CHAR_WAIT_STATE, + COMMAND_SET_CAMERA_BEHIND_PLAYER, + COMMAND_SET_MOTION_BLUR, + COMMAND_PRINT_STRING_IN_STRING, + COMMAND_CREATE_RANDOM_CHAR, + COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR, + COMMAND_SET_2_REPEATED_PHONE_MESSAGES, + COMMAND_SET_2_PHONE_MESSAGES, + COMMAND_SET_3_REPEATED_PHONE_MESSAGES, + COMMAND_SET_3_PHONE_MESSAGES, + COMMAND_SET_4_REPEATED_PHONE_MESSAGES, + COMMAND_SET_4_PHONE_MESSAGES, + COMMAND_IS_SNIPER_BULLET_IN_AREA, + COMMAND_GIVE_PLAYER_DETONATOR, + COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR, + COMMAND_SET_OBJECT_VELOCITY, + COMMAND_SET_OBJECT_COLLISION, + COMMAND_IS_ICECREAM_JINGLE_ON, + COMMAND_PRINT_STRING_IN_STRING_NOW, + COMMAND_PRINT_STRING_IN_STRING_SOON, + COMMAND_SET_5_REPEATED_PHONE_MESSAGES, + COMMAND_SET_5_PHONE_MESSAGES, + COMMAND_SET_6_REPEATED_PHONE_MESSAGES, + COMMAND_SET_6_PHONE_MESSAGES, + COMMAND_IS_POINT_OBSCURED_BY_A_MISSION_ENTITY, + COMMAND_LOAD_ALL_MODELS_NOW, + COMMAND_ADD_TO_OBJECT_VELOCITY, + COMMAND_DRAW_SPRITE, + COMMAND_DRAW_RECT, + COMMAND_LOAD_SPRITE, + COMMAND_LOAD_TEXTURE_DICTIONARY, + COMMAND_REMOVE_TEXTURE_DICTIONARY, + COMMAND_SET_OBJECT_DYNAMIC, + COMMAND_SET_CHAR_ANIM_SPEED, + COMMAND_PLAY_MISSION_PASSED_TUNE, + COMMAND_CLEAR_AREA, + COMMAND_FREEZE_ONSCREEN_TIMER, + COMMAND_SWITCH_CAR_SIREN, + COMMAND_SWITCH_PED_ROADS_ON_ANGLED, + COMMAND_SWITCH_PED_ROADS_OFF_ANGLED, + COMMAND_SWITCH_ROADS_ON_ANGLED, + COMMAND_SWITCH_ROADS_OFF_ANGLED, + COMMAND_SET_CAR_WATERTIGHT, + COMMAND_ADD_MOVING_PARTICLE_EFFECT, + COMMAND_SET_CHAR_CANT_BE_DRAGGED_OUT, + COMMAND_TURN_CAR_TO_FACE_COORD, + COMMAND_IS_CRANE_LIFTING_CAR, + COMMAND_DRAW_SPHERE, + COMMAND_SET_CAR_STATUS, + COMMAND_IS_CHAR_MALE, + COMMAND_SCRIPT_NAME, + COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL, + COMMAND_FIND_DRUG_PLANE_COORDINATES, + COMMAND_SAVE_INT_TO_DEBUG_FILE, + COMMAND_SAVE_FLOAT_TO_DEBUG_FILE, + COMMAND_SAVE_NEWLINE_TO_DEBUG_FILE, + COMMAND_POLICE_RADIO_MESSAGE, + COMMAND_SET_CAR_STRONG, + COMMAND_REMOVE_ROUTE, + COMMAND_SWITCH_RUBBISH, + COMMAND_REMOVE_PARTICLE_EFFECTS_IN_AREA, + COMMAND_SWITCH_STREAMING, + COMMAND_IS_GARAGE_OPEN, + COMMAND_IS_GARAGE_CLOSED, + COMMAND_START_CATALINA_HELI, + COMMAND_CATALINA_HELI_TAKE_OFF, + COMMAND_REMOVE_CATALINA_HELI, + COMMAND_HAS_CATALINA_HELI_BEEN_SHOT_DOWN, + COMMAND_SWAP_NEAREST_BUILDING_MODEL, + COMMAND_SWITCH_WORLD_PROCESSING, + COMMAND_REMOVE_ALL_PLAYER_WEAPONS, + COMMAND_GRAB_CATALINA_HELI, + COMMAND_CLEAR_AREA_OF_CARS, + COMMAND_SET_ROTATING_GARAGE_DOOR, + COMMAND_ADD_SPHERE, + COMMAND_REMOVE_SPHERE, + COMMAND_CATALINA_HELI_FLY_AWAY, + COMMAND_SET_EVERYONE_IGNORE_PLAYER, + COMMAND_STORE_CAR_CHAR_IS_IN_NO_SAVE, + COMMAND_STORE_CAR_PLAYER_IS_IN_NO_SAVE, + COMMAND_IS_PHONE_DISPLAYING_MESSAGE, + COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING, + COMMAND_DISPLAY_ONSCREEN_COUNTER_WITH_STRING, + COMMAND_CREATE_RANDOM_CAR_FOR_CAR_PARK, + COMMAND_IS_COLLISION_IN_MEMORY, + COMMAND_SET_WANTED_MULTIPLIER, + COMMAND_SET_CAMERA_IN_FRONT_OF_PLAYER, + COMMAND_IS_CAR_VISIBLY_DAMAGED, + COMMAND_DOES_OBJECT_EXIST, + COMMAND_LOAD_SCENE, + COMMAND_ADD_STUCK_CAR_CHECK, + COMMAND_REMOVE_STUCK_CAR_CHECK, + COMMAND_IS_CAR_STUCK, + COMMAND_LOAD_MISSION_AUDIO, + COMMAND_HAS_MISSION_AUDIO_LOADED, + COMMAND_PLAY_MISSION_AUDIO, + COMMAND_HAS_MISSION_AUDIO_FINISHED, + COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING, + COMMAND_HAS_IMPORT_GARAGE_SLOT_BEEN_FILLED, + COMMAND_CLEAR_THIS_PRINT, + COMMAND_CLEAR_THIS_BIG_PRINT, + COMMAND_SET_MISSION_AUDIO_POSITION, + COMMAND_ACTIVATE_SAVE_MENU, + COMMAND_HAS_SAVE_GAME_FINISHED, + COMMAND_NO_SPECIAL_CAMERA_FOR_THIS_GARAGE, + COMMAND_ADD_BLIP_FOR_PICKUP_OLD, + COMMAND_ADD_BLIP_FOR_PICKUP, + COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP, + COMMAND_SET_PED_DENSITY_MULTIPLIER, + COMMAND_FORCE_RANDOM_PED_TYPE, + COMMAND_SET_TEXT_DRAW_BEFORE_FADE, + COMMAND_GET_COLLECTABLE1S_COLLECTED, + COMMAND_REGISTER_EL_BURRO_TIME, + COMMAND_SET_SPRITES_DRAW_BEFORE_FADE, + COMMAND_SET_TEXT_RIGHT_JUSTIFY, + COMMAND_PRINT_HELP, + COMMAND_CLEAR_HELP, + COMMAND_FLASH_HUD_OBJECT, + COMMAND_FLASH_RADAR_BLIP, + COMMAND_IS_CHAR_IN_CONTROL, + COMMAND_SET_GENERATE_CARS_AROUND_CAMERA, + COMMAND_CLEAR_SMALL_PRINTS, + COMMAND_HAS_MILITARY_CRANE_COLLECTED_ALL_CARS, + COMMAND_SET_UPSIDEDOWN_CAR_NOT_DAMAGED, + COMMAND_CAN_PLAYER_START_MISSION, + COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE, + COMMAND_USE_TEXT_COMMANDS, + COMMAND_SET_THREAT_FOR_PED_TYPE, + COMMAND_CLEAR_THREAT_FOR_PED_TYPE, + COMMAND_GET_CAR_COLOURS, + COMMAND_SET_ALL_CARS_CAN_BE_DAMAGED, + COMMAND_SET_CAR_CAN_BE_DAMAGED, + COMMAND_MAKE_PLAYER_UNSAFE, + COMMAND_LOAD_COLLISION, + COMMAND_GET_BODY_CAST_HEALTH, + COMMAND_SET_CHARS_CHATTING, + COMMAND_MAKE_PLAYER_SAFE, + COMMAND_SET_CAR_STAYS_IN_CURRENT_LEVEL, + COMMAND_SET_CHAR_STAYS_IN_CURRENT_LEVEL, + COMMAND_REGISTER_4X4_ONE_TIME, + COMMAND_REGISTER_4X4_TWO_TIME, + COMMAND_REGISTER_4X4_THREE_TIME, + COMMAND_REGISTER_4X4_MAYHEM_TIME, + COMMAND_REGISTER_LIFE_SAVED, + COMMAND_REGISTER_CRIMINAL_CAUGHT, + COMMAND_REGISTER_AMBULANCE_LEVEL, + COMMAND_REGISTER_FIRE_EXTINGUISHED, + COMMAND_TURN_PHONE_ON, + COMMAND_REGISTER_LONGEST_DODO_FLIGHT, + COMMAND_REGISTER_DEFUSE_BOMB_TIME, + COMMAND_SET_TOTAL_NUMBER_OF_KILL_FRENZIES, + COMMAND_BLOW_UP_RC_BUGGY, + COMMAND_REMOVE_CAR_FROM_CHASE, + COMMAND_IS_FRENCH_GAME, + COMMAND_IS_GERMAN_GAME, + COMMAND_CLEAR_MISSION_AUDIO, + COMMAND_SET_FADE_IN_AFTER_NEXT_ARREST, + COMMAND_SET_FADE_IN_AFTER_NEXT_DEATH, + COMMAND_SET_GANG_PED_MODEL_PREFERENCE, + COMMAND_SET_CHAR_USE_PEDNODE_SEEK, + COMMAND_SWITCH_VEHICLE_WEAPONS, + COMMAND_SET_GET_OUT_OF_JAIL_FREE, + COMMAND_SET_FREE_HEALTH_CARE, + COMMAND_IS_CAR_DOOR_CLOSED, + COMMAND_LOAD_AND_LAUNCH_MISSION, + COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL, + COMMAND_SET_OBJECT_DRAW_LAST, + COMMAND_GET_AMMO_IN_PLAYER_WEAPON, + COMMAND_GET_AMMO_IN_CHAR_WEAPON, + COMMAND_REGISTER_KILL_FRENZY_PASSED, + COMMAND_SET_CHAR_SAY, + COMMAND_SET_NEAR_CLIP, + COMMAND_SET_RADIO_CHANNEL, + COMMAND_OVERRIDE_HOSPITAL_LEVEL, + COMMAND_OVERRIDE_POLICE_STATION_LEVEL, + COMMAND_FORCE_RAIN, + COMMAND_DOES_GARAGE_CONTAIN_CAR, + COMMAND_SET_CAR_TRACTION, + COMMAND_ARE_MEASUREMENTS_IN_METRES, + COMMAND_CONVERT_METRES_TO_FEET, + COMMAND_MARK_ROADS_BETWEEN_LEVELS, + COMMAND_MARK_PED_ROADS_BETWEEN_LEVELS, + COMMAND_SET_CAR_AVOID_LEVEL_TRANSITIONS, + COMMAND_SET_CHAR_AVOID_LEVEL_TRANSITIONS, + COMMAND_IS_THREAT_FOR_PED_TYPE, + COMMAND_CLEAR_AREA_OF_CHARS, + COMMAND_SET_TOTAL_NUMBER_OF_MISSIONS, + COMMAND_CONVERT_METRES_TO_FEET_INT, + COMMAND_REGISTER_FASTEST_TIME, + COMMAND_REGISTER_HIGHEST_SCORE, + COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER, + COMMAND_IS_CAR_PASSENGER_SEAT_FREE, + COMMAND_GET_CHAR_IN_CAR_PASSENGER_SEAT, + COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL, + COMMAND_START_CREDITS, + COMMAND_STOP_CREDITS, + COMMAND_ARE_CREDITS_FINISHED, + COMMAND_CREATE_SINGLE_PARTICLE, + COMMAND_SET_CHAR_IGNORE_LEVEL_TRANSITIONS, + COMMAND_GET_CHASE_CAR, + COMMAND_START_BOAT_FOAM_ANIMATION, + COMMAND_UPDATE_BOAT_FOAM_ANIMATION, + COMMAND_SET_MUSIC_DOES_FADE, + COMMAND_SET_INTRO_IS_PLAYING, + COMMAND_SET_PLAYER_HOOKER, + COMMAND_PLAY_END_OF_GAME_TUNE, + COMMAND_STOP_END_OF_GAME_TUNE, + COMMAND_GET_CAR_MODEL, + COMMAND_IS_PLAYER_SITTING_IN_CAR, + COMMAND_IS_PLAYER_SITTING_IN_ANY_CAR, + COMMAND_SET_SCRIPT_FIRE_AUDIO, + COMMAND_ARE_ANY_CAR_CHEATS_ACTIVATED, + COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS, + COMMAND_IS_PLAYER_LIFTING_A_PHONE, + COMMAND_IS_CHAR_SITTING_IN_CAR, + COMMAND_IS_CHAR_SITTING_IN_ANY_CAR, + COMMAND_IS_PLAYER_ON_FOOT, + COMMAND_IS_CHAR_ON_FOOT, + COMMAND_LOAD_COLLISION_WITH_SCREEN, + COMMAND_LOAD_SPLASH_SCREEN, + COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS, + COMMAND_MAKE_CRAIGS_CAR_A_BIT_STRONGER, + COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER, + COMMAND_LOAD_END_OF_GAME_TUNE, + COMMAND_ENABLE_PLAYER_CONTROL_CAMERA, + COMMAND_SET_OBJECT_ROTATION, + COMMAND_GET_DEBUG_CAMERA_COORDINATES, + COMMAND_GET_DEBUG_CAMERA_FRONT_VECTOR, + COMMAND_IS_PLAYER_TARGETTING_ANY_CHAR, + COMMAND_IS_PLAYER_TARGETTING_CHAR, + COMMAND_IS_PLAYER_TARGETTING_OBJECT, + COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME, + COMMAND_DISPLAY_TEXT_WITH_NUMBER, + COMMAND_DISPLAY_TEXT_WITH_2_NUMBERS, + COMMAND_FAIL_CURRENT_MISSION, + COMMAND_GET_CLOSEST_OBJECT_OF_TYPE, + COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT, + COMMAND_SET_ALL_OCCUPANTS_OF_CAR_LEAVE_CAR, + COMMAND_SET_INTERPOLATION_PARAMETERS, + COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_TOWARDS_POINT, + COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_AWAY_POINT, + COMMAND_GET_DEBUG_CAMERA_POINT_AT, + COMMAND_ATTACH_CHAR_TO_CAR, + COMMAND_DETACH_CHAR_FROM_CAR, + COMMAND_SET_CAR_CHANGE_LANE, + COMMAND_CLEAR_CHAR_LAST_WEAPON_DAMAGE, + COMMAND_CLEAR_CAR_LAST_WEAPON_DAMAGE, + COMMAND_GET_RANDOM_COP_IN_AREA, + COMMAND_GET_RANDOM_COP_IN_ZONE, + COMMAND_SET_CHAR_OBJ_FLEE_CAR, + COMMAND_GET_DRIVER_OF_CAR, + COMMAND_GET_NUMBER_OF_FOLLOWERS, + COMMAND_GIVE_REMOTE_CONTROLLED_MODEL_TO_PLAYER, + COMMAND_GET_CURRENT_PLAYER_WEAPON, + COMMAND_GET_CURRENT_CHAR_WEAPON, + COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D, + COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D, + COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D, + COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D, + COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D, + COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D, + COMMAND_SET_CAR_TEMP_ACTION, + COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT, + COMMAND_SET_CAR_HANDBRAKE_STOP, + COMMAND_IS_CHAR_ON_ANY_BIKE, + COMMAND_LOCATE_SNIPER_BULLET_2D, + COMMAND_LOCATE_SNIPER_BULLET_3D, + COMMAND_GET_NUMBER_OF_SEATS_IN_MODEL, + COMMAND_IS_PLAYER_ON_ANY_BIKE, + COMMAND_IS_CHAR_LYING_DOWN, + COMMAND_CAN_CHAR_SEE_DEAD_CHAR, + COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER, +}; \ No newline at end of file From 12af85ca3d29e155f40323ad07a77f96a4aececf Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 8 Jul 2019 08:46:42 +0200 Subject: [PATCH 13/30] cleaned up patching of virtual functions; started CAutomobile --- src/control/Script.h | 10 +- src/core/Instance.cpp | 13 ++ src/core/Instance.h | 10 + src/core/Placeable.cpp | 12 +- src/core/Placeable.h | 3 - src/entities/Building.cpp | 11 +- src/entities/Building.h | 3 - src/entities/Dummy.cpp | 14 +- src/entities/Dummy.h | 5 - src/entities/Entity.cpp | 40 ++-- src/entities/Entity.h | 20 +- src/entities/Physical.cpp | 29 ++- src/entities/Physical.h | 26 +-- src/entities/Treadable.cpp | 10 +- src/entities/Treadable.h | 3 +- src/modelinfo/BaseModelInfo.cpp | 8 +- src/modelinfo/BaseModelInfo.h | 2 - src/modelinfo/ClumpModelInfo.cpp | 20 +- src/modelinfo/ClumpModelInfo.h | 7 - src/modelinfo/MloInstance.cpp | 7 - src/modelinfo/MloInstance.h | 9 - src/modelinfo/PedModelInfo.cpp | 12 +- src/modelinfo/PedModelInfo.h | 4 - src/modelinfo/SimpleModelInfo.cpp | 16 +- src/modelinfo/SimpleModelInfo.h | 5 - src/modelinfo/VehicleModelInfo.cpp | 14 +- src/modelinfo/VehicleModelInfo.h | 5 +- src/objects/CutsceneHead.cpp | 17 +- src/objects/CutsceneHead.h | 5 - src/objects/CutsceneObject.cpp | 26 ++- src/objects/CutsceneObject.h | 20 +- src/objects/DummyObject.cpp | 10 +- src/objects/DummyObject.h | 1 - src/objects/Object.cpp | 11 +- src/objects/Object.h | 3 - src/objects/ParticleObject.cpp | 10 +- src/objects/ParticleObject.h | 2 - src/objects/Projectile.cpp | 10 +- src/objects/Projectile.h | 1 - src/peds/CivilianPed.cpp | 13 +- src/peds/CivilianPed.h | 7 +- src/peds/CopPed.cpp | 10 +- src/peds/CopPed.h | 1 - src/peds/EmergencyPed.cpp | 10 +- src/peds/EmergencyPed.h | 2 - src/peds/Ped.cpp | 28 ++- src/peds/Ped.h | 33 ++-- src/peds/PlayerPed.cpp | 13 +- src/peds/PlayerPed.h | 1 - src/render/Draw.cpp | 1 + src/vehicles/Automobile.cpp | 308 ++++++++++++++++++++++++++++- src/vehicles/Automobile.h | 62 +++++- src/vehicles/Boat.cpp | 10 +- src/vehicles/Boat.h | 1 - src/vehicles/DamageManager.cpp | 1 + src/vehicles/DamageManager.h | 34 ++-- src/vehicles/Heli.cpp | 8 +- src/vehicles/Heli.h | 1 - src/vehicles/Plane.cpp | 10 +- src/vehicles/Plane.h | 1 - src/vehicles/Train.cpp | 10 +- src/vehicles/Train.h | 1 - src/vehicles/Vehicle.cpp | 19 +- src/vehicles/Vehicle.h | 30 ++- 64 files changed, 771 insertions(+), 278 deletions(-) create mode 100644 src/core/Instance.cpp create mode 100644 src/core/Instance.h delete mode 100644 src/modelinfo/MloInstance.cpp delete mode 100644 src/modelinfo/MloInstance.h diff --git a/src/control/Script.h b/src/control/Script.h index 5759cf82..96e1aed5 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -1,10 +1,12 @@ #pragma once #include "common.h" -#include "Collision.h" -#include "Ped.h" -#include "Object.h" #include "Sprite2d.h" -#include "Vehicle.h" + +class CEntity; +class CBuilding; +class CVehicle; +class CPed; +class CObject; struct CScriptRectangle { diff --git a/src/core/Instance.cpp b/src/core/Instance.cpp new file mode 100644 index 00000000..5426605f --- /dev/null +++ b/src/core/Instance.cpp @@ -0,0 +1,13 @@ +#include "common.h" +#include "patcher.h" +#include "Instance.h" + +class CInstance_ : public CInstance +{ +public: + void dtor() { CInstance::~CInstance(); } +}; + +STARTPATCHES + InjectHook(0x50BE90, &CInstance_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/core/Instance.h b/src/core/Instance.h new file mode 100644 index 00000000..1038c005 --- /dev/null +++ b/src/core/Instance.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Placeable.h" + +// unused + +class CInstance : CPlaceable +{ +public: +}; diff --git a/src/core/Placeable.cpp b/src/core/Placeable.cpp index b4b2a37b..c1fe705e 100644 --- a/src/core/Placeable.cpp +++ b/src/core/Placeable.cpp @@ -63,9 +63,17 @@ CPlaceable::IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z1 <= GetPosition().z && GetPosition().z <= z2; } +class CPlaceable_ : public CPlaceable +{ +public: + CPlaceable *ctor(void) { return ::new (this) CPlaceable(); } + void dtor(void) { CPlaceable::~CPlaceable(); } +}; + STARTPATCHES - InjectHook(0x49F9A0, &CPlaceable::ctor, PATCH_JUMP); - InjectHook(0x49F9E0, &CPlaceable::dtor, PATCH_JUMP); + InjectHook(0x49F9A0, &CPlaceable_::ctor, PATCH_JUMP); + InjectHook(0x49F9E0, &CPlaceable_::dtor, PATCH_JUMP); + InjectHook(0x49FA00, &CPlaceable::SetHeading, PATCH_JUMP); InjectHook(0x49FA50, (bool (CPlaceable::*)(float, float, float, float))&CPlaceable::IsWithinArea, PATCH_JUMP); InjectHook(0x49FAF0, (bool (CPlaceable::*)(float, float, float, float, float, float))&CPlaceable::IsWithinArea, PATCH_JUMP); diff --git a/src/core/Placeable.h b/src/core/Placeable.h index 868ca9e7..bd1d50ab 100644 --- a/src/core/Placeable.h +++ b/src/core/Placeable.h @@ -19,8 +19,5 @@ public: void SetHeading(float angle); bool IsWithinArea(float x1, float y1, float x2, float y2); bool IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z2); - - CPlaceable *ctor(void) { return ::new (this) CPlaceable(); } - void dtor(void) { this->CPlaceable::~CPlaceable(); } }; static_assert(sizeof(CPlaceable) == 0x4C, "CPlaceable: error"); diff --git a/src/entities/Building.cpp b/src/entities/Building.cpp index b9fca96f..188cbfe7 100644 --- a/src/entities/Building.cpp +++ b/src/entities/Building.cpp @@ -21,8 +21,15 @@ CBuilding::ReplaceWithNewModel(int32 id) CStreaming::RequestModel(id, STREAMFLAGS_DONT_REMOVE); } +class CBuilding_ : public CBuilding +{ +public: + CBuilding *ctor(void) { return ::new (this) CBuilding(); } + void dtor(void) { CBuilding::~CBuilding(); } +}; + STARTPATCHES - InjectHook(0x4057D0, &CBuilding::ctor, PATCH_JUMP); - InjectHook(0x405800, &CBuilding::dtor, PATCH_JUMP); + InjectHook(0x4057D0, &CBuilding_::ctor, PATCH_JUMP); + InjectHook(0x405800, &CBuilding_::dtor, PATCH_JUMP); InjectHook(0x405850, &CBuilding::ReplaceWithNewModel, PATCH_JUMP); ENDPATCHES diff --git a/src/entities/Building.h b/src/entities/Building.h index 89d0a460..7b837f46 100644 --- a/src/entities/Building.h +++ b/src/entities/Building.h @@ -15,8 +15,5 @@ public: void ReplaceWithNewModel(int32 id); virtual bool GetIsATreadable(void) { return false; } - - CBuilding *ctor(void) { return ::new (this) CBuilding(); } - void dtor(void) { this->CBuilding::~CBuilding(); } }; static_assert(sizeof(CBuilding) == 0x64, "CBuilding: error"); diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp index 5401c1fa..176e5682 100644 --- a/src/entities/Dummy.cpp +++ b/src/entities/Dummy.cpp @@ -51,8 +51,16 @@ CDummy::Remove(void) } } +class CDummy_ : public CDummy +{ +public: + void Add_(void) { CDummy::Add(); } + void Remove_(void) { CDummy::Remove(); } + void dtor(void) { CDummy::~CDummy(); } +}; + STARTPATCHES - InjectHook(0x473810, &CDummy::dtor, PATCH_JUMP); - InjectHook(0x473860, &CDummy::Add_, PATCH_JUMP); - InjectHook(0x473AD0, &CDummy::Remove_, PATCH_JUMP); + InjectHook(0x473810, &CDummy_::dtor, PATCH_JUMP); + InjectHook(0x473860, &CDummy_::Add_, PATCH_JUMP); + InjectHook(0x473AD0, &CDummy_::Remove_, PATCH_JUMP); ENDPATCHES diff --git a/src/entities/Dummy.h b/src/entities/Dummy.h index 59359bb5..fcfd23fb 100644 --- a/src/entities/Dummy.h +++ b/src/entities/Dummy.h @@ -14,10 +14,5 @@ public: static void *operator new(size_t); static void operator delete(void*, size_t); - - // to make patching virtual functions possible - void Add_(void) { CDummy::Add(); } - void Remove_(void) { CDummy::Remove(); } - void dtor(void) { this->CDummy::~CDummy(); } }; static_assert(sizeof(CDummy) == 0x68, "CDummy: error"); diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index fac7f17f..105f14c3 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -865,10 +865,35 @@ CEntity::ModifyMatrixForBannerInWind(void) UpdateRwFrame(); } +class CEntity_ : public CEntity +{ +public: + CEntity *ctor(void) { return ::new (this) CEntity(); } + void dtor(void) { this->CEntity::~CEntity(); } + void Add_(void) { CEntity::Add(); } + void Remove_(void) { CEntity::Remove(); } + void SetModelIndex_(uint32 i) { CEntity::SetModelIndex(i); } + void CreateRwObject_(void) { CEntity::CreateRwObject(); } + void DeleteRwObject_(void) { CEntity::DeleteRwObject(); } + CRect GetBoundRect_(void) { return CEntity::GetBoundRect(); } + void PreRender_(void) { CEntity::PreRender(); } + void Render_(void) { CEntity::Render(); } + bool SetupLighting_(void) { return CEntity::SetupLighting(); } +}; + STARTPATCHES - InjectHook(0x473C30, &CEntity::ctor, PATCH_JUMP); - InjectHook(0x473E40, &CEntity::dtor, PATCH_JUMP); - InjectHook(0x473E70, &CEntity::SetModelIndex_, PATCH_JUMP); + InjectHook(0x473C30, &CEntity_::ctor, PATCH_JUMP); + InjectHook(0x473E40, &CEntity_::dtor, PATCH_JUMP); + InjectHook(0x473E70, &CEntity_::SetModelIndex_, PATCH_JUMP); + InjectHook(0x475080, &CEntity_::Add_, PATCH_JUMP); + InjectHook(0x475310, &CEntity_::Remove_, PATCH_JUMP); + InjectHook(0x473EA0, &CEntity_::CreateRwObject_, PATCH_JUMP); + InjectHook(0x473F90, &CEntity_::DeleteRwObject_, PATCH_JUMP); + InjectHook(0x474000, &CEntity_::GetBoundRect_, PATCH_JUMP); + InjectHook(0x474350, &CEntity_::PreRender_, PATCH_JUMP); + InjectHook(0x474BD0, &CEntity_::Render_, PATCH_JUMP); + InjectHook(0x4A7C60, &CEntity_::SetupLighting_, PATCH_JUMP); + InjectHook(0x4742C0, (void (CEntity::*)(CVector&))&CEntity::GetBoundCentre, PATCH_JUMP); InjectHook(0x474310, &CEntity::GetBoundRadius, PATCH_JUMP); InjectHook(0x474C10, &CEntity::GetIsTouching, PATCH_JUMP); @@ -889,13 +914,4 @@ STARTPATCHES InjectHook(0x475670, &CEntity::ModifyMatrixForTreeInWind, PATCH_JUMP); InjectHook(0x475830, &CEntity::ModifyMatrixForBannerInWind, PATCH_JUMP); InjectHook(0x4FA530, &CEntity::ProcessLightsForEntity, PATCH_JUMP); - - InjectHook(0x475080, &CEntity::Add_, PATCH_JUMP); - InjectHook(0x475310, &CEntity::Remove_, PATCH_JUMP); - InjectHook(0x473EA0, &CEntity::CreateRwObject_, PATCH_JUMP); - InjectHook(0x473F90, &CEntity::DeleteRwObject_, PATCH_JUMP); - InjectHook(0x474000, &CEntity::GetBoundRect_, PATCH_JUMP); - InjectHook(0x474350, &CEntity::PreRender_, PATCH_JUMP); - InjectHook(0x474BD0, &CEntity::Render_, PATCH_JUMP); - InjectHook(0x4A7C60, &CEntity::SetupLighting_, PATCH_JUMP); ENDPATCHES diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 92c4c351..d055d25f 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -95,12 +95,12 @@ public: CReference *m_pFirstReference; CEntity(void); - virtual ~CEntity(void); + ~CEntity(void); virtual void Add(void); virtual void Remove(void); - virtual void SetModelIndex(uint32 i) { m_modelIndex = i; CreateRwObject(); } - virtual void SetModelIndexNoCreate(uint32 i) { m_modelIndex = i; } + virtual void SetModelIndex(uint32 id) { m_modelIndex = id; CreateRwObject(); } + virtual void SetModelIndexNoCreate(uint32 id) { m_modelIndex = id; } virtual void CreateRwObject(void); virtual void DeleteRwObject(void); virtual CRect GetBoundRect(void); @@ -145,19 +145,5 @@ public: void ModifyMatrixForTreeInWind(void); void ModifyMatrixForBannerInWind(void); void ProcessLightsForEntity(void); - - - // to make patching virtual functions possible - CEntity *ctor(void) { return ::new (this) CEntity(); } - void dtor(void) { this->CEntity::~CEntity(); } - void Add_(void) { CEntity::Add(); } - void Remove_(void) { CEntity::Remove(); } - void SetModelIndex_(uint32 i) { CEntity::SetModelIndex(i); } - void CreateRwObject_(void) { CEntity::CreateRwObject(); } - void DeleteRwObject_(void) { CEntity::DeleteRwObject(); } - CRect GetBoundRect_(void) { return CEntity::GetBoundRect(); } - void PreRender_(void) { CEntity::PreRender(); } - void Render_(void) { CEntity::Render(); } - bool SetupLighting_(void) { return CEntity::SetupLighting(); } }; static_assert(sizeof(CEntity) == 0x64, "CEntity: error"); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index d6a82658..3d45bf52 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -3,6 +3,7 @@ #include "World.h" #include "Timer.h" #include "ModelIndices.h" +#include "Treadable.h" #include "Vehicle.h" #include "Ped.h" #include "Object.h" @@ -1932,16 +1933,28 @@ CPhysical::ProcessCollision(void) RemoveAndAdd(); } +class CPhysical_ : public CPhysical +{ +public: + void dtor(void) { CPhysical::~CPhysical(); } + void Add_(void) { CPhysical::Add(); } + void Remove_(void) { CPhysical::Remove(); } + CRect GetBoundRect_(void) { return CPhysical::GetBoundRect(); } + void ProcessControl_(void) { CPhysical::ProcessControl(); } + void ProcessShift_(void) { CPhysical::ProcessShift(); } + void ProcessCollision_(void) { CPhysical::ProcessCollision(); } + int32 ProcessEntityCollision_(CEntity *ent, CColPoint *point) { return CPhysical::ProcessEntityCollision(ent, point); } +}; STARTPATCHES - InjectHook(0x495130, &CPhysical::dtor, PATCH_JUMP); - InjectHook(0x4951F0, &CPhysical::Add_, PATCH_JUMP); - InjectHook(0x4954B0, &CPhysical::Remove_, PATCH_JUMP); - InjectHook(0x495540, &CPhysical::RemoveAndAdd, PATCH_JUMP); - InjectHook(0x495F10, &CPhysical::ProcessControl_, PATCH_JUMP); - InjectHook(0x496F10, &CPhysical::ProcessShift_, PATCH_JUMP); - InjectHook(0x4961A0, &CPhysical::ProcessCollision_, PATCH_JUMP); - InjectHook(0x49F790, &CPhysical::ProcessEntityCollision_, PATCH_JUMP); + InjectHook(0x495130, &CPhysical_::dtor, PATCH_JUMP); + InjectHook(0x4951F0, &CPhysical_::Add_, PATCH_JUMP); + InjectHook(0x4954B0, &CPhysical_::Remove_, PATCH_JUMP); + InjectHook(0x495540, &CPhysical_::RemoveAndAdd, PATCH_JUMP); + InjectHook(0x495F10, &CPhysical_::ProcessControl_, PATCH_JUMP); + InjectHook(0x496F10, &CPhysical_::ProcessShift_, PATCH_JUMP); + InjectHook(0x4961A0, &CPhysical_::ProcessCollision_, PATCH_JUMP); + InjectHook(0x49F790, &CPhysical_::ProcessEntityCollision_, PATCH_JUMP); InjectHook(0x4958F0, &CPhysical::AddToMovingList, PATCH_JUMP); InjectHook(0x495940, &CPhysical::RemoveFromMovingList, PATCH_JUMP); InjectHook(0x497180, &CPhysical::AddCollisionRecord, PATCH_JUMP); diff --git a/src/entities/Physical.h b/src/entities/Physical.h index 81d3d649..c1f9f1d9 100644 --- a/src/entities/Physical.h +++ b/src/entities/Physical.h @@ -3,12 +3,13 @@ #include "Lists.h" #include "Timer.h" #include "Entity.h" -#include "Treadable.h" enum { PHYSICAL_MAX_COLLISIONRECORDS = 6 }; +class CTreadable; + class CPhysical : public CEntity { public: @@ -65,13 +66,14 @@ public: ~CPhysical(void); // from CEntity - virtual void Add(void); - virtual void Remove(void); - virtual CRect GetBoundRect(void); - virtual void ProcessControl(void); + void Add(void); + void Remove(void); + CRect GetBoundRect(void); + void ProcessControl(void); + void ProcessShift(void); + void ProcessCollision(void); + virtual int32 ProcessEntityCollision(CEntity *ent, CColPoint *point); - virtual void ProcessShift(void); - virtual void ProcessCollision(void); void RemoveAndAdd(void); void AddToMovingList(void); @@ -137,15 +139,5 @@ public: bool ProcessCollisionSectorList(CPtrList *lists); bool CheckCollision(void); bool CheckCollision_SimpleCar(void); - - // to make patching virtual functions possible - void dtor(void) { this->CPhysical::~CPhysical(); } - void Add_(void) { CPhysical::Add(); } - void Remove_(void) { CPhysical::Remove(); } - CRect GetBoundRect_(void) { return CPhysical::GetBoundRect(); } - void ProcessControl_(void) { CPhysical::ProcessControl(); } - void ProcessShift_(void) { CPhysical::ProcessShift(); } - void ProcessCollision_(void) { CPhysical::ProcessCollision(); } - int32 ProcessEntityCollision_(CEntity *ent, CColPoint *point) { return CPhysical::ProcessEntityCollision(ent, point); } }; static_assert(sizeof(CPhysical) == 0x128, "CPhysical: error"); diff --git a/src/entities/Treadable.cpp b/src/entities/Treadable.cpp index 230d1633..ea949f00 100644 --- a/src/entities/Treadable.cpp +++ b/src/entities/Treadable.cpp @@ -7,6 +7,12 @@ void *CTreadable::operator new(size_t sz) { return CPools::GetTreadablePool()->New(); } void CTreadable::operator delete(void *p, size_t sz) { CPools::GetTreadablePool()->Delete((CTreadable*)p); } +class CTreadable_ : public CTreadable +{ +public: + void dtor(void) { CTreadable::~CTreadable(); } +}; + STARTPATCHES - InjectHook(0x405A10, &CTreadable::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x405A10, &CTreadable_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/entities/Treadable.h b/src/entities/Treadable.h index 2194638d..d82ff52b 100644 --- a/src/entities/Treadable.h +++ b/src/entities/Treadable.h @@ -11,7 +11,6 @@ public: int16 m_nodeIndicesCars[12]; int16 m_nodeIndicesPeds[12]; - virtual bool GetIsATreadable(void) { return true; } - void dtor(void) { this->CTreadable::~CTreadable(); } + bool GetIsATreadable(void) { return true; } }; static_assert(sizeof(CTreadable) == 0x94, "CTreadable: error"); diff --git a/src/modelinfo/BaseModelInfo.cpp b/src/modelinfo/BaseModelInfo.cpp index 37f94c93..830ead51 100644 --- a/src/modelinfo/BaseModelInfo.cpp +++ b/src/modelinfo/BaseModelInfo.cpp @@ -101,9 +101,15 @@ CBaseModelInfo::Get2dEffect(int n) } +class CBaseModelInfo_ : public CBaseModelInfo +{ +public: + void Shutdown_(void) { CBaseModelInfo::Shutdown(); } +}; STARTPATCHES // can't easily replace ctor at 4F6A50 - InjectHook(0x4F6A90, &CBaseModelInfo::Shutdown_, PATCH_JUMP); + InjectHook(0x4F6A90, &CBaseModelInfo_::Shutdown_, PATCH_JUMP); + InjectHook(0x4F6AC0, &CBaseModelInfo::DeleteCollisionModel, PATCH_JUMP); InjectHook(0x4F6B70, &CBaseModelInfo::ClearTexDictionary, PATCH_JUMP); InjectHook(0x4F6BA0, &CBaseModelInfo::AddRef, PATCH_JUMP); diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h index da72990f..a9bafb64 100644 --- a/src/modelinfo/BaseModelInfo.h +++ b/src/modelinfo/BaseModelInfo.h @@ -62,8 +62,6 @@ public: void Init2dEffects(void); void Add2dEffect(C2dEffect *fx); C2dEffect *Get2dEffect(int n); - - void Shutdown_(void) { this->CBaseModelInfo::Shutdown(); } }; static_assert(sizeof(CBaseModelInfo) == 0x30, "CBaseModelInfo: error"); diff --git a/src/modelinfo/ClumpModelInfo.cpp b/src/modelinfo/ClumpModelInfo.cpp index 24deed38..d666313b 100644 --- a/src/modelinfo/ClumpModelInfo.cpp +++ b/src/modelinfo/ClumpModelInfo.cpp @@ -139,12 +139,22 @@ CClumpModelInfo::GetFrameFromId(RpClump *clump, int32 id) } +class CClumpModelInfo_ : public CClumpModelInfo +{ +public: + void DeleteRwObject_(void) { this->CClumpModelInfo::DeleteRwObject(); } + RwObject *CreateInstance_1(void) { return CClumpModelInfo::CreateInstance(); } + RwObject *CreateInstance_2(RwMatrix *m) { return CClumpModelInfo::CreateInstance(m); } + RwObject *GetRwObject_(void) { return CClumpModelInfo::GetRwObject(); } + void SetClump_(RpClump *clump) { CClumpModelInfo::SetClump(clump); } +}; + STARTPATCHES - InjectHook(0x4F8800, &CClumpModelInfo::DeleteRwObject_, PATCH_JUMP); - InjectHook(0x4F8920, &CClumpModelInfo::CreateInstance_1, PATCH_JUMP); - InjectHook(0x4F88A0, &CClumpModelInfo::CreateInstance_2, PATCH_JUMP); - InjectHook(0x50C1C0, &CClumpModelInfo::GetRwObject_, PATCH_JUMP); - InjectHook(0x4F8830, &CClumpModelInfo::SetClump_, PATCH_JUMP); + InjectHook(0x4F8800, &CClumpModelInfo_::DeleteRwObject_, PATCH_JUMP); + InjectHook(0x4F8920, &CClumpModelInfo_::CreateInstance_1, PATCH_JUMP); + InjectHook(0x4F88A0, &CClumpModelInfo_::CreateInstance_2, PATCH_JUMP); + InjectHook(0x50C1C0, &CClumpModelInfo_::GetRwObject_, PATCH_JUMP); + InjectHook(0x4F8830, &CClumpModelInfo_::SetClump_, PATCH_JUMP); InjectHook(0x4F8940, &CClumpModelInfo::SetAtomicRendererCB, PATCH_JUMP); InjectHook(0x4F8960, &CClumpModelInfo::FindFrameFromNameCB, PATCH_JUMP); InjectHook(0x4F8A10, &CClumpModelInfo::FindFrameFromNameWithoutIdCB, PATCH_JUMP); diff --git a/src/modelinfo/ClumpModelInfo.h b/src/modelinfo/ClumpModelInfo.h index 909d241b..d491bdb9 100644 --- a/src/modelinfo/ClumpModelInfo.h +++ b/src/modelinfo/ClumpModelInfo.h @@ -49,12 +49,5 @@ public: static void FillFrameArray(RpClump *clump, RwFrame **frames); static RwFrame *FillFrameArrayCB(RwFrame *frame, void *data); static RwFrame *GetFrameFromId(RpClump *clump, int32 id); - - - void DeleteRwObject_(void) { this->CClumpModelInfo::DeleteRwObject(); } - RwObject *CreateInstance_1(void) { return this->CClumpModelInfo::CreateInstance(); } - RwObject *CreateInstance_2(RwMatrix *m) { return this->CClumpModelInfo::CreateInstance(m); } - RwObject *GetRwObject_(void) { return this->CClumpModelInfo::GetRwObject(); } - void SetClump_(RpClump *clump) { this->CClumpModelInfo::SetClump(clump); } }; static_assert(sizeof(CClumpModelInfo) == 0x34, "CClumpModelInfo: error"); diff --git a/src/modelinfo/MloInstance.cpp b/src/modelinfo/MloInstance.cpp deleted file mode 100644 index dbd83727..00000000 --- a/src/modelinfo/MloInstance.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "common.h" -#include "patcher.h" -#include "MloInstance.h" - -STARTPATCHES -InjectHook(0x50BE90, &CMloInstance::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file diff --git a/src/modelinfo/MloInstance.h b/src/modelinfo/MloInstance.h deleted file mode 100644 index 00afc379..00000000 --- a/src/modelinfo/MloInstance.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "Placeable.h" - -class CMloInstance : CPlaceable -{ -public: - void dtor() { this->CMloInstance::~CMloInstance(); } -}; \ No newline at end of file diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp index 775148c9..747cbc99 100644 --- a/src/modelinfo/PedModelInfo.cpp +++ b/src/modelinfo/PedModelInfo.cpp @@ -189,9 +189,17 @@ CPedModelInfo::CreateHitColModel(void) m_hitColModel = colmodel; } + +class CPedModelInfo_ : public CPedModelInfo +{ +public: + void DeleteRwObject_(void) { CPedModelInfo::DeleteRwObject(); } + void SetClump_(RpClump *clump) { CPedModelInfo::SetClump(clump); } +}; + STARTPATCHES - InjectHook(0x510210, &CPedModelInfo::SetClump_, PATCH_JUMP); - InjectHook(0x510280, &CPedModelInfo::DeleteRwObject_, PATCH_JUMP); + InjectHook(0x510210, &CPedModelInfo_::SetClump_, PATCH_JUMP); + InjectHook(0x510280, &CPedModelInfo_::DeleteRwObject_, PATCH_JUMP); InjectHook(0x510390, &CPedModelInfo::SetLowDetailClump, PATCH_JUMP); InjectHook(0x5104D0, &CPedModelInfo::CreateHitColModel, PATCH_JUMP); ENDPATCHES diff --git a/src/modelinfo/PedModelInfo.h b/src/modelinfo/PedModelInfo.h index 7be2c195..bec46b4e 100644 --- a/src/modelinfo/PedModelInfo.h +++ b/src/modelinfo/PedModelInfo.h @@ -39,9 +39,5 @@ public: void SetLowDetailClump(RpClump*); void CreateHitColModel(void); CColModel *GetHitColModel(void) { return m_hitColModel; } - - - void DeleteRwObject_(void) { this->CPedModelInfo::DeleteRwObject(); } - void SetClump_(RpClump *clump) { this->CPedModelInfo::SetClump(clump); } }; static_assert(sizeof(CPedModelInfo) == 0x54, "CPedModelInfo: error"); diff --git a/src/modelinfo/SimpleModelInfo.cpp b/src/modelinfo/SimpleModelInfo.cpp index ea7a3f9e..dd5010fa 100644 --- a/src/modelinfo/SimpleModelInfo.cpp +++ b/src/modelinfo/SimpleModelInfo.cpp @@ -154,12 +154,20 @@ CSimpleModelInfo::SetupBigBuilding(void) } } +class CSimpleModelInfo_ : public CSimpleModelInfo +{ +public: + void DeleteRwObject_(void) { CSimpleModelInfo::DeleteRwObject(); } + RwObject *CreateInstance_1(void) { return CSimpleModelInfo::CreateInstance(); } + RwObject *CreateInstance_2(RwMatrix *m) { return CSimpleModelInfo::CreateInstance(m); } + RwObject *GetRwObject_(void) { return CSimpleModelInfo::GetRwObject(); } +}; STARTPATCHES - InjectHook(0x5179B0, &CSimpleModelInfo::DeleteRwObject_, PATCH_JUMP); - InjectHook(0x517B60, &CSimpleModelInfo::CreateInstance_1, PATCH_JUMP); - InjectHook(0x517AC0, &CSimpleModelInfo::CreateInstance_2, PATCH_JUMP); - InjectHook(0x4A9BA0, &CSimpleModelInfo::GetRwObject_, PATCH_JUMP); + InjectHook(0x5179B0, &CSimpleModelInfo_::DeleteRwObject_, PATCH_JUMP); + InjectHook(0x517B60, &CSimpleModelInfo_::CreateInstance_1, PATCH_JUMP); + InjectHook(0x517AC0, &CSimpleModelInfo_::CreateInstance_2, PATCH_JUMP); + InjectHook(0x4A9BA0, &CSimpleModelInfo_::GetRwObject_, PATCH_JUMP); InjectHook(0x517990, &CSimpleModelInfo::Init, PATCH_JUMP); InjectHook(0x517C60, &CSimpleModelInfo::IncreaseAlpha, PATCH_JUMP); InjectHook(0x517950, &CSimpleModelInfo::SetAtomic, PATCH_JUMP); diff --git a/src/modelinfo/SimpleModelInfo.h b/src/modelinfo/SimpleModelInfo.h index d5b572a6..35d48669 100644 --- a/src/modelinfo/SimpleModelInfo.h +++ b/src/modelinfo/SimpleModelInfo.h @@ -48,10 +48,5 @@ public: return (CSimpleModelInfo*)m_atomics[2]; } void SetRelatedModel(CSimpleModelInfo *m){ m_atomics[2] = (RpAtomic*)m; } - - void DeleteRwObject_(void) { this->CSimpleModelInfo::DeleteRwObject(); } - RwObject *CreateInstance_1(void) { return this->CSimpleModelInfo::CreateInstance(); } - RwObject *CreateInstance_2(RwMatrix *m) { return this->CSimpleModelInfo::CreateInstance(m); } - RwObject *GetRwObject_(void) { return this->CSimpleModelInfo::GetRwObject(); } }; static_assert(sizeof(CSimpleModelInfo) == 0x4C, "CSimpleModelInfo: error"); diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp index f112d546..810ed042 100644 --- a/src/modelinfo/VehicleModelInfo.cpp +++ b/src/modelinfo/VehicleModelInfo.cpp @@ -1098,10 +1098,18 @@ CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(int id) return n - 1; } +class CVehicleModelInfo_ : public CVehicleModelInfo +{ +public: + void DeleteRwObject_(void) { CVehicleModelInfo::DeleteRwObject(); } + RwObject *CreateInstance_(void) { return CVehicleModelInfo::CreateInstance(); } + void SetClump_(RpClump *clump) { CVehicleModelInfo::SetClump(clump); } +}; + STARTPATCHES - InjectHook(0x51FDC0, &CVehicleModelInfo::DeleteRwObject_, PATCH_JUMP); - InjectHook(0x51FCB0, &CVehicleModelInfo::CreateInstance_, PATCH_JUMP); - InjectHook(0x51FC60, &CVehicleModelInfo::SetClump_, PATCH_JUMP); + InjectHook(0x51FDC0, &CVehicleModelInfo_::DeleteRwObject_, PATCH_JUMP); + InjectHook(0x51FCB0, &CVehicleModelInfo_::CreateInstance_, PATCH_JUMP); + InjectHook(0x51FC60, &CVehicleModelInfo_::SetClump_, PATCH_JUMP); InjectHook(0x51FE10, &CVehicleModelInfo::CollapseFramesCB, PATCH_JUMP); InjectHook(0x51FE50, &CVehicleModelInfo::MoveObjectsCB, PATCH_JUMP); diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h index 2e2f1be2..f66bc21f 100644 --- a/src/modelinfo/VehicleModelInfo.h +++ b/src/modelinfo/VehicleModelInfo.h @@ -10,6 +10,7 @@ enum { }; enum { + ATOMIC_FLAG_NONE = 0x0, ATOMIC_FLAG_OK = 0x1, ATOMIC_FLAG_DAM = 0x2, ATOMIC_FLAG_LEFT = 0x4, @@ -131,9 +132,5 @@ public: static void ShutdownEnvironmentMaps(void); static int GetMaximumNumberOfPassengersFromNumberOfDoors(int id); - - void DeleteRwObject_(void) { this->CVehicleModelInfo::DeleteRwObject(); } - RwObject *CreateInstance_(void) { return this->CVehicleModelInfo::CreateInstance(); } - void SetClump_(RpClump *clump) { this->CVehicleModelInfo::SetClump(clump); } }; static_assert(sizeof(CVehicleModelInfo) == 0x1F8, "CVehicleModelInfo: error"); diff --git a/src/objects/CutsceneHead.cpp b/src/objects/CutsceneHead.cpp index a9c47777..c423d0b8 100644 --- a/src/objects/CutsceneHead.cpp +++ b/src/objects/CutsceneHead.cpp @@ -109,10 +109,19 @@ CCutsceneHead::PlayAnimation(const char *animName) } } +class CCutsceneHead_ : public CCutsceneHead +{ +public: + void CreateRwObject_(void) { CCutsceneHead::CreateRwObject(); } + void DeleteRwObject_(void) { CCutsceneHead::DeleteRwObject(); } + void ProcessControl_(void) { CCutsceneHead::ProcessControl(); } + void Render_(void) { CCutsceneHead::Render(); } +}; + STARTPATCHES - InjectHook(0x4BA650, &CCutsceneHead::CreateRwObject_, PATCH_JUMP); - InjectHook(0x4BA690, &CCutsceneHead::DeleteRwObject_, PATCH_JUMP); - InjectHook(0x4BA760, &CCutsceneHead::ProcessControl_, PATCH_JUMP); - InjectHook(0x4BA800, &CCutsceneHead::Render_, PATCH_JUMP); + InjectHook(0x4BA650, &CCutsceneHead_::CreateRwObject_, PATCH_JUMP); + InjectHook(0x4BA690, &CCutsceneHead_::DeleteRwObject_, PATCH_JUMP); + InjectHook(0x4BA760, &CCutsceneHead_::ProcessControl_, PATCH_JUMP); + InjectHook(0x4BA800, &CCutsceneHead_::Render_, PATCH_JUMP); InjectHook(0x4BA6A0, &CCutsceneHead::PlayAnimation, PATCH_JUMP); ENDPATCHES diff --git a/src/objects/CutsceneHead.h b/src/objects/CutsceneHead.h index de4f011f..52b66ede 100644 --- a/src/objects/CutsceneHead.h +++ b/src/objects/CutsceneHead.h @@ -15,10 +15,5 @@ public: void Render(void); void PlayAnimation(const char *animName); - - void CreateRwObject_(void) { CCutsceneHead::CreateRwObject(); } - void DeleteRwObject_(void) { CCutsceneHead::DeleteRwObject(); } - void ProcessControl_(void) { CCutsceneHead::ProcessControl(); } - void Render_(void) { CCutsceneHead::Render(); } }; static_assert(sizeof(CCutsceneHead) == 0x19C, "CCutsceneHead: error"); diff --git a/src/objects/CutsceneObject.cpp b/src/objects/CutsceneObject.cpp index ede5be5b..2f667a5d 100644 --- a/src/objects/CutsceneObject.cpp +++ b/src/objects/CutsceneObject.cpp @@ -89,12 +89,24 @@ CCutsceneObject::RemoveLighting(bool reset) CRenderer::RemoveVehiclePedLights(this, reset); } +class CCutsceneObject_ : public CCutsceneObject +{ +public: + void dtor(void) { this->CCutsceneObject::~CCutsceneObject(); } + void SetModelIndex_(uint32 id) { CCutsceneObject::SetModelIndex(id); } + void ProcessControl_(void) { CCutsceneObject::ProcessControl(); } + void PreRender_(void) { CCutsceneObject::PreRender(); } + void Render_(void) { CCutsceneObject::Render(); } + bool SetupLighting_(void) { return CCutsceneObject::SetupLighting(); } + void RemoveLighting_(bool reset) { CCutsceneObject::RemoveLighting(reset); } +}; + STARTPATCHES - InjectHook(0x4BA960, &CCutsceneObject::dtor, PATCH_JUMP); - InjectHook(0x4BA980, &CCutsceneObject::SetModelIndex_, PATCH_JUMP); - InjectHook(0x4BA9C0, &CCutsceneObject::ProcessControl_, PATCH_JUMP); - InjectHook(0x4BAA40, &CCutsceneObject::PreRender_, PATCH_JUMP); - InjectHook(0x4BAAA0, &CCutsceneObject::Render_, PATCH_JUMP); - InjectHook(0x4A7E70, &CCutsceneObject::SetupLighting_, PATCH_JUMP); - InjectHook(0x4A7F00, &CCutsceneObject::RemoveLighting_, PATCH_JUMP); + InjectHook(0x4BA960, &CCutsceneObject_::dtor, PATCH_JUMP); + InjectHook(0x4BA980, &CCutsceneObject_::SetModelIndex_, PATCH_JUMP); + InjectHook(0x4BA9C0, &CCutsceneObject_::ProcessControl_, PATCH_JUMP); + InjectHook(0x4BAA40, &CCutsceneObject_::PreRender_, PATCH_JUMP); + InjectHook(0x4BAAA0, &CCutsceneObject_::Render_, PATCH_JUMP); + InjectHook(0x4A7E70, &CCutsceneObject_::SetupLighting_, PATCH_JUMP); + InjectHook(0x4A7F00, &CCutsceneObject_::RemoveLighting_, PATCH_JUMP); ENDPATCHES diff --git a/src/objects/CutsceneObject.h b/src/objects/CutsceneObject.h index 9360651e..31c3a528 100644 --- a/src/objects/CutsceneObject.h +++ b/src/objects/CutsceneObject.h @@ -7,19 +7,11 @@ class CCutsceneObject : public CObject public: CCutsceneObject(void); - virtual void SetModelIndex(uint32 id); - virtual void ProcessControl(void); - virtual void PreRender(void); - virtual void Render(void); - virtual bool SetupLighting(void); - virtual void RemoveLighting(bool reset); - - void dtor(void) { this->CCutsceneObject::~CCutsceneObject(); } - void SetModelIndex_(uint32 id) { CCutsceneObject::SetModelIndex(id); } - void ProcessControl_(void) { CCutsceneObject::ProcessControl(); } - void PreRender_(void) { CCutsceneObject::PreRender(); } - void Render_(void) { CCutsceneObject::Render(); } - bool SetupLighting_(void) { return CCutsceneObject::SetupLighting(); } - void RemoveLighting_(bool reset) { CCutsceneObject::RemoveLighting(reset); } + void SetModelIndex(uint32 id); + void ProcessControl(void); + void PreRender(void); + void Render(void); + bool SetupLighting(void); + void RemoveLighting(bool reset); }; static_assert(sizeof(CCutsceneObject) == 0x198, "CCutsceneObject: error"); diff --git a/src/objects/DummyObject.cpp b/src/objects/DummyObject.cpp index 1e4b2ae0..41b15129 100644 --- a/src/objects/DummyObject.cpp +++ b/src/objects/DummyObject.cpp @@ -12,6 +12,12 @@ CDummyObject::CDummyObject(CObject *obj) m_level = obj->m_level; } +class CDummyObject_ : public CDummyObject +{ +public: + void dtor(void) { CDummyObject::~CDummyObject(); } +}; + STARTPATCHES - InjectHook(0x4BAB70, &CDummyObject::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x4BAB70, &CDummyObject_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/objects/DummyObject.h b/src/objects/DummyObject.h index 10554bdd..d4dce609 100644 --- a/src/objects/DummyObject.h +++ b/src/objects/DummyObject.h @@ -9,6 +9,5 @@ class CDummyObject : public CDummy public: CDummyObject(void) {} CDummyObject(CObject *obj); - void dtor(void) { this->CDummyObject::~CDummyObject(); } }; static_assert(sizeof(CDummyObject) == 0x68, "CDummyObject: error"); diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 6712d77b..e13a2ad0 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -87,7 +87,14 @@ CObject::RemoveLighting(bool reset) WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); } +class CObject_ : public CObject +{ +public: + void dtor(void) { this->CObject::~CObject(); } + void Render_(void) { CObject::Render(); } +}; + STARTPATCHES - InjectHook(0x4BAE00, &CObject::dtor, PATCH_JUMP); - InjectHook(0x4BB1E0, &CObject::Render_, PATCH_JUMP); + InjectHook(0x4BAE00, &CObject_::dtor, PATCH_JUMP); + InjectHook(0x4BB1E0, &CObject_::Render_, PATCH_JUMP); ENDPATCHES diff --git a/src/objects/Object.h b/src/objects/Object.h index de4c8e05..8afc4d0a 100644 --- a/src/objects/Object.h +++ b/src/objects/Object.h @@ -74,8 +74,5 @@ public: void ObjectDamage(float amount); static void DeleteAllTempObjectInArea(CVector, float); - - void dtor(void) { this->CObject::~CObject(); } - void Render_(void) { CObject::Render(); } }; static_assert(sizeof(CObject) == 0x198, "CObject: error"); diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp index cf6e84bf..25f223e1 100644 --- a/src/objects/ParticleObject.cpp +++ b/src/objects/ParticleObject.cpp @@ -18,6 +18,12 @@ void CParticleObject::UpdateAll() ((void (__cdecl *)())0x4BCA30)(); } +class CParticleObject_ : public CParticleObject +{ +public: + void dtor() { CParticleObject::~CParticleObject(); } +}; + STARTPATCHES - InjectHook(0x4BC420, &CParticleObject::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x4BC420, &CParticleObject_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/objects/ParticleObject.h b/src/objects/ParticleObject.h index def7b7de..6ec090e7 100644 --- a/src/objects/ParticleObject.h +++ b/src/objects/ParticleObject.h @@ -34,6 +34,4 @@ public: static void AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, bool remove); static void Initialise(); static void UpdateAll(); - - void dtor() { this->CParticleObject::~CParticleObject(); } }; diff --git a/src/objects/Projectile.cpp b/src/objects/Projectile.cpp index e21323de..c6c2d6e1 100644 --- a/src/objects/Projectile.cpp +++ b/src/objects/Projectile.cpp @@ -2,6 +2,12 @@ #include "patcher.h" #include "Projectile.h" +class CProjectile_ : public CProjectile +{ +public: + void dtor(void) { CProjectile::~CProjectile(); } +}; + STARTPATCHES - InjectHook(0x4BFED0, &CProjectile::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x4BFED0, &CProjectile_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/objects/Projectile.h b/src/objects/Projectile.h index a8e826b6..4d5041f8 100644 --- a/src/objects/Projectile.h +++ b/src/objects/Projectile.h @@ -7,5 +7,4 @@ class CProjectile : public CObject { public: - void dtor(void) { this->CProjectile::~CProjectile(); } }; diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp index a4881e71..cf8a0580 100644 --- a/src/peds/CivilianPed.cpp +++ b/src/peds/CivilianPed.cpp @@ -13,7 +13,14 @@ CCivilianPed::CCivilianPed(int pedtype, int mi) : CPed(pedtype) } } +class CCivilianPed_ : public CCivilianPed +{ +public: + CCivilianPed *ctor(int pedtype, int mi) { return ::new (this) CCivilianPed(pedtype, mi); }; + void dtor(void) { CCivilianPed::~CCivilianPed(); } +}; + STARTPATCHES - InjectHook(0x4BFF30, &CCivilianPed::ctor, PATCH_JUMP); - InjectHook(0x4BFFC0, &CCivilianPed::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x4BFF30, &CCivilianPed_::ctor, PATCH_JUMP); + InjectHook(0x4BFFC0, &CCivilianPed_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/peds/CivilianPed.h b/src/peds/CivilianPed.h index 8d004ad7..14859a5c 100644 --- a/src/peds/CivilianPed.h +++ b/src/peds/CivilianPed.h @@ -6,11 +6,8 @@ class CCivilianPed : public CPed { public: CCivilianPed(int, int); - virtual ~CCivilianPed(void) { } + ~CCivilianPed(void) { } - virtual void ProcessControl(void); - - CCivilianPed *ctor(int pedtype, int mi) { return ::new (this) CCivilianPed(pedtype, mi); }; - void dtor(void) { this->CCivilianPed::~CCivilianPed(); } + void ProcessControl(void); }; static_assert(sizeof(CCivilianPed) == 0x53C, "CCivilianPed: error"); diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp index 041185ee..0ac0473f 100644 --- a/src/peds/CopPed.cpp +++ b/src/peds/CopPed.cpp @@ -9,6 +9,12 @@ CCopPed::~CCopPed() WRAPPER void CCopPed::ClearPursuit(void) { EAXJMP(0x4C28C0); } +class CCopPed_ : public CCopPed +{ +public: + void dtor(void) { CCopPed::~CCopPed(); } +}; + STARTPATCHES - InjectHook(0x4C13E0, &CCopPed::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x4C13E0, &CCopPed_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/peds/CopPed.h b/src/peds/CopPed.h index b938dfc2..5827f9bc 100644 --- a/src/peds/CopPed.h +++ b/src/peds/CopPed.h @@ -65,7 +65,6 @@ public: int8 field_1367; ~CCopPed(); - void dtor(void) { this->CCopPed::~CCopPed(); } void ClearPursuit(void); }; diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp index 7b847896..664bd6f6 100644 --- a/src/peds/EmergencyPed.cpp +++ b/src/peds/EmergencyPed.cpp @@ -2,6 +2,12 @@ #include "patcher.h" #include "EmergencyPed.h" +class CEmergencyPed_ : public CEmergencyPed +{ +public: + void dtor(void) { CEmergencyPed::~CEmergencyPed(); } +}; + STARTPATCHES -InjectHook(0x4C2EF0, &CEmergencyPed::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x4C2EF0, &CEmergencyPed_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/peds/EmergencyPed.h b/src/peds/EmergencyPed.h index fa07f3ee..f21996e8 100644 --- a/src/peds/EmergencyPed.h +++ b/src/peds/EmergencyPed.h @@ -7,7 +7,5 @@ class CEmergencyPed : public CPed public: // 0x53C uint8 stuff[24]; - - void dtor(void) { this->CEmergencyPed::~CEmergencyPed(); } }; static_assert(sizeof(CEmergencyPed) == 0x554, "CEmergencyPed: error"); diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 016fea2f..20f26688 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -2893,9 +2893,28 @@ WRAPPER void CPed::PedLandCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0 WRAPPER void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4C6580); } WRAPPER void CPed::RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D6550); } +class CPed_ : public CPed +{ +public: + CPed* ctor(uint32 pedType) { return ::new (this) CPed(pedType); } + void dtor(void) { CPed::~CPed(); } + + void SetModelIndex_(uint32 mi) { CPed::SetModelIndex(mi); } + void FlagToDestroyWhenNextProcessed_(void) { CPed::FlagToDestroyWhenNextProcessed(); } + bool SetupLighting_(void) { return CPed::SetupLighting(); } + void RemoveLighting_(bool reset) { CPed::RemoveLighting(reset); } + void Teleport_(CVector pos) { CPed::Teleport(pos); } +}; + STARTPATCHES - InjectHook(0x4C41C0, &CPed::ctor, PATCH_JUMP); - InjectHook(0x4C50D0, &CPed::dtor, PATCH_JUMP); + InjectHook(0x4C41C0, &CPed_::ctor, PATCH_JUMP); + InjectHook(0x4C50D0, &CPed_::dtor, PATCH_JUMP); + InjectHook(0x4C52A0, &CPed_::SetModelIndex_, PATCH_JUMP); + InjectHook(0x4D6570, &CPed_::FlagToDestroyWhenNextProcessed_, PATCH_JUMP); + InjectHook(0x4A7D30, &CPed_::SetupLighting_, PATCH_JUMP); + InjectHook(0x4A7DC0, &CPed_::RemoveLighting_, PATCH_JUMP); + InjectHook(0x4D3E70, &CPed_::Teleport_, PATCH_JUMP); + InjectHook(0x4CF8F0, &CPed::AddWeaponModel, PATCH_JUMP); InjectHook(0x4C6AA0, &CPed::AimGun, PATCH_JUMP); InjectHook(0x4EB470, &CPed::ApplyHeadShot, PATCH_JUMP); @@ -2926,11 +2945,6 @@ STARTPATCHES InjectHook(0x4CC6C0, &CPed::PlayFootSteps, PATCH_JUMP); InjectHook(0x4C5350, &CPed::BuildPedLists, PATCH_JUMP); InjectHook(0x4CF9B0, &CPed::GiveWeapon, PATCH_JUMP); - InjectHook(0x4C52A0, &CPed::SetModelIndex_, PATCH_JUMP); - InjectHook(0x4D6570, &CPed::FlagToDestroyWhenNextProcessed_, PATCH_JUMP); - InjectHook(0x4A7D30, &CPed::SetupLighting_, PATCH_JUMP); - InjectHook(0x4A7DC0, &CPed::RemoveLighting_, PATCH_JUMP); - InjectHook(0x4D3E70, &CPed::Teleport_, PATCH_JUMP); InjectHook(0x4C7EA0, &CPed::CalculateNewOrientation, PATCH_JUMP); InjectHook(0x4C78F0, &CPed::WorkOutHeadingForMovingFirstPerson, PATCH_JUMP); InjectHook(0x4C73F0, &CPed::CalculateNewVelocity, PATCH_JUMP); diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 0493eeee..6b04404b 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -399,22 +399,20 @@ public: static void operator delete(void*, int); CPed(uint32 pedType); - virtual ~CPed(void); + ~CPed(void); + + void SetModelIndex(uint32 mi); + void ProcessControl(void); + void Teleport(CVector); + void PreRender(void); + void Render(void); + bool SetupLighting(void); + void RemoveLighting(bool); + void FlagToDestroyWhenNextProcessed(void); + int32 ProcessEntityCollision(CEntity*, CColPoint*); - virtual void SetModelIndex(uint32 mi); - virtual void ProcessControl(void); - virtual void Teleport(CVector); - virtual void PreRender(void); - virtual void Render(void); - virtual bool SetupLighting(void); - virtual void RemoveLighting(bool); - virtual void FlagToDestroyWhenNextProcessed(void); - virtual int32 ProcessEntityCollision(CEntity*, CColPoint*); virtual void SetMoveAnim(void); - CPed* ctor(uint32 pedType) { return ::new (this) CPed(pedType); } - void dtor(void) { this->CPed::~CPed(); } - void AddWeaponModel(int id); void AimGun(void); void KillPedWithCar(CVehicle *veh, float impulse); @@ -465,7 +463,7 @@ public: void RegisterThreatWithGangPeds(CEntity*); bool TurnBody(void); void Chat(void); - void MakeChangesForNewWeapon(int8); + void MakeChangesForNewWeapon(int8); // Static methods @@ -545,13 +543,6 @@ public: PedState GetPedState(void) { return m_nPedState; } void SetPedState(PedState state) { m_nPedState = state; } - // to make patching virtual functions possible - void SetModelIndex_(uint32 mi) { CPed::SetModelIndex(mi); } - void FlagToDestroyWhenNextProcessed_(void) { CPed::FlagToDestroyWhenNextProcessed(); } - bool SetupLighting_(void) { return CPed::SetupLighting(); } - void RemoveLighting_(bool reset) { CPed::RemoveLighting(reset); } - void Teleport_(CVector pos) { CPed::Teleport(pos); } - // set by 0482:set_threat_reaction_range_multiplier opcode static uint16 &distanceMultToCountPedNear; diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 7eb01db0..07cb5541 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -21,8 +21,13 @@ void CPlayerPed::ClearWeaponTarget() ClearPointGunAt(); } -STARTPATCHES -InjectHook(0x4EFB30, &CPlayerPed::dtor, PATCH_JUMP); -InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP); +class CPlayerPed_ : public CPlayerPed +{ +public: + void dtor(void) { CPlayerPed::~CPlayerPed(); } +}; -ENDPATCHES \ No newline at end of file +STARTPATCHES + InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP); + InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP); +ENDPATCHES diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index 4f325da3..1a106b38 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -41,7 +41,6 @@ public: ~CPlayerPed(); - void dtor(void) { this->CPlayerPed::~CPlayerPed(); } void ReApplyMoveAnims(void); void ClearWeaponTarget(); }; diff --git a/src/render/Draw.cpp b/src/render/Draw.cpp index f825ba42..5a377214 100644 --- a/src/render/Draw.cpp +++ b/src/render/Draw.cpp @@ -29,6 +29,7 @@ CDraw::FindAspectRatio(void) switch (FrontEndMenuManager.m_PrefsUseWideScreen) { case AR_AUTO: return SCREEN_WIDTH / SCREEN_HEIGHT; + default: case AR_4_3: return 4.0f / 3.0f; case AR_16_9: diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 80131179..23fa8ba0 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -1,18 +1,316 @@ #include "common.h" #include "patcher.h" +#include "VisibilityPlugins.h" +#include "HandlingMgr.h" #include "Automobile.h" +bool &CAutomobile::m_sAllTaxiLights = *(bool*)0x95CD21; + +WRAPPER CAutomobile* CAutomobile::ctor(int, uint8) { EAXJMP(0x52C6B0); } + CAutomobile::CAutomobile(int mi, uint8 owner) { ctor(mi, owner); } -WRAPPER CAutomobile* CAutomobile::ctor(int, uint8) { EAXJMP(0x52C6B0); } -WRAPPER void CAutomobile::SetDoorDamage(int32, uint32, bool) { EAXJMP(0x530200); } -WRAPPER void CAutomobile::SetPanelDamage(int32, uint32, bool) { EAXJMP(0x5301A0); } -WRAPPER void CAutomobile::SetBumperDamage(int32, uint32, bool) { EAXJMP(0x530120); } +void +CAutomobile::SetModelIndex(uint32 id) +{ + CVehicle::SetModelIndex(id); + SetupModelNodes(); +} + +WRAPPER void CAutomobile::ProcessControl(void) { EAXJMP(0x531470); } +WRAPPER void CAutomobile::Teleport(CVector v) { EAXJMP(0x535180); } +WRAPPER void CAutomobile::PreRender(void) { EAXJMP(0x535B40); } +WRAPPER void CAutomobile::Render(void) { EAXJMP(0x539EA0); } + + +WRAPPER void CAutomobile::ProcessControlInputs(uint8) { EAXJMP(0x53B660); } + +void +CAutomobile::GetComponentWorldPosition(int32 component, CVector &pos) +{ + if(m_aCarNodes[component] == nil){ + printf("CarNode missing: %d %d\n", GetModelIndex(), component); + return; + } + RwMatrix *ltm = RwFrameGetLTM(m_aCarNodes[component]); + pos = *RwMatrixGetPos(ltm); +} + +bool +CAutomobile::IsComponentPresent(int32 comp) +{ + return m_aCarNodes[comp] != nil; +} + +void +CAutomobile::SetComponentRotation(int32 component, CVector rotation) +{ + CMatrix mat(RwFrameGetMatrix(m_aCarNodes[component])); + CVector pos = *mat.GetPosition(); + // BUG: all these set the whole matrix + mat.SetRotateX(DEGTORAD(rotation.x)); + mat.SetRotateY(DEGTORAD(rotation.y)); + mat.SetRotateZ(DEGTORAD(rotation.z)); + *mat.GetPosition() += pos; + mat.UpdateRW(); +} + +WRAPPER void CAutomobile::OpenDoor(int32, eDoors door, float) { EAXJMP(0x52E750); } +WRAPPER void CAutomobile::ProcessOpenDoor(uint32, uint32, float) { EAXJMP(0x52E910); } + +bool +CAutomobile::IsDoorReady(eDoors door) +{ + if(Doors[door].IsClosed() || IsDoorMissing(door)) + return true; + int doorflag = 0; + // TODO: enum? + switch(door){ + case DOOR_FRONT_LEFT: doorflag = 1; break; + case DOOR_FRONT_RIGHT: doorflag = 4; break; + case DOOR_REAR_LEFT: doorflag = 2; break; + case DOOR_REAR_RIGHT: doorflag = 8; break; + } + return (doorflag & m_nGettingInFlags) == 0; +} + +bool +CAutomobile::IsDoorFullyOpen(eDoors door) +{ + return Doors[door].IsFullyOpen() || IsDoorMissing(door); +} + +bool +CAutomobile::IsDoorClosed(eDoors door) +{ + return !!Doors[door].IsClosed(); +} + +bool +CAutomobile::IsDoorMissing(eDoors door) +{ + return Damage.GetDoorStatus(door) == DOOR_STATUS_MISSING; +} + +void +CAutomobile::RemoveRefsToVehicle(CEntity *ent) +{ + int i; + for(i = 0; i < 4; i++) + if(m_aGroundPhysical[i] == ent) + m_aGroundPhysical[i] = nil; +} + +WRAPPER void CAutomobile::BlowUpCar(CEntity *ent) { EAXJMP(0x53BC60); } +WRAPPER bool CAutomobile::SetUpWheelColModel(CColModel *colModel) { EAXJMP(0x53BF70); } +WRAPPER void CAutomobile::BurstTyre(uint8 tyre) { EAXJMP(0x53C0E0); } +WRAPPER bool CAutomobile::IsRoomForPedToLeaveCar(uint32, CVector *) { EAXJMP(0x53C5B0); } + +float +CAutomobile::GetHeightAboveRoad(void) +{ + return m_fHeightAboveRoad; +} + +WRAPPER void CAutomobile::PlayCarHorn(void) { EAXJMP(0x53C450); } + + + + + +WRAPPER void CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) { EAXJMP(0x530300); } + +void +CAutomobile::SetPanelDamage(int32 component, ePanels panel, bool noFlyingComponents) +{ + int status = Damage.GetPanelStatus(panel); + if(m_aCarNodes[component] == nil) + return; + if(status == PANEL_STATUS_SMASHED1){ + // show damaged part + SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_DAM); + }else if(status == PANEL_STATUS_MISSING){ + if(!noFlyingComponents) + SpawnFlyingComponent(component, COMPGROUP_PANEL); + // hide both + SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_NONE); + } +} + +void +CAutomobile::SetBumperDamage(int32 component, ePanels panel, bool noFlyingComponents) +{ + int status = Damage.GetPanelStatus(panel); + if(m_aCarNodes[component] == nil){ + printf("Trying to damage component %d of %s\n", + component, CModelInfo::GetModelInfo(GetModelIndex())->GetName()); + return; + } + if(status == PANEL_STATUS_SMASHED1){ + // show damaged part + SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_DAM); + }else if(status == PANEL_STATUS_MISSING){ + if(!noFlyingComponents) + SpawnFlyingComponent(component, COMPGROUP_BUMPER); + // hide both + SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_NONE); + } +} + +void +CAutomobile::SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents) +{ + int status = Damage.GetDoorStatus(door); + if(m_aCarNodes[component] == nil){ + printf("Trying to damage component %d of %s\n", + component, CModelInfo::GetModelInfo(GetModelIndex())->GetName()); + return; + } + + if(door == DOOR_BOOT && status == DOOR_STATUS_SWINGING && m_handling->Flags & HANDLING_NOSWING_BOOT){ + Damage.SetDoorStatus(DOOR_BOOT, DOOR_STATUS_MISSING); + status = DOOR_STATUS_MISSING; + } + + if(status == DOOR_STATUS_SMASHED){ + // show damaged part + SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_DAM); + }else if(status == DOOR_STATUS_SWINGING){ + // turn off angle cull for swinging doors + RwFrameForAllObjects(m_aCarNodes[component], CVehicleModelInfo::SetAtomicFlagCB, (void*)ATOMIC_FLAG_NOCULL); + }else if(status == DOOR_STATUS_MISSING){ + if(!noFlyingComponents){ + if(door == DOOR_BONNET) + SpawnFlyingComponent(component, COMPGROUP_BONNET); + else if(door == DOOR_BOOT) + SpawnFlyingComponent(component, COMPGROUP_BOOT); + else + SpawnFlyingComponent(component, COMPGROUP_DOOR); + } + // hide both + SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_NONE); + } +} + + +static RwObject* +SetVehicleAtomicVisibilityCB(RwObject *object, void *data) +{ + uint32 flags = (uint32)(uintptr)data; + RpAtomic *atomic = (RpAtomic*)object; + if((CVisibilityPlugins::GetAtomicId(atomic) & (ATOMIC_FLAG_OK|ATOMIC_FLAG_DAM)) == flags) + RpAtomicSetFlags(atomic, rpATOMICRENDER); + else + RpAtomicSetFlags(atomic, 0); + return object; +} + +void +CAutomobile::SetComponentVisibility(RwFrame *frame, uint32 flags) +{ + HideAllComps(); + m_veh_flagC2 = true; + RwFrameForAllObjects(frame, SetVehicleAtomicVisibilityCB, (void*)flags); +} + +void +CAutomobile::SetupModelNodes(void) +{ + int i; + for(i = 0; i < NUM_CAR_NODES; i++) + m_aCarNodes[i] = nil; + CClumpModelInfo::FillFrameArray((RpClump*)m_rwObject, m_aCarNodes); +} + +void +CAutomobile::SetTaxiLight(bool light) +{ + bTaxiLight = light; +} + +bool +CAutomobile::GetAllWheelsOffGround(void) +{ + return m_nWheelsOnGround == 0; +} + +void +CAutomobile::HideAllComps(void) +{ + // empty +} + +void +CAutomobile::ShowAllComps(void) +{ + // empty +} + +void +CAutomobile::ReduceHornCounter(void) +{ + if(m_nCarHornTimer != 0) + m_nCarHornTimer--; +} + +void +CAutomobile::SetAllTaxiLights(bool set) +{ + m_sAllTaxiLights = set; +} + +class CAutomobile_ : public CAutomobile +{ +public: + void dtor() { CAutomobile::~CAutomobile(); } + void SetModelIndex_(uint32 id) { CAutomobile::SetModelIndex(id); } + void ProcessControl_(void) { CAutomobile::ProcessControl(); } + void Teleport_(CVector v) { CAutomobile::Teleport(v); } + void PreRender_(void) { CAutomobile::PreRender(); } + void Render_(void) { CAutomobile::Render(); } + + void ProcessControlInputs_(uint8 x) { CAutomobile::ProcessControlInputs(x); } + void GetComponentWorldPosition_(int32 component, CVector &pos) { CAutomobile::GetComponentWorldPosition(component, pos); } + bool IsComponentPresent_(int32 component) { return CAutomobile::IsComponentPresent(component); } + void SetComponentRotation_(int32 component, CVector rotation) { CAutomobile::SetComponentRotation(component, rotation); } + void OpenDoor_(int32 component, eDoors door, float ratio) { CAutomobile::OpenDoor(component, door, ratio); } + void ProcessOpenDoor_(uint32 component, uint32 anim, float time) { CAutomobile::ProcessOpenDoor(component, anim, time); } + bool IsDoorReady_(eDoors door) { return CAutomobile::IsDoorReady(door); } + bool IsDoorFullyOpen_(eDoors door) { return CAutomobile::IsDoorFullyOpen(door); } + bool IsDoorClosed_(eDoors door) { return CAutomobile::IsDoorClosed(door); } + bool IsDoorMissing_(eDoors door) { return CAutomobile::IsDoorMissing(door); } + void RemoveRefsToVehicle_(CEntity *ent) { CAutomobile::RemoveRefsToVehicle(ent); } + void BlowUpCar_(CEntity *ent) { CAutomobile::BlowUpCar(ent); } + bool SetUpWheelColModel_(CColModel *colModel) { CAutomobile::SetUpWheelColModel(colModel); } + void BurstTyre_(uint8 tyre) { CAutomobile::BurstTyre(tyre); } + bool IsRoomForPedToLeaveCar_(uint32 door, CVector *pos) { return CAutomobile::IsRoomForPedToLeaveCar(door, pos); } + float GetHeightAboveRoad_(void) { return CAutomobile::GetHeightAboveRoad(); } + void PlayCarHorn_(void) { CAutomobile::PlayCarHorn(); } +}; STARTPATCHES - InjectHook(0x52D170, &CAutomobile::dtor, PATCH_JUMP); + InjectHook(0x52D170, &CAutomobile_::dtor, PATCH_JUMP); + InjectHook(0x52D190, &CAutomobile_::SetModelIndex_, PATCH_JUMP); + InjectHook(0x52E5F0, &CAutomobile_::GetComponentWorldPosition_, PATCH_JUMP); + InjectHook(0x52E660, &CAutomobile_::IsComponentPresent_, PATCH_JUMP); + InjectHook(0x52E680, &CAutomobile_::SetComponentRotation_, PATCH_JUMP); + InjectHook(0x52EF10, &CAutomobile_::IsDoorReady_, PATCH_JUMP); + InjectHook(0x52EF90, &CAutomobile_::IsDoorFullyOpen_, PATCH_JUMP); + InjectHook(0x52EFD0, &CAutomobile_::IsDoorClosed_, PATCH_JUMP); + InjectHook(0x52F000, &CAutomobile_::IsDoorMissing_, PATCH_JUMP); + InjectHook(0x53BF40, &CAutomobile_::RemoveRefsToVehicle_, PATCH_JUMP); + InjectHook(0x437690, &CAutomobile_::GetHeightAboveRoad_, PATCH_JUMP); + InjectHook(0x5301A0, &CAutomobile::SetPanelDamage, PATCH_JUMP); + InjectHook(0x530120, &CAutomobile::SetBumperDamage, PATCH_JUMP); + InjectHook(0x530200, &CAutomobile::SetDoorDamage, PATCH_JUMP); + InjectHook(0x5300E0, &CAutomobile::SetComponentVisibility, PATCH_JUMP); + InjectHook(0x52D1B0, &CAutomobile::SetupModelNodes, PATCH_JUMP); + InjectHook(0x53C420, &CAutomobile::SetTaxiLight, PATCH_JUMP); + InjectHook(0x53BC40, &CAutomobile::GetAllWheelsOffGround, PATCH_JUMP); + InjectHook(0x5308C0, &CAutomobile::ReduceHornCounter, PATCH_JUMP); + InjectHook(0x53C440, &CAutomobile::SetAllTaxiLights, PATCH_JUMP); ENDPATCHES diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index c20d078b..a9def14f 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -15,13 +15,22 @@ public: float m_aSuspensionSpringRatio[4]; float m_aSuspensionSpringRatioPrev[4]; float m_aWheelSkidThing[4]; - int field_49C; + float field_49C; bool m_aWheelSkidmarkMuddy[4]; bool m_aWheelSkidmarkBloody[4]; float m_aWheelRotation[4]; float m_aWheelPosition[4]; float m_aWheelSpeed[4]; - uint8 stuff3[12]; + uint8 field_4D8; + uint8 m_auto_flagA1 : 1; + uint8 m_auto_flagA2 : 1; + uint8 m_auto_flagA4 : 1; + uint8 bTaxiLight : 1; + uint8 m_auto_flagA10 : 1; + uint8 m_auto_flagA20 : 1; + uint8 m_auto_flagA40 : 1; + uint8 m_auto_flagA80 : 1; + uint8 field_4DA[10]; uint32 m_nBusDoorTimerEnd; uint32 m_nBusDoorTimerStart; float m_aSuspensionSpringLength[4]; @@ -44,11 +53,52 @@ public: uint8 stuff5[5]; int32 m_aWheelState[4]; + static bool &m_sAllTaxiLights; + CAutomobile(int, uint8); + + // from CEntity + void SetModelIndex(uint32 id); + void ProcessControl(void); + void Teleport(CVector v); + void PreRender(void); + void Render(void); + + // from CVehicle + void ProcessControlInputs(uint8); + void GetComponentWorldPosition(int32 component, CVector &pos); + bool IsComponentPresent(int32 component); + void SetComponentRotation(int32 component, CVector rotation); + void OpenDoor(int32, eDoors door, float); + void ProcessOpenDoor(uint32, uint32, float); + bool IsDoorReady(eDoors door); + bool IsDoorFullyOpen(eDoors door); + bool IsDoorClosed(eDoors door); + bool IsDoorMissing(eDoors door); + void RemoveRefsToVehicle(CEntity *ent); + void BlowUpCar(CEntity *ent); + bool SetUpWheelColModel(CColModel *colModel); + void BurstTyre(uint8 tyre); + bool IsRoomForPedToLeaveCar(uint32, CVector *); + float GetHeightAboveRoad(void); + void PlayCarHorn(void); + + void SpawnFlyingComponent(int32 component, uint32 type); + + void SetPanelDamage(int32 component, ePanels panel, bool noFlyingComponents); + void SetBumperDamage(int32 component, ePanels panel, bool noFlyingComponents); + void SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents); + + void SetComponentVisibility(RwFrame *frame, uint32 flags); + void SetupModelNodes(void); + void SetTaxiLight(bool light); + bool GetAllWheelsOffGround(void); + void HideAllComps(void); + void ShowAllComps(void); + void ReduceHornCounter(void); + + static void SetAllTaxiLights(bool set); + CAutomobile* ctor(int, uint8); - void SetDoorDamage(int32, uint32, bool); /* TODO: eDoors */ - void SetPanelDamage(int32, uint32, bool); /* TODO: ePanels */ - void SetBumperDamage(int32, uint32, bool); /* TODO: ePanels */ - void dtor() { this->CAutomobile::~CAutomobile(); } }; static_assert(sizeof(CAutomobile) == 0x5A8, "CAutomobile: error"); diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 076a910e..e46d7247 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -9,6 +9,12 @@ CBoat::CBoat(int mi, uint8 owner) WRAPPER CBoat* CBoat::ctor(int, uint8) { EAXJMP(0x53E3E0); } +class CBoat_ : public CBoat +{ +public: + void dtor() { CBoat::~CBoat(); }; +}; + STARTPATCHES -InjectHook(0x53E790, &CBoat::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x53E790, &CBoat_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/vehicles/Boat.h b/src/vehicles/Boat.h index 6d6482a4..6d365395 100644 --- a/src/vehicles/Boat.h +++ b/src/vehicles/Boat.h @@ -12,6 +12,5 @@ public: CBoat(int, uint8); CBoat* ctor(int, uint8); - void dtor() { this->CBoat::~CBoat(); }; }; static_assert(sizeof(CBoat) == 0x484, "CBoat: error"); diff --git a/src/vehicles/DamageManager.cpp b/src/vehicles/DamageManager.cpp index 1a7f25ed..380537f2 100644 --- a/src/vehicles/DamageManager.cpp +++ b/src/vehicles/DamageManager.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "patcher.h" #include "General.h" +#include "Vehicle.h" #include "DamageManager.h" diff --git a/src/vehicles/DamageManager.h b/src/vehicles/DamageManager.h index 1fdbc6b1..0914ded3 100644 --- a/src/vehicles/DamageManager.h +++ b/src/vehicles/DamageManager.h @@ -4,6 +4,22 @@ // TODO: move some of this into Vehicle.h +enum eDoorStatus +{ + DOOR_STATUS_OK, + DOOR_STATUS_SMASHED, + DOOR_STATUS_SWINGING, + DOOR_STATUS_MISSING +}; + +enum ePanelStatus +{ + PANEL_STATUS_OK, + PANEL_STATUS_SMASHED1, + PANEL_STATUS_SMASHED2, + PANEL_STATUS_MISSING, +}; + enum tComponent { COMPONENT_DEFAULT, @@ -37,23 +53,7 @@ enum tComponentGroup COMPGROUP_DEFAULT, }; -enum eLights -{ - VEHLIGHT_FRONT_LEFT, - VEHLIGHT_FRONT_RIGHT, - VEHLIGHT_REAR_LEFT, - VEHLIGHT_REAR_RIGHT, -}; - -enum { - VEHPANEL_FRONT_LEFT, - VEHPANEL_FRONT_RIGHT, - VEHPANEL_REAR_LEFT, - VEHPANEL_REAR_RIGHT, - VEHPANEL_WINDSCREEN, - VEHBUMPER_FRONT, - VEHBUMPER_REAR, -}; +enum eLights; class CDamageManager { diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp index 01ee5375..d43e8c19 100644 --- a/src/vehicles/Heli.cpp +++ b/src/vehicles/Heli.cpp @@ -10,6 +10,12 @@ CHeli::CHeli(int mi, uint8 owner) WRAPPER CHeli* CHeli::ctor(int, uint8) { EAXJMP(0x547220); } WRAPPER void CHeli::SpecialHeliPreRender(void) { EAXJMP(0x54AE10); } +class CHeli_ : public CHeli +{ +public: + void dtor(void) { CHeli::~CHeli(); } +}; + STARTPATCHES -InjectHook(0x5474A0, &CHeli::dtor, PATCH_JUMP); + InjectHook(0x5474A0, &CHeli_::dtor, PATCH_JUMP); ENDPATCHES diff --git a/src/vehicles/Heli.h b/src/vehicles/Heli.h index da7bb171..db873ae2 100644 --- a/src/vehicles/Heli.h +++ b/src/vehicles/Heli.h @@ -10,7 +10,6 @@ public: CHeli(int, uint8); CHeli* ctor(int, uint8); - void dtor(void) { this->CHeli::~CHeli(); } static void SpecialHeliPreRender(void); }; diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp index 6e30bced..3bad1e07 100644 --- a/src/vehicles/Plane.cpp +++ b/src/vehicles/Plane.cpp @@ -14,6 +14,12 @@ CPlane::~CPlane() DeleteRwObject(); } +class CPlane_ : public CPlane +{ +public: + void dtor(void) { CPlane::~CPlane(); } +}; + STARTPATCHES -InjectHook(0x54B270, &CPlane::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x54B270, &CPlane_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/vehicles/Plane.h b/src/vehicles/Plane.h index e26008f6..1f54e529 100644 --- a/src/vehicles/Plane.h +++ b/src/vehicles/Plane.h @@ -12,7 +12,6 @@ public: CPlane(int, uint8); ~CPlane(void); CPlane* ctor(int, uint8); - void dtor(void) { this->CPlane::~CPlane(); } void FlagToDestroyWhenNextProcessed() { bRemoveFromWorld = true; } }; static_assert(sizeof(CPlane) == 0x29C, "CPlane: error"); diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp index 62fd53ec..b7fd6ca1 100644 --- a/src/vehicles/Train.cpp +++ b/src/vehicles/Train.cpp @@ -9,6 +9,12 @@ CTrain::CTrain(int mi, uint8 owner) WRAPPER CTrain* CTrain::ctor(int, uint8) { EAXJMP(0x54E2A0); } +class CTrain_ : public CTrain +{ +public: + void dtor(void) { CTrain::~CTrain(); } +}; + STARTPATCHES -InjectHook(0x54E450, &CTrain::dtor, PATCH_JUMP); -ENDPATCHES \ No newline at end of file + InjectHook(0x54E450, &CTrain_::dtor, PATCH_JUMP); +ENDPATCHES diff --git a/src/vehicles/Train.h b/src/vehicles/Train.h index 84b6faf5..5e1e2e35 100644 --- a/src/vehicles/Train.h +++ b/src/vehicles/Train.h @@ -21,6 +21,5 @@ public: CTrain(int, uint8); CTrain* ctor(int, uint8); - void dtor(void) { this->CTrain::~CTrain(); } }; static_assert(sizeof(CTrain) == 0x2E4, "CTrain: error"); diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index dccd9195..1a22e98a 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -460,11 +460,22 @@ CVehicle::IsSphereTouchingVehicle(float sx, float sy, float sz, float radius) return true; } + +class CVehicle_ : public CVehicle +{ +public: + void dtor(void) { CVehicle::~CVehicle(); } + void SetModelIndex_(uint32 id) { CVehicle::SetModelIndex(id); } + bool SetupLighting_(void) { return CVehicle::SetupLighting(); } + void RemoveLighting_(bool reset) { CVehicle::RemoveLighting(reset); } + float GetHeightAboveRoad_(void) { return CVehicle::GetHeightAboveRoad(); } +}; + STARTPATCHES - InjectHook(0x551170, &CVehicle::SetModelIndex_, PATCH_JUMP); - InjectHook(0x4A7DD0, &CVehicle::SetupLighting_, PATCH_JUMP); - InjectHook(0x4A7E60, &CVehicle::RemoveLighting_, PATCH_JUMP); - InjectHook(0x417E60, &CVehicle::GetHeightAboveRoad_, PATCH_JUMP); + InjectHook(0x551170, &CVehicle_::SetModelIndex_, PATCH_JUMP); + InjectHook(0x4A7DD0, &CVehicle_::SetupLighting_, PATCH_JUMP); + InjectHook(0x4A7E60, &CVehicle_::RemoveLighting_, PATCH_JUMP); + InjectHook(0x417E60, &CVehicle_::GetHeightAboveRoad_, PATCH_JUMP); InjectHook(0x552880, &CVehicle::IsLawEnforcementVehicle, PATCH_JUMP); InjectHook(0x552820, &CVehicle::ChangeLawEnforcerState, PATCH_JUMP); diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 39a56fe0..0f9003db 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -69,6 +69,25 @@ enum eDoors DOOR_REAR_RIGHT }; +enum ePanels +{ + VEHPANEL_FRONT_LEFT, + VEHPANEL_FRONT_RIGHT, + VEHPANEL_REAR_LEFT, + VEHPANEL_REAR_RIGHT, + VEHPANEL_WINDSCREEN, + VEHBUMPER_FRONT, + VEHBUMPER_REAR, +}; + +enum eLights +{ + VEHLIGHT_FRONT_LEFT, + VEHLIGHT_FRONT_RIGHT, + VEHLIGHT_REAR_LEFT, + VEHLIGHT_REAR_RIGHT, +}; + class CVehicle : public CPhysical { public: @@ -115,7 +134,7 @@ public: uint8 m_veh_flagB80 : 1; uint8 m_veh_flagC1 : 1; - uint8 m_veh_flagC2 : 1; + uint8 m_veh_flagC2 : 1; // bIsDamaged uint8 m_veh_flagC4 : 1; uint8 m_veh_flagC8 : 1; uint8 m_veh_flagC10 : 1; @@ -169,7 +188,7 @@ public: ~CVehicle(void); // from CEntity - void SetModelIndex(uint32 i); + void SetModelIndex(uint32 id); bool SetupLighting(void); void RemoveLighting(bool); void FlagToDestroyWhenNextProcessed(void) {} @@ -225,13 +244,6 @@ public: static bool &bCheat4; static bool &bCheat5; static bool &m_bDisableMouseSteering; - - - void dtor(void) { CVehicle::~CVehicle(); } - void SetModelIndex_(uint32 id) { CVehicle::SetModelIndex(id); } - bool SetupLighting_(void) { return CVehicle::SetupLighting(); } - void RemoveLighting_(bool reset) { CVehicle::RemoveLighting(reset); } - float GetHeightAboveRoad_(void) { return CVehicle::GetHeightAboveRoad(); } }; static_assert(sizeof(CVehicle) == 0x288, "CVehicle: error"); From edf5ac2626ce17b74037281aa3c9730902b4b1d4 Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 8 Jul 2019 17:07:34 +0200 Subject: [PATCH 14/30] little changes; one more function of CAutomobile --- src/control/Replay.cpp | 56 ++++++++++++++++++------------------- src/core/Placeable.h | 8 +++--- src/entities/Entity.cpp | 14 +++++----- src/entities/Physical.cpp | 4 +-- src/math/Matrix.h | 46 +++++++++++++++--------------- src/peds/Ped.cpp | 28 +++++++++---------- src/peds/Ped.h | 23 +-------------- src/vehicles/Automobile.cpp | 39 ++++++++++++++++++++++++-- src/vehicles/Vehicle.h | 23 +++++++++++++++ 9 files changed, 138 insertions(+), 103 deletions(-) diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index d0264415..9041a003 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -469,7 +469,7 @@ void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayB CMatrix ped_matrix; pp->matrix.DecompressIntoFullMatrix(ped_matrix); ped->GetMatrix() = ped->GetMatrix() * CMatrix(1.0f - interpolation); - *ped->GetMatrix().GetPosition() *= (1.0f - interpolation); + ped->GetMatrix().GetPosition() *= (1.0f - interpolation); ped->GetMatrix() += CMatrix(interpolation) * ped_matrix; if (pp->vehicle_index) { ped->m_pMyVehicle = CPools::GetVehiclePool()->GetSlot(pp->vehicle_index - 1); @@ -666,7 +666,7 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI CMatrix vehicle_matrix; vp->matrix.DecompressIntoFullMatrix(vehicle_matrix); vehicle->GetMatrix() = vehicle->GetMatrix() * CMatrix(1.0f - interpolation); - *vehicle->GetMatrix().GetPosition() *= (1.0f - interpolation); + vehicle->GetMatrix().GetPosition() *= (1.0f - interpolation); vehicle->GetMatrix() += CMatrix(interpolation) * vehicle_matrix; vehicle->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f); vehicle->m_fHealth = 4 * vp->health; @@ -847,7 +847,7 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo { tGeneralPacket* pg = (tGeneralPacket*)&ptr[offset]; TheCamera.GetMatrix() = TheCamera.GetMatrix() * CMatrix(split); - *TheCamera.GetMatrix().GetPosition() *= split; + TheCamera.GetMatrix().GetPosition() *= split; TheCamera.GetMatrix() += CMatrix(interpolation) * pg->camera_pos; RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); @@ -979,34 +979,34 @@ void CReplay::ProcessReplayCamera(void) switch (CameraMode) { case REPLAYCAMMODE_TOPDOWN: { - *TheCamera.GetMatrix().GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f); - *TheCamera.GetMatrix().GetForward() = CVector(0.0f, 0.0f, -1.0f); - *TheCamera.GetMatrix().GetUp() = CVector(0.0f, 1.0f, 0.0f); - *TheCamera.GetMatrix().GetRight() = CVector(1.0f, 0.0f, 0.0f); + TheCamera.GetMatrix().GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f); + TheCamera.GetMatrix().GetForward() = CVector(0.0f, 0.0f, -1.0f); + TheCamera.GetMatrix().GetUp() = CVector(0.0f, 1.0f, 0.0f); + TheCamera.GetMatrix().GetRight() = CVector(1.0f, 0.0f, 0.0f); RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); - pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward(); - pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp(); - pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight(); + pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition(); + pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward(); + pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp(); + pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight(); break; } case REPLAYCAMMODE_FIXED: { - *TheCamera.GetMatrix().GetPosition() = CVector(CameraFixedX, CameraFixedY, CameraFixedZ); + TheCamera.GetMatrix().GetPosition() = CVector(CameraFixedX, CameraFixedY, CameraFixedZ); CVector forward(CameraFocusX - CameraFixedX, CameraFocusY - CameraFixedY, CameraFocusZ - CameraFixedZ); forward.Normalise(); CVector right = CrossProduct(CVector(0.0f, 0.0f, 1.0f), forward); right.Normalise(); CVector up = CrossProduct(forward, right); up.Normalise(); - *TheCamera.GetMatrix().GetForward() = forward; - *TheCamera.GetMatrix().GetUp() = up; - *TheCamera.GetMatrix().GetRight() = right; + TheCamera.GetMatrix().GetForward() = forward; + TheCamera.GetMatrix().GetUp() = up; + TheCamera.GetMatrix().GetRight() = right; RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); - pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward(); - pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp(); - pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight(); + pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition(); + pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward(); + pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp(); + pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight(); break; } default: @@ -1189,7 +1189,7 @@ void CReplay::RestoreStuffFromMem(void) CMatrix tmp1; tmp1.Attach(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_RF]), false); CMatrix tmp2(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_LF]), false); - *tmp1.GetPosition() += CVector(tmp2.GetPosition()->x + 0.1f, 0.0f, tmp2.GetPosition()->z); + tmp1.GetPosition() += CVector(tmp2.GetPosition().x + 0.1f, 0.0f, tmp2.GetPosition().z); tmp1.UpdateRW(); } if (vehicle->IsCar()){ @@ -1525,15 +1525,15 @@ void CReplay::ProcessLookAroundCam(void) right.Normalise(); CVector up = CrossProduct(forward, right); up.Normalise(); - *TheCamera.GetMatrix().GetForward() = forward; - *TheCamera.GetMatrix().GetUp() = up; - *TheCamera.GetMatrix().GetRight() = right; - *TheCamera.GetMatrix().GetPosition() = camera_pt; + TheCamera.GetMatrix().GetForward() = forward; + TheCamera.GetMatrix().GetUp() = up; + TheCamera.GetMatrix().GetRight() = right; + TheCamera.GetMatrix().GetPosition() = camera_pt; RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); - pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward(); - pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp(); - pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight(); + pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition(); + pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward(); + pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp(); + pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight(); TheCamera.CalculateDerivedValues(); RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera)); diff --git a/src/core/Placeable.h b/src/core/Placeable.h index bd1d50ab..1dfece69 100644 --- a/src/core/Placeable.h +++ b/src/core/Placeable.h @@ -10,10 +10,10 @@ public: CPlaceable(void); virtual ~CPlaceable(void); - CVector &GetPosition(void) { return *m_matrix.GetPosition(); } - CVector &GetRight(void) { return *m_matrix.GetRight(); } - CVector &GetForward(void) { return *m_matrix.GetForward(); } - CVector &GetUp(void) { return *m_matrix.GetUp(); } + CVector &GetPosition(void) { return m_matrix.GetPosition(); } + CVector &GetRight(void) { return m_matrix.GetRight(); } + CVector &GetForward(void) { return m_matrix.GetForward(); } + CVector &GetUp(void) { return m_matrix.GetUp(); } CMatrix &GetMatrix(void) { return m_matrix; } void SetTransform(RwMatrix *m) { m_matrix = CMatrix(m, false); } void SetHeading(float angle); diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 105f14c3..d562ced5 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -632,7 +632,7 @@ CEntity::ProcessLightsForEntity(void) lightOn = true; else lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>1 ^ m_randomSeed) & 3) + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) lightOn = true; break; case LIGHT_FLICKER_NIGHT: @@ -641,7 +641,7 @@ CEntity::ProcessLightsForEntity(void) lightOn = true; else lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>1 ^ m_randomSeed) & 3) + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3) lightOn = true; } break; @@ -680,7 +680,7 @@ CEntity::ProcessLightsForEntity(void) lightOn = true; else lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>1 ^ m_randomSeed*8) & 3) + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) lightOn = true; } break; @@ -693,7 +693,7 @@ CEntity::ProcessLightsForEntity(void) lightOn = true; else lightFlickering = true; - if((CTimer::GetTimeInMilliseconds()>>1 ^ m_randomSeed*8) & 3) + if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3) lightOn = true; } } @@ -815,8 +815,8 @@ CEntity::ModifyMatrixForTreeInWind(void) strength = 0.005f; } - mat.GetUp()->x = strength * flutter; - mat.GetUp()->y = mat.GetUp()->x; + mat.GetUp().x = strength * flutter; + mat.GetUp().y = mat.GetUp().x; mat.UpdateRW(); UpdateRwFrame(); @@ -847,7 +847,7 @@ CEntity::ModifyMatrixForBannerInWind(void) else strength = 0.66f; - t = ((int)(GetMatrix().GetPosition()->x + GetMatrix().GetPosition()->y) << 10) + 16*CTimer::GetTimeInMilliseconds(); + t = ((int)(GetMatrix().GetPosition().x + GetMatrix().GetPosition().y) << 10) + 16*CTimer::GetTimeInMilliseconds(); f = (t & 0x7FF)/(float)0x800; flutter = f * BannerWindTabel[(t>>11)+1 & 0x1F] + (1.0f - f) * BannerWindTabel[(t>>11) & 0x1F]; diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index 3d45bf52..b2512ec2 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -1883,7 +1883,7 @@ CPhysical::ProcessCollision(void) if(IsPed() && m_vecMoveSpeed.z == 0.0f && !ped->m_ped_flagA2 && ped->bIsStanding) - savedMatrix.GetPosition()->z = GetPosition().z; + savedMatrix.GetPosition().z = GetPosition().z; GetMatrix() = savedMatrix; CTimer::SetTimeStep(savedTimeStep); return; @@ -1891,7 +1891,7 @@ CPhysical::ProcessCollision(void) if(IsPed() && m_vecMoveSpeed.z == 0.0f && !ped->m_ped_flagA2 && ped->bIsStanding) - savedMatrix.GetPosition()->z = GetPosition().z; + savedMatrix.GetPosition().z = GetPosition().z; GetMatrix() = savedMatrix; CTimer::SetTimeStep(savedTimeStep); if(IsVehicle()){ diff --git a/src/math/Matrix.h b/src/math/Matrix.h index 5cc7d12f..eda75e4a 100644 --- a/src/math/Matrix.h +++ b/src/math/Matrix.h @@ -78,10 +78,10 @@ public: return *this; } - CVector *GetPosition(void){ return (CVector*)&m_matrix.pos; } - CVector *GetRight(void) { return (CVector*)&m_matrix.right; } - CVector *GetForward(void) { return (CVector*)&m_matrix.up; } - CVector *GetUp(void) { return (CVector*)&m_matrix.at; } + CVector &GetPosition(void){ return *(CVector*)&m_matrix.pos; } + CVector &GetRight(void) { return *(CVector*)&m_matrix.right; } + CVector &GetForward(void) { return *(CVector*)&m_matrix.up; } + CVector &GetUp(void) { return *(CVector*)&m_matrix.at; } void SetScale(float s){ m_matrix.right.x = s; m_matrix.right.y = 0.0f; @@ -190,9 +190,9 @@ public: m_matrix.pos.z = 0.0f; } void Reorthogonalise(void){ - CVector &r = *GetRight(); - CVector &f = *GetForward(); - CVector &u = *GetUp(); + CVector &r = GetRight(); + CVector &f = GetForward(); + CVector &u = GetUp(); u = CrossProduct(r, f); u.Normalise(); r = CrossProduct(f, u); @@ -327,24 +327,24 @@ class CCompressedMatrixNotAligned public: void CompressFromFullMatrix(CMatrix &other) { - m_rightX = 127.0f * other.GetRight()->x; - m_rightY = 127.0f * other.GetRight()->y; - m_rightZ = 127.0f * other.GetRight()->z; - m_upX = 127.0f * other.GetForward()->x; - m_upY = 127.0f * other.GetForward()->y; - m_upZ = 127.0f * other.GetForward()->z; - m_vecPos = *other.GetPosition(); + m_rightX = 127.0f * other.GetRight().x; + m_rightY = 127.0f * other.GetRight().y; + m_rightZ = 127.0f * other.GetRight().z; + m_upX = 127.0f * other.GetForward().x; + m_upY = 127.0f * other.GetForward().y; + m_upZ = 127.0f * other.GetForward().z; + m_vecPos = other.GetPosition(); } void DecompressIntoFullMatrix(CMatrix &other) { - other.GetRight()->x = m_rightX / 127.0f; - other.GetRight()->y = m_rightY / 127.0f; - other.GetRight()->z = m_rightZ / 127.0f; - other.GetForward()->x = m_upX / 127.0f; - other.GetForward()->y = m_upY / 127.0f; - other.GetForward()->z = m_upZ / 127.0f; - *other.GetUp() = CrossProduct(*other.GetRight(), *other.GetForward()); - *other.GetPosition() = m_vecPos; + other.GetRight().x = m_rightX / 127.0f; + other.GetRight().y = m_rightY / 127.0f; + other.GetRight().z = m_rightZ / 127.0f; + other.GetForward().x = m_upX / 127.0f; + other.GetForward().y = m_upY / 127.0f; + other.GetForward().z = m_upZ / 127.0f; + other.GetUp() = CrossProduct(other.GetRight(), other.GetForward()); + other.GetPosition() = m_vecPos; other.Reorthogonalise(); } -}; \ No newline at end of file +}; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 20f26688..692fc4f2 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -63,7 +63,7 @@ CPed::~CPed(void) CWorld::Remove(this); CRadar::ClearBlipForEntity(BLIP_CHAR, CPools::GetPedPool()->GetIndex(this)); if (bInVehicle && m_pMyVehicle){ - uint8 door_flag = GetVehEnterExitFlag(m_vehEnterType); + uint8 door_flag = GetVehDoorFlag(m_vehEnterType); if (m_pMyVehicle->pDriver == this) m_pMyVehicle->pDriver = nil; else { @@ -309,7 +309,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_fRotationCur = 0.0f; m_headingRate = 15.0f; m_fRotationDest = 0.0f; - m_vehEnterType = VEHICLE_ENTER_FRONT_LEFT; + m_vehEnterType = CAR_DOOR_LF; m_walkAroundType = 0; m_pCurrentPhysSurface = nil; m_vecOffsetFromPhysSurface = CVector(0.0f, 0.0f, 0.0f); @@ -1334,7 +1334,7 @@ CPed::BeingDraggedFromCar(void) if (animAssoc) animAssoc->blendDelta = -1000.0f; - if (m_vehEnterType == VEHICLE_ENTER_FRONT_LEFT || m_vehEnterType == VEHICLE_ENTER_REAR_LEFT) { + if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) { if (m_ped_flagF10) { enterAnim = ANIM_CAR_QJACKED; } else if (m_pMyVehicle->bLowVehicle) { @@ -1342,7 +1342,7 @@ CPed::BeingDraggedFromCar(void) } else { enterAnim = ANIM_CAR_JACKED_LHS; } - } else if (m_vehEnterType == VEHICLE_ENTER_FRONT_RIGHT || m_vehEnterType == VEHICLE_ENTER_REAR_RIGHT) { + } else if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) { if (m_pMyVehicle->bLowVehicle) enterAnim = ANIM_CAR_LJACKED_RHS; else @@ -1396,7 +1396,7 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg) ped->m_pSeekTarget = nil; vehicle = ped->m_pMyVehicle; - vehicle->m_nGettingOutFlags &= ~GetVehEnterExitFlag(ped->m_vehEnterType); + vehicle->m_nGettingOutFlags &= ~GetVehDoorFlag(ped->m_vehEnterType); if (vehicle->pDriver == ped) { vehicle->RemoveDriver(); @@ -1448,7 +1448,7 @@ CPed::GetLocalPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enter float seatOffset; vehModel = (CVehicleModelInfo*) CModelInfo::GetModelInfo(veh->m_modelIndex); - if (veh->bIsVan && (enterType == VEHICLE_ENTER_REAR_LEFT || enterType == VEHICLE_ENTER_REAR_RIGHT)) { + if (veh->bIsVan && (enterType == CAR_DOOR_LR || enterType == CAR_DOOR_RR)) { seatOffset = 0.0f; vehDoorOffset = offsetToOpenVanDoor; } else { @@ -1461,7 +1461,7 @@ CPed::GetLocalPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enter } switch (enterType) { - case VEHICLE_ENTER_FRONT_RIGHT: + case CAR_DOOR_RF: if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_BOAT_RUDDER]; else @@ -1471,13 +1471,13 @@ CPed::GetLocalPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enter vehDoorOffset.x = -vehDoorOffset.x; break; - case VEHICLE_ENTER_REAR_RIGHT: + case CAR_DOOR_RR: vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_REAR_SEATS]; vehDoorPos.x += seatOffset; vehDoorOffset.x = -vehDoorOffset.x; break; - case VEHICLE_ENTER_FRONT_LEFT: + case CAR_DOOR_LF: if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_BOAT_RUDDER]; else @@ -1486,7 +1486,7 @@ CPed::GetLocalPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enter vehDoorPos.x = -(vehDoorPos.x + seatOffset); break; - case VEHICLE_ENTER_REAR_LEFT: + case CAR_DOOR_LR: vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_REAR_SEATS]; vehDoorPos.x = -(vehDoorPos.x + seatOffset); break; @@ -1584,7 +1584,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) if (veh->GetUp().z <= -0.8f) vehIsUpsideDown = true; - if (m_vehEnterType == VEHICLE_ENTER_FRONT_RIGHT || m_vehEnterType == VEHICLE_ENTER_REAR_RIGHT) { + if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) { if (vehIsUpsideDown) { m_fRotationDest = -PI + veh->GetForward().Heading(); } else if (veh->bIsBus) { @@ -1592,7 +1592,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) } else { m_fRotationDest = veh->GetForward().Heading(); } - } else if (m_vehEnterType == VEHICLE_ENTER_FRONT_LEFT || m_vehEnterType == VEHICLE_ENTER_REAR_LEFT) { + } else if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) { if (vehIsUpsideDown) { m_fRotationDest = veh->GetForward().Heading(); } else if (veh->bIsBus) { @@ -1763,7 +1763,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) CMatrix vehDoorMat(veh->GetMatrix()); GetLocalPositionToOpenCarDoor(&output, veh, m_vehEnterType, 0.0f); - *vehDoorMat.GetPosition() += Multiply3x3(vehDoorMat, output); + vehDoorMat.GetPosition() += Multiply3x3(vehDoorMat, output); GetMatrix() = vehDoorMat; } @@ -2696,7 +2696,7 @@ CPed::QuitEnteringCar(void) if (veh->m_nNumGettingIn != 0) veh->m_nNumGettingIn--; - veh->m_nGettingInFlags = GetVehEnterExitFlag(m_vehEnterType); + veh->m_nGettingInFlags = GetVehDoorFlag(m_vehEnterType); } bUsesCollision = true; diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 6b04404b..2390d1d4 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -76,13 +76,6 @@ enum eObjective : uint32 { OBJECTIVE_35 }; -enum eVehEnter : uint16 { - VEHICLE_ENTER_FRONT_RIGHT = 11, - VEHICLE_ENTER_REAR_RIGHT = 12, - VEHICLE_ENTER_FRONT_LEFT = 15, - VEHICLE_ENTER_REAR_LEFT = 16, -}; - enum { RANDOM_CHAR = 1, MISSION_CHAR, @@ -321,7 +314,7 @@ public: float m_fRotationCur; float m_fRotationDest; float m_headingRate; - eVehEnter m_vehEnterType; + uint16 m_vehEnterType; uint16 m_walkAroundType; CEntity *m_pCurrentPhysSurface; CVector m_vecOffsetFromPhysSurface; @@ -526,20 +519,6 @@ public: CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; } CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; } RwFrame *GetNodeFrame(int nodeId) { return m_pFrames[nodeId]->frame; } - static uint8 GetVehEnterExitFlag(eVehEnter vehEnter) { - switch (vehEnter) { - case VEHICLE_ENTER_FRONT_RIGHT: - return 4; - case VEHICLE_ENTER_REAR_RIGHT: - return 8; - case VEHICLE_ENTER_FRONT_LEFT: - return 1; - case VEHICLE_ENTER_REAR_LEFT: - return 2; - default: - return 0; - } - } PedState GetPedState(void) { return m_nPedState; } void SetPedState(PedState state) { m_nPedState = state; } diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 23fa8ba0..c06c958c 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "patcher.h" #include "VisibilityPlugins.h" +#include "SurfaceTable.h" #include "HandlingMgr.h" #include "Automobile.h" @@ -55,7 +56,7 @@ CAutomobile::SetComponentRotation(int32 component, CVector rotation) mat.SetRotateX(DEGTORAD(rotation.x)); mat.SetRotateY(DEGTORAD(rotation.y)); mat.SetRotateZ(DEGTORAD(rotation.z)); - *mat.GetPosition() += pos; + mat.GetPosition() += pos; mat.UpdateRW(); } @@ -106,7 +107,38 @@ CAutomobile::RemoveRefsToVehicle(CEntity *ent) } WRAPPER void CAutomobile::BlowUpCar(CEntity *ent) { EAXJMP(0x53BC60); } -WRAPPER bool CAutomobile::SetUpWheelColModel(CColModel *colModel) { EAXJMP(0x53BF70); } + +bool +CAutomobile::SetUpWheelColModel(CColModel *colModel) +{ + CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); + CColModel *vehColModel = mi->GetColModel(); + + colModel->boundingSphere = vehColModel->boundingSphere; + colModel->boundingBox = vehColModel->boundingBox; + + CMatrix mat; + mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF])); + colModel->spheres[0].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_LF); + mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LB])); + colModel->spheres[1].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_LR); + mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF])); + colModel->spheres[2].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_RF); + mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RB])); + colModel->spheres[3].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_RR); + + if(m_aCarNodes[CAR_WHEEL_LM] != nil && m_aCarNodes[CAR_WHEEL_RM] != nil){ + mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LM])); + colModel->spheres[4].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_RF); + mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RM])); + colModel->spheres[5].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_TIRE, CAR_PIECE_WHEEL_RR); + colModel->numSpheres = 6; + }else + colModel->numSpheres = 4; + + return true; +} + WRAPPER void CAutomobile::BurstTyre(uint8 tyre) { EAXJMP(0x53C0E0); } WRAPPER bool CAutomobile::IsRoomForPedToLeaveCar(uint32, CVector *) { EAXJMP(0x53C5B0); } @@ -285,7 +317,7 @@ public: bool IsDoorMissing_(eDoors door) { return CAutomobile::IsDoorMissing(door); } void RemoveRefsToVehicle_(CEntity *ent) { CAutomobile::RemoveRefsToVehicle(ent); } void BlowUpCar_(CEntity *ent) { CAutomobile::BlowUpCar(ent); } - bool SetUpWheelColModel_(CColModel *colModel) { CAutomobile::SetUpWheelColModel(colModel); } + bool SetUpWheelColModel_(CColModel *colModel) { return CAutomobile::SetUpWheelColModel(colModel); } void BurstTyre_(uint8 tyre) { CAutomobile::BurstTyre(tyre); } bool IsRoomForPedToLeaveCar_(uint32 door, CVector *pos) { return CAutomobile::IsRoomForPedToLeaveCar(door, pos); } float GetHeightAboveRoad_(void) { return CAutomobile::GetHeightAboveRoad(); } @@ -303,6 +335,7 @@ STARTPATCHES InjectHook(0x52EFD0, &CAutomobile_::IsDoorClosed_, PATCH_JUMP); InjectHook(0x52F000, &CAutomobile_::IsDoorMissing_, PATCH_JUMP); InjectHook(0x53BF40, &CAutomobile_::RemoveRefsToVehicle_, PATCH_JUMP); + InjectHook(0x53BF70, &CAutomobile_::SetUpWheelColModel_, PATCH_JUMP); InjectHook(0x437690, &CAutomobile_::GetHeightAboveRoad_, PATCH_JUMP); InjectHook(0x5301A0, &CAutomobile::SetPanelDamage, PATCH_JUMP); InjectHook(0x530120, &CAutomobile::SetBumperDamage, PATCH_JUMP); diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 0f9003db..1e70d171 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -88,6 +88,14 @@ enum eLights VEHLIGHT_REAR_RIGHT, }; +enum +{ + CAR_PIECE_WHEEL_LF = 13, + CAR_PIECE_WHEEL_LR, + CAR_PIECE_WHEEL_RF, + CAR_PIECE_WHEEL_RR, +}; + class CVehicle : public CPhysical { public: @@ -250,3 +258,18 @@ static_assert(sizeof(CVehicle) == 0x288, "CVehicle: error"); static_assert(offsetof(CVehicle, m_pCurSurface) == 0x1E0, "CVehicle: error"); static_assert(offsetof(CVehicle, m_nAlarmState) == 0x1A0, "CVehicle: error"); static_assert(offsetof(CVehicle, m_nLastWeaponDamage) == 0x228, "CVehicle: error"); + +inline uint8 GetVehDoorFlag(int32 carnode) { + switch (carnode) { + case CAR_DOOR_LF: + return 1; + case CAR_DOOR_LR: + return 2; + case CAR_DOOR_RF: + return 4; + case CAR_DOOR_RR: + return 8; + default: + return 0; + } +} From 2ae112fdf6b90bb4435dba34bcc2a23604e1e158 Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 8 Jul 2019 21:37:47 +0200 Subject: [PATCH 15/30] more CAutomobile --- src/audio/DMAudio.cpp | 2 +- src/control/Replay.cpp | 2 +- src/core/Frontend.cpp | 8 +- src/core/Placeable.h | 5 + src/core/config.h | 2 + src/core/re3.cpp | 10 + src/entities/Physical.cpp | 8 +- src/entities/Physical.h | 18 ++ src/math/Matrix.h | 27 +++ src/modelinfo/VehicleModelInfo.cpp | 8 +- src/modelinfo/VehicleModelInfo.h | 2 +- src/objects/Object.cpp | 9 +- src/objects/Object.h | 1 + src/peds/Ped.cpp | 8 +- src/vehicles/Automobile.cpp | 365 ++++++++++++++++++++++++++++- src/vehicles/Automobile.h | 18 +- src/vehicles/DamageManager.h | 6 + src/vehicles/Vehicle.h | 10 +- 18 files changed, 475 insertions(+), 34 deletions(-) diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp index 60454bdd..6a53623c 100644 --- a/src/audio/DMAudio.cpp +++ b/src/audio/DMAudio.cpp @@ -19,7 +19,7 @@ WRAPPER void cDMAudio::ChangeMusicMode(uint8 mode) { EAXJMP(0x57CCF0); } WRAPPER void cDMAudio::PlayFrontEndSound(uint32, uint32) { EAXJMP(0x57CC20); } WRAPPER void cDMAudio::PlayFrontEndTrack(uint32, uint32) { EAXJMP(0x57CC80); } WRAPPER void cDMAudio::StopFrontEndTrack() { EAXJMP(0x57CCB0); } -WRAPPER void cDMAudio::PlayOneShot(int32, uint16, float) { EAXJMP(0x57C840); } +WRAPPER void cDMAudio::PlayOneShot(int32, uint16 /*eSound*/, float) { EAXJMP(0x57C840); } WRAPPER void cDMAudio::SetMusicMasterVolume(int8) { EAXJMP(0x57C8C0); } WRAPPER void cDMAudio::SetEffectsMasterVolume(int8) { EAXJMP(0x57C890); } WRAPPER int8 cDMAudio::SetCurrent3DProvider(int8) { EAXJMP(0x57C9B0); } diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 9041a003..56e37dae 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -1012,7 +1012,7 @@ void CReplay::ProcessReplayCamera(void) default: break; } - TheCamera.m_vecGameCamPos = *TheCamera.GetMatrix().GetPosition(); + TheCamera.m_vecGameCamPos = TheCamera.GetMatrix().GetPosition(); TheCamera.CalculateDerivedValues(); RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera)); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index fdb2420b..2fa9d8ea 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -2261,7 +2261,7 @@ bool GetPadMoveUp() return (CPad::GetPad(0)->NewState.DPadUp && !CPad::GetPad(0)->OldState.DPadUp) || (CPad::GetPad(0)->NewKeyState.UP && !CPad::GetPad(0)->OldKeyState.UP) || - (CPad::GetPad(0)->NewState.LeftStickY < 0 && !CPad::GetPad(0)->OldState.LeftStickY < 0); + (CPad::GetPad(0)->NewState.LeftStickY < 0 && !(CPad::GetPad(0)->OldState.LeftStickY < 0)); } bool GetPadMoveDown() @@ -2269,7 +2269,7 @@ bool GetPadMoveDown() return (CPad::GetPad(0)->NewState.DPadDown && !CPad::GetPad(0)->OldState.DPadDown) || (CPad::GetPad(0)->NewKeyState.DOWN && !CPad::GetPad(0)->OldKeyState.DOWN) || - (CPad::GetPad(0)->NewState.LeftStickY > 0 && !CPad::GetPad(0)->OldState.LeftStickY > 0); + (CPad::GetPad(0)->NewState.LeftStickY > 0 && !(CPad::GetPad(0)->OldState.LeftStickY > 0)); } bool GetPadMoveLeft() @@ -2277,7 +2277,7 @@ bool GetPadMoveLeft() return (CPad::GetPad(0)->NewState.DPadLeft && !CPad::GetPad(0)->OldState.DPadLeft) || (CPad::GetPad(0)->NewKeyState.LEFT && !CPad::GetPad(0)->OldKeyState.LEFT) || - (CPad::GetPad(0)->NewState.LeftStickX < 0 && !CPad::GetPad(0)->OldState.LeftStickX < 0); + (CPad::GetPad(0)->NewState.LeftStickX < 0 && !(CPad::GetPad(0)->OldState.LeftStickX < 0)); } bool GetPadMoveRight() @@ -2285,7 +2285,7 @@ bool GetPadMoveRight() return (CPad::GetPad(0)->NewState.DPadRight && !CPad::GetPad(0)->OldState.DPadRight) || (CPad::GetPad(0)->NewKeyState.RIGHT && !CPad::GetPad(0)->OldKeyState.RIGHT) || - (CPad::GetPad(0)->NewState.LeftStickX > 0 && !CPad::GetPad(0)->OldState.LeftStickX > 0); + (CPad::GetPad(0)->NewState.LeftStickX > 0 && !(CPad::GetPad(0)->OldState.LeftStickX > 0)); } bool GetMouseForward() diff --git a/src/core/Placeable.h b/src/core/Placeable.h index 1dfece69..648b315c 100644 --- a/src/core/Placeable.h +++ b/src/core/Placeable.h @@ -17,6 +17,11 @@ public: CMatrix &GetMatrix(void) { return m_matrix; } void SetTransform(RwMatrix *m) { m_matrix = CMatrix(m, false); } void SetHeading(float angle); + void SetOrientation(float x, float y, float z){ + CVector pos = m_matrix.GetPosition(); + m_matrix.SetRotate(x, y, z); + m_matrix.Translate(pos); + } bool IsWithinArea(float x1, float y1, float x2, float y2); bool IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z2); }; diff --git a/src/core/config.h b/src/core/config.h index c3b66ff7..b1efd4b6 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -30,6 +30,8 @@ enum Config { NUMDUMMIES = 2802, // 2368 on PS2 NUMAUDIOSCRIPTOBJECTS = 256, + NUMTEMPOBJECTS = 30, + // Link list lengths // TODO: alpha list NUMCOLCACHELINKS = 200, diff --git a/src/core/re3.cpp b/src/core/re3.cpp index d6e81214..f266ffab 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -154,6 +154,15 @@ spawnCar(int id) } #endif +void +FixCar(void) +{ + CVehicle *veh = FindPlayerVehicle(); + if(veh == nil || !veh->IsCar()) + return; + ((CAutomobile*)veh)->Fix(); +} + void DebugMenuPopulate(void) { @@ -198,6 +207,7 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Cheats", "Strong grip", StrongGripCheat); DebugMenuAddCmd("Cheats", "Nasty limbs", NastyLimbsCheat); + DebugMenuAddCmd("Debug", "Fix Car", FixCar); DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil); DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil); DebugMenuAddVarBool8("Debug", "Show Collision Polys", (int8*)&gbShowCollisionPolys, nil); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index b2512ec2..c67dad84 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -457,7 +457,7 @@ CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector & float compression = 1.0f - springRatio; if(compression > 0.0f){ float step = min(CTimer::GetTimeStep(), 3.0f); - float impulse = -0.008f*m_fMass*step * springConst * compression * bias*2.0f; + float impulse = -GRAVITY*m_fMass*step * springConst * compression * bias*2.0f; ApplyMoveForce(springDir*impulse); ApplyTurnForce(springDir*impulse, point); } @@ -489,7 +489,7 @@ void CPhysical::ApplyGravity(void) { if(bAffectedByGravity) - m_vecMoveSpeed.z -= 0.008f * CTimer::GetTimeStep(); + m_vecMoveSpeed.z -= GRAVITY * CTimer::GetTimeStep(); } void @@ -1783,7 +1783,7 @@ CPhysical::ProcessShift(void) } bIsStuck = false; bIsInSafePosition = true; - m_fDistanceTravelled = (GetPosition() - *matrix.GetPosition()).Magnitude(); + m_fDistanceTravelled = (GetPosition() - matrix.GetPosition()).Magnitude(); RemoveAndAdd(); } } @@ -1925,7 +1925,7 @@ CPhysical::ProcessCollision(void) } } bHitByTrain = false; - m_fDistanceTravelled = (GetPosition() - *savedMatrix.GetPosition()).Magnitude(); + m_fDistanceTravelled = (GetPosition() - savedMatrix.GetPosition()).Magnitude(); m_phy_flagA80 = false; bIsStuck = false; diff --git a/src/entities/Physical.h b/src/entities/Physical.h index c1f9f1d9..c2fce334 100644 --- a/src/entities/Physical.h +++ b/src/entities/Physical.h @@ -8,6 +8,8 @@ enum { PHYSICAL_MAX_COLLISIONRECORDS = 6 }; +#define GRAVITY (0.008f) + class CTreadable; class CPhysical : public CEntity @@ -108,7 +110,23 @@ public: } const CVector &GetMoveSpeed() { return m_vecMoveSpeed; } + void SetMoveSpeed(float x, float y, float z) { + m_vecMoveSpeed.x = x; + m_vecMoveSpeed.y = y; + m_vecMoveSpeed.z = z; + } const CVector &GetTurnSpeed() { return m_vecTurnSpeed; } + void SetTurnSpeed(float x, float y, float z) { + m_vecTurnSpeed.x = x; + m_vecTurnSpeed.y = y; + m_vecTurnSpeed.z = z; + } + const CVector &GetCenterOfMass() { return m_vecCentreOfMass; } + void SetCenterOfMass(float x, float y, float z) { + m_vecCentreOfMass.x = x; + m_vecCentreOfMass.y = y; + m_vecCentreOfMass.z = z; + } void ApplyMoveSpeed(void); void ApplyTurnSpeed(void); diff --git a/src/math/Matrix.h b/src/math/Matrix.h index eda75e4a..b7d6c207 100644 --- a/src/math/Matrix.h +++ b/src/math/Matrix.h @@ -82,6 +82,32 @@ public: CVector &GetRight(void) { return *(CVector*)&m_matrix.right; } CVector &GetForward(void) { return *(CVector*)&m_matrix.up; } CVector &GetUp(void) { return *(CVector*)&m_matrix.at; } + + void SetTranslate(float x, float y, float z){ + m_matrix.right.x = 1.0f; + m_matrix.right.y = 0.0f; + m_matrix.right.z = 0.0f; + + m_matrix.up.x = 0.0f; + m_matrix.up.y = 1.0f; + m_matrix.up.z = 0.0f; + + m_matrix.at.x = 0.0f; + m_matrix.at.y = 0.0f; + m_matrix.at.z = 1.0f; + + m_matrix.pos.x = x; + m_matrix.pos.y = y; + m_matrix.pos.z = z; + } + void SetTranslate(const CVector &trans){ SetTranslate(trans.x, trans.y, trans.z); } + void Translate(float x, float y, float z){ + m_matrix.pos.x += x; + m_matrix.pos.y += y; + m_matrix.pos.z += z; + } + void Translate(const CVector &trans){ Translate(trans.x, trans.y, trans.z); } + void SetScale(float s){ m_matrix.right.x = s; m_matrix.right.y = 0.0f; @@ -99,6 +125,7 @@ public: m_matrix.pos.y = 0.0f; m_matrix.pos.z = 0.0f; } + void SetRotateXOnly(float angle){ float c = cos(angle); float s = sin(angle); diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp index 810ed042..9b2924e9 100644 --- a/src/modelinfo/VehicleModelInfo.cpp +++ b/src/modelinfo/VehicleModelInfo.cpp @@ -414,11 +414,13 @@ CVehicleModelInfo::SetAtomicFlagCB(RwObject *object, void *data) return object; } -RpAtomic* -CVehicleModelInfo::ClearAtomicFlagCB(RpAtomic *atomic, void *data) +RwObject* +CVehicleModelInfo::ClearAtomicFlagCB(RwObject *object, void *data) { + RpAtomic *atomic = (RpAtomic*)object; + assert(RwObjectGetType(object) == rpATOMIC); CVisibilityPlugins::ClearAtomicFlag(atomic, (int)data); - return atomic; + return object; } RwObject* diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h index f66bc21f..37f47489 100644 --- a/src/modelinfo/VehicleModelInfo.h +++ b/src/modelinfo/VehicleModelInfo.h @@ -107,7 +107,7 @@ public: void SetAtomicRenderCallbacks(void); static RwObject *SetAtomicFlagCB(RwObject *object, void *data); - static RpAtomic *ClearAtomicFlagCB(RpAtomic *atomic, void *data); + static RwObject *ClearAtomicFlagCB(RwObject *atomic, void *data); void SetVehicleComponentFlags(RwFrame *frame, uint32 flags); void PreprocessHierarchy(void); void GetWheelPosn(int32 n, CVector &pos); diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index e13a2ad0..9bfaf681 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -7,6 +7,7 @@ #include "Object.h" WRAPPER void CObject::ObjectDamage(float amount) { EAXJMP(0x4BB240); } +WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); } int16 &CObject::nNoTempObjects = *(int16*)0x95CCA2; @@ -85,7 +86,13 @@ CObject::RemoveLighting(bool reset) WorldReplaceScorchedLightsWithNormal(Scene.world); } -WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); } + +void +CObject::RefModelInfo(int32 modelId) +{ + m_nRefModelIndex = modelId; + CModelInfo::GetModelInfo(modelId)->AddRef(); +} class CObject_ : public CObject { diff --git a/src/objects/Object.h b/src/objects/Object.h index 8afc4d0a..d31a998a 100644 --- a/src/objects/Object.h +++ b/src/objects/Object.h @@ -72,6 +72,7 @@ public: void RemoveLighting(bool reset); void ObjectDamage(float amount); + void RefModelInfo(int32 modelId); static void DeleteAllTempObjectInArea(CVector, float); }; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 692fc4f2..bf36d403 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -669,7 +669,7 @@ CPed::AimGun(void) vector.y = pos.y; vector.z = pos.z; } else { - vector = *(m_pSeekTarget->GetPosition()); + vector = m_pSeekTarget->GetPosition(); } Say(SOUND_PED_ATTACK); @@ -1540,7 +1540,7 @@ CPed::GetPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enterType, GetLocalPositionToOpenCarDoor(output, veh, enterType, offset); doorPos = Multiply3x3(vehMat, *output); - *output = *veh->GetPosition() + doorPos; + *output = veh->GetPosition() + doorPos; } void @@ -1659,7 +1659,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) CVector neededPos; if (phase == LINE_UP_TO_CAR_2) { - neededPos = *GetPosition(); + neededPos = GetPosition(); } else { GetPositionToOpenCarDoor(&neededPos, veh, m_vehEnterType, seatPosMult); } @@ -2087,7 +2087,7 @@ CPed::CalculateNewOrientation(void) if (CReplay::IsPlayingBack() || !IsPedInControl()) return; - CVector pos = *GetPosition(); + CVector pos = GetPosition(); GetMatrix().SetRotate(0.0f, 0.0f, m_fRotationCur); diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index c06c958c..3968991b 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -1,8 +1,15 @@ #include "common.h" #include "patcher.h" +#include "General.h" +#include "ModelIndices.h" #include "VisibilityPlugins.h" +#include "DMAudio.h" +#include "World.h" #include "SurfaceTable.h" #include "HandlingMgr.h" +#include "CarCtrl.h" +#include "Ped.h" +#include "Object.h" #include "Automobile.h" bool &CAutomobile::m_sAllTaxiLights = *(bool*)0x95CD21; @@ -23,7 +30,22 @@ CAutomobile::SetModelIndex(uint32 id) } WRAPPER void CAutomobile::ProcessControl(void) { EAXJMP(0x531470); } -WRAPPER void CAutomobile::Teleport(CVector v) { EAXJMP(0x535180); } + +void +CAutomobile::Teleport(CVector pos) +{ + CWorld::Remove(this); + + GetPosition() = pos; + SetOrientation(0.0f, 0.0f, 0.0f); + SetMoveSpeed(0.0f, 0.0f, 0.0f); + SetTurnSpeed(0.0f, 0.0f, 0.0f); + + ResetSuspension(); + + CWorld::Add(this); +} + WRAPPER void CAutomobile::PreRender(void) { EAXJMP(0x535B40); } WRAPPER void CAutomobile::Render(void) { EAXJMP(0x539EA0); } @@ -51,16 +73,53 @@ void CAutomobile::SetComponentRotation(int32 component, CVector rotation) { CMatrix mat(RwFrameGetMatrix(m_aCarNodes[component])); - CVector pos = *mat.GetPosition(); + CVector pos = mat.GetPosition(); // BUG: all these set the whole matrix mat.SetRotateX(DEGTORAD(rotation.x)); mat.SetRotateY(DEGTORAD(rotation.y)); mat.SetRotateZ(DEGTORAD(rotation.z)); - mat.GetPosition() += pos; + mat.Translate(pos); + mat.UpdateRW(); +} + +void +CAutomobile::OpenDoor(int32 component, eDoors door, float openRatio) +{ + CMatrix mat(RwFrameGetMatrix(m_aCarNodes[component])); + CVector pos = mat.GetPosition(); + float axes[3] = { 0.0f, 0.0f, 0.0f }; + float wasClosed = false; + + if(Doors[door].IsClosed()){ + // enable angle cull for closed doors + RwFrameForAllObjects(m_aCarNodes[component], CVehicleModelInfo::ClearAtomicFlagCB, (void*)ATOMIC_FLAG_NOCULL); + wasClosed = true; + } + + Doors[door].Open(openRatio); + + if(wasClosed && Doors[door].RetAngleWhenClosed() != Doors[door].m_fAngle){ + // door opened + HideAllComps(); + // turn off angle cull for swinging door + RwFrameForAllObjects(m_aCarNodes[component], CVehicleModelInfo::SetAtomicFlagCB, (void*)ATOMIC_FLAG_NOCULL); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_DOOR_OPEN_BONNET + door, 0.0f); + } + + if(!wasClosed && openRatio == 0.0f){ + // door closed + if(Damage.GetDoorStatus(door) == DOOR_STATUS_SWINGING) + Damage.SetDoorStatus(door, DOOR_STATUS_OK); // huh? + ShowAllComps(); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_DOOR_CLOSE_BONNET + door, 0.0f); + } + + axes[Doors[door].m_nAxis] = Doors[door].m_fAngle; + mat.SetRotate(axes[0], axes[1], axes[2]); + mat.Translate(pos); mat.UpdateRW(); } -WRAPPER void CAutomobile::OpenDoor(int32, eDoors door, float) { EAXJMP(0x52E750); } WRAPPER void CAutomobile::ProcessOpenDoor(uint32, uint32, float) { EAXJMP(0x52E910); } bool @@ -139,7 +198,31 @@ CAutomobile::SetUpWheelColModel(CColModel *colModel) return true; } -WRAPPER void CAutomobile::BurstTyre(uint8 tyre) { EAXJMP(0x53C0E0); } +// this probably isn't used in III yet +void +CAutomobile::BurstTyre(uint8 wheel) +{ + switch(wheel){ + case CAR_PIECE_WHEEL_LF: wheel = VEHWHEEL_FRONT_LEFT; break; + case CAR_PIECE_WHEEL_LR: wheel = VEHWHEEL_REAR_LEFT; break; + case CAR_PIECE_WHEEL_RF: wheel = VEHWHEEL_FRONT_RIGHT; break; + case CAR_PIECE_WHEEL_RR: wheel = VEHWHEEL_REAR_RIGHT; break; + } + + int status = Damage.GetWheelStatus(wheel); + if(status == WHEEL_STATUS_OK){ + Damage.SetWheelStatus(wheel, WHEEL_STATUS_BURST); + + if(m_status == STATUS_SIMPLE){ + m_status = STATUS_PHYSICS; + CCarCtrl::SwitchVehicleToRealPhysics(this); + } + + ApplyMoveForce(GetRight() * CGeneral::GetRandomNumberInRange(-0.3f, 0.3f)); + ApplyTurnForce(GetRight() * CGeneral::GetRandomNumberInRange(-0.3f, 0.3f), GetForward()); + } +} + WRAPPER bool CAutomobile::IsRoomForPedToLeaveCar(uint32, CVector *) { EAXJMP(0x53C5B0); } float @@ -148,13 +231,269 @@ CAutomobile::GetHeightAboveRoad(void) return m_fHeightAboveRoad; } -WRAPPER void CAutomobile::PlayCarHorn(void) { EAXJMP(0x53C450); } +void +CAutomobile::PlayCarHorn(void) +{ + int r; + + if(m_nCarHornTimer != 0) + return; + + r = CGeneral::GetRandomNumber() & 7; + if(r < 2){ + m_nCarHornTimer = 45; + }else if(r < 4){ + if(pDriver) + pDriver->Say(SOUND_PED_CAR_COLLISION); + m_nCarHornTimer = 45; + }else{ + if(pDriver) + pDriver->Say(SOUND_PED_CAR_COLLISION); + } +} +void +CAutomobile::ResetSuspension(void) +{ + int i; + for(i = 0; i < 4; i++){ + m_aSuspensionSpringRatio[i] = 1.0f; + m_aWheelSkidThing[i] = 0.0f; + m_aWheelRotation[i] = 0.0f; + m_aWheelState[i] = 0; // TODO: enum? + } +} +void +CAutomobile::ProcessSwingingDoor(int32 component, eDoors door) +{ + if(Damage.GetDoorStatus(door) != DOOR_STATUS_SWINGING) + return; + CMatrix mat(RwFrameGetMatrix(m_aCarNodes[component])); + CVector pos = mat.GetPosition(); + float axes[3] = { 0.0f, 0.0f, 0.0f }; -WRAPPER void CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) { EAXJMP(0x530300); } + Doors[door].Process(this); + axes[Doors[door].m_nAxis] = Doors[door].m_fAngle; + mat.SetRotate(axes[0], axes[1], axes[2]); + mat.Translate(pos); + mat.UpdateRW(); +} + +void +CAutomobile::Fix(void) +{ + int component; + + Damage.ResetDamageStatus(); + + if(m_handling->Flags & HANDLING_NO_DOORS){ + Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_MISSING); + Damage.SetDoorStatus(DOOR_FRONT_RIGHT, DOOR_STATUS_MISSING); + Damage.SetDoorStatus(DOOR_REAR_LEFT, DOOR_STATUS_MISSING); + Damage.SetDoorStatus(DOOR_REAR_RIGHT, DOOR_STATUS_MISSING); + } + + bIsDamaged = false; + RpClumpForAllAtomics((RpClump*)m_rwObject, CVehicleModelInfo::HideAllComponentsAtomicCB, (void*)ATOMIC_FLAG_DAM); + + for(component = CAR_BUMP_FRONT; component < NUM_CAR_NODES; component++){ + if(m_aCarNodes[component]){ + CMatrix mat(RwFrameGetMatrix(m_aCarNodes[component])); + mat.SetTranslate(mat.GetPosition()); + mat.UpdateRW(); + } + } +} + +void +CAutomobile::SetupDamageAfterLoad(void) +{ + if(m_aCarNodes[CAR_BUMP_FRONT]) + SetBumperDamage(CAR_BUMP_FRONT, VEHBUMPER_FRONT); + if(m_aCarNodes[CAR_BONNET]) + SetDoorDamage(CAR_BONNET, DOOR_BONNET); + if(m_aCarNodes[CAR_BUMP_REAR]) + SetBumperDamage(CAR_BUMP_REAR, VEHBUMPER_REAR); + if(m_aCarNodes[CAR_BOOT]) + SetDoorDamage(CAR_BOOT, DOOR_BOOT); + if(m_aCarNodes[CAR_DOOR_LF]) + SetDoorDamage(CAR_DOOR_LF, DOOR_FRONT_LEFT); + if(m_aCarNodes[CAR_DOOR_RF]) + SetDoorDamage(CAR_DOOR_RF, DOOR_FRONT_RIGHT); + if(m_aCarNodes[CAR_DOOR_LR]) + SetDoorDamage(CAR_DOOR_LR, DOOR_REAR_LEFT); + if(m_aCarNodes[CAR_DOOR_RR]) + SetDoorDamage(CAR_DOOR_RR, DOOR_REAR_RIGHT); + if(m_aCarNodes[CAR_WING_LF]) + SetPanelDamage(CAR_WING_LF, VEHPANEL_FRONT_LEFT); + if(m_aCarNodes[CAR_WING_RF]) + SetPanelDamage(CAR_WING_RF, VEHPANEL_FRONT_RIGHT); + if(m_aCarNodes[CAR_WING_LR]) + SetPanelDamage(CAR_WING_LR, VEHPANEL_REAR_LEFT); + if(m_aCarNodes[CAR_WING_RR]) + SetPanelDamage(CAR_WING_RR, VEHPANEL_REAR_RIGHT); +} + +RwObject* +GetCurrentAtomicObjectCB(RwObject *object, void *data) +{ + RpAtomic *atomic = (RpAtomic*)object; + assert(RwObjectGetType(object) == rpATOMIC); + if(RpAtomicGetFlags(atomic) & rpATOMICRENDER) + *(RpAtomic**)data = atomic; + return object; +} + +CColPoint aTempPedColPts[32]; // this name doesn't make any sense + +CObject* +CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) +{ + RpAtomic *atomic; + RwFrame *frame; + RwMatrix *matrix; + CObject *obj; + + if(CObject::nNoTempObjects >= NUMTEMPOBJECTS) + return nil; + + atomic = nil; + RwFrameForAllObjects(m_aCarNodes[component], GetCurrentAtomicObjectCB, &atomic); + if(atomic == nil) + return nil; + + obj = new CObject; + if(obj == nil) + return nil; + + if(component == CAR_WINDSCREEN){ + obj->SetModelIndexNoCreate(MI_CAR_BONNET); + }else switch(type){ + case COMPGROUP_BUMPER: + obj->SetModelIndexNoCreate(MI_CAR_BUMPER); + break; + case COMPGROUP_WHEEL: + obj->SetModelIndexNoCreate(MI_CAR_WHEEL); + break; + case COMPGROUP_DOOR: + obj->SetModelIndexNoCreate(MI_CAR_DOOR); + obj->SetCenterOfMass(0.0f, -0.5f, 0.0f); + break; + case COMPGROUP_BONNET: + obj->SetModelIndexNoCreate(MI_CAR_BONNET); + obj->SetCenterOfMass(0.0f, 0.4f, 0.0f); + break; + case COMPGROUP_BOOT: + obj->SetModelIndexNoCreate(MI_CAR_BOOT); + obj->SetCenterOfMass(0.0f, -0.3f, 0.0f); + break; + case COMPGROUP_PANEL: + default: + obj->SetModelIndexNoCreate(MI_CAR_PANEL); + break; + } + + // object needs base model + obj->RefModelInfo(GetModelIndex()); + + // create new atomic + matrix = RwFrameGetLTM(m_aCarNodes[component]); + frame = RwFrameCreate(); + atomic = RpAtomicClone(atomic); + *RwFrameGetMatrix(frame) = *matrix; + RpAtomicSetFrame(atomic, frame); + CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); + obj->AttachToRwObject((RwObject*)atomic); + + // init object + obj->m_fMass = 10.0f; + obj->m_fTurnMass = 25.0f; + obj->m_fAirResistance = 0.97f; + obj->m_fElasticity = 0.1f; + obj->m_fBuoyancy = obj->m_fMass*GRAVITY/0.75f; + obj->ObjectCreatedBy = TEMP_OBJECT; + obj->bIsStatic = true; + obj->bIsPickup = false; + obj->bUseVehicleColours = true; + obj->m_colour1 = m_currentColour1; + obj->m_colour2 = m_currentColour2; + + // life time - the more objects the are, the shorter this one will live + CObject::nNoTempObjects++; + if(CObject::nNoTempObjects > 20) + obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000/5.0f; + else if(CObject::nNoTempObjects > 10) + obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000/2.0f; + else + obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000; + + obj->m_vecMoveSpeed = m_vecMoveSpeed; + if(obj->m_vecMoveSpeed.z > 0.0f){ + obj->m_vecMoveSpeed.z *= 1.5f; + }else if(GetUp().z > 0.0f && + (component == COMPGROUP_BONNET || component == COMPGROUP_BOOT || component == CAR_WINDSCREEN)){ + obj->m_vecMoveSpeed.z *= -1.5f; + obj->m_vecMoveSpeed.z += 0.04f; + }else{ + obj->m_vecMoveSpeed.z *= 0.25f; + } + obj->m_vecMoveSpeed.x *= 0.75f; + obj->m_vecMoveSpeed.y *= 0.75f; + + obj->m_vecTurnSpeed = m_vecTurnSpeed*2.0f; + + // push component away from car + CVector dist = obj->GetPosition() - GetPosition(); + dist.Normalise(); + if(component == COMPGROUP_BONNET || component == COMPGROUP_BOOT || component == CAR_WINDSCREEN){ + // push these up some + dist += GetUp(); + if(GetUp().z > 0.0f){ + // simulate fast upward movement if going fast + float speed = CVector2D(m_vecMoveSpeed).MagnitudeSqr(); + obj->GetPosition() += GetUp()*speed; + } + } + obj->ApplyMoveForce(dist); + + if(type == COMPGROUP_WHEEL){ + obj->m_fTurnMass = 5.0f; + obj->m_vecTurnSpeed.x = 0.5f; + obj->m_fAirResistance = 0.99f; + } + + if(CCollision::ProcessColModels(obj->GetMatrix(), *CModelInfo::GetModelInfo(obj->GetModelIndex())->GetColModel(), + this->GetMatrix(), *CModelInfo::GetModelInfo(this->GetModelIndex())->GetColModel(), + aTempPedColPts, nil, nil) > 0) + obj->m_pCollidingEntity = this; + + if(bRenderScorched) + obj->bRenderScorched = true; + + CWorld::Add(obj); + + return obj; +} + +CObject* +CAutomobile::RemoveBonnetInPedCollision(void) +{ + CObject *obj; + + if(Damage.GetDoorStatus(DOOR_BONNET) != DOOR_STATUS_SWINGING && + Doors[DOOR_BONNET].RetAngleWhenOpen()*0.4f < Doors[DOOR_BONNET].m_fAngle){ + // BUG? why not COMPGROUP_BONNET? + obj = SpawnFlyingComponent(CAR_BONNET, COMPGROUP_DOOR); + // make both doors invisible on car + SetComponentVisibility(m_aCarNodes[CAR_BONNET], ATOMIC_FLAG_NONE); + Damage.SetDoorStatus(DOOR_BONNET, DOOR_STATUS_MISSING); + return obj; + } + return nil; +} void CAutomobile::SetPanelDamage(int32 component, ePanels panel, bool noFlyingComponents) @@ -245,7 +584,7 @@ void CAutomobile::SetComponentVisibility(RwFrame *frame, uint32 flags) { HideAllComps(); - m_veh_flagC2 = true; + bIsDamaged = true; RwFrameForAllObjects(frame, SetVehicleAtomicVisibilityCB, (void*)flags); } @@ -327,16 +666,26 @@ public: STARTPATCHES InjectHook(0x52D170, &CAutomobile_::dtor, PATCH_JUMP); InjectHook(0x52D190, &CAutomobile_::SetModelIndex_, PATCH_JUMP); + InjectHook(0x535180, &CAutomobile_::Teleport_, PATCH_JUMP); InjectHook(0x52E5F0, &CAutomobile_::GetComponentWorldPosition_, PATCH_JUMP); InjectHook(0x52E660, &CAutomobile_::IsComponentPresent_, PATCH_JUMP); InjectHook(0x52E680, &CAutomobile_::SetComponentRotation_, PATCH_JUMP); + InjectHook(0x52E750, &CAutomobile_::OpenDoor_, PATCH_JUMP); InjectHook(0x52EF10, &CAutomobile_::IsDoorReady_, PATCH_JUMP); InjectHook(0x52EF90, &CAutomobile_::IsDoorFullyOpen_, PATCH_JUMP); InjectHook(0x52EFD0, &CAutomobile_::IsDoorClosed_, PATCH_JUMP); InjectHook(0x52F000, &CAutomobile_::IsDoorMissing_, PATCH_JUMP); InjectHook(0x53BF40, &CAutomobile_::RemoveRefsToVehicle_, PATCH_JUMP); InjectHook(0x53BF70, &CAutomobile_::SetUpWheelColModel_, PATCH_JUMP); + InjectHook(0x53C0E0, &CAutomobile_::BurstTyre_, PATCH_JUMP); InjectHook(0x437690, &CAutomobile_::GetHeightAboveRoad_, PATCH_JUMP); + InjectHook(0x53C450, &CAutomobile_::PlayCarHorn_, PATCH_JUMP); + InjectHook(0x5353A0, &CAutomobile::ResetSuspension, PATCH_JUMP); + InjectHook(0x535250, &CAutomobile::ProcessSwingingDoor, PATCH_JUMP); + InjectHook(0x53C240, &CAutomobile::Fix, PATCH_JUMP); + InjectHook(0x53C310, &CAutomobile::SetupDamageAfterLoad, PATCH_JUMP); + InjectHook(0x530300, &CAutomobile::SpawnFlyingComponent, PATCH_JUMP); + InjectHook(0x535320, &CAutomobile::RemoveBonnetInPedCollision, PATCH_JUMP); InjectHook(0x5301A0, &CAutomobile::SetPanelDamage, PATCH_JUMP); InjectHook(0x530120, &CAutomobile::SetBumperDamage, PATCH_JUMP); InjectHook(0x530200, &CAutomobile::SetDoorDamage, PATCH_JUMP); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index a9def14f..33e86b9d 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -4,6 +4,8 @@ #include "DamageManager.h" #include "Door.h" +class CObject; + class CAutomobile : public CVehicle { public: @@ -69,7 +71,7 @@ public: void GetComponentWorldPosition(int32 component, CVector &pos); bool IsComponentPresent(int32 component); void SetComponentRotation(int32 component, CVector rotation); - void OpenDoor(int32, eDoors door, float); + void OpenDoor(int32 component, eDoors door, float openRatio); void ProcessOpenDoor(uint32, uint32, float); bool IsDoorReady(eDoors door); bool IsDoorFullyOpen(eDoors door); @@ -83,12 +85,16 @@ public: float GetHeightAboveRoad(void); void PlayCarHorn(void); - void SpawnFlyingComponent(int32 component, uint32 type); - - void SetPanelDamage(int32 component, ePanels panel, bool noFlyingComponents); - void SetBumperDamage(int32 component, ePanels panel, bool noFlyingComponents); - void SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents); + void ProcessSwingingDoor(int32 component, eDoors door); + void ResetSuspension(void); + void SetupDamageAfterLoad(void); + CObject *SpawnFlyingComponent(int32 component, uint32 type); + CObject *RemoveBonnetInPedCollision(void); + void SetPanelDamage(int32 component, ePanels panel, bool noFlyingComponents = false); + void SetBumperDamage(int32 component, ePanels panel, bool noFlyingComponents = false); + void SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents = false); + void Fix(void); void SetComponentVisibility(RwFrame *frame, uint32 flags); void SetupModelNodes(void); void SetTaxiLight(bool light); diff --git a/src/vehicles/DamageManager.h b/src/vehicles/DamageManager.h index 0914ded3..b815f724 100644 --- a/src/vehicles/DamageManager.h +++ b/src/vehicles/DamageManager.h @@ -20,6 +20,12 @@ enum ePanelStatus PANEL_STATUS_MISSING, }; +enum eWheelStatus +{ + WHEEL_STATUS_OK, + WHEEL_STATUS_BURST +}; + enum tComponent { COMPONENT_DEFAULT, diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 1e70d171..e974eb88 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -88,6 +88,14 @@ enum eLights VEHLIGHT_REAR_RIGHT, }; +enum eWheels +{ + VEHWHEEL_FRONT_LEFT, + VEHWHEEL_FRONT_RIGHT, + VEHWHEEL_REAR_LEFT, + VEHWHEEL_REAR_RIGHT, +}; + enum { CAR_PIECE_WHEEL_LF = 13, @@ -142,7 +150,7 @@ public: uint8 m_veh_flagB80 : 1; uint8 m_veh_flagC1 : 1; - uint8 m_veh_flagC2 : 1; // bIsDamaged + uint8 bIsDamaged : 1; uint8 m_veh_flagC4 : 1; uint8 m_veh_flagC8 : 1; uint8 m_veh_flagC10 : 1; From 69ee4acc97504ffedf09995e75da62417abeb231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Mon, 8 Jul 2019 23:03:50 +0300 Subject: [PATCH 16/30] One driver owns all the cars fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: eray orçunus --- src/core/FileLoader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index fdc3b9d7..b949eb98 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -813,6 +813,7 @@ CFileLoader::LoadPedObject(const char *line) if(strcmp(animGroup, CAnimManager::GetAnimGroupName((AssocGroupId)animGroupId)) == 0) break; mi->m_animGroup = animGroupId; + mi->m_carsCanDrive = carsCanDrive; // ??? CModelInfo::GetModelInfo(MI_LOPOLYGUY)->SetColModel(&CTempColModels::ms_colModelPed1); From 74fcbc8c0a6bbac8e8057655c5f1133e15c63656 Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 9 Jul 2019 09:57:44 +0200 Subject: [PATCH 17/30] more CAutomobile --- src/control/AutoPilot.h | 6 +- src/control/Replay.cpp | 8 +- src/core/Camera.cpp | 10 +- src/core/Collision.cpp | 2 +- src/core/Collision.h | 2 +- src/entities/Entity.h | 2 + src/entities/Physical.cpp | 4 +- src/entities/Physical.h | 4 +- src/objects/Object.cpp | 1 + src/objects/Object.h | 1 + src/peds/Ped.cpp | 15 +- src/peds/Ped.h | 2 +- src/render/Renderer.cpp | 2 +- src/vehicles/Automobile.cpp | 348 +++++++++++++++++++++++++++++++++++- src/vehicles/Automobile.h | 10 +- src/vehicles/Vehicle.cpp | 4 +- src/vehicles/Vehicle.h | 10 +- 17 files changed, 395 insertions(+), 36 deletions(-) diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h index 97b02f5c..351fd117 100644 --- a/src/control/AutoPilot.h +++ b/src/control/AutoPilot.h @@ -59,9 +59,9 @@ enum eCarDrivingStyle : uint8 class CAutoPilot { public: - void *m_currentAddress; - void *m_startingRouteNode; - void *m_PreviousRouteNode; + uint32 m_currentAddress; + uint32 m_startingRouteNode; + uint32 m_PreviousRouteNode; uint32 m_nTotalSpeedScaleFactor; uint32 m_nSpeedScaleFactor; uint32 m_nCurrentPathNodeInfo; diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 56e37dae..2bdb9dfe 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -290,14 +290,14 @@ void CReplay::RecordThisFrame(void) CPed* p = peds->GetSlot(i); if (!p || !p->m_rwObject) continue; - if (!p->bRecordedForReplay){ + if (!p->bHasAlreadyBeenRecorded){ tPedHeaderPacket* ph = (tPedHeaderPacket*)&Record.m_pBase[Record.m_nOffset]; ph->type = REPLAYPACKET_PED_HEADER; ph->index = i; ph->mi = p->GetModelIndex(); ph->pedtype = p->m_nPedType; Record.m_nOffset += sizeof(*ph); - p->bRecordedForReplay = true; + p->bHasAlreadyBeenRecorded = true; } StorePedUpdate(p, i); } @@ -1346,14 +1346,14 @@ void CReplay::MarkEverythingAsNew(void) CVehicle* v = CPools::GetVehiclePool()->GetSlot(i); if (!v) continue; - v->bRecordedForReplay = false; + v->bHasAlreadyBeenRecorded = false; } i = CPools::GetPedPool()->GetSize(); while (i--) { CPed* p = CPools::GetPedPool()->GetSlot(i); if (!p) continue; - p->bRecordedForReplay = false; + p->bHasAlreadyBeenRecorded = false; } } #endif diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 58e65d24..832f9455 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -678,9 +678,13 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl else if(TargetZOffSet == m_fUnknownZOffSet && TargetZOffSet > m_fCamBufferedHeight){ // TODO: figure this out bool foo = false; - switch(((CPhysical*)CamTargetEntity)->m_nLastCollType) - case 2: case 3: case 5: - case 11: case 23: case 26: + switch(((CPhysical*)CamTargetEntity)->m_nSurfaceTouched) + case SURFACE_GRASS: + case SURFACE_DIRT: + case SURFACE_PAVEMENT: + case SURFACE_STEEL: + case SURFACE_TIRE: + case SURFACE_STONE: foo = true; if(foo) WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.4f, 0.05f, false); diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index d15ccca5..94da1338 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -1173,7 +1173,7 @@ enum { // This checks model A's spheres and lines against model B's spheres, boxes and triangles. // Returns the number of A's spheres that collide. // Returned ColPoints are in world space. -// NB: lines do not seem to be supported very well, use with caution +// NB: only vehicles can have col models with lines, exactly 4, one for each wheel int32 CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, diff --git a/src/core/Collision.h b/src/core/Collision.h index 5a9058d3..b2fe6564 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -147,7 +147,7 @@ public: static bool ProcessSphereTriangle(const CColSphere &sph, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq); static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough); static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly); - static int32 ProcessColModels(const CMatrix &matrix1, CColModel &model1, const CMatrix &matrix2, CColModel &model2, CColPoint *point1, CColPoint *point2, float *linedists); + static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists); // TODO: // CCollision::IsStoredPolyStillValidVerticalLine diff --git a/src/entities/Entity.h b/src/entities/Entity.h index d055d25f..12a631d2 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -94,6 +94,8 @@ public: uint16 m_level; // int16 CReference *m_pFirstReference; + CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); } + CEntity(void); ~CEntity(void); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index c67dad84..88287e26 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -62,7 +62,7 @@ CPhysical::CPhysical(void) m_phy_flagA10 = false; m_phy_flagA20 = false; - m_nLastCollType = 0; + m_nSurfaceTouched = SURFACE_DEFAULT; } CPhysical::~CPhysical(void) @@ -1918,7 +1918,7 @@ CPhysical::ProcessCollision(void) bHitByTrain || m_status == STATUS_PLAYER || IsPed() && ped->IsPlayer()){ if(IsVehicle()) - ((CVehicle*)this)->m_veh_flagD4 = true; + ((CVehicle*)this)->bVehicleColProcessed = true; if(CheckCollision()){ GetMatrix() = savedMatrix; return; diff --git a/src/entities/Physical.h b/src/entities/Physical.h index c2fce334..5bd98815 100644 --- a/src/entities/Physical.h +++ b/src/entities/Physical.h @@ -61,7 +61,7 @@ public: uint8 bHitByTrain : 1; // from nick uint8 m_phy_flagA80 : 1; - uint8 m_nLastCollType; + uint8 m_nSurfaceTouched; uint8 m_nZoneLevel; CPhysical(void); @@ -75,7 +75,7 @@ public: void ProcessShift(void); void ProcessCollision(void); - virtual int32 ProcessEntityCollision(CEntity *ent, CColPoint *point); + virtual int32 ProcessEntityCollision(CEntity *ent, CColPoint *colpoints); void RemoveAndAdd(void); void AddToMovingList(void); diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 9bfaf681..f3ba8087 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -10,6 +10,7 @@ WRAPPER void CObject::ObjectDamage(float amount) { EAXJMP(0x4BB240); } WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); } int16 &CObject::nNoTempObjects = *(int16*)0x95CCA2; +int16 &CObject::nBodyCastHealth = *(int16*)0x5F7D4C; // 1000 void *CObject::operator new(size_t sz) { return CPools::GetObjectPool()->New(); } void CObject::operator delete(void *p, size_t sz) { CPools::GetObjectPool()->Delete((CObject*)p); } diff --git a/src/objects/Object.h b/src/objects/Object.h index d31a998a..0ce1a3aa 100644 --- a/src/objects/Object.h +++ b/src/objects/Object.h @@ -60,6 +60,7 @@ public: int8 m_colour1, m_colour2; static int16 &nNoTempObjects; + static int16 &nBodyCastHealth; static void *operator new(size_t); static void operator delete(void*, size_t); diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index bf36d403..e0e0b913 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -10,6 +10,7 @@ #include "Ped.h" #include "PlayerPed.h" #include "General.h" +#include "SurfaceTable.h" #include "VisibilityPlugins.h" #include "AudioManager.h" #include "HandlingMgr.h" @@ -430,7 +431,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_ped_flagI1 = false; m_ped_flagI2 = false; m_ped_flagI4 = false; - bRecordedForReplay = false; + bHasAlreadyBeenRecorded = false; m_ped_flagI10 = false; #ifdef KANGAROO_CHEAT m_ped_flagI80 = false; @@ -1772,12 +1773,12 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) static void particleProduceFootDust(CPed *ped, CVector *pos, float size, int times) { - switch (ped->m_nLastCollType) + switch (ped->m_nSurfaceTouched) { - case 1: // somewhere hard - case 3: // soft dirt - case 5: // pavement - case 18:// sand + case SURFACE_TARMAC: + case SURFACE_DIRT: + case SURFACE_PAVEMENT: + case SURFACE_SAND: for (int i = 0; i < times; ++i) { CVector adjustedPos = *pos; adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); @@ -1879,7 +1880,7 @@ CPed::PlayFootSteps(void) } } - if (m_nLastCollType == 19) { // Water + if (m_nSurfaceTouched == SURFACE_PUDDLE) { float pedSpeed = CVector2D(m_vecMoveSpeed).Magnitude(); if (pedSpeed > 0.03f && CTimer::GetFrameCounter() % 2 == 0 && pedSpeed > 0.13f) { float particleSize = pedSpeed * 2.0f; diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 2390d1d4..6aba79cf 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -251,7 +251,7 @@ public: uint8 m_ped_flagI1 : 1; uint8 m_ped_flagI2 : 1; uint8 m_ped_flagI4 : 1; - uint8 bRecordedForReplay : 1; + uint8 bHasAlreadyBeenRecorded : 1; uint8 m_ped_flagI10 : 1; uint8 m_ped_flagI20 : 1; uint8 m_ped_flagI40 : 1; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index a6f28443..69df63ba 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1160,7 +1160,7 @@ CRenderer::IsVehicleCullZoneVisible(CEntity *ent) case STATUS_PHYSICS: case STATUS_ABANDONED: case STATUS_WRECKED: - return !(v->m_pCurSurface && v->m_pCurSurface->bZoneCulled2); + return !(v->m_pCurGroundEntity && v->m_pCurGroundEntity->bZoneCulled2); return true; } diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 3968991b..267e901a 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -8,6 +8,7 @@ #include "SurfaceTable.h" #include "HandlingMgr.h" #include "CarCtrl.h" +#include "PathFind.h" #include "Ped.h" #include "Object.h" #include "Automobile.h" @@ -50,6 +51,90 @@ WRAPPER void CAutomobile::PreRender(void) { EAXJMP(0x535B40); } WRAPPER void CAutomobile::Render(void) { EAXJMP(0x539EA0); } +int32 +CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) +{ + int i; + CColModel *colModel; + + if(m_status != STATUS_SIMPLE) + bVehicleColProcessed = true; + + if(m_veh_flagC80) + colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel; + else + colModel = GetColModel(); + + int numWheelCollisions = 0; + float prevRatios[4] = { 0.0f, 0.0f, 0.0f, 0.0f}; + for(i = 0; i < 4; i++) + prevRatios[i] = m_aSuspensionSpringRatio[i]; + + int numCollisions = CCollision::ProcessColModels(GetMatrix(), *colModel, + ent->GetMatrix(), *ent->GetColModel(), + colpoints, + m_aWheelColPoints, m_aSuspensionSpringRatio); + + // m_aSuspensionSpringRatio are now set to the point where the tyre touches ground. + // In ProcessControl these will be re-normalized to ignore the tyre radius. + + if(field_EF || m_phy_flagA80 || + GetModelIndex() == MI_DODO && (ent->m_status == STATUS_PHYSICS || ent->m_status == STATUS_SIMPLE)){ + // don't do line collision + for(i = 0; i < 4; i++) + m_aSuspensionSpringRatio[i] = prevRatios[i]; + }else{ + for(i = 0; i < 4; i++) + if(m_aSuspensionSpringRatio[i] < 1.0f && m_aSuspensionSpringRatio[i] < prevRatios[i]){ + numWheelCollisions++; + + // wheel is touching a physical + if(ent->IsVehicle() || ent->IsObject()){ + CPhysical *phys = (CPhysical*)ent; + + m_aGroundPhysical[i] = phys; + phys->RegisterReference((CEntity**)&m_aGroundPhysical[i]); + m_aGroundOffset[i] = m_aWheelColPoints[i].point - phys->GetPosition(); + + if(phys->GetModelIndex() == MI_BODYCAST && m_status == STATUS_PLAYER){ + // damage body cast + float speed = m_vecMoveSpeed.MagnitudeSqr(); + if(speed > 0.1f){ + CObject::nBodyCastHealth -= 0.1f*m_fMass*speed; + DMAudio.PlayOneShot(m_audioEntityId, SOUND_PED_BODYCAST_HIT, 0.0f); + } + + // move body cast + if(phys->bIsStatic){ + phys->bIsStatic = false; + phys->m_nStaticFrames = 0; + phys->ApplyMoveForce(m_vecMoveSpeed / speed); + phys->AddToMovingList(); + } + } + } + + m_nSurfaceTouched = m_aWheelColPoints[i].surfaceB; + if(ent->IsBuilding()) + m_pCurGroundEntity = ent; + } + } + + if(numCollisions > 0 || numWheelCollisions > 0){ + AddCollisionRecord(ent); + if(!ent->IsBuilding()) + ((CPhysical*)ent)->AddCollisionRecord(this); + + if(numCollisions > 0) + if(ent->IsBuilding() || + ent->IsObject() && ((CPhysical*)ent)->bInfiniteMass) + bHasHitWall = true; + } + + return numCollisions; +} + + WRAPPER void CAutomobile::ProcessControlInputs(uint8) { EAXJMP(0x53B660); } void @@ -120,7 +205,114 @@ CAutomobile::OpenDoor(int32 component, eDoors door, float openRatio) mat.UpdateRW(); } -WRAPPER void CAutomobile::ProcessOpenDoor(uint32, uint32, float) { EAXJMP(0x52E910); } +inline void ProcessDoorOpenAnimation(CAutomobile *car, uint32 component, eDoors door, float time, float start, float end) +{ + if(time > start && time < end){ + float ratio = (time - start)/(end - start); + if(car->Doors[door].GetAngleOpenRatio() < ratio) + car->OpenDoor(component, door, ratio); + }else if(time > end){ + car->OpenDoor(component, door, 1.0f); + } +} + +inline void ProcessDoorCloseAnimation(CAutomobile *car, uint32 component, eDoors door, float time, float start, float end) +{ + if(time > start && time < end){ + float ratio = 1.0f - (time - start)/(end - start); + if(car->Doors[door].GetAngleOpenRatio() > ratio) + car->OpenDoor(component, door, ratio); + }else if(time > end){ + car->OpenDoor(component, door, 0.0f); + } +} + +inline void ProcessDoorOpenCloseAnimation(CAutomobile *car, uint32 component, eDoors door, float time, float start, float mid, float end) +{ + if(time > start && time < mid){ + // open + float ratio = (time - start)/(mid - start); + if(car->Doors[door].GetAngleOpenRatio() < ratio) + car->OpenDoor(component, door, ratio); + }else if(time > mid && time < end){ + // close + float ratio = 1.0f - (time - mid)/(end - mid); + if(car->Doors[door].GetAngleOpenRatio() > ratio) + car->OpenDoor(component, door, ratio); + }else if(time > end){ + car->OpenDoor(component, door, 0.0f); + } +} +void +CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time) +{ + eDoors door; + + switch(component){ + case CAR_DOOR_RF: door = DOOR_FRONT_RIGHT; break; + case CAR_DOOR_RR: door = DOOR_REAR_RIGHT; break; + case CAR_DOOR_LF: door = DOOR_FRONT_LEFT; break; + case CAR_DOOR_LR: door = DOOR_REAR_LEFT; break; + default: assert(0); + } + + if(IsDoorMissing(door)) + return; + + switch(anim){ + case ANIM_CAR_QJACK: + case ANIM_CAR_OPEN_LHS: + case ANIM_CAR_OPEN_RHS: + ProcessDoorOpenAnimation(this, component, door, time, 0.66f, 0.8f); + break; + case ANIM_CAR_CLOSEDOOR_LHS: + case ANIM_CAR_CLOSEDOOR_LOW_LHS: + case ANIM_CAR_CLOSEDOOR_RHS: + case ANIM_CAR_CLOSEDOOR_LOW_RHS: + ProcessDoorCloseAnimation(this, component, door, time, 0.2f, 0.63f); + break; + case ANIM_CAR_ROLLDOOR: + case ANIM_CAR_ROLLDOOR_LOW: + ProcessDoorOpenCloseAnimation(this, component, door, time, 0.1f, 0.6f, 0.95f); + break; + break; + case ANIM_CAR_GETOUT_LHS: + case ANIM_CAR_GETOUT_LOW_LHS: + case ANIM_CAR_GETOUT_RHS: + case ANIM_CAR_GETOUT_LOW_RHS: + ProcessDoorOpenAnimation(this, component, door, time, 0.06f, 0.43f); + break; + case ANIM_CAR_CLOSE_LHS: + case ANIM_CAR_CLOSE_RHS: + ProcessDoorCloseAnimation(this, component, door, time, 0.1f, 0.23f); + break; + case ANIM_CAR_PULLOUT_RHS: + case ANIM_CAR_PULLOUT_LOW_RHS: + OpenDoor(component, door, 1.0f); + case ANIM_COACH_OPEN_L: + case ANIM_COACH_OPEN_R: + ProcessDoorOpenAnimation(this, component, door, time, 0.66f, 0.8f); + break; + case ANIM_COACH_OUT_L: + ProcessDoorOpenAnimation(this, component, door, time, 0.0f, 0.3f); + break; + case ANIM_VAN_OPEN_L: + case ANIM_VAN_OPEN: + ProcessDoorOpenAnimation(this, component, door, time, 0.37f, 0.55f); + break; + case ANIM_VAN_CLOSE_L: + case ANIM_VAN_CLOSE: + ProcessDoorCloseAnimation(this, component, door, time, 0.5f, 0.8f); + break; + case ANIM_VAN_GETOUT_L: + case ANIM_VAN_GETOUT: + ProcessDoorOpenAnimation(this, component, door, time, 0.5f, 0.6f); + break; + case NUM_ANIMS: + OpenDoor(component, door, time); + break; + } +} bool CAutomobile::IsDoorReady(eDoors door) @@ -252,6 +444,16 @@ CAutomobile::PlayCarHorn(void) } } +void +CAutomobile::PlayHornIfNecessary(void) +{ + // TODO: flags + if(m_autoPilot.m_nCarCtrlFlags & 2 || + m_autoPilot.m_nCarCtrlFlags & 1) + if(!HasCarStoppedBecauseOfLight()) + PlayCarHorn(); +} + void CAutomobile::ResetSuspension(void) @@ -265,6 +467,139 @@ CAutomobile::ResetSuspension(void) } } +void +CAutomobile::SetupSuspensionLines(void) +{ + int i; + CVector posn; + CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); + CColModel *colModel = mi->GetColModel(); + + // Each suspension line starts at the uppermost wheel position + // and extends down to the lowermost point on the tyre + for(i = 0; i < 4; i++){ + mi->GetWheelPosn(i, posn); + m_aWheelPosition[i] = posn.z; + + // uppermost wheel position + posn.z += m_handling->fSuspensionUpperLimit; + colModel->lines[i].p0 = posn; + + // lowermost wheel position + posn.z += m_handling->fSuspensionLowerLimit - m_handling->fSuspensionUpperLimit; + // lowest point on tyre + posn.z -= mi->m_wheelScale*0.5f; + colModel->lines[i].p1 = posn; + + // this is length of the spring at rest + m_aSuspensionSpringLength[i] = m_handling->fSuspensionUpperLimit - m_handling->fSuspensionLowerLimit; + m_aSuspensionLineLength[i] = colModel->lines[i].p0.z - colModel->lines[i].p1.z; + } + + // Compress spring somewhat to get normal height on road + m_fHeightAboveRoad = -(colModel->lines[0].p0.z + (colModel->lines[0].p1.z - colModel->lines[0].p0.z)* + (1.0f - 1.0f/(8.0f*m_handling->fSuspensionForceLevel))); + for(i = 0; i < 4; i++) + m_aWheelPosition[i] = mi->m_wheelScale*0.5f - m_fHeightAboveRoad; + + // adjust col model to include suspension lines + if(colModel->boundingBox.min.z > colModel->lines[0].p1.z) + colModel->boundingBox.min.z = colModel->lines[0].p1.z; + float radius = max(colModel->boundingBox.min.Magnitude(), colModel->boundingBox.max.Magnitude()); + if(colModel->boundingSphere.radius < radius) + colModel->boundingSphere.radius = radius; + + if(GetModelIndex() == MI_RCBANDIT){ + colModel->boundingSphere.radius = 2.0f; + for(i = 0; i < colModel->numSpheres; i++) + colModel->spheres[i].radius = 0.3f; + } +} + +bool +CAutomobile::HasCarStoppedBecauseOfLight(void) +{ + int i; + + if(m_status != STATUS_SIMPLE && m_status != STATUS_PHYSICS) + return false; + + if(m_autoPilot.m_currentAddress && m_autoPilot.m_startingRouteNode){ + CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_currentAddress]; + for(i = 0; i < curnode->numLinks; i++) + if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_startingRouteNode) + break; + if(i < curnode->numLinks && + ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO + return true; + } + + if(m_autoPilot.m_currentAddress && m_autoPilot.m_PreviousRouteNode){ + CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_currentAddress]; + for(i = 0; i < curnode->numLinks; i++) + if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_PreviousRouteNode) + break; + if(i < curnode->numLinks && + ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO + return true; + } + + return false; +} + +void +CAutomobile::SetBusDoorTimer(uint32 timer, uint8 type) +{ + if(timer < 1000) + timer = 1000; + if(type == 0) + // open and close + m_nBusDoorTimerStart = CTimer::GetTimeInMilliseconds(); + else + // only close + m_nBusDoorTimerStart = CTimer::GetTimeInMilliseconds() - 500; + m_nBusDoorTimerEnd = m_nBusDoorTimerStart + timer; +} + +void +CAutomobile::ProcessAutoBusDoors(void) +{ + if(CTimer::GetTimeInMilliseconds() < m_nBusDoorTimerEnd){ + if(m_nBusDoorTimerEnd != 0 && CTimer::GetTimeInMilliseconds() > m_nBusDoorTimerEnd-500){ + // close door + if(!IsDoorMissing(DOOR_FRONT_LEFT) && (m_nGettingInFlags & 1) == 0){ + if(IsDoorClosed(DOOR_FRONT_LEFT)){ + m_nBusDoorTimerEnd = CTimer::GetTimeInMilliseconds(); + OpenDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT, 0.0f); + }else{ + OpenDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT, + 1.0f - (CTimer::GetTimeInMilliseconds() - (m_nBusDoorTimerEnd-500))/500.0f); + } + } + + if(!IsDoorMissing(DOOR_FRONT_RIGHT) && (m_nGettingInFlags & 4) == 0){ + if(IsDoorClosed(DOOR_FRONT_RIGHT)){ + m_nBusDoorTimerEnd = CTimer::GetTimeInMilliseconds(); + OpenDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT, 0.0f); + }else{ + OpenDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT, + 1.0f - (CTimer::GetTimeInMilliseconds() - (m_nBusDoorTimerEnd-500))/500.0f); + } + } + } + }else{ + // ended + if(m_nBusDoorTimerStart){ + if(!IsDoorMissing(DOOR_FRONT_LEFT) && (m_nGettingInFlags & 1) == 0) + OpenDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT, 0.0f); + if(!IsDoorMissing(DOOR_FRONT_RIGHT) && (m_nGettingInFlags & 4) == 0) + OpenDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT, 0.0f); + m_nBusDoorTimerStart = 0; + m_nBusDoorTimerEnd = 0; + } + } +} + void CAutomobile::ProcessSwingingDoor(int32 component, eDoors door) { @@ -465,8 +800,8 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) obj->m_fAirResistance = 0.99f; } - if(CCollision::ProcessColModels(obj->GetMatrix(), *CModelInfo::GetModelInfo(obj->GetModelIndex())->GetColModel(), - this->GetMatrix(), *CModelInfo::GetModelInfo(this->GetModelIndex())->GetColModel(), + if(CCollision::ProcessColModels(obj->GetMatrix(), *obj->GetColModel(), + this->GetMatrix(), *this->GetColModel(), aTempPedColPts, nil, nil) > 0) obj->m_pCollidingEntity = this; @@ -644,6 +979,8 @@ public: void PreRender_(void) { CAutomobile::PreRender(); } void Render_(void) { CAutomobile::Render(); } + int32 ProcessEntityCollision_(CEntity *ent, CColPoint *colpoints){ return CAutomobile::ProcessEntityCollision(ent, colpoints); } + void ProcessControlInputs_(uint8 x) { CAutomobile::ProcessControlInputs(x); } void GetComponentWorldPosition_(int32 component, CVector &pos) { CAutomobile::GetComponentWorldPosition(component, pos); } bool IsComponentPresent_(int32 component) { return CAutomobile::IsComponentPresent(component); } @@ -667,6 +1004,7 @@ STARTPATCHES InjectHook(0x52D170, &CAutomobile_::dtor, PATCH_JUMP); InjectHook(0x52D190, &CAutomobile_::SetModelIndex_, PATCH_JUMP); InjectHook(0x535180, &CAutomobile_::Teleport_, PATCH_JUMP); + InjectHook(0x53B270, &CAutomobile_::ProcessEntityCollision_, PATCH_JUMP); InjectHook(0x52E5F0, &CAutomobile_::GetComponentWorldPosition_, PATCH_JUMP); InjectHook(0x52E660, &CAutomobile_::IsComponentPresent_, PATCH_JUMP); InjectHook(0x52E680, &CAutomobile_::SetComponentRotation_, PATCH_JUMP); @@ -681,6 +1019,10 @@ STARTPATCHES InjectHook(0x437690, &CAutomobile_::GetHeightAboveRoad_, PATCH_JUMP); InjectHook(0x53C450, &CAutomobile_::PlayCarHorn_, PATCH_JUMP); InjectHook(0x5353A0, &CAutomobile::ResetSuspension, PATCH_JUMP); + InjectHook(0x52D210, &CAutomobile::SetupSuspensionLines, PATCH_JUMP); + InjectHook(0x42E220, &CAutomobile::HasCarStoppedBecauseOfLight, PATCH_JUMP); + InjectHook(0x53D320, &CAutomobile::SetBusDoorTimer, PATCH_JUMP); + InjectHook(0x53D370, &CAutomobile::ProcessAutoBusDoors, PATCH_JUMP); InjectHook(0x535250, &CAutomobile::ProcessSwingingDoor, PATCH_JUMP); InjectHook(0x53C240, &CAutomobile::Fix, PATCH_JUMP); InjectHook(0x53C310, &CAutomobile::SetupDamageAfterLoad, PATCH_JUMP); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 33e86b9d..fc859f92 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -66,6 +66,9 @@ public: void PreRender(void); void Render(void); + // from CPhysical + int32 ProcessEntityCollision(CEntity *ent, CColPoint *colpoints); + // from CVehicle void ProcessControlInputs(uint8); void GetComponentWorldPosition(int32 component, CVector &pos); @@ -85,8 +88,13 @@ public: float GetHeightAboveRoad(void); void PlayCarHorn(void); - void ProcessSwingingDoor(int32 component, eDoors door); + void PlayHornIfNecessary(void); void ResetSuspension(void); + void SetupSuspensionLines(void); + bool HasCarStoppedBecauseOfLight(void); + void SetBusDoorTimer(uint32 timer, uint8 type); + void ProcessAutoBusDoors(void); + void ProcessSwingingDoor(int32 component, eDoors door); void SetupDamageAfterLoad(void); CObject *SpawnFlyingComponent(int32 component, uint32 type); CObject *RemoveBonnetInPedCollision(void); diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 1a22e98a..6ea0e61e 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -92,7 +92,7 @@ CVehicle::RemoveLighting(bool reset) float CVehicle::GetHeightAboveRoad(void) { - return -1.0f * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.min.z; + return -1.0f * GetColModel()->boundingBox.min.z; } @@ -442,7 +442,7 @@ CVehicle::IsSphereTouchingVehicle(float sx, float sy, float sz, float radius) float x, y, z; // sphere relative to vehicle CVector sph = CVector(sx, sy, sz) - GetPosition(); - CColModel *colmodel = CModelInfo::GetModelInfo(GetModelIndex())->GetColModel(); + CColModel *colmodel = GetColModel(); x = DotProduct(sph, GetRight()); if(colmodel->boundingBox.min.x - radius > x || diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index e974eb88..5aa0a770 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -123,7 +123,7 @@ public: int8 m_nGettingOutFlags; uint8 m_nNumMaxPassengers; char field_1CD[19]; - CEntity *m_pCurSurface; + CEntity *m_pCurGroundEntity; CFire *m_pCarFire; float m_fSteerAngle; float m_fGasPedal; @@ -160,9 +160,9 @@ public: uint8 m_veh_flagD1 : 1; uint8 m_veh_flagD2 : 1; - uint8 m_veh_flagD4 : 1; - uint8 m_veh_flagD8 : 1; - uint8 bRecordedForReplay : 1; + uint8 bVehicleColProcessed : 1; + uint8 bIsCarParkVehicle : 1; + uint8 bHasAlreadyBeenRecorded : 1; uint8 m_veh_flagD20 : 1; uint8 m_veh_flagD40 : 1; uint8 m_veh_flagD80 : 1; @@ -263,7 +263,7 @@ public: }; static_assert(sizeof(CVehicle) == 0x288, "CVehicle: error"); -static_assert(offsetof(CVehicle, m_pCurSurface) == 0x1E0, "CVehicle: error"); +static_assert(offsetof(CVehicle, m_pCurGroundEntity) == 0x1E0, "CVehicle: error"); static_assert(offsetof(CVehicle, m_nAlarmState) == 0x1A0, "CVehicle: error"); static_assert(offsetof(CVehicle, m_nLastWeaponDamage) == 0x228, "CVehicle: error"); From a65dd41da736a12866526abc1405cbaa154771a8 Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 9 Jul 2019 18:50:35 +0200 Subject: [PATCH 18/30] yet more CAutomobile --- src/control/Darkel.cpp | 8 +-- src/control/Darkel.h | 7 ++- src/core/Camera.cpp | 1 + src/core/Camera.h | 2 + src/core/Explosion.cpp | 5 ++ src/core/Explosion.h | 15 +++++ src/core/Fire.cpp | 6 +- src/core/Fire.h | 21 ++++--- src/core/Wanted.cpp | 10 ++- src/core/Wanted.h | 1 + src/peds/Ped.cpp | 1 + src/peds/Ped.h | 1 + src/peds/PlayerPed.cpp | 13 ++++ src/peds/PlayerPed.h | 2 + src/vehicles/Automobile.cpp | 117 +++++++++++++++++++++++++++++++++++- src/vehicles/Automobile.h | 2 + src/vehicles/Vehicle.h | 12 ++-- 17 files changed, 201 insertions(+), 23 deletions(-) create mode 100644 src/core/Explosion.cpp create mode 100644 src/core/Explosion.h diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index f050a540..ab28f96e 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -123,18 +123,18 @@ eKillFrenzyStatus CDarkel::ReadStatus() } #if 1 -WRAPPER int32 CDarkel::RegisterCarBlownUpByPlayer(eKillFrenzyStatus status) { EAXJMP(0x421070); } +WRAPPER void CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle) { EAXJMP(0x421070); } #else -int32 CDarkel::RegisterCarBlownUpByPlayer(eKillFrenzyStatus status) +int32 CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle) { return 0; } #endif #if 1 -WRAPPER void CDarkel::RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag) { EAXJMP(0x420F60); } +WRAPPER void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot) { EAXJMP(0x420F60); } #else -void CDarkel::RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag) +void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot) { diff --git a/src/control/Darkel.h b/src/control/Darkel.h index da1df24a..35d849d2 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -1,6 +1,9 @@ #pragma once #include "Weapon.h" +class CVehicle; +class CPed; + enum eKillFrenzyStatus { KILLFRENZY_NONE, @@ -37,8 +40,8 @@ public: static void Init(); static int16 QueryModelsKilledByPlayer(int32 modelId); static eKillFrenzyStatus ReadStatus(); - static int32 RegisterCarBlownUpByPlayer(eKillFrenzyStatus status); - static void RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag); + static void RegisterCarBlownUpByPlayer(CVehicle *vehicle); + static void RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot = false); static void RegisterKillNotByPlayer(); static void ResetModelsKilledByPlayer(); static void ResetOnPlayerDeath(); diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 832f9455..0f4503bb 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -18,6 +18,7 @@ const float DefaultFOV = 70.0f; // beta: 80.0f CCamera &TheCamera = *(CCamera*)0x6FACF8; bool &CCamera::m_bUseMouse3rdPerson = *(bool *)0x5F03D8; +WRAPPER void CCamera::CamShake(float strength, float x, float y, float z) { EAXJMP(0x46B200); } WRAPPER void CCamera::DrawBordersForWideScreen(void) { EAXJMP(0x46B430); } WRAPPER void CCamera::CalculateDerivedValues(void) { EAXJMP(0x46EEA0); } WRAPPER void CCamera::Restore(void) { EAXJMP(0x46F990); } diff --git a/src/core/Camera.h b/src/core/Camera.h index db5fff46..f00a213e 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -454,6 +454,8 @@ int m_iModeObbeCamIsInForCar; void ProcessMusicFade(void); void SetFadeColour(uint8 r, uint8 g, uint8 b); + void CamShake(float strength, float x, float y, float z); + void SetMotionBlur(int r, int g, int b, int a, int type); void SetMotionBlurAlpha(int a); void RenderMotionBlur(void); diff --git a/src/core/Explosion.cpp b/src/core/Explosion.cpp new file mode 100644 index 00000000..f55cbcd6 --- /dev/null +++ b/src/core/Explosion.cpp @@ -0,0 +1,5 @@ +#include "common.h" +#include "patcher.h" +#include "Explosion.h" + +WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); } diff --git a/src/core/Explosion.h b/src/core/Explosion.h new file mode 100644 index 00000000..69508490 --- /dev/null +++ b/src/core/Explosion.h @@ -0,0 +1,15 @@ +#pragma once + +class CEntity; + +enum eExplosionType +{ + EXPLOSION_3 = 3, + EXPLOSION_4 +}; + +class CExplosion +{ +public: + static void AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32); +}; diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index 05d72199..bc59de2f 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -2,4 +2,8 @@ #include "patcher.h" #include "Fire.h" -WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); } \ No newline at end of file +CFireManager &gFireManager = *(CFireManager*)0x8F31D0; + +WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); } + +WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); } diff --git a/src/core/Fire.h b/src/core/Fire.h index c7f83fd8..9c9e1dec 100644 --- a/src/core/Fire.h +++ b/src/core/Fire.h @@ -1,13 +1,13 @@ #pragma once -#include "common.h" -#include "Entity.h" + +class CEntity; class CFire { - char m_bIsOngoing; - char m_bExists; - char m_bPropogationFlag; - char m_bAudioSet; + bool m_bIsOngoing; + bool m_bExists; + bool m_bPropogationFlag; + bool m_bAudioSet; CVector m_vecPos; CEntity *m_pEntity; CEntity *m_pSource; @@ -20,4 +20,11 @@ class CFire public: void Extinguish(void); -}; \ No newline at end of file +}; + +class CFireManager +{ +public: + void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32); +}; +extern CFireManager &gFireManager; diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp index 21853308..4608bfef 100644 --- a/src/core/Wanted.cpp +++ b/src/core/Wanted.cpp @@ -34,7 +34,7 @@ int CWanted::NumOfHelisRequired() return 2; default: return 0; - }; + } } void CWanted::SetWantedLevel(int32 level) @@ -70,11 +70,17 @@ void CWanted::SetWantedLevel(int32 level) UpdateWantedLevel(); } +void CWanted::SetWantedLevelNoDrop(int32 level) +{ + if (level > m_nWantedLevel) + SetWantedLevel(level); +} + void CWanted::ClearQdCrimes() { for (int i = 0; i < 16; i++) { m_sCrimes[i].m_eCrimeType = CRIME_NONE; - }; + } } void CWanted::UpdateWantedLevel() diff --git a/src/core/Wanted.h b/src/core/Wanted.h index d14bb905..d3f6638b 100644 --- a/src/core/Wanted.h +++ b/src/core/Wanted.h @@ -42,6 +42,7 @@ public: bool AreArmyRequired(); int NumOfHelisRequired(); void SetWantedLevel(int32); + void SetWantedLevelNoDrop(int32 level); void ClearQdCrimes(); void UpdateWantedLevel(); }; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index e0e0b913..28cb8823 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -28,6 +28,7 @@ WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); } WRAPPER void CPed::Say(uint16 audio) { EAXJMP(0x4E5A10); } WRAPPER void CPed::SetDie(AnimationId anim, float arg1, float arg2) { EAXJMP(0x4D37D0); } +WRAPPER void CPed::SetDead(void) { EAXJMP(0x4D3970); } WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); } WRAPPER void CPed::RestorePreviousState(void) { EAXJMP(0x4C5E30); } WRAPPER void CPed::ClearAttack(void) { EAXJMP(0x4E6790); } diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 6aba79cf..f48c30ba 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -414,6 +414,7 @@ public: void SetLookFlag(float direction, bool unknown); void SetLookTimer(int time); void SetDie(AnimationId anim, float arg1, float arg2); + void SetDead(void); void ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer); void RemoveBodyPart(PedNode nodeId, int8 unknown); void SpawnFlyingComponent(int, int8 unknown); diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 07cb5541..43206e08 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -21,6 +21,19 @@ void CPlayerPed::ClearWeaponTarget() ClearPointGunAt(); } +void +CPlayerPed::SetWantedLevel(int32 level) +{ + m_pWanted->SetWantedLevel(level); +} + +void +CPlayerPed::SetWantedLevelNoDrop(int32 level) +{ + m_pWanted->SetWantedLevelNoDrop(level); +} + + class CPlayerPed_ : public CPlayerPed { public: diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index 1a106b38..8b617a43 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -43,6 +43,8 @@ public: void ReApplyMoveAnims(void); void ClearWeaponTarget(); + void SetWantedLevel(int32 level); + void SetWantedLevelNoDrop(int32 level); }; static_assert(sizeof(CPlayerPed) == 0x5F0, "CPlayerPed: error"); diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 267e901a..54557dc2 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -4,15 +4,22 @@ #include "ModelIndices.h" #include "VisibilityPlugins.h" #include "DMAudio.h" +#include "Camera.h" +#include "Darkel.h" +#include "Fire.h" +#include "Explosion.h" #include "World.h" #include "SurfaceTable.h" #include "HandlingMgr.h" #include "CarCtrl.h" #include "PathFind.h" #include "Ped.h" +#include "PlayerPed.h" #include "Object.h" #include "Automobile.h" +RwObject *GetCurrentAtomicObjectCB(RwObject *object, void *data); + bool &CAutomobile::m_sAllTaxiLights = *(bool*)0x95CD21; WRAPPER CAutomobile* CAutomobile::ctor(int, uint8) { EAXJMP(0x52C6B0); } @@ -357,7 +364,88 @@ CAutomobile::RemoveRefsToVehicle(CEntity *ent) m_aGroundPhysical[i] = nil; } -WRAPPER void CAutomobile::BlowUpCar(CEntity *ent) { EAXJMP(0x53BC60); } +void +CAutomobile::BlowUpCar(CEntity *culprit) +{ + int i; + RpAtomic *atomic; + + if(!bCanBeDamaged) + return; + + // explosion pushes vehicle up + m_vecMoveSpeed.z += 0.13f; + m_status = STATUS_WRECKED; + bRenderScorched = true; + m_nTimeOfDeath = CTimer::GetTimeInMilliseconds(); + Damage.FuckCarCompletely(); + + if(GetModelIndex() != MI_RCBANDIT){ + SetBumperDamage(CAR_BUMP_FRONT, VEHBUMPER_FRONT); + SetBumperDamage(CAR_BUMP_REAR, VEHBUMPER_REAR); + SetDoorDamage(CAR_BONNET, DOOR_BONNET); + SetDoorDamage(CAR_BOOT, DOOR_BOOT); + SetDoorDamage(CAR_DOOR_LF, DOOR_FRONT_LEFT); + SetDoorDamage(CAR_DOOR_RF, DOOR_FRONT_RIGHT); + SetDoorDamage(CAR_DOOR_LR, DOOR_REAR_LEFT); + SetDoorDamage(CAR_DOOR_RR, DOOR_REAR_RIGHT); + SpawnFlyingComponent(CAR_WHEEL_LF, COMPGROUP_WHEEL); + RwFrameForAllObjects(m_aCarNodes[CAR_WHEEL_LF], GetCurrentAtomicObjectCB, &atomic); + if(atomic) + RpAtomicSetFlags(atomic, 0); + } + + m_fHealth = 0.0f; + m_nBombTimer = 0; + m_auto_flagA1 = false; + m_auto_flagA2 = false; + m_auto_flagA4 = false; + + TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z); + + // kill driver and passengers + if(pDriver){ + CDarkel::RegisterKillByPlayer(pDriver, WEAPONTYPE_EXPLOSION); + if(pDriver->GetPedState() == PED_DRIVING){ + pDriver->SetDead(); + if(!pDriver->IsPlayer()) + pDriver->FlagToDestroyWhenNextProcessed(); + }else + pDriver->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); + } + for(i = 0; i < m_nNumMaxPassengers; i++){ + if(pPassengers[i]){ + CDarkel::RegisterKillByPlayer(pPassengers[i], WEAPONTYPE_EXPLOSION); + if(pPassengers[i]->GetPedState() == PED_DRIVING){ + pPassengers[i]->SetDead(); + if(!pPassengers[i]->IsPlayer()) + pPassengers[i]->FlagToDestroyWhenNextProcessed(); + }else + pPassengers[i]->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); + } + } + + bEngineOn = false; + bLightsOn = false; + m_bSirenOrAlarm = false; + bTaxiLight = false; + if(bIsAmbulanceOnDuty){ + bIsAmbulanceOnDuty = false; + CCarCtrl::NumAmbulancesOnDuty--; + } + if(bIsFireTruckOnDuty){ + bIsFireTruckOnDuty = false; + CCarCtrl::NumFiretrucksOnDuty--; + } + ChangeLawEnforcerState(false); + + gFireManager.StartFire(this, culprit, 0.8f, 1); // TODO + CDarkel::RegisterCarBlownUpByPlayer(this); + if(GetModelIndex() == MI_RCBANDIT) + CExplosion::AddExplosion(this, culprit, EXPLOSION_4, GetPosition(), 0); // TODO + else + CExplosion::AddExplosion(this, culprit, EXPLOSION_3, GetPosition(), 0); // TODO +} bool CAutomobile::SetUpWheelColModel(CColModel *colModel) @@ -516,6 +604,31 @@ CAutomobile::SetupSuspensionLines(void) } } +// called on police cars +void +CAutomobile::ScanForCrimes(void) +{ + if(FindPlayerVehicle() && FindPlayerVehicle()->IsCar()) + if(FindPlayerVehicle()->m_nAlarmState != -1) + // if player's alarm is on, increase wanted level + if((FindPlayerVehicle()->GetPosition() - GetPosition()).MagnitudeSqr() < sq(20.0f)) + CWorld::Players[CWorld::PlayerInFocus].m_pPed->SetWantedLevelNoDrop(1); +} + +void +CAutomobile::BlowUpCarsInPath(void) +{ + int i; + + if(m_vecMoveSpeed.Magnitude() > 0.1f) + for(i = 0; i < m_nCollisionRecords; i++) + if(m_aCollisionRecords[i] && + m_aCollisionRecords[i]->IsVehicle() && + m_aCollisionRecords[i]->GetModelIndex() != MI_RHINO && + !m_aCollisionRecords[i]->bRenderScorched) + ((CVehicle*)m_aCollisionRecords[i])->BlowUpCar(this); +} + bool CAutomobile::HasCarStoppedBecauseOfLight(void) { @@ -1014,12 +1127,14 @@ STARTPATCHES InjectHook(0x52EFD0, &CAutomobile_::IsDoorClosed_, PATCH_JUMP); InjectHook(0x52F000, &CAutomobile_::IsDoorMissing_, PATCH_JUMP); InjectHook(0x53BF40, &CAutomobile_::RemoveRefsToVehicle_, PATCH_JUMP); + InjectHook(0x53BC60, &CAutomobile_::BlowUpCar_, PATCH_JUMP); InjectHook(0x53BF70, &CAutomobile_::SetUpWheelColModel_, PATCH_JUMP); InjectHook(0x53C0E0, &CAutomobile_::BurstTyre_, PATCH_JUMP); InjectHook(0x437690, &CAutomobile_::GetHeightAboveRoad_, PATCH_JUMP); InjectHook(0x53C450, &CAutomobile_::PlayCarHorn_, PATCH_JUMP); InjectHook(0x5353A0, &CAutomobile::ResetSuspension, PATCH_JUMP); InjectHook(0x52D210, &CAutomobile::SetupSuspensionLines, PATCH_JUMP); + InjectHook(0x53E000, &CAutomobile::BlowUpCarsInPath, PATCH_JUMP); InjectHook(0x42E220, &CAutomobile::HasCarStoppedBecauseOfLight, PATCH_JUMP); InjectHook(0x53D320, &CAutomobile::SetBusDoorTimer, PATCH_JUMP); InjectHook(0x53D370, &CAutomobile::ProcessAutoBusDoors, PATCH_JUMP); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index fc859f92..0e9bd945 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -91,6 +91,8 @@ public: void PlayHornIfNecessary(void); void ResetSuspension(void); void SetupSuspensionLines(void); + void ScanForCrimes(void); + void BlowUpCarsInPath(void); bool HasCarStoppedBecauseOfLight(void); void SetBusDoorTimer(uint32 timer, uint8 type); void ProcessAutoBusDoors(void); diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 5aa0a770..cd877da5 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -150,19 +150,19 @@ public: uint8 m_veh_flagB80 : 1; uint8 m_veh_flagC1 : 1; - uint8 bIsDamaged : 1; + uint8 bIsDamaged : 1; // This vehicle has been damaged and is displaying all its components uint8 m_veh_flagC4 : 1; uint8 m_veh_flagC8 : 1; uint8 m_veh_flagC10 : 1; uint8 m_veh_flagC20 : 1; - uint8 m_veh_flagC40 : 1; + uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions uint8 m_veh_flagC80 : 1; uint8 m_veh_flagD1 : 1; uint8 m_veh_flagD2 : 1; - uint8 bVehicleColProcessed : 1; - uint8 bIsCarParkVehicle : 1; - uint8 bHasAlreadyBeenRecorded : 1; + uint8 bVehicleColProcessed : 1;// Has ProcessEntityCollision been processed for this car? + uint8 bIsCarParkVehicle : 1; // Car has been created using the special CAR_PARK script command + uint8 bHasAlreadyBeenRecorded : 1; // Used for replays uint8 m_veh_flagD20 : 1; uint8 m_veh_flagD40 : 1; uint8 m_veh_flagD80 : 1; @@ -189,7 +189,7 @@ public: int8 field_22B; uint8 m_nCarHornTimer; int8 field_22D; - uint8 m_nSirenOrAlarm; + bool m_bSirenOrAlarm; int8 field_22F; // TODO: this is an array CStoredCollPoly m_frontCollPoly; // poly which is under front part of car From 11ae1b06ae658db4be9675dcad4da30493ff0bbc Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Tue, 9 Jul 2019 23:38:05 +0300 Subject: [PATCH 19/30] RunningScript: 1/12 --- src/control/Script.cpp | 699 ++++++++++++++++++++++++++++++++++- src/control/Script.h | 8 +- src/core/Camera.cpp | 1 + src/core/Camera.h | 1 + src/modelinfo/ModelIndices.h | 3 +- src/peds/PlayerPed.cpp | 3 + src/peds/PlayerPed.h | 4 + 7 files changed, 715 insertions(+), 4 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index ae2a45aa..d70b5ddb 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -99,7 +99,7 @@ void CMissionCleanup::AddEntityToList(int32 id, uint8 type) void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) { for (int i = 0; i < MAX_CLEANUP; i++){ - if (m_sEntities[i].type == type && m_sEntities[i].id == 0){ + if (m_sEntities[i].type == type && m_sEntities[i].id == id){ m_sEntities[i].id = 0; m_sEntities[i].type = CLEANUP_UNUSED; } @@ -681,7 +681,698 @@ int8 CRunningScript::ProcessOneCommand() return -1; } -WRAPPER int8 CRunningScript::ProcessCommandsFrom0To99(int32 command) { EAXJMP(0x439650); } +int8 CRunningScript::ProcessCommandsFrom0To99(int32 command) +{ + switch (command) { + case COMMAND_NOP: + return 0; + case COMMAND_WAIT: + CollectParameters(&m_nIp, 1); + m_nWakeTime = CTimer::GetTimeInMilliseconds() + ScriptParams[0]; + return 1; + case COMMAND_GOTO: + CollectParameters(&m_nIp, 1); + SetIP(ScriptParams[0] >= 0 ? ScriptParams[0] : SIZE_MAIN_SCRIPT - ScriptParams[0]); + /* Known issue: GOTO to 0. It might have been "better" to use > instead of >= */ + /* simply because it never makes sense to jump to start of the script */ + /* but jumping to start of a custom mission is an issue for simple mission-like scripts */ + /* However, it's not an issue for actual mission scripts, because they follow a structure */ + /* and never start with a loop. */ + return 0; + case COMMAND_SHAKE_CAM: + CollectParameters(&m_nIp, 1); + TheCamera.CamShake(ScriptParams[0] / 1000.0f); + return 0; + case COMMAND_SET_VAR_INT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *ptr = ScriptParams[0]; + return 0; + } + case COMMAND_SET_VAR_FLOAT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr = *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_SET_LVAR_INT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *ptr = ScriptParams[0]; + return 0; + } + case COMMAND_SET_LVAR_FLOAT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr = *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_ADD_VAL_TO_INT_VAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *ptr += ScriptParams[0]; + return 0; + } + case COMMAND_ADD_VAL_TO_FLOAT_VAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr += *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_ADD_VAL_TO_INT_LVAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *ptr += ScriptParams[0]; + return 0; + } + case COMMAND_ADD_VAL_TO_FLOAT_LVAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr += *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_SUB_VAL_FROM_INT_VAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *ptr -= ScriptParams[0]; + return 0; + } + case COMMAND_SUB_VAL_FROM_FLOAT_VAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr -= *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_SUB_VAL_FROM_INT_LVAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *ptr -= ScriptParams[0]; + return 0; + } + case COMMAND_SUB_VAL_FROM_FLOAT_LVAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr -= *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_MULT_INT_VAR_BY_VAL: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *ptr *= ScriptParams[0]; + return 0; + } + case COMMAND_MULT_FLOAT_VAR_BY_VAL: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr *= *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_MULT_INT_LVAR_BY_VAL: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *ptr *= ScriptParams[0]; + return 0; + } + case COMMAND_MULT_FLOAT_LVAR_BY_VAL: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr *= *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_DIV_INT_VAR_BY_VAL: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *ptr /= ScriptParams[0]; + return 0; + } + case COMMAND_DIV_FLOAT_VAR_BY_VAL: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr /= *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_DIV_INT_LVAR_BY_VAL: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *ptr /= ScriptParams[0]; + return 0; + } + case COMMAND_DIV_FLOAT_LVAR_BY_VAL: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr /= *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_IS_INT_VAR_GREATER_THAN_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr > ScriptParams[0]); + return 0; + } + case COMMAND_IS_INT_LVAR_GREATER_THAN_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr > ScriptParams[0]); + return 0; + } + case COMMAND_IS_NUMBER_GREATER_THAN_INT_VAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(ScriptParams[0] > *ptr); + return 0; + } + case COMMAND_IS_NUMBER_GREATER_THAN_INT_LVAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(ScriptParams[0] > *ptr); + return 0; + } + case COMMAND_IS_INT_VAR_GREATER_THAN_INT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*ptr1 > *ptr2); + return 0; + } + case COMMAND_IS_INT_LVAR_GREATER_THAN_INT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*ptr1 > *ptr2); + return 0; + } + case COMMAND_IS_INT_VAR_GREATER_THAN_INT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*ptr1 > *ptr2); + return 0; + } + case COMMAND_IS_INT_LVAR_GREATER_THAN_INT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*ptr1 > *ptr2); + return 0; + } + case COMMAND_IS_FLOAT_VAR_GREATER_THAN_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*(float*)ptr > *(float*)&ScriptParams[0]); + return 0; + } + case COMMAND_IS_FLOAT_LVAR_GREATER_THAN_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*(float*)ptr > *(float*)&ScriptParams[0]); + return 0; + } + case COMMAND_IS_NUMBER_GREATER_THAN_FLOAT_VAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*(float*)&ScriptParams[0] > *(float*)ptr); + return 0; + } + case COMMAND_IS_NUMBER_GREATER_THAN_FLOAT_LVAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*(float*)&ScriptParams[0] > *(float*)ptr); + return 0; + } + case COMMAND_IS_FLOAT_VAR_GREATER_THAN_FLOAT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*(float*)ptr1 > *(float*)ptr2); + return 0; + } + case COMMAND_IS_FLOAT_LVAR_GREATER_THAN_FLOAT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*(float*)ptr1 > *(float*)ptr2); + return 0; + } + case COMMAND_IS_FLOAT_VAR_GREATER_THAN_FLOAT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*(float*)ptr1 > *(float*)ptr2); + return 0; + } + case COMMAND_IS_FLOAT_LVAR_GREATER_THAN_FLOAT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*(float*)ptr1 > *(float*)ptr2); + return 0; + } + case COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr >= ScriptParams[0]); + return 0; + } + case COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr >= ScriptParams[0]); + return 0; + } + case COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_INT_VAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(ScriptParams[0] >= *ptr); + return 0; + } + case COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_INT_LVAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(ScriptParams[0] >= *ptr); + return 0; + } + case COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*ptr1 >= *ptr2); + return 0; + } + case COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*ptr1 >= *ptr2); + return 0; + } + case COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*ptr1 >= *ptr2); + return 0; + } + case COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*ptr1 >= *ptr2); + return 0; + } + case COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*(float*)ptr >= *(float*)&ScriptParams[0]); + return 0; + } + case COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*(float*)ptr >= *(float*)&ScriptParams[0]); + return 0; + } + case COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_VAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*(float*)&ScriptParams[0] >= *(float*)ptr); + return 0; + } + case COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_LVAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*(float*)&ScriptParams[0] >= *(float*)ptr); + return 0; + } + case COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*(float*)ptr1 >= *(float*)ptr2); + return 0; + } + case COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*(float*)ptr1 >= *(float*)ptr2); + return 0; + } + case COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*(float*)ptr1 >= *(float*)ptr2); + return 0; + } + case COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*(float*)ptr1 >= *(float*)ptr2); + return 0; + } + case COMMAND_IS_INT_VAR_EQUAL_TO_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr == ScriptParams[0]); + return 0; + } + case COMMAND_IS_INT_LVAR_EQUAL_TO_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr == ScriptParams[0]); + return 0; + } + case COMMAND_IS_INT_VAR_EQUAL_TO_INT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*ptr1 == *ptr2); + return 0; + } + case COMMAND_IS_INT_VAR_EQUAL_TO_INT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*ptr1 == *ptr2); + return 0; + } + case COMMAND_IS_INT_LVAR_EQUAL_TO_INT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*ptr1 == *ptr2); + return 0; + } + case COMMAND_IS_FLOAT_VAR_EQUAL_TO_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*(float*)ptr == *(float*)&ScriptParams[0]); + return 0; + } + case COMMAND_IS_FLOAT_LVAR_EQUAL_TO_NUMBER: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*(float*)ptr == *(float*)&ScriptParams[0]); + return 0; + } + case COMMAND_IS_FLOAT_VAR_EQUAL_TO_FLOAT_VAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(*(float*)ptr1 == *(float*)ptr2); + return 0; + } + case COMMAND_IS_FLOAT_VAR_EQUAL_TO_FLOAT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*(float*)ptr1 == *(float*)ptr2); + return 0; + } + case COMMAND_IS_FLOAT_LVAR_EQUAL_TO_FLOAT_LVAR: + { + int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(*(float*)ptr1 == *(float*)ptr2); + return 0; + } + case COMMAND_GOTO_IF_TRUE: + CollectParameters(&m_nIp, 1); + if (m_bCondResult) + SetIP(ScriptParams[0] >= 0 ? ScriptParams[0] : SIZE_MAIN_SCRIPT - ScriptParams[0]); + /* Check COMMAND_GOTO note. */ + return 0; + case COMMAND_GOTO_IF_FALSE: + CollectParameters(&m_nIp, 1); + if (!m_bCondResult) + SetIP(ScriptParams[0] >= 0 ? ScriptParams[0] : SIZE_MAIN_SCRIPT - ScriptParams[0]); + /* Check COMMAND_GOTO note. */ + return 0; + case COMMAND_TERMINATE_THIS_SCRIPT: + if (m_bMissionFlag) + CTheScripts::bAlreadyRunningAMissionScript = false; + RemoveScriptFromList(&CTheScripts::pActiveScripts); + AddScriptToList(&CTheScripts::pIdleScripts); + return 1; + case COMMAND_START_NEW_SCRIPT: + { + CollectParameters(&m_nIp, 1); + assert(ScriptParams[0] >= 0); + CRunningScript* pNew = CTheScripts::StartNewScript(ScriptParams[0]); + int8 type = CTheScripts::Read1ByteFromScript(&m_nIp); + float tmp; + for (int i = 0; type != ARGUMENT_END; type = CTheScripts::Read1ByteFromScript(&m_nIp), i++) { + switch (type) { + case ARGUMENT_INT32: + pNew->m_anLocalVariables[i] = CTheScripts::Read4BytesFromScript(&m_nIp); + break; + case ARGUMENT_GLOBALVAR: + pNew->m_anLocalVariables[i] = *(int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(&m_nIp)]; + break; + case ARGUMENT_LOCALVAR: + pNew->m_anLocalVariables[i] = m_anLocalVariables[CTheScripts::Read2BytesFromScript(&m_nIp)]; + break; + case ARGUMENT_INT8: + pNew->m_anLocalVariables[i] = CTheScripts::Read1ByteFromScript(&m_nIp); + break; + case ARGUMENT_INT16: + pNew->m_anLocalVariables[i] = CTheScripts::Read2BytesFromScript(&m_nIp); + break; + case ARGUMENT_FLOAT: + tmp = CTheScripts::ReadFloatFromScript(&m_nIp); + pNew->m_anLocalVariables[i] = *(int32*)&tmp; + break; + default: + break; + } + } + return 0; + } + case COMMAND_GOSUB: + CollectParameters(&m_nIp, 1); + assert(m_nStackPointer < MAX_STACK_DEPTH); + m_anStack[m_nStackPointer++] = m_nIp; + SetIP(ScriptParams[0] >= 0 ? ScriptParams[0] : SIZE_MAIN_SCRIPT - ScriptParams[0]); + return 0; + case COMMAND_RETURN: + assert(m_nStackPointer > 0); /* No more SSU */ + SetIP(m_anStack[--m_nStackPointer]); + return 0; + case COMMAND_LINE: + CollectParameters(&m_nIp, 6); + /* Something must have been here */ + return 0; + case COMMAND_CREATE_PLAYER: + { + CollectParameters(&m_nIp, 4); + int32 index = ScriptParams[0]; + assert(index < 1); /* Constant? Also no more double player glitch */ + debug("&&&&&&&&&&&&&Creating player: %d\n", index); + if (!CStreaming::HasModelLoaded(MI_PLAYER)) { + CStreaming::RequestSpecialModel(MI_PLAYER, "player", STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY); + CStreaming::LoadAllRequestedModels(false); + } + CPlayerPed::SetupPlayerPed(index); + CWorld::Players[index].m_pPed->CharCreatedBy = MISSION_CHAR; + CPlayerPed::DeactivatePlayerPed(index); + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + pos.z += CWorld::Players[index].m_pPed->GetDistanceFromCentreOfMassToBaseOfModel(); + CWorld::Players[index].m_pPed->GetPosition() = pos; + CTheScripts::ClearSpaceForMissionEntity(pos, CWorld::Players[index].m_pPed); + CPlayerPed::ReactivatePlayerPed(index); + ScriptParams[0] = index; + StoreParameters(&m_nIp, 1); + return 0; + } + case COMMAND_GET_PLAYER_COORDINATES: + { + CVector pos; + CollectParameters(&m_nIp, 1); + if (CWorld::Players[ScriptParams[0]].m_pPed->bInVehicle) + pos = CWorld::Players[ScriptParams[0]].m_pPed->m_pMyVehicle->GetPosition(); + else + pos = CWorld::Players[ScriptParams[0]].m_pPed->GetPosition(); + *(CVector*)&ScriptParams[0] = pos; + StoreParameters(&m_nIp, 3); + } + case COMMAND_SET_PLAYER_COORDINATES: + { + CollectParameters(&m_nIp, 4); + CVector pos = *(CVector*)&ScriptParams[1]; + int index = ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + CPlayerPed* ped = CWorld::Players[index].m_pPed; + if (!ped->bInVehicle) { + pos.z += ped->GetDistanceFromCentreOfMassToBaseOfModel(); + ped->Teleport(pos); + CTheScripts::ClearSpaceForMissionEntity(pos, ped); + return 0; + } + pos.z += ped->m_pMyVehicle->GetDistanceFromCentreOfMassToBaseOfModel(); + if (ped->m_pMyVehicle->IsBoat()) + ped->m_pMyVehicle->Teleport(pos); + else + ped->m_pMyVehicle->Teleport(pos); + /* I'll keep this condition here but obviously it is absolutely pointless */ + /* It's clearly present in disassembly so it had to be in original code */ + CTheScripts::ClearSpaceForMissionEntity(pos, ped->m_pMyVehicle); + return 0; + } + case COMMAND_IS_PLAYER_IN_AREA_2D: + { + CollectParameters(&m_nIp, 6); + CPlayerPed* ped = CWorld::Players[ScriptParams[0]].m_pPed; + float x1, y1, x2, y2; + x1 = *(float*)&ScriptParams[1]; + y1 = *(float*)&ScriptParams[2]; + x2 = *(float*)&ScriptParams[3]; + y2 = *(float*)&ScriptParams[4]; + if (!ped->bInVehicle) + UpdateCompareFlag(ped->IsWithinArea(x1, y1, x2, y2)); + else + UpdateCompareFlag(ped->m_pMyVehicle->IsWithinArea(x1, y1, x2, y2)); + if (!ScriptParams[5]) + return 0; + CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f); + if (CTheScripts::DbgFlag) + CTheScripts::DrawDebugSquare(x1, y1, x2, y2); + return 0; + } + case COMMAND_IS_PLAYER_IN_AREA_3D: + { + CollectParameters(&m_nIp, 8); + CPlayerPed* ped = CWorld::Players[ScriptParams[0]].m_pPed; + float x1, y1, z1, x2, y2, z2; + x1 = *(float*)&ScriptParams[1]; + y1 = *(float*)&ScriptParams[2]; + z1 = *(float*)&ScriptParams[3]; + x2 = *(float*)&ScriptParams[4]; + y2 = *(float*)&ScriptParams[5]; + z2 = *(float*)&ScriptParams[6]; + if (ped->bInVehicle) + UpdateCompareFlag(ped->IsWithinArea(x1, y1, z1, x2, y2, z2)); + else + UpdateCompareFlag(ped->m_pMyVehicle->IsWithinArea(x1, y1, z1, x2, y2, z2)); + if (!ScriptParams[7]) + return 0; + CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f); + if (CTheScripts::DbgFlag) + CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2); + return 0; + } + case COMMAND_ADD_INT_VAR_TO_INT_VAR: + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_ADD_INT_LVAR_TO_INT_VAR: + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_ADD_INT_VAR_TO_INT_LVAR: + *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_ADD_INT_LVAR_TO_INT_LVAR: + *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_ADD_FLOAT_VAR_TO_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_ADD_FLOAT_VAR_TO_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_SUB_INT_VAR_FROM_INT_VAR: + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_SUB_INT_LVAR_FROM_INT_LVAR: + *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + default: + break; + } + return -1; +} + +void CRunningScript::UpdateCompareFlag(bool flag) +{ + if (m_bNotFlag) + flag = !flag; + if (m_nAndOrState == 0){ + m_bCondResult = flag; + return; + } + if (m_nAndOrState >= 1 && m_nAndOrState <= 8) { /* Maybe enums?*/ + m_bCondResult &= flag; + if (m_nAndOrState == 1){ + m_nAndOrState = 0; + return; + } + }else if (m_nAndOrState >= 21 && m_nAndOrState <= 28){ + m_bCondResult |= flag; + if (m_nAndOrState == 21) { + m_nAndOrState = 0; + return; + } + }else{ + return; + } + m_nAndOrState--; +} + + WRAPPER int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) { EAXJMP(0x43AEA0); } WRAPPER int8 CRunningScript::ProcessCommandsFrom200To299(int32 command) { EAXJMP(0x43D530); } WRAPPER int8 CRunningScript::ProcessCommandsFrom300To399(int32 command) { EAXJMP(0x43ED30); } @@ -696,7 +1387,11 @@ WRAPPER int8 CRunningScript::ProcessCommandsFrom1100To1199(int32 command) { EAXJ WRAPPER void CTheScripts::DrawScriptSpheres() { EAXJMP(0x44FAC0); } WRAPPER void CRunningScript::DoDeatharrestCheck() { EAXJMP(0x452A30); } +WRAPPER void CTheScripts::DrawDebugSquare(float, float, float, float) { EAXJMP(0x452D00); } +WRAPPER void CTheScripts::DrawDebugCube(float, float, float, float, float, float) { EAXJMP(0x453100); } WRAPPER void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2) { EAXJMP(0x4534E0); } +WRAPPER void CTheScripts::ClearSpaceForMissionEntity(const CVector&, CEntity*) { EAXJMP(0x454060); } +WRAPPER void CTheScripts::HighlightImportantArea(uint32, float, float, float, float, float) { EAXJMP(0x454320); } WRAPPER void CTheScripts::CleanUpThisVehicle(CVehicle*) { EAXJMP(0x4548D0); } WRAPPER void CTheScripts::CleanUpThisPed(CPed*) { EAXJMP(0x4547A0); } WRAPPER void CTheScripts::CleanUpThisObject(CObject*) { EAXJMP(0x454910); } diff --git a/src/control/Script.h b/src/control/Script.h index 13290e0f..0cbd40c0 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -112,6 +112,7 @@ public: int8 ProcessCommandsFrom900To999(int32); int8 ProcessCommandsFrom1000To1099(int32); int8 ProcessCommandsFrom1100To1199(int32); + void UpdateCompareFlag(bool); }; enum { @@ -193,7 +194,8 @@ public: }; enum { - ARGUMENT_INT32 = 1, + ARGUMENT_END = 0, + ARGUMENT_INT32, ARGUMENT_GLOBALVAR, ARGUMENT_LOCALVAR, ARGUMENT_INT8, @@ -307,6 +309,10 @@ public: static void UpdateObjectIndices(); static void ReadMultiScriptFileOffsetsFromScript(); static void DrawScriptSpheres(); + static void ClearSpaceForMissionEntity(const CVector&, CEntity*); + static void HighlightImportantArea(uint32, float, float, float, float, float); + static void DrawDebugSquare(float, float, float, float); + static void DrawDebugCube(float, float, float, float, float, float); static int32 Read4BytesFromScript(uint32* pIp){ int32 retval = 0; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 58e65d24..6cafaade 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -22,6 +22,7 @@ WRAPPER void CCamera::DrawBordersForWideScreen(void) { EAXJMP(0x46B430); } WRAPPER void CCamera::CalculateDerivedValues(void) { EAXJMP(0x46EEA0); } WRAPPER void CCamera::Restore(void) { EAXJMP(0x46F990); } WRAPPER void CCamera::SetWidescreenOff(void) { EAXJMP(0x46FF10); } +WRAPPER void CCamera::CamShake(float) { EAXJMP(0x46B100); } bool CCamera::IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat) diff --git a/src/core/Camera.h b/src/core/Camera.h index db5fff46..da0e55eb 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -463,6 +463,7 @@ int m_iModeObbeCamIsInForCar; void DrawBordersForWideScreen(void); void Restore(void); void SetWidescreenOff(void); + void CamShake(float); void dtor(void) { this->CCamera::~CCamera(); } }; diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h index 95b5eb43..0d9ffb53 100644 --- a/src/modelinfo/ModelIndices.h +++ b/src/modelinfo/ModelIndices.h @@ -164,7 +164,8 @@ // expand as needed enum { - MI_COP = 1, + MI_PLAYER = 0, + MI_COP, MI_SWAT, MI_FBI, MI_ARMY, diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 07cb5541..9005e29f 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -10,6 +10,9 @@ CPlayerPed::~CPlayerPed() } WRAPPER void CPlayerPed::ReApplyMoveAnims(void) { EAXJMP(0x4F07C0); } +WRAPPER void CPlayerPed::SetupPlayerPed(int32) { EAXJMP(0x4EFB60); } +WRAPPER void CPlayerPed::DeactivatePlayerPed(int32) { EAXJMP(0x4EFC00); } +WRAPPER void CPlayerPed::ReactivatePlayerPed(int32) { EAXJMP(0x4EFC20); } void CPlayerPed::ClearWeaponTarget() { diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index 1a106b38..25bbdf4a 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -43,6 +43,10 @@ public: void ReApplyMoveAnims(void); void ClearWeaponTarget(); + + static void SetupPlayerPed(int32); + static void DeactivatePlayerPed(int32); + static void ReactivatePlayerPed(int32); }; static_assert(sizeof(CPlayerPed) == 0x5F0, "CPlayerPed: error"); From 7174dffebccac082c0985285e575ce21e75c8bd5 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 10 Jul 2019 00:01:02 +0300 Subject: [PATCH 20/30] fix --- src/control/Script.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index d70b5ddb..8e9033b6 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -1237,6 +1237,7 @@ int8 CRunningScript::ProcessCommandsFrom0To99(int32 command) pos = CWorld::Players[ScriptParams[0]].m_pPed->GetPosition(); *(CVector*)&ScriptParams[0] = pos; StoreParameters(&m_nIp, 3); + return 0; } case COMMAND_SET_PLAYER_COORDINATES: { From 702cd0076506dad26abc3c5239a2cfddfa7deb00 Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 9 Jul 2019 23:49:44 +0200 Subject: [PATCH 21/30] more CVehicle --- src/audio/DMAudio.cpp | 2 +- src/audio/DMAudio.h | 2 +- src/control/AutoPilot.h | 39 +++++++- src/core/PlayerInfo.cpp | 3 +- src/core/PlayerInfo.h | 1 + src/core/re3.cpp | 6 +- src/vehicles/Automobile.cpp | 25 ++--- src/vehicles/Automobile.h | 7 +- src/vehicles/Vehicle.cpp | 195 ++++++++++++++++++++++++++++++++++++ src/vehicles/Vehicle.h | 28 +++++- 10 files changed, 278 insertions(+), 30 deletions(-) diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp index 6a53623c..b4fee67f 100644 --- a/src/audio/DMAudio.cpp +++ b/src/audio/DMAudio.cpp @@ -19,7 +19,7 @@ WRAPPER void cDMAudio::ChangeMusicMode(uint8 mode) { EAXJMP(0x57CCF0); } WRAPPER void cDMAudio::PlayFrontEndSound(uint32, uint32) { EAXJMP(0x57CC20); } WRAPPER void cDMAudio::PlayFrontEndTrack(uint32, uint32) { EAXJMP(0x57CC80); } WRAPPER void cDMAudio::StopFrontEndTrack() { EAXJMP(0x57CCB0); } -WRAPPER void cDMAudio::PlayOneShot(int32, uint16 /*eSound*/, float) { EAXJMP(0x57C840); } +WRAPPER void cDMAudio::PlayOneShot(int32 audioentity, uint16 sound/*eSound*/, float) { EAXJMP(0x57C840); } WRAPPER void cDMAudio::SetMusicMasterVolume(int8) { EAXJMP(0x57C8C0); } WRAPPER void cDMAudio::SetEffectsMasterVolume(int8) { EAXJMP(0x57C890); } WRAPPER int8 cDMAudio::SetCurrent3DProvider(int8) { EAXJMP(0x57C9B0); } diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h index 72e8d316..8be09ac6 100644 --- a/src/audio/DMAudio.h +++ b/src/audio/DMAudio.h @@ -190,7 +190,7 @@ public: void PlayFrontEndSound(uint32, uint32); void PlayFrontEndTrack(uint32, uint32); void StopFrontEndTrack(); - void PlayOneShot(int32, uint16, float); + void PlayOneShot(int32 audioentity, uint16 sound/*eSound*/, float); void SetMusicMasterVolume(int8); void SetEffectsMasterVolume(int8); int8 SetCurrent3DProvider(int8); diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h index 351fd117..364cb633 100644 --- a/src/control/AutoPilot.h +++ b/src/control/AutoPilot.h @@ -59,9 +59,9 @@ enum eCarDrivingStyle : uint8 class CAutoPilot { public: - uint32 m_currentAddress; - uint32 m_startingRouteNode; - uint32 m_PreviousRouteNode; + uint32 m_nCurrentRouteNode; + uint32 m_nNextRouteNode; + uint32 m_nPrevRouteNode; uint32 m_nTotalSpeedScaleFactor; uint32 m_nSpeedScaleFactor; uint32 m_nCurrentPathNodeInfo; @@ -80,10 +80,41 @@ public: uint8 m_nAnimationTime; float m_fMaxTrafficSpeed; uint8 m_nCruiseSpeed; - uint8 m_nCarCtrlFlags; + uint8 m_flag1 : 1; + uint8 m_flag2 : 1; + uint8 m_flag4 : 1; + uint8 m_flag8 : 1; + uint8 m_flag10 : 1; CVector m_vecDestinationCoors; void *m_aPathFindNodesInfo[8]; uint16 m_nPathFindNodesCount; CVehicle *m_pTargetCar; + + CAutoPilot(void) { + m_nPrevRouteNode = 0; + m_nNextRouteNode = m_nPrevRouteNode; + m_nCurrentRouteNode = m_nNextRouteNode; + m_nTotalSpeedScaleFactor = 0; + m_nSpeedScaleFactor = 1000; + m_nPreviousPathNodeInfo = 0; + m_nNextPathNodeInfo = m_nPreviousPathNodeInfo; + m_nCurrentPathNodeInfo = m_nNextPathNodeInfo; + m_nNextDirection = 1; + m_nCurrentDirecton = m_nNextDirection; + m_nCurrentPathDirection = 0; + m_nPreviousPathDirection = m_nCurrentPathDirection; + m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS; + m_nCarMission = MISSION_NONE; + m_nAnimationId = TEMPACT_NONE; + m_nCruiseSpeed = 10; + m_fMaxTrafficSpeed = 10.0f; + m_flag2 = false; + m_flag1 = false; + m_nPathFindNodesCount = 0; + m_pTargetCar = 0; + m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + m_nTimeSwitchedToRealPhysics = m_nTimeToStartMission; + m_flag8 = false; + } }; static_assert(sizeof(CAutoPilot) == 0x70, "CAutoPilot: error"); diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 59efe2ae..9d003e76 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -2,4 +2,5 @@ #include "patcher.h" #include "PlayerInfo.h" -WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); } \ No newline at end of file +WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); } +WRAPPER void CPlayerInfo::AwardMoneyForExplosion(CVehicle *vehicle) { EAXJMP(0x4A15F0); } diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index e2b42fe7..a9763766 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -67,6 +67,7 @@ public: RwTexture *m_pSkinTexture; void MakePlayerSafe(bool); + void AwardMoneyForExplosion(CVehicle *vehicle); }; static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error"); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index f266ffab..8bb9caee 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -158,8 +158,12 @@ void FixCar(void) { CVehicle *veh = FindPlayerVehicle(); - if(veh == nil || !veh->IsCar()) + if(veh == nil) return; + veh->m_fHealth = 1000.0f; + if(!veh->IsCar()) + return; + ((CAutomobile*)veh)->Damage.SetEngineStatus(0); ((CAutomobile*)veh)->Fix(); } diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 54557dc2..7d3f8ee3 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -24,9 +24,9 @@ bool &CAutomobile::m_sAllTaxiLights = *(bool*)0x95CD21; WRAPPER CAutomobile* CAutomobile::ctor(int, uint8) { EAXJMP(0x52C6B0); } -CAutomobile::CAutomobile(int mi, uint8 owner) +CAutomobile::CAutomobile(int mi, uint8 CreatedBy) { - ctor(mi, owner); + ctor(mi, CreatedBy); } @@ -397,9 +397,7 @@ CAutomobile::BlowUpCar(CEntity *culprit) m_fHealth = 0.0f; m_nBombTimer = 0; - m_auto_flagA1 = false; - m_auto_flagA2 = false; - m_auto_flagA4 = false; + m_auto_flagA7 = 0; TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z); @@ -535,9 +533,8 @@ CAutomobile::PlayCarHorn(void) void CAutomobile::PlayHornIfNecessary(void) { - // TODO: flags - if(m_autoPilot.m_nCarCtrlFlags & 2 || - m_autoPilot.m_nCarCtrlFlags & 1) + if(m_autoPilot.m_flag2 || + m_autoPilot.m_flag1) if(!HasCarStoppedBecauseOfLight()) PlayCarHorn(); } @@ -637,20 +634,20 @@ CAutomobile::HasCarStoppedBecauseOfLight(void) if(m_status != STATUS_SIMPLE && m_status != STATUS_PHYSICS) return false; - if(m_autoPilot.m_currentAddress && m_autoPilot.m_startingRouteNode){ - CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_currentAddress]; + if(m_autoPilot.m_nCurrentRouteNode && m_autoPilot.m_nNextRouteNode){ + CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_nCurrentRouteNode]; for(i = 0; i < curnode->numLinks; i++) - if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_startingRouteNode) + if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_nNextRouteNode) break; if(i < curnode->numLinks && ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO return true; } - if(m_autoPilot.m_currentAddress && m_autoPilot.m_PreviousRouteNode){ - CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_currentAddress]; + if(m_autoPilot.m_nCurrentRouteNode && m_autoPilot.m_nPrevRouteNode){ + CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_nCurrentRouteNode]; for(i = 0; i < curnode->numLinks; i++) - if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_PreviousRouteNode) + if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_nPrevRouteNode) break; if(i < curnode->numLinks && ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 0e9bd945..60e08d0a 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -24,9 +24,7 @@ public: float m_aWheelPosition[4]; float m_aWheelSpeed[4]; uint8 field_4D8; - uint8 m_auto_flagA1 : 1; - uint8 m_auto_flagA2 : 1; - uint8 m_auto_flagA4 : 1; + uint8 m_auto_flagA7 : 1; uint8 bTaxiLight : 1; uint8 m_auto_flagA10 : 1; uint8 m_auto_flagA20 : 1; @@ -39,7 +37,8 @@ public: float m_aSuspensionLineLength[4]; float m_fHeightAboveRoad; float m_fImprovedHandling; - uint8 stuff6[32]; + uint8 stuff6[28]; + float field_530; CPhysical *m_aGroundPhysical[4]; // physicals touching wheels CVector m_aGroundOffset[4]; // from ground object to colpoint CEntity *m_pBlowUpEntity; diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 6ea0e61e..c541bae5 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -1,7 +1,9 @@ #include "common.h" #include "main.h" #include "patcher.h" +#include "General.h" #include "Timer.h" +#include "Pad.h" #include "Vehicle.h" #include "Pools.h" #include "HandlingMgr.h" @@ -13,6 +15,7 @@ #include "PointLights.h" #include "Renderer.h" #include "DMAudio.h" +#include "MusicManager.h" #include "Radar.h" bool &CVehicle::bWheelsOnlyCheat = *(bool *)0x95CD78; @@ -27,6 +30,79 @@ void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehicleP void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); } void CVehicle::operator delete(void *p, int handle) { CPools::GetVehiclePool()->Delete((CVehicle*)p); } +CVehicle::CVehicle(uint8 CreatedBy) +{ + int i; + + m_nCurrentGear = 0; + field_208 = 0; + m_fSteerRatio = 0.0f; + m_type = ENTITY_TYPE_VEHICLE; + VehicleCreatedBy = CreatedBy; + bIsLocked = false; + bIsLawEnforcer = false; + bIsAmbulanceOnDuty = false; + bIsFireTruckOnDuty = false; + CCarCtrl::UpdateCarCount(this, false); + m_fHealth = 1000.0f; + bEngineOn = true; + bFreebies = true; + pDriver = nil; + m_nNumPassengers = 0; + m_nNumGettingIn = 0; + m_nGettingInFlags = 0; + m_nGettingOutFlags = 0; + m_nNumMaxPassengers = 8; + for(i = 0; i < m_nNumMaxPassengers; i++) + pPassengers[i] = nil; + m_nBombTimer = 0; + m_pWhoSetMeOnFire = nil; + field_1FB = 0; + m_veh_flagB10 = false; + m_veh_flagB40 = false; + m_veh_flagB80 = false; + m_veh_flagC1 = false; + bIsDamaged = false; + m_veh_flagC8 = false; + m_veh_flagC10 = false; + m_veh_flagC4 = false; + m_veh_flagC20 = false; + bCanBeDamaged = true; + m_veh_flagC80 = false; + m_veh_flagD1 = false; + m_veh_flagD2 = false; + m_nGunFiringTime = 0; + field_214 = 0; + bLightsOn = false; + bVehicleColProcessed = false; + field_1F9 = 0; + bIsCarParkVehicle = false; + bHasAlreadyBeenRecorded = false; + m_bSirenOrAlarm = 0; + m_nCarHornTimer = 0; + field_22D = 0; + m_nAlarmState = 0; + m_nDoorLock = CARLOCK_UNLOCKED; + m_nLastWeaponDamage = -1; + field_220 = 0.0; + field_21C = field_220; + m_audioEntityId = DMAudio.CreateEntity(0, this); + if(m_audioEntityId) + DMAudio.SetEntityStatus(m_audioEntityId, true); + m_nRadioStation = CGeneral::GetRandomNumber() % USERTRACK; + m_pCurGroundEntity = nil; + field_22A = 0; + field_22B = 0; + field_22F = 0; + m_aCollPolys[0].valid = false; + m_aCollPolys[1].valid = false; + m_autoPilot.m_nCarMission = MISSION_NONE; + m_autoPilot.m_nAnimationId = TEMPACT_NONE; + m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + m_autoPilot.m_flag4 = false; + m_autoPilot.m_flag10 = false; +} + CVehicle::~CVehicle() { m_nAlarmState = 0; @@ -54,6 +130,67 @@ CVehicle::~CVehicle() } } +void +CVehicle::FlyingControl(eFlightModel flightModel) +{ + switch(flightModel){ + case FLIGHT_MODEL_DODO: + { + // This seems pretty magic + + // Move Left/Right + float moveSpeed = m_vecMoveSpeed.Magnitude(); + float sideSpeed = DotProduct(m_vecMoveSpeed, GetRight()); + float sideImpulse = -1.0f * sideSpeed / moveSpeed; + float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward()); + float magic = m_vecMoveSpeed.MagnitudeSqr() * sq(fwdSpeed); + float turnImpulse = (sideImpulse*0.003f + m_fSteerAngle*0.001f) * + magic*m_fTurnMass*CTimer::GetTimeStep(); + ApplyTurnForce(turnImpulse*GetRight(), -4.0f*GetForward()); + + float impulse = sideImpulse*0.2f * + magic*m_fMass*CTimer::GetTimeStep(); + ApplyMoveForce(impulse*GetRight()); + ApplyTurnForce(impulse*GetRight(), 2.0f*GetUp()); + + + // Move Up/Down + moveSpeed = m_vecMoveSpeed.Magnitude(); + float upSpeed = DotProduct(m_vecMoveSpeed, GetUp()); + float upImpulse = -1.0f * upSpeed / moveSpeed; + turnImpulse = (upImpulse*0.002f + -CPad::GetPad(0)->GetSteeringUpDown()/128.0f*0.001f) * + magic*m_fTurnMass*CTimer::GetTimeStep(); + ApplyTurnForce(turnImpulse*GetUp(), -4.0f*GetForward()); + + impulse = (upImpulse*3.5f + 0.5f)*0.05f * + magic*m_fMass*CTimer::GetTimeStep(); + if(GRAVITY*m_fMass*CTimer::GetTimeStep() < impulse && + GetPosition().z > 100.0f) + impulse = 0.9f*GRAVITY*m_fMass*CTimer::GetTimeStep(); + CVector com = Multiply3x3(GetMatrix(), m_vecCentreOfMass); + ApplyMoveForce(impulse*GetUp()); + ApplyTurnForce(impulse*GetUp(), 2.0f*GetUp() + com); + + + m_vecTurnSpeed.y *= powf(0.9f, CTimer::GetTimeStep()); + moveSpeed = m_vecMoveSpeed.MagnitudeSqr(); + if(moveSpeed > 2.25f) + m_vecMoveSpeed *= 1.5f/sqrt(moveSpeed); + + float turnSpeed = m_vecTurnSpeed.MagnitudeSqr(); + if(turnSpeed > 0.04f) + m_vecTurnSpeed *= 0.2f/sqrt(turnSpeed); + } + break; + + case FLIGHT_MODEL_RCPLANE: + case FLIGHT_MODEL_SEAPLANE: + assert(0 && "Plane flight model not implemented"); + case FLIGHT_MODEL_HELI: + assert(0 && "Heli flight model not implemented"); + } +} + void CVehicle::SetModelIndex(uint32 id) { @@ -96,6 +233,60 @@ CVehicle::GetHeightAboveRoad(void) } +void +CVehicle::ExtinguishCarFire(void) +{ + m_fHealth = max(m_fHealth, 300.0f); + if(m_pCarFire) + m_pCarFire->Extinguish(); + if(IsCar()){ + CAutomobile *car = (CAutomobile*)this; + if(car->Damage.GetEngineStatus() >= 225) + car->Damage.SetEngineStatus(215); + car->field_530 = 0.0f; + } +} + +void +CVehicle::ProcessDelayedExplosion(void) +{ + if(m_nBombTimer == 0) + return; + + if(m_nBombTimer == 0){ + int tick = CTimer::GetTimeStep()/60.0f*1000.0f; + if(tick > m_nBombTimer) + m_nBombTimer = 0; + else + m_nBombTimer -= tick; + + if(IsCar() && ((CAutomobile*)this)->m_auto_flagA7 == 4 && (m_nBombTimer & 0xFE00) != 0xFE00) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_BOMB_TICK, 0.0f); + + if(FindPlayerVehicle() != this && m_pWhoSetMeOnFire == FindPlayerPed()) + CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this); + BlowUpCar(m_pWhoSetMeOnFire); + } +} + +float +CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius) +{ + float angularVelocity; + switch(state){ + case WHEEL_STATE_1: + angularVelocity = -1.1f; // constant speed forward + break; + case WHEEL_STATE_3: + angularVelocity = 0.0f; // not moving + break; + default: + angularVelocity = -DotProduct(fwd, speed) / radius; // forward speed + break; + } + return angularVelocity * CTimer::GetTimeStep(); +} + bool CVehicle::IsLawEnforcementVehicle(void) { @@ -477,6 +668,10 @@ STARTPATCHES InjectHook(0x4A7E60, &CVehicle_::RemoveLighting_, PATCH_JUMP); InjectHook(0x417E60, &CVehicle_::GetHeightAboveRoad_, PATCH_JUMP); + InjectHook(0x552BB0, &CVehicle::FlyingControl, PATCH_JUMP); + InjectHook(0x552AF0, &CVehicle::ExtinguishCarFire, PATCH_JUMP); + InjectHook(0x551C90, &CVehicle::ProcessDelayedExplosion, PATCH_JUMP); + InjectHook(0x551280, &CVehicle::ProcessWheelRotation, PATCH_JUMP); InjectHook(0x552880, &CVehicle::IsLawEnforcementVehicle, PATCH_JUMP); InjectHook(0x552820, &CVehicle::ChangeLawEnforcerState, PATCH_JUMP); InjectHook(0x552200, &CVehicle::UsesSiren, PATCH_JUMP); diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index cd877da5..76ea76cb 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -104,6 +104,21 @@ enum CAR_PIECE_WHEEL_RR, }; +enum tWheelState +{ + WHEEL_STATE_1 = 1, // constant velocity + WHEEL_STATE_3 = 3, // not moving +}; + +enum eFlightModel +{ + FLIGHT_MODEL_DODO, + // not used in III + FLIGHT_MODEL_RCPLANE, + FLIGHT_MODEL_HELI, + FLIGHT_MODEL_SEAPLANE +}; + class CVehicle : public CPhysical { public: @@ -179,7 +194,7 @@ public: uint32 m_nTimeOfDeath; int16 field_214; int16 m_nBombTimer; // goes down with each frame - CPed *m_pWhoDetonatedMe; + CPed *m_pWhoSetMeOnFire; float field_21C; float field_220; eCarLock m_nDoorLock; @@ -191,9 +206,7 @@ public: int8 field_22D; bool m_bSirenOrAlarm; int8 field_22F; - // TODO: this is an array - CStoredCollPoly m_frontCollPoly; // poly which is under front part of car - CStoredCollPoly m_rearCollPoly; // poly which is under rear part of car + CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car float m_fSteerRatio; eVehicleType m_vehType; @@ -202,6 +215,8 @@ public: static void operator delete(void*, size_t); static void operator delete(void*, int); + CVehicle(void) {} // FAKE + CVehicle(uint8 CreatedBy); ~CVehicle(void); // from CEntity void SetModelIndex(uint32 id); @@ -232,6 +247,11 @@ public: bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; } bool IsHeli(void) { return m_vehType == VEHICLE_TYPE_HELI; } bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; } + + void FlyingControl(eFlightModel flightModel); + void ExtinguishCarFire(void); + void ProcessDelayedExplosion(void); + float ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius); bool IsLawEnforcementVehicle(void); void ChangeLawEnforcerState(uint8 enable); bool UsesSiren(uint32 id); From 5b04393bb47b424b8bab6864afe4d50e8a7026fe Mon Sep 17 00:00:00 2001 From: _AG Date: Wed, 10 Jul 2019 09:57:08 +0200 Subject: [PATCH 22/30] More frontend inputs. --- src/core/ControllerConfig.cpp | 1 + src/core/ControllerConfig.h | 3 +- src/core/Frontend.cpp | 346 +++++++++++++++++++++++++--------- src/core/Frontend.h | 36 +++- src/core/MenuScreens.h | 4 +- src/core/PlayerInfo.cpp | 8 + src/core/PlayerInfo.h | 6 +- src/core/Text.cpp | 2 + src/core/Text.h | 1 + 9 files changed, 310 insertions(+), 97 deletions(-) diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index d7567ac4..e3a586b2 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -21,6 +21,7 @@ WRAPPER void CControllerConfigManager::InitDefaultControlConfigJoyPad(unsigned i WRAPPER void CControllerConfigManager::ClearSimButtonPressCheckers() { EAXJMP(0x58D220); } WRAPPER void CControllerConfigManager::AffectPadFromKeyBoard() { EAXJMP(0x58D0C0); } WRAPPER void CControllerConfigManager::AffectPadFromMouse() { EAXJMP(0x58D1A0); } +WRAPPER void CControllerConfigManager::ClearSettingsAssociatedWithAction(int, int) { EAXJMP(0x58EB40); } void CControllerConfigManager::LoadSettings(int32 file) { diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h index 581efe05..8a434245 100644 --- a/src/core/ControllerConfig.h +++ b/src/core/ControllerConfig.h @@ -50,7 +50,8 @@ public: void ClearSimButtonPressCheckers(); void AffectPadFromKeyBoard(); void AffectPadFromMouse(); - + void ClearSettingsAssociatedWithAction(int, int); + }; VALIDATE_SIZE(CControllerConfigManager, 0x143C); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 2fa9d8ea..17a5ad30 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -24,6 +24,8 @@ #include "Vehicle.h" #include "MBlur.h" #include "PlayerSkin.h" +#include "PlayerInfo.h" +#include "World.h" int32 &CMenuManager::OS_Language = *(int32*)0x5F2F78; int8 &CMenuManager::m_PrefsUseVibration = *(int8*)0x95CD92; @@ -50,7 +52,9 @@ int8 &CMenuManager::m_bFrontEnd_ReloadObrTxtGxt = *(int8*)0x628CFC; int32 &CMenuManager::m_PrefsMusicVolume = *(int32*)0x5F2E4C; int32 &CMenuManager::m_PrefsSfxVolume = *(int32*)0x5F2E48; -uint8 *CMenuManager::m_PrefsSkinFile = (uint8*)0x5F2E74; +char *CMenuManager::m_PrefsSkinFile = (char*)0x5F2E74; + +int32 &CMenuManager::m_KeyPressedCode = *(int32*)0x5F2E70; CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8; @@ -59,11 +63,14 @@ float lodMultiplier = *(float*)0x5F726C; // Stuff not in CMenuManager: int VibrationTime; -char* pEditString; -int32 pControlEdit; +char* pEditString = (char*)0x628D00; +int32 &pControlEdit = *(int32*)0x628D08; int8 DisplayComboButtonErrMsg; -bool MouseButtonJustClicked; -bool JoyButtonJustClicked; +int8 MouseButtonJustClicked; +int8 JoyButtonJustClicked; +int32 &nTimeForSomething = *(int32*)0x628D54; +int32 TypeOfControl = 0; +int32 *pControlTemp = 0; // Frontend inputs. bool GetPadBack(); @@ -135,12 +142,28 @@ char *MenuFilenames[] = { nil, nil }; -#if 1 -WRAPPER void CMenuManager::BuildStatLine(char *, void *, uint16, void *) { EAXJMP(0x483870); } +#if 0 +WRAPPER void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* stat2) { EAXJMP(0x483870); } #else -void CMenuManager::BuildStatLine(char *, void *, uint16, void *) +void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* stat2) { + if (!text) + return; + if (stat) { + if (aFloat) + sprintf(gString, "%.2f"); + else + sprintf(gString, "%d"); + } + else if (stat2) { + if (aFloat) + sprintf(gString, "%.2f %s %.2f", stat, UnicodeToAscii(TheText.Get("FEST_OO")), stat2); + else + sprintf(gString, "%d %s %d", stat, UnicodeToAscii(TheText.Get("FEST_OO")), stat2); + } + + wcscpy((wchar_t*)gUString, (wchar_t*)TheText.Get(text)); } #endif @@ -164,11 +187,11 @@ void CMenuManager::CentreMousePointer() #endif #if 1 -WRAPPER void CMenuManager::CheckCodesForControls(int, int) { EAXJMP(0x48A950); } +WRAPPER int CMenuManager::CheckCodesForControls(int32) { EAXJMP(0x48A950); } #else -void CMenuManager::CheckCodesForControls() +void CMenuManager::CheckCodesForControls(int, int) { - + DisplayComboButtonErrMsg = 0; } #endif @@ -719,9 +742,9 @@ void CMenuManager::Draw() m_nPrevOption = m_nCurrOption; if (GetMouseForward()) - m_nHoverOption = IGNORE_OPTION; + m_nHoverOption = HOVEROPTION_NULL; else - m_nHoverOption = ACTIVATE_OPTION; + m_nHoverOption = HOVEROPTION_DEFAULT; } } } @@ -1291,75 +1314,144 @@ WRAPPER void CMenuManager::Process(void) { EAXJMP(0x485100); } #else void CMenuManager::Process(void) { - if (m_bSaveMenuActive && TheCamera.GetScreenFadeStatus()) + if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus()) return; - field_113 = 0; + field_112 = 0; + m_bLanguageLoaded = false; + m_bStartGameLoading = false; InitialiseChangedLanguageSettings(); + // SwitchMenuOnAndOff(); - if (m_bMenuActive) { - LoadAllTextures(); - - if (m_nCurrScreen == MENUPAGE_DELETING) { - bool SlotPopulated = false; - - if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) { - PcSaveHelper.PopulateSlotInfo(); - SlotPopulated = true; - } - - if (SlotPopulated) { - m_nPrevScreen = m_nCurrScreen; - m_nCurrScreen = MENUPAGE_DELETE_SUCCESS; - m_nCurrOption = 0; - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); - } - else - SaveLoadFileError_SetUpErrorScreen(); - } - if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { - int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); - PcSaveHelper.PopulateSlotInfo(); - if (SaveSlot) { - m_nPrevScreen = m_nCurrScreen; - m_nCurrScreen = MENUPAGE_SAVE_SUCCESSFUL; - m_nCurrOption = 0; - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); - } - else - SaveLoadFileError_SetUpErrorScreen(); - } - if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) { - if (CheckSlotDataValid(m_nCurrSaveSlot)) { - TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == 0; - if (m_PrefsVsyncDisp != m_PrefsVsync) - m_PrefsVsync = m_PrefsVsyncDisp; - DMAudio.Service(); - m_bStartGameLoading = 1; - RequestFrontEndShutdown(); - m_bLoadingSavedGame = 1; - b_FoundRecentSavedGameWantToLoad = 1; - DMAudio.SetEffectsFadeVol(0); - DMAudio.SetMusicFadeVol(0); - DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); - } - else - SaveLoadFileError_SetUpErrorScreen(); - } - - ProcessButtonPresses(); - } - else { + // Be able to re-open menu correctly. + if (!m_bMenuActive) { if (GetPadExitEnter()) RequestFrontEndStartUp(); UnloadTextures(); - m_nPrevScreen = MENUPAGE_NONE; - m_nCurrScreen = m_nPrevScreen; - m_nCurrOption = MENUROW_0; + field_452 = 0; + SwitchToNewScreen(MENUPAGE_NONE); + pEditString = 0; + field_113 = 0; + return; } + + // Load frontend textures. + LoadAllTextures(); + + // Set save/delete game pages. + if (m_nCurrScreen == MENUPAGE_DELETING) { + bool SlotPopulated = false; + + if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) { + PcSaveHelper.PopulateSlotInfo(); + SlotPopulated = true; + } + + if (SlotPopulated) { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = MENUPAGE_DELETE_SUCCESS; + m_nCurrOption = 0; + m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + else + SaveLoadFileError_SetUpErrorScreen(); + } + if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { + int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); + PcSaveHelper.PopulateSlotInfo(); + if (SaveSlot) { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = MENUPAGE_SAVE_SUCCESSFUL; + m_nCurrOption = 0; + m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + else + SaveLoadFileError_SetUpErrorScreen(); + } + if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) { + if (CheckSlotDataValid(m_nCurrSaveSlot)) { + TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == 0; + if (m_PrefsVsyncDisp != m_PrefsVsync) + m_PrefsVsync = m_PrefsVsyncDisp; + DMAudio.Service(); + m_bStartGameLoading = 1; + RequestFrontEndShutdown(); + m_bLoadingSavedGame = 1; + b_FoundRecentSavedGameWantToLoad = 1; + DMAudio.SetEffectsFadeVol(0); + DMAudio.SetMusicFadeVol(0); + DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); + } + else + SaveLoadFileError_SetUpErrorScreen(); + } + + ProcessButtonPresses(); + + // Set binding keys. + if (pEditString && !CPad::EditString(pEditString, 0)) { + if (!pEditString) + strcpy(pEditString, "NoName"); + pEditString = 0; + SaveSettings(); + } + + if (field_113) { + if ((m_nCurrScreen == MENUPAGE_13 || m_nCurrScreen == MENUPAGE_16) && CTimer::GetTimeInMillisecondsPauseMode() > field_558) + SwitchToNewScreen(m_nPrevScreen); + + // Reset pad shaking. + if (VibrationTime && CTimer::GetTimeInMillisecondsPauseMode() > VibrationTime) { + CPad::GetPad(0)->StopPadsShaking(); + VibrationTime = 0; + } + + if (m_bStartGameLoading) { + if (m_bGameNotLoaded) + DMAudio.Service(); + } + } + + if (!field_456) { + JoyButtonJustClicked = 0; + CPad::EditCodesForControls(&pControlEdit, 0); + MouseButtonJustClicked = 0; + + if (GetMouseForward()) + MouseButtonJustClicked = 1; + else { + if (GetMouseBack()) + MouseButtonJustClicked = 3; + } + + JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); + + if (JoyButtonJustClicked) + TypeOfControl = 3; + if (MouseButtonJustClicked) + TypeOfControl = 2; + if (pControlEdit != 1056) + TypeOfControl = 0; + + if (field_534) { + if (!m_bKeyChangeNotProcessed) { + if (pControlEdit != 1056 || MouseButtonJustClicked || JoyButtonJustClicked) + CheckCodesForControls(TypeOfControl); + + field_535 = 1; + return; + } + } + else { + pControlEdit = 0; + field_113 = 0; + m_KeyPressedCode = -1; + } + } + field_456 = 0; } #endif @@ -1368,7 +1460,7 @@ WRAPPER void CMenuManager::ProcessButtonPresses() { EAXJMP(0x4856F0); } #else void CMenuManager::ProcessButtonPresses() { - // Update Mouse Position + // Update mouse position m_nMouseOldPosX = m_nMousePosX; m_nMouseOldPosY = m_nMousePosY; @@ -1390,6 +1482,70 @@ void CMenuManager::ProcessButtonPresses() else if (GetPadInput()) m_bShowMouse = false; + if (m_nCurrScreen == MENUPAGE_MULTIPLAYER_FIND_GAME || m_nCurrScreen == MENUPAGE_SKIN_SELECT || m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { + if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) + field_440 = m_nSkinsTotal; + + if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { + field_440 = m_ControlMethod ? 30 : 25; + + if (field_44C > field_440) + field_44C = field_440 - 1; + } + + if (!GetPadBack() || m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS || field_535) + field_535 = 0; + else if (field_536 == 19) { + m_nHoverOption = 42; + field_113 = 1; + field_456 = 1; + m_bKeyChangeNotProcessed = 1; + //pControlEdit = m_KeyPressedCode; + } + + if (GetPadForward()) { + switch (field_536) { + case 19: + if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { + field_113 = 1; + field_456 = 1; + //pControlEdit = m_KeyPressedCode; + } + if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { + strcpy(m_PrefsSkinFile, m_aSkinName); + CWorld::Players->SetPlayerSkin(m_PrefsSkinFile); + field_536 = 9; + } + + m_nHoverOption = HOVEROPTION_NULL; + SaveSettings(); + break; + case 21: + strcpy(m_PrefsSkinFile, m_aSkinName); + CWorld::Players->SetPlayerSkin(m_PrefsSkinFile); + field_536 = 9; + break; + default: + break; + }; + } + + bool once = false; + if (!once) { + once = true; + nTimeForSomething = 0; + } + + if ((CTimer::GetTimeInMillisecondsPauseMode() - nTimeForSomething) > 200) { + field_520 = 0; + field_521 = 0; + field_522 = 0; + field_523 = 0; + field_524 = 0; + nTimeForSomething = CTimer::GetTimeInMillisecondsPauseMode(); + } + } + // Get number of menu options. uint8 NumberOfMenuOptions = GetNumberOfMenuOptions(); @@ -1436,6 +1592,14 @@ void CMenuManager::ProcessButtonPresses() RequestFrontEndShutdown(); PlayEscSound = true; break; + case MENUPAGE_KEYBOARD_CONTROLS: + if (!m_bKeyChangeNotProcessed) { + m_bKeyChangeNotProcessed = true; + field_534 = 0; + } + else + SwitchToNewScreen(aScreens[m_nCurrScreen].m_PreviousPage[0]); + break; default: SwitchToNewScreen(aScreens[m_nCurrScreen].m_PreviousPage[0]); PlayEscSound = true; @@ -1446,17 +1610,34 @@ void CMenuManager::ProcessButtonPresses() DMAudio.PlayFrontEndSound(SOUND_FRONTEND_EXIT, 0); } - // TODO: finish hover options. - // Set mouse buttons. + // Set hover options, how it is supposed to be used isn't really clear yet. if (GetMouseForward()) { switch (m_nHoverOption) { - case ACTIVATE_OPTION: + case HOVEROPTION_DEFAULT: if (m_nCurrOption || m_nCurrScreen != MENUPAGE_PAUSE_MENU) m_nCurrOption = m_nPrevOption; - m_nHoverOption = ACTIVATE_OPTION; + m_nHoverOption = HOVEROPTION_DEFAULT; + break; + case HOVEROPTION_12: + m_nHoverOption = HOVEROPTION_14; + break; + case HOVEROPTION_13: + m_nHoverOption = HOVEROPTION_15; + break; + case HOVEROPTION_19: + m_nHoverOption = HOVEROPTION_20; + break; + case HOVEROPTION_CHANGESKIN: + if (m_nSkinsTotal > 0) { + m_pSelectedSkin = m_sSkin.field_304; + strcpy(m_PrefsSkinFile, m_aSkinName); + CWorld::Players->SetPlayerSkin(m_PrefsSkinFile); + SaveSettings(); + } break; default: + m_nHoverOption = HOVEROPTION_NULL; break; }; } @@ -1495,14 +1676,6 @@ void CMenuManager::ProcessButtonPresses() default: break; }; - - // Reset pad shaking. - if (VibrationTime != 0) { - if (CTimer::GetTimeInMillisecondsPauseMode() > VibrationTime) { - CPad::GetPad(0)->StopShaking(0); - VibrationTime = 0; - } - } } #endif @@ -1683,6 +1856,9 @@ void CMenuManager::ProcessOnOffMenuOptions() case MENUACTION_UPDATEMEMCARDSAVE: RequestFrontEndShutdown(); break; + case MENUACTION_GETKEY: + //*pControlEdit = m_KeyPressedCode; + break; case MENUACTION_INVVERT: MousePointerStateHelper.bInvertVertically = MousePointerStateHelper.bInvertVertically == false; return; @@ -2204,7 +2380,7 @@ void CMenuManager::SetDefaultPreferences(int8 screen) m_PrefsVsync = true; m_PrefsLOD = 1.2f; m_PrefsVsyncDisp = true; - lodMultiplier = 1.2; + lodMultiplier = 1.2f; CMBlur::BlurOn = true; CMBlur::MotionBlurOpen(Scene.camera); m_PrefsUseVibration = false; diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 9b9377da..ede036d2 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -306,8 +306,29 @@ enum eMenuAction enum eCheckHover { - ACTIVATE_OPTION = 2, - IGNORE_OPTION = 42, + HOVEROPTION_0, + HOVEROPTION_1, + HOVEROPTION_DEFAULT, + HOVEROPTION_3, + HOVEROPTION_4, + HOVEROPTION_5, + HOVEROPTION_6, + HOVEROPTION_7, + HOVEROPTION_8, + HOVEROPTION_9, + HOVEROPTION_10, + HOVEROPTION_11, + HOVEROPTION_12, + HOVEROPTION_13, + HOVEROPTION_14, + HOVEROPTION_15, + HOVEROPTION_16, + HOVEROPTION_17, + HOVEROPTION_18, + HOVEROPTION_19, + HOVEROPTION_20, + HOVEROPTION_CHANGESKIN, + HOVEROPTION_NULL = 42, }; enum eMenuColumns @@ -348,7 +369,7 @@ struct tSkinInfo char skinName[256]; char currSkinName[256]; char date[256]; - int field_304; + tSkinInfo *field_304; }; struct CMenuScreen @@ -388,7 +409,7 @@ public: int32 m_nMouseTempPosX; int32 m_nMouseTempPosY; bool m_bShowMouse; - tSkinInfo field_12C; + tSkinInfo m_sSkin; tSkinInfo *m_pSelectedSkin; tSkinInfo *field_438; float field_43C; @@ -450,16 +471,17 @@ public: static int8 &m_bFrontEnd_ReloadObrTxtGxt; static int32 &m_PrefsMusicVolume; static int32 &m_PrefsSfxVolume; - static uint8 *m_PrefsSkinFile; + static char *m_PrefsSkinFile; + static int32 &m_KeyPressedCode; static bool &m_bStartUpFrontEndRequested; static bool &m_bShutDownFrontEndRequested; static bool &m_PrefsAllowNastyGame; public: - void BuildStatLine(char *, void *, uint16, void *); + void BuildStatLine(char *text, float *stat, bool aFloat, float* stat2); static void CentreMousePointer(); - void CheckCodesForControls(int, int); + int CheckCodesForControls(int32); bool CheckHover(int x1, int x2, int y1, int y2); void CheckSliderMovement(int); int CostructStatLine(int); diff --git a/src/core/MenuScreens.h b/src/core/MenuScreens.h index 2da81f1d..866dfc03 100644 --- a/src/core/MenuScreens.h +++ b/src/core/MenuScreens.h @@ -43,7 +43,7 @@ const CMenuScreen aScreens[] = { { "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, MENUROW_2, MENUROW_2, MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - //MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, @@ -273,7 +273,7 @@ const CMenuScreen aScreens[] = { MENUACTION_CHANGEMENU, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, MENUACTION_CHANGEMENU, "FET_LAN", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, - //MENUACTION_CHANGEMENU, "FET_PSU", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT, + MENUACTION_CHANGEMENU, "FET_PSU", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT, MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 9d003e76..81c7a199 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -1,6 +1,14 @@ #include "common.h" #include "patcher.h" #include "PlayerInfo.h" +#include "Frontend.h" WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); } +WRAPPER void CPlayerInfo::LoadPlayerSkin() { EAXJMP(0x4A1700); } WRAPPER void CPlayerInfo::AwardMoneyForExplosion(CVehicle *vehicle) { EAXJMP(0x4A15F0); } + +void CPlayerInfo::SetPlayerSkin(char *skin) +{ + strncpy(m_aSkinName, skin, 32); + LoadPlayerSkin(); +} diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index a9763766..d8128424 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -63,11 +63,13 @@ public: bool m_bFastReload; bool m_bGetOutOfJailFree; bool m_bGetOutOfHospitalFree; - uint8 m_aSkinName[32]; + char m_aSkinName[32]; RwTexture *m_pSkinTexture; void MakePlayerSafe(bool); - void AwardMoneyForExplosion(CVehicle *vehicle); + void LoadPlayerSkin(); + void AwardMoneyForExplosion(CVehicle *vehicle); + void SetPlayerSkin(char* skin); }; static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error"); diff --git a/src/core/Text.cpp b/src/core/Text.cpp index d7d63467..b834a44d 100644 --- a/src/core/Text.cpp +++ b/src/core/Text.cpp @@ -210,6 +210,8 @@ AsciiToUnicode(const char *src, uint16 *dst) while((*dst++ = *src++) != '\0'); } +WRAPPER char UnicodeToAscii(wchar * src) { EAXJMP(0x52C2F0); } + void TextCopy(wchar *dst, const wchar *src) { diff --git a/src/core/Text.h b/src/core/Text.h index 2592e6b8..15ab7a8f 100644 --- a/src/core/Text.h +++ b/src/core/Text.h @@ -1,6 +1,7 @@ #pragma once void AsciiToUnicode(const char *src, wchar *dst); +char UnicodeToAscii(wchar *src); void TextCopy(wchar *dst, const wchar *src); struct CKeyEntry From 1aeb34f547e0be994b7c5979e68049b6d9f35d9d Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 10 Jul 2019 11:05:49 +0200 Subject: [PATCH 23/30] CVehicle::ProcessWheel --- src/vehicles/HandlingMgr.h | 2 + src/vehicles/Vehicle.cpp | 198 ++++++++++++++++++++++++++++--------- src/vehicles/Vehicle.h | 6 +- 3 files changed, 158 insertions(+), 48 deletions(-) diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h index 958e2351..2627fbae 100644 --- a/src/vehicles/HandlingMgr.h +++ b/src/vehicles/HandlingMgr.h @@ -119,7 +119,9 @@ VALIDATE_SIZE(tHandlingData, 0xD8); class cHandlingDataMgr { float field_0; // unused it seems +public: float field_4; // wheel related +private: float field_8; // float field_C; // unused it seems float field_10; // diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index c541bae5..13e02566 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -130,6 +130,47 @@ CVehicle::~CVehicle() } } +void +CVehicle::SetModelIndex(uint32 id) +{ + CEntity::SetModelIndex(id); + m_aExtras[0] = CVehicleModelInfo::ms_compsUsed[0]; + m_aExtras[1] = CVehicleModelInfo::ms_compsUsed[1]; + m_nNumMaxPassengers = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(id); +} + +bool +CVehicle::SetupLighting(void) +{ + ActivateDirectional(); + SetAmbientColoursForPedsCarsAndObjects(); + + if(bRenderScorched){ + WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f); + }else{ + CVector coors = GetPosition(); + float lighting = CPointLights::GenerateLightsAffectingObject(&coors); + if(!bHasBlip && lighting != 1.0f){ + SetAmbientAndDirectionalColours(lighting); + return true; + } + } + + return false; +} + +void +CVehicle::RemoveLighting(bool reset) +{ + CRenderer::RemoveVehiclePedLights(this, reset); +} + +float +CVehicle::GetHeightAboveRoad(void) +{ + return -1.0f * GetColModel()->boundingBox.min.z; +} + void CVehicle::FlyingControl(eFlightModel flightModel) { @@ -192,47 +233,127 @@ CVehicle::FlyingControl(eFlightModel flightModel) } void -CVehicle::SetModelIndex(uint32 id) +CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint, + int32 wheelsOnGround, float thrust, float brake, float adhesion, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, uint16 wheelStatus) { - CEntity::SetModelIndex(id); - m_aExtras[0] = CVehicleModelInfo::ms_compsUsed[0]; - m_aExtras[1] = CVehicleModelInfo::ms_compsUsed[1]; - m_nNumMaxPassengers = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(id); -} + // BUG: using statics here is probably a bad idea + static bool bAlreadySkidding = false; // this is never reset + static bool bBraking; + static bool bDriving; -bool -CVehicle::SetupLighting(void) -{ - ActivateDirectional(); - SetAmbientColoursForPedsCarsAndObjects(); + // how much force we want to apply in these axes + float fwd = 0.0f; + float right = 0.0f; - if(bRenderScorched){ - WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f); - }else{ - CVector coors = GetPosition(); - float lighting = CPointLights::GenerateLightsAffectingObject(&coors); - if(!bHasBlip && lighting != 1.0f){ - SetAmbientAndDirectionalColours(lighting); - return true; + bBraking = brake != 0.0f; + if(bBraking) + thrust = 0.0f; + bDriving = thrust != 0.0f; + + float contactSpeedFwd = DotProduct(wheelContactSpeed, wheelFwd); + float contactSpeedRight = DotProduct(wheelContactSpeed, wheelRight); + + if(*wheelState != WHEEL_STATE_0) + bAlreadySkidding = true; + *wheelState = WHEEL_STATE_0; + + adhesion *= CTimer::GetTimeStep(); + if(bAlreadySkidding) + adhesion *= m_handling->fTractionLoss; + + // moving sideways + if(contactSpeedRight != 0.0f){ + // exert opposing force + right = -contactSpeedRight/wheelsOnGround; + + if(wheelStatus == WHEEL_STATUS_BURST){ + float fwdspeed = min(contactSpeedFwd, 0.3f); + right += fwdspeed * CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); } } - return false; -} + if(bDriving){ + fwd = thrust; -void -CVehicle::RemoveLighting(bool reset) -{ - CRenderer::RemoveVehiclePedLights(this, reset); + // limit sideways force (why?) + if(right > 0.0f){ + if(right > adhesion) + right = adhesion; + }else{ + if(right < -adhesion) + right = -adhesion; + } + }else if(contactSpeedFwd != 0.0f){ + fwd = -contactSpeedFwd/wheelsOnGround; + + if(!bBraking){ + if(m_fGasPedal < 0.01f){ + if(GetModelIndex() == MI_RCBANDIT) + brake = 0.2f * mod_HandlingManager.field_4 / m_fMass; + else + brake = mod_HandlingManager.field_4 / m_fMass; + } + } + + if(brake > adhesion){ + if(fabs(contactSpeedFwd) > 0.005f) + *wheelState = WHEEL_STATE_STATIC; + }else { + if(fwd > 0.0f){ + if(fwd > brake) + fwd = brake; + }else{ + if(fwd < -brake) + fwd = -brake; + } + } + } + + if(sq(adhesion) < sq(right) + sq(fwd)){ + if(*wheelState != WHEEL_STATE_STATIC){ + if(bDriving && contactSpeedFwd < 0.2f) + *wheelState = WHEEL_STATE_1; + else + *wheelState = WHEEL_STATE_2; + } + + float l = sqrt(sq(right) + sq(fwd)); + float tractionLoss = bAlreadySkidding ? 1.0f : m_handling->fTractionLoss; + right *= adhesion * tractionLoss / l; + fwd *= adhesion * tractionLoss / l; + } + + if(fwd != 0.0f || right != 0.0f){ + CVector direction = fwd*wheelFwd + right*wheelRight; + float speed = direction.Magnitude(); + direction.Normalise(); + + float impulse = speed*m_fMass; + float turnImpulse = speed*GetMass(wheelContactPoint, direction); + + ApplyMoveForce(impulse * direction); + ApplyTurnForce(turnImpulse * direction, wheelContactPoint); + } } float -CVehicle::GetHeightAboveRoad(void) +CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius) { - return -1.0f * GetColModel()->boundingBox.min.z; + float angularVelocity; + switch(state){ + case WHEEL_STATE_1: + angularVelocity = -1.1f; // constant speed forward + break; + case WHEEL_STATE_STATIC: + angularVelocity = 0.0f; // not moving + break; + default: + angularVelocity = -DotProduct(fwd, speed) / radius; // forward speed + break; + } + return angularVelocity * CTimer::GetTimeStep(); } - void CVehicle::ExtinguishCarFire(void) { @@ -269,24 +390,6 @@ CVehicle::ProcessDelayedExplosion(void) } } -float -CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius) -{ - float angularVelocity; - switch(state){ - case WHEEL_STATE_1: - angularVelocity = -1.1f; // constant speed forward - break; - case WHEEL_STATE_3: - angularVelocity = 0.0f; // not moving - break; - default: - angularVelocity = -DotProduct(fwd, speed) / radius; // forward speed - break; - } - return angularVelocity * CTimer::GetTimeStep(); -} - bool CVehicle::IsLawEnforcementVehicle(void) { @@ -669,9 +772,10 @@ STARTPATCHES InjectHook(0x417E60, &CVehicle_::GetHeightAboveRoad_, PATCH_JUMP); InjectHook(0x552BB0, &CVehicle::FlyingControl, PATCH_JUMP); + InjectHook(0x5512E0, &CVehicle::ProcessWheel, PATCH_JUMP); + InjectHook(0x551280, &CVehicle::ProcessWheelRotation, PATCH_JUMP); InjectHook(0x552AF0, &CVehicle::ExtinguishCarFire, PATCH_JUMP); InjectHook(0x551C90, &CVehicle::ProcessDelayedExplosion, PATCH_JUMP); - InjectHook(0x551280, &CVehicle::ProcessWheelRotation, PATCH_JUMP); InjectHook(0x552880, &CVehicle::IsLawEnforcementVehicle, PATCH_JUMP); InjectHook(0x552820, &CVehicle::ChangeLawEnforcerState, PATCH_JUMP); InjectHook(0x552200, &CVehicle::UsesSiren, PATCH_JUMP); diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 76ea76cb..c293b8a6 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -106,8 +106,10 @@ enum enum tWheelState { + WHEEL_STATE_0 = 0, WHEEL_STATE_1 = 1, // constant velocity - WHEEL_STATE_3 = 3, // not moving + WHEEL_STATE_2 = 2, // normal + WHEEL_STATE_STATIC = 3, // not moving }; enum eFlightModel @@ -249,6 +251,8 @@ public: bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; } void FlyingControl(eFlightModel flightModel); + void ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint, + int32 wheelsOnGround, float thrust, float brake, float adhesion, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, uint16 wheelStatus); void ExtinguishCarFire(void); void ProcessDelayedExplosion(void); float ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius); From d360229b5b3a3ef82a8defd6672bfda81ded9326 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 10 Jul 2019 13:42:48 +0200 Subject: [PATCH 24/30] fixed some stuff in frontend, badly broke others; disabled reversed frontend for the moment --- src/core/Frontend.cpp | 457 ++++++++++++++++++++++++------------------ src/core/Frontend.h | 2 +- src/core/Text.cpp | 44 +++- src/core/Text.h | 5 +- src/core/main.cpp | 8 +- src/core/main.h | 8 +- 6 files changed, 322 insertions(+), 202 deletions(-) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 17a5ad30..a846efc6 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -27,6 +27,8 @@ #include "PlayerInfo.h" #include "World.h" +#define ALL_ORIGINAL_FRONTEND 1 + int32 &CMenuManager::OS_Language = *(int32*)0x5F2F78; int8 &CMenuManager::m_PrefsUseVibration = *(int8*)0x95CD92; int8 &CMenuManager::m_DisplayControllerOnFoot = *(int8*)0x95CD8D; @@ -62,9 +64,9 @@ CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8; float lodMultiplier = *(float*)0x5F726C; // Stuff not in CMenuManager: -int VibrationTime; +uint32 VibrationTime; char* pEditString = (char*)0x628D00; -int32 &pControlEdit = *(int32*)0x628D08; +int32 *&pControlEdit = *(int32**)0x628D08; int8 DisplayComboButtonErrMsg; int8 MouseButtonJustClicked; int8 JoyButtonJustClicked; @@ -73,6 +75,7 @@ int32 TypeOfControl = 0; int32 *pControlTemp = 0; // Frontend inputs. + bool GetPadBack(); bool GetPadExitEnter(); bool GetPadForward(); @@ -80,6 +83,11 @@ bool GetPadMoveUp(); bool GetPadMoveDown(); bool GetPadMoveLeft(); bool GetPadMoveRight(); +bool GetMouseClickLeft(); +bool GetMouseClickRight(); +bool GetMouseClickMiddle(); +bool GetMouseWheelUp(); +bool GetMouseWheelDown(); bool GetMouseForward(); bool GetMouseBack(); bool GetMousePos(); @@ -142,7 +150,7 @@ char *MenuFilenames[] = { nil, nil }; -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* stat2) { EAXJMP(0x483870); } #else void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* stat2) @@ -150,24 +158,27 @@ void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* st if (!text) return; - if (stat) { - if (aFloat) - sprintf(gString, "%.2f"); - else - sprintf(gString, "%d"); + if (stat2) { + if (aFloat) + sprintf(gString2, " %.2f %s %.2f", *stat, UnicodeToAscii(TheText.Get("FEST_OO")), *stat2); + else + sprintf(gString2, " %d %s %d", *(int*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(int*)stat2); } else if (stat2) { - if (aFloat) - sprintf(gString, "%.2f %s %.2f", stat, UnicodeToAscii(TheText.Get("FEST_OO")), stat2); - else - sprintf(gString, "%d %s %d", stat, UnicodeToAscii(TheText.Get("FEST_OO")), stat2); + if (aFloat) + sprintf(gString2, " %.2f", *stat); + else + sprintf(gString2, " %d", *(int*)stat); } + else + gString2[0] = '\0'; - wcscpy((wchar_t*)gUString, (wchar_t*)TheText.Get(text)); + UnicodeStrcpy(gUString, TheText.Get(text)); + AsciiToUnicode(gString2, gUString2); } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::CentreMousePointer() { EAXJMP(0x48ACE0); } #else void CMenuManager::CentreMousePointer() @@ -195,7 +206,7 @@ void CMenuManager::CheckCodesForControls(int, int) } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER bool CMenuManager::CheckHover(int, int, int, int) { EAXJMP(0x48ACA0); } #else bool CMenuManager::CheckHover(int x1, int x2, int y1, int y2) @@ -274,7 +285,7 @@ void CMenuManager::CheckSliderMovement(int value) TheCamera.m_fMouseAccelVertical = fMouseSens; SaveSettings(); break; - }; + } } #if 1 @@ -286,7 +297,7 @@ int CMenuManager::CostructStatLine(int) } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::DisplayHelperText() { EAXJMP(0x48B490); } #else void CMenuManager::DisplayHelperText() @@ -326,7 +337,7 @@ void CMenuManager::DisplayHelperText() break; default: break; - }; + } CFont::SetAlignment(ALIGN_CENTER); CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f)); @@ -339,7 +350,7 @@ void CMenuManager::DisplayHelperText() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER float CMenuManager::DisplaySlider(float, float, float, float, float, float) { EAXJMP(0x488420); } #else float CMenuManager::DisplaySlider(float x, float y, float leftSize, float rightSize, float rectSize, float progress) @@ -365,12 +376,12 @@ float CMenuManager::DisplaySlider(float x, float y, float leftSize, float rightS float _s = SCREEN_SCALE_X(2.0f); CSprite2d::DrawRect(CRect(_x + _s, _y + _s, _w + _s, _h + _s), CRGBA(0, 0, 0, FadeIn(255))); // Shadow CSprite2d::DrawRect(CRect(i * rectSize/16.0f + x, y + sizeRange - ((16 - i) * leftSize + i * rightSize)/16.0f, SCREEN_SCALE_X(10.0f) + i * rectSize/16.0f + x, y + sizeRange), color); - }; + } return input; } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::DoSettingsBeforeStartingAGame() { EAXJMP(0x48AB40); } #else void CMenuManager::DoSettingsBeforeStartingAGame() @@ -389,7 +400,7 @@ void CMenuManager::DoSettingsBeforeStartingAGame() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::Draw() { EAXJMP(0x47AE00); } #else void CMenuManager::Draw() @@ -450,7 +461,7 @@ void CMenuManager::Draw() default: str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName); break; - }; + } CFont::SetDropShadowPosition(MENUDROP_COLOR_SIZE); CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(MENUDROP_COLOR_A))); @@ -503,7 +514,7 @@ void CMenuManager::Draw() case 3: textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEC_CF4"); break; - }; + } break; case MENUACTION_CTRLDISPLAY: break; @@ -533,7 +544,7 @@ void CMenuManager::Draw() case AR_16_9: textToPrint[MENUCOLUMN_RIGHT] = (wchar*)L"16:9"; break; - }; + } #endif break; case MENUACTION_RADIO: @@ -583,7 +594,7 @@ void CMenuManager::Draw() case 2: textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEA_4SP"); break; - }; + } } break; case MENUACTION_CTRLMETHOD: @@ -594,7 +605,7 @@ void CMenuManager::Draw() case 1: textToPrint[MENUCOLUMN_LEFT] = TheText.Get("FET_CCN"); break; - }; + } break; case MENUACTION_DYNAMICACOUSTIC: textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(m_PrefsDMA ? "FEM_ON" : "FEM_OFF"); @@ -602,7 +613,7 @@ void CMenuManager::Draw() case MENUACTION_MOUSESTEER: textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(m_bDisableMouseSteering ? "FEM_ON" : "FEM_OFF"); break; - }; + } CFont::SetDropShadowPosition(MENUDROP_COLOR_SIZE); CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(MENUDROP_COLOR_A))); @@ -690,7 +701,7 @@ void CMenuManager::Draw() default: vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(MENUCOLUMN_MID_Y); break; - }; + } } if (i > 0) @@ -767,7 +778,7 @@ void CMenuManager::Draw() case MENUACTION_MOUSESENS: DisplaySlider(SCREEN_SCALE_FROM_RIGHT(MENUSLIDER_X), vecPositions.y - SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(18.0f), SCREEN_SCALE_X(256.0f), TheCamera.m_fMouseAccelHorzntl * 200.0f); break; - }; + } // Radio icons. float fIconSpacing = 59.52f; @@ -816,9 +827,9 @@ void CMenuManager::Draw() case MENUPAGE_MOUSE_CONTROLS: DisplayHelperText(); break; - }; + } } - }; + } } #endif @@ -849,7 +860,7 @@ void CMenuManager::DrawControllerSetupScreen() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::DrawFrontEnd(void) { EAXJMP(0x47A540); } #else void CMenuManager::DrawFrontEnd() @@ -873,7 +884,7 @@ void CMenuManager::DrawFrontEnd() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::DrawFrontEndNormal(void) { EAXJMP(0x47A5B0); } #else void CMenuManager::DrawFrontEndNormal() @@ -927,7 +938,7 @@ void CMenuManager::DrawFrontEndNormal() case MENUPAGE_OPTIONS: previousSprite = MENUSPRITE_PLAYERSET; break; - }; + } if (m_nPrevScreen == MENUPAGE_NONE) CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255)); @@ -972,7 +983,7 @@ void CMenuManager::DrawFrontEndNormal() case MENUPAGE_OPTIONS: currentSprite = MENUSPRITE_PLAYERSET; break; - }; + } uint32 savedShade; uint32 savedAlpha; @@ -1016,7 +1027,7 @@ void CMenuManager::DrawFrontEndNormal() default: CMenuManager::Draw(); break; - }; + } CFont::DrawFonts(); @@ -1035,7 +1046,7 @@ void CMenuManager::DrawPlayerSetupScreen() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER int CMenuManager::FadeIn(int alpha) { EAXJMP(0x48AC60); } #else int CMenuManager::FadeIn(int alpha) @@ -1070,7 +1081,7 @@ int CMenuManager::GetStartOptionsCntrlConfigScreens() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::InitialiseChangedLanguageSettings() { EAXJMP(0x47A4D0); } #else void CMenuManager::InitialiseChangedLanguageSettings() @@ -1092,12 +1103,12 @@ void CMenuManager::InitialiseChangedLanguageSettings() break; default: break; - }; + } } } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::LoadAllTextures() { EAXJMP(0x47A230); } #else void CMenuManager::LoadAllTextures() @@ -1133,7 +1144,7 @@ void CMenuManager::LoadAllTextures() for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); i++) { m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i]); m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); - }; + } CTxdStore::PopCurrentTxd(); @@ -1146,7 +1157,7 @@ void CMenuManager::LoadAllTextures() for (int i = 0; i < ARRAY_SIZE(MenuFilenames)/2; i++) { m_aMenuSprites[i].SetTexture(MenuFilenames[i*2], MenuFilenames[i*2+1]); m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); - }; + } CTxdStore::PopCurrentTxd(); @@ -1155,7 +1166,7 @@ void CMenuManager::LoadAllTextures() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::LoadSettings() { EAXJMP(0x488EE0); } #else void CMenuManager::LoadSettings() @@ -1174,13 +1185,13 @@ void CMenuManager::LoadSettings() if (strncmp(&Ver, "THIS FILE IS NOT VALID YET", 26)) { CFileMgr::Seek(fileHandle, 0, 0); ControlsManager.LoadSettings(fileHandle); - CFileMgr::Read(fileHandle, buf(&gString), 20); - CFileMgr::Read(fileHandle, buf(&gString), 20); - CFileMgr::Read(fileHandle, buf(&gString), 4); - CFileMgr::Read(fileHandle, buf(&gString), 4); - CFileMgr::Read(fileHandle, buf(&gString), 1); - CFileMgr::Read(fileHandle, buf(&gString), 1); - CFileMgr::Read(fileHandle, buf(&gString), 1); + CFileMgr::Read(fileHandle, buf(gString), 20); + CFileMgr::Read(fileHandle, buf(gString), 20); + CFileMgr::Read(fileHandle, buf(gString), 4); + CFileMgr::Read(fileHandle, buf(gString), 4); + CFileMgr::Read(fileHandle, buf(gString), 1); + CFileMgr::Read(fileHandle, buf(gString), 1); + CFileMgr::Read(fileHandle, buf(gString), 1); CFileMgr::Read(fileHandle, buf(&TheCamera.m_bHeadBob), 1); CFileMgr::Read(fileHandle, buf(&TheCamera.m_fMouseAccelHorzntl), 4); CFileMgr::Read(fileHandle, buf(&TheCamera.m_fMouseAccelVertical), 4); @@ -1276,7 +1287,7 @@ void CMenuManager::PrintBriefs() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::PrintErrorMessage() { EAXJMP(0x484F70); } #else void CMenuManager::PrintErrorMessage() @@ -1309,157 +1320,180 @@ void CMenuManager::PrintStats() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::Process(void) { EAXJMP(0x485100); } #else void CMenuManager::Process(void) { - if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus()) + field_112 = 0; + + if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0) return; - field_112 = 0; - m_bLanguageLoaded = false; + //m_bLanguageLoaded = false; //XXX m_bStartGameLoading = false; InitialiseChangedLanguageSettings(); - // + if (GetPadExitEnter()) //XXX only escape + RequestFrontEndStartUp(); + SwitchMenuOnAndOff(); // Be able to re-open menu correctly. - if (!m_bMenuActive) { - if (GetPadExitEnter()) - RequestFrontEndStartUp(); + if (m_bMenuActive) { - UnloadTextures(); - field_452 = 0; - SwitchToNewScreen(MENUPAGE_NONE); - pEditString = 0; - field_113 = 0; - return; - } + // Load frontend textures. + LoadAllTextures(); - // Load frontend textures. - LoadAllTextures(); + // Set save/delete game pages. + if (m_nCurrScreen == MENUPAGE_DELETING) { + bool SlotPopulated = false; - // Set save/delete game pages. - if (m_nCurrScreen == MENUPAGE_DELETING) { - bool SlotPopulated = false; + if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) { + PcSaveHelper.PopulateSlotInfo(); + SlotPopulated = true; + } - if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) { + if (SlotPopulated) { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = MENUPAGE_DELETE_SUCCESS; + m_nCurrOption = 0; + m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + else + SaveLoadFileError_SetUpErrorScreen(); + } + if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { + int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); PcSaveHelper.PopulateSlotInfo(); - SlotPopulated = true; + if (SaveSlot) { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = MENUPAGE_SAVE_SUCCESSFUL; + m_nCurrOption = 0; + m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); + } + else + SaveLoadFileError_SetUpErrorScreen(); } - - if (SlotPopulated) { - m_nPrevScreen = m_nCurrScreen; - m_nCurrScreen = MENUPAGE_DELETE_SUCCESS; - m_nCurrOption = 0; - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); - } - else - SaveLoadFileError_SetUpErrorScreen(); - } - if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { - int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); - PcSaveHelper.PopulateSlotInfo(); - if (SaveSlot) { - m_nPrevScreen = m_nCurrScreen; - m_nCurrScreen = MENUPAGE_SAVE_SUCCESSFUL; - m_nCurrOption = 0; - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); - } - else - SaveLoadFileError_SetUpErrorScreen(); - } - if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) { - if (CheckSlotDataValid(m_nCurrSaveSlot)) { - TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == 0; - if (m_PrefsVsyncDisp != m_PrefsVsync) - m_PrefsVsync = m_PrefsVsyncDisp; - DMAudio.Service(); - m_bStartGameLoading = 1; - RequestFrontEndShutdown(); - m_bLoadingSavedGame = 1; - b_FoundRecentSavedGameWantToLoad = 1; - DMAudio.SetEffectsFadeVol(0); - DMAudio.SetMusicFadeVol(0); - DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); - } - else - SaveLoadFileError_SetUpErrorScreen(); - } - - ProcessButtonPresses(); - - // Set binding keys. - if (pEditString && !CPad::EditString(pEditString, 0)) { - if (!pEditString) - strcpy(pEditString, "NoName"); - pEditString = 0; - SaveSettings(); - } - - if (field_113) { - if ((m_nCurrScreen == MENUPAGE_13 || m_nCurrScreen == MENUPAGE_16) && CTimer::GetTimeInMillisecondsPauseMode() > field_558) - SwitchToNewScreen(m_nPrevScreen); - - // Reset pad shaking. - if (VibrationTime && CTimer::GetTimeInMillisecondsPauseMode() > VibrationTime) { - CPad::GetPad(0)->StopPadsShaking(); - VibrationTime = 0; - } - - if (m_bStartGameLoading) { - if (m_bGameNotLoaded) + if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) { + if (CheckSlotDataValid(m_nCurrSaveSlot)) { + TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == 0; + if (m_PrefsVsyncDisp != m_PrefsVsync) + m_PrefsVsync = m_PrefsVsyncDisp; DMAudio.Service(); + m_bStartGameLoading = 1; + RequestFrontEndShutdown(); + m_bLoadingSavedGame = 1; + b_FoundRecentSavedGameWantToLoad = 1; + DMAudio.SetEffectsFadeVol(0); + DMAudio.SetMusicFadeVol(0); + DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); + } + else + SaveLoadFileError_SetUpErrorScreen(); } - } - if (!field_456) { - JoyButtonJustClicked = 0; - CPad::EditCodesForControls(&pControlEdit, 0); - MouseButtonJustClicked = 0; + ProcessButtonPresses(); - if (GetMouseForward()) - MouseButtonJustClicked = 1; - else { - if (GetMouseBack()) + // Set binding keys. + if (pEditString && CPad::EditString(pEditString, 0) == nil) { + if (*pEditString == 0) + strcpy(pEditString, "NoName"); + pEditString = nil; + SaveSettings(); + } + + if (field_113 && !field_456) { + pControlEdit = CPad::EditCodesForControls(pControlEdit, 1); + JoyButtonJustClicked = 0; + MouseButtonJustClicked = 0; + + if (GetMouseClickLeft()) + MouseButtonJustClicked = 1; + else if (GetMouseClickRight()) MouseButtonJustClicked = 3; - } + else if (GetMouseClickMiddle()) + MouseButtonJustClicked = 2; + else if (GetMouseWheelUp()) + MouseButtonJustClicked = 4; + else if (GetMouseWheelDown()) + MouseButtonJustClicked = 5; + //XXX two more buttons - JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); + JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); - if (JoyButtonJustClicked) - TypeOfControl = 3; - if (MouseButtonJustClicked) - TypeOfControl = 2; - if (pControlEdit != 1056) - TypeOfControl = 0; + if (JoyButtonJustClicked) + TypeOfControl = 3; + if (MouseButtonJustClicked) + TypeOfControl = 2; + if (*pControlEdit != rsNULL) + TypeOfControl = 0; - if (field_534) { - if (!m_bKeyChangeNotProcessed) { - if (pControlEdit != 1056 || MouseButtonJustClicked || JoyButtonJustClicked) + if (!field_534) { + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); + pControlEdit = nil; + field_113 = 0; + m_KeyPressedCode = -1; + field_456 = 0; + } + else if (!m_bKeyChangeNotProcessed) { + if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked) CheckCodesForControls(TypeOfControl); field_535 = 1; - return; + } + else { + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); + for (int i = 0; i < 4; i++) + ControlsManager.ClearSettingsAssociatedWithAction(m_CurrCntrlAction, i); + field_534 = false; + m_bKeyChangeNotProcessed = false; + pControlEdit = nil; + field_113 = 0; + m_KeyPressedCode = -1; + field_456 = 0; } } - else { - pControlEdit = 0; - field_113 = 0; - m_KeyPressedCode = -1; + + if ((m_nCurrScreen == MENUPAGE_13 || m_nCurrScreen == MENUPAGE_16) && CTimer::GetTimeInMillisecondsPauseMode() > field_558) { + m_nCurrScreen = m_nPrevScreen; + m_nCurrOption = 0; + } + + // Reset pad shaking. + if (VibrationTime && CTimer::GetTimeInMillisecondsPauseMode() > VibrationTime) { + CPad::StopPadsShaking(); + VibrationTime = 0; } } - field_456 = 0; + else { + UnloadTextures(); + field_452 = 0; + // byte_5F33E4 = 1; // unused + m_nPrevScreen = 0; + m_nCurrScreen = m_nPrevScreen; + m_nCurrOption = 0; + pEditString = nil; + field_113 = 0; + } + + if (!m_bStartGameLoading) { + if (m_bGameNotLoaded) + DMAudio.Service(); + } } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::ProcessButtonPresses() { EAXJMP(0x4856F0); } #else void CMenuManager::ProcessButtonPresses() { + if(pEditString) + return; + if(pControlEdit) + return; + // Update mouse position m_nMouseOldPosX = m_nMousePosX; m_nMouseOldPosY = m_nMousePosY; @@ -1500,7 +1534,7 @@ void CMenuManager::ProcessButtonPresses() field_113 = 1; field_456 = 1; m_bKeyChangeNotProcessed = 1; - //pControlEdit = m_KeyPressedCode; + pControlEdit = &m_KeyPressedCode; } if (GetPadForward()) { @@ -1509,7 +1543,7 @@ void CMenuManager::ProcessButtonPresses() if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { field_113 = 1; field_456 = 1; - //pControlEdit = m_KeyPressedCode; + pControlEdit = &m_KeyPressedCode; } if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { strcpy(m_PrefsSkinFile, m_aSkinName); @@ -1527,7 +1561,7 @@ void CMenuManager::ProcessButtonPresses() break; default: break; - }; + } } bool once = false; @@ -1604,7 +1638,7 @@ void CMenuManager::ProcessButtonPresses() SwitchToNewScreen(aScreens[m_nCurrScreen].m_PreviousPage[0]); PlayEscSound = true; break; - }; + } if (PlayEscSound) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_EXIT, 0); @@ -1639,7 +1673,7 @@ void CMenuManager::ProcessButtonPresses() default: m_nHoverOption = HOVEROPTION_NULL; break; - }; + } } // Process all menu options here, but first check if it's an option or a redirect. @@ -1675,11 +1709,11 @@ void CMenuManager::ProcessButtonPresses() break; default: break; - }; + } } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::ProcessOnOffMenuOptions() { EAXJMP(0x48AE60); } #else void CMenuManager::ProcessOnOffMenuOptions() @@ -1740,7 +1774,7 @@ void CMenuManager::ProcessOnOffMenuOptions() case AR_16_9: m_PrefsUseWideScreen = AR_AUTO; break; - }; + } } else { switch (m_PrefsUseWideScreen) { @@ -1753,7 +1787,7 @@ void CMenuManager::ProcessOnOffMenuOptions() case AR_16_9: m_PrefsUseWideScreen = AR_4_3; break; - }; + } } #endif SaveSettings(); @@ -1999,7 +2033,7 @@ void CMenuManager::ProcessOnOffMenuOptions() case 2: m_PrefsSpeakers = 0; break; - }; + } } else { switch (m_PrefsSpeakers) { @@ -2012,7 +2046,7 @@ void CMenuManager::ProcessOnOffMenuOptions() case 2: m_PrefsSpeakers = 1; break; - }; + } } DMAudio.SetSpeakerConfig(m_PrefsSpeakers); @@ -2040,11 +2074,11 @@ void CMenuManager::ProcessOnOffMenuOptions() case MENUACTION_MOUSESTEER: m_bDisableMouseSteering = m_bDisableMouseSteering == false; return; - }; + } } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::RequestFrontEndShutdown() { EAXJMP(0x488750); } #else void CMenuManager::RequestFrontEndShutdown() @@ -2054,7 +2088,7 @@ void CMenuManager::RequestFrontEndShutdown() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::RequestFrontEndStartUp() { EAXJMP(0x488770); } #else void CMenuManager::RequestFrontEndStartUp() @@ -2063,7 +2097,7 @@ void CMenuManager::RequestFrontEndStartUp() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::ResetHelperText() { EAXJMP(0x48B470); } #else void CMenuManager::ResetHelperText() @@ -2073,7 +2107,7 @@ void CMenuManager::ResetHelperText() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::SaveLoadFileError_SetUpErrorScreen() { EAXJMP(0x488930); } #else void CMenuManager::SaveLoadFileError_SetUpErrorScreen() @@ -2116,8 +2150,8 @@ void CMenuManager::SaveLoadFileError_SetUpErrorScreen() } #endif -#if 0 -WRAPPER void CMenuManager::SetHelperText() { EAXJMP(0x48B450); } +#if ALL_ORIGINAL_FRONTEND +WRAPPER void CMenuManager::SetHelperText(int text) { EAXJMP(0x48B450); } #else void CMenuManager::SetHelperText(int text) { @@ -2126,7 +2160,7 @@ void CMenuManager::SetHelperText(int text) } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::SaveSettings() { EAXJMP(0x488CC0); } #else void CMenuManager::SaveSettings() @@ -2173,7 +2207,7 @@ void CMenuManager::SaveSettings() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::ShutdownJustMenu() { EAXJMP(0x488920); } #else void CMenuManager::ShutdownJustMenu() @@ -2184,7 +2218,7 @@ void CMenuManager::ShutdownJustMenu() #endif // We won't ever use this again. -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER float CMenuManager::StretchX(float) { EAXJMP(0x48ABE0); } #else float CMenuManager::StretchX(float x) @@ -2196,7 +2230,7 @@ float CMenuManager::StretchX(float x) } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER float CMenuManager::StretchY(float) { EAXJMP(0x48AC20); } #else float CMenuManager::StretchY(float y) @@ -2208,7 +2242,7 @@ float CMenuManager::StretchY(float y) } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::SwitchMenuOnAndOff() { EAXJMP(0x488790); } #else void CMenuManager::SwitchMenuOnAndOff() @@ -2230,7 +2264,7 @@ void CMenuManager::SwitchMenuOnAndOff() ShutdownJustMenu(); SaveSettings(); m_bStartUpFrontEndRequested = false; - pControlEdit = 0; + pControlEdit = nil; m_bShutDownFrontEndRequested = false; DisplayComboButtonErrMsg = 0; CPad::GetPad(0)->Clear(0); @@ -2254,7 +2288,7 @@ void CMenuManager::SwitchMenuOnAndOff() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::UnloadTextures() { EAXJMP(0x47A440); } #else void CMenuManager::UnloadTextures() @@ -2279,7 +2313,7 @@ void CMenuManager::UnloadTextures() } #endif -#if 0 +#if ALL_ORIGINAL_FRONTEND WRAPPER void CMenuManager::WaitForUserCD(void) { EAXJMP(0x48ADD0); } #else void CMenuManager::WaitForUserCD() @@ -2307,7 +2341,7 @@ uint8 CMenuManager::GetNumberOfMenuOptions() break; ++Rows; - }; + } return Rows; } @@ -2406,7 +2440,7 @@ void CMenuManager::SetDefaultPreferences(int8 screen) CVehicle::m_bDisableMouseSteering = true; TheCamera.m_bHeadBob = false; break; - }; + } } // Frontend inputs. @@ -2464,18 +2498,47 @@ bool GetPadMoveRight() (CPad::GetPad(0)->NewState.LeftStickX > 0 && !(CPad::GetPad(0)->OldState.LeftStickX > 0)); } -bool GetMouseForward() +bool GetMouseClickLeft() { return (CPad::GetPad(0)->NewMouseControllerState.LMB && !CPad::GetPad(0)->OldMouseControllerState.LMB); } -bool GetMouseBack() +bool GetMouseClickRight() { return (CPad::GetPad(0)->NewMouseControllerState.RMB && !CPad::GetPad(0)->OldMouseControllerState.RMB); } +bool GetMouseClickMiddle() +{ + return + (CPad::GetPad(0)->NewMouseControllerState.MMB && !CPad::GetPad(0)->OldMouseControllerState.MMB); +} + +bool GetMouseWheelUp() +{ + return + (CPad::GetPad(0)->NewMouseControllerState.WHEELUP && !CPad::GetPad(0)->OldMouseControllerState.WHEELUP); +} + +bool GetMouseWheelDown() +{ + return + (CPad::GetPad(0)->NewMouseControllerState.WHEELDN && !CPad::GetPad(0)->OldMouseControllerState.WHEELDN); +} + + +bool GetMouseForward() +{ + return GetMouseClickLeft(); +} + +bool GetMouseBack() +{ + return GetMouseClickRight; +} + bool GetMousePos() { return @@ -2484,14 +2547,12 @@ bool GetMousePos() bool GetMouseMoveLeft() { - return - (CPad::GetPad(0)->NewMouseControllerState.WHEELDN && !CPad::GetPad(0)->OldMouseControllerState.WHEELDN != 0.0f); + return GetMouseWheelDown(); } bool GetMouseMoveRight() { - return - (CPad::GetPad(0)->NewMouseControllerState.WHEELUP && !CPad::GetPad(0)->OldMouseControllerState.WHEELUP != 0.0f); + return GetMouseWheelUp(); } bool GetPadInput() @@ -2516,6 +2577,7 @@ bool GetMouseInput() } STARTPATCHES +#ifndef ALL_ORIGINAL_FRONTEND InjectHook(0x47A230, &CMenuManager::LoadAllTextures, PATCH_JUMP); InjectHook(0x47A440, &CMenuManager::UnloadTextures, PATCH_JUMP); InjectHook(0x485100, &CMenuManager::Process, PATCH_JUMP); @@ -2526,4 +2588,5 @@ STARTPATCHES for (int i = 1; i < ARRAY_SIZE(aScreens); i++) Patch(0x611930 + sizeof(CMenuScreen) * i, aScreens[i]); +#endif ENDPATCHES \ No newline at end of file diff --git a/src/core/Frontend.h b/src/core/Frontend.h index ede036d2..9a3cdd50 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -448,7 +448,7 @@ public: int m_nCurrOption; int m_nPrevOption; int m_nPrevScreen; - int field_558; + uint32 field_558; int m_nCurrSaveSlot; int m_nScreenChangeDelayTimer; diff --git a/src/core/Text.cpp b/src/core/Text.cpp index b834a44d..dfa9815c 100644 --- a/src/core/Text.cpp +++ b/src/core/Text.cpp @@ -210,7 +210,48 @@ AsciiToUnicode(const char *src, uint16 *dst) while((*dst++ = *src++) != '\0'); } -WRAPPER char UnicodeToAscii(wchar * src) { EAXJMP(0x52C2F0); } +char* +UnicodeToAscii(wchar *src) +{ + static char aStr[256]; + int len; + for(len = 0; src && *src != 0 && len < 256-1; len++, src++) + if(*src < 256) + aStr[len] = *src; + else + aStr[len] = '#'; + aStr[len] = '\0'; + return aStr; +} + +char* +UnicodeToAsciiForSaveLoad(wchar *src) +{ + // exact same code as above + static char aStr[256]; + int len; + for(len = 0; src && *src != 0 && len < 256-1; len++, src++) + if(*src < 256) + aStr[len] = *src; + else + aStr[len] = '#'; + aStr[len] = '\0'; + return aStr; +} + +void +UnicodeStrcpy(wchar *dst, const wchar *src) +{ + while((*dst++ = *src++) != '\0'); +} + +int +UnicodeStrlen(const wchar *str) +{ + int len; + for(len = 0; *str != 0; len++, str++); + return len; +} void TextCopy(wchar *dst, const wchar *src) @@ -218,6 +259,7 @@ TextCopy(wchar *dst, const wchar *src) while((*dst++ = *src++) != '\0'); } + STARTPATCHES InjectHook(0x52C3C0, &CText::Load, PATCH_JUMP); InjectHook(0x52C580, &CText::Unload, PATCH_JUMP); diff --git a/src/core/Text.h b/src/core/Text.h index 15ab7a8f..f554628c 100644 --- a/src/core/Text.h +++ b/src/core/Text.h @@ -1,7 +1,10 @@ #pragma once void AsciiToUnicode(const char *src, wchar *dst); -char UnicodeToAscii(wchar *src); +char *UnicodeToAscii(wchar *src); +char *UnicodeToAsciiForSaveLoad(wchar *src); +void UnicodeStrcpy(wchar *dst, const wchar *src); +int UnicodeStrlen(const wchar *str); void TextCopy(wchar *dst, const wchar *src); struct CKeyEntry diff --git a/src/core/main.cpp b/src/core/main.cpp index e7f42780..9ac271f9 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -54,8 +54,14 @@ GlobalScene &Scene = *(GlobalScene*)0x726768; uint8 work_buff[55000]; -char gString[256]; +//char gString[256]; +//char gString2[512]; +//wchar gUString[256]; +//wchar gUString2[256]; +char *gString = (char*)0x711B40; +char *gString2 = (char*)0x878A40; wchar *gUString = (wchar*)0x74B018; +wchar *gUString2 = (wchar*)0x6EDD70; bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8; diff --git a/src/core/main.h b/src/core/main.h index bdb0e008..dabc0f7b 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -8,8 +8,14 @@ struct GlobalScene extern GlobalScene &Scene; extern uint8 work_buff[55000]; -extern char gString[256]; +//extern char gString[256]; +//extern char gString2[512]; +//extern wchar gUString[256]; +//extern wchar gUString2[256]; +extern char *gString; +extern char *gString2; extern wchar *gUString; +extern wchar *gUString2; extern bool &b_FoundRecentSavedGameWantToLoad; class CSprite2d; From b14be6697bd609bfd957576047754cabd8cd3019 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 10 Jul 2019 14:00:10 +0200 Subject: [PATCH 25/30] fixed COMMAND_IS_PLAYER_IN_AREA_3D --- src/control/Script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 8e9033b6..b50c101e 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -1295,9 +1295,9 @@ int8 CRunningScript::ProcessCommandsFrom0To99(int32 command) y2 = *(float*)&ScriptParams[5]; z2 = *(float*)&ScriptParams[6]; if (ped->bInVehicle) - UpdateCompareFlag(ped->IsWithinArea(x1, y1, z1, x2, y2, z2)); - else UpdateCompareFlag(ped->m_pMyVehicle->IsWithinArea(x1, y1, z1, x2, y2, z2)); + else + UpdateCompareFlag(ped->IsWithinArea(x1, y1, z1, x2, y2, z2)); if (!ScriptParams[7]) return 0; CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f); From 86681c6f18b5741ba25bbbb7319bb832ffa4807a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Wed, 10 Jul 2019 09:06:43 +0300 Subject: [PATCH 26/30] Phone start, ped spinning and cop car fix, and some love to CPed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: eray orçunus --- src/control/Phones.cpp | 37 +++++++++++++++++++ src/control/Phones.h | 28 ++++++++++++++ src/core/World.cpp | 78 +++++++++++++++++++++++++++++++++++++++ src/core/World.h | 4 +- src/entities/Physical.cpp | 2 +- src/peds/Ped.cpp | 40 +++++++++++++++++++- src/peds/Ped.h | 11 +++--- 7 files changed, 191 insertions(+), 9 deletions(-) diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp index fa4f83e5..1d3a9777 100644 --- a/src/control/Phones.cpp +++ b/src/control/Phones.cpp @@ -2,5 +2,42 @@ #include "patcher.h" #include "Phones.h" +CPhoneInfo &gPhoneInfo = * (CPhoneInfo*) * (uintptr*)0x732A20; + +int +CPhoneInfo::FindNearestFreePhone(CVector *pos) +{ + int nearestPhoneId = -1; + float nearestPhoneDist = 60.0f; + + for (int phoneId = 0; phoneId < m_nMax; phoneId++) { + + if (gPhoneInfo.m_aPhones[phoneId].m_nState == 0) { + float phoneDist = (m_aPhones[phoneId].m_vecPos - *pos).Magnitude2D(); + + if (phoneDist < nearestPhoneDist) { + nearestPhoneDist = phoneDist; + nearestPhoneId = phoneId; + } + } + } + return nearestPhoneId; +} + +bool +CPhoneInfo::PhoneAtThisPosition(CVector pos) +{ + for (int phoneId = 0; phoneId < m_nMax; phoneId++) { + if (pos.x == m_aPhones[phoneId].m_vecPos.x && pos.y == m_aPhones[phoneId].m_vecPos.y) + return true; + } + return false; +} + +STARTPATCHES + InjectHook(0x42F720, &CPhoneInfo::FindNearestFreePhone, PATCH_JUMP); + InjectHook(0x42FD50, &CPhoneInfo::PhoneAtThisPosition, PATCH_JUMP); +ENDPATCHES + WRAPPER void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x42F570); } WRAPPER void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x42F470); } diff --git a/src/control/Phones.h b/src/control/Phones.h index a29043ed..7ac34c3a 100644 --- a/src/control/Phones.h +++ b/src/control/Phones.h @@ -1,6 +1,34 @@ #pragma once +#include "Physical.h" #include "AnimBlendAssociation.h" +struct CPhone +{ + CVector m_vecPos; + uint16 *m_apMessages[6]; + int32 field_24; + CEntity *m_pEntity; + int32 m_nState; + uint8 field_30; +}; + +static_assert(sizeof(CPhone) == 0x34, "CPhone: error"); + +class CPhoneInfo { +public: + int32 m_nMax; + int32 m_nNum; + CPhone m_aPhones[50]; + + CPhoneInfo() { } + ~CPhoneInfo() { } + + int FindNearestFreePhone(CVector*); + bool PhoneAtThisPosition(CVector); +}; + +extern CPhoneInfo &gPhoneInfo; + void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg); void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg); \ No newline at end of file diff --git a/src/core/World.cpp b/src/core/World.cpp index 538e15c5..a31f87a7 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -564,6 +564,82 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo return true; } +void +CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector ¢re, float distance, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects) +{ + float distSqr = distance * distance; + float objDistSqr; + + for (CPtrNode *node = list.first; node; node = node->next) { + CEntity *object = (CEntity*)node->item; + if (object->m_scanCode != CWorld::GetCurrentScanCode()) { + object->m_scanCode = CWorld::GetCurrentScanCode(); + + CVector diff = centre - object->GetPosition(); + if (ignoreZ) + objDistSqr = diff.MagnitudeSqr2D(); + else + objDistSqr = diff.MagnitudeSqr(); + + if (objDistSqr < distSqr && *nextObject < lastObject) { + if (objects) { + objects[*nextObject] = object; + } + (*nextObject)++; + } + } + } +} + +void +CWorld::FindObjectsInRange(CVector ¢re, float distance, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies) +{ + int minX = GetSectorIndexX(centre.x - distance); + if (minX <= 0) + minX = 0; + + int minY = GetSectorIndexY(centre.y - distance); + if (minY <= 0) + minY = 0; + + int maxX = GetSectorIndexX(centre.x + distance); + if (maxX >= 100) + maxX = 100; + + int maxY = GetSectorIndexY(centre.y + distance); + if (maxY >= 100) + maxY = 100; + + AdvanceCurrentScanCode(); + + *nextObject = 0; + for(int curY = minY; curY <= maxY; curY++) { + for(int curX = minX; curX <= maxX; curX++) { + CSector *sector = GetSector(curX, curY); + if (checkBuildings) { + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, distance, ignoreZ, nextObject, lastObject, objects); + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects); + } + if (checkVehicles) { + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, distance, ignoreZ, nextObject, lastObject, objects); + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects); + } + if (checkPeds) { + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, distance, ignoreZ, nextObject, lastObject, objects); + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects); + } + if (checkObjects) { + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, distance, ignoreZ, nextObject, lastObject, objects); + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects); + } + if (checkDummies) { + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, distance, ignoreZ, nextObject, lastObject, objects); + CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects); + } + } + } +} + float CWorld::FindGroundZForCoord(float x, float y) { @@ -712,6 +788,8 @@ STARTPATCHES InjectHook(0x4B2000, CWorld::GetIsLineOfSightSectorClear, PATCH_JUMP); InjectHook(0x4B2160, CWorld::GetIsLineOfSightSectorListClear, PATCH_JUMP); + InjectHook(0x4B2200, CWorld::FindObjectsInRange, PATCH_JUMP); + InjectHook(0x4B2540, CWorld::FindObjectsInRangeSectorList, PATCH_JUMP); InjectHook(0x4B3A80, CWorld::FindGroundZForCoord, PATCH_JUMP); InjectHook(0x4B3AE0, CWorld::FindGroundZFor3DCoord, PATCH_JUMP); InjectHook(0x4B3B50, CWorld::FindRoofZFor3DCoord, PATCH_JUMP); diff --git a/src/core/World.h b/src/core/World.h index 3b7090da..d6063d70 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -93,7 +93,9 @@ public: static bool GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false); static bool GetIsLineOfSightSectorClear(CSector §or, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false); static bool GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects = false); - + + static void FindObjectsInRangeSectorList(CPtrList&, CVector&, float, bool, short*, short, CEntity**); + static void FindObjectsInRange(CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool); static float FindGroundZForCoord(float x, float y); static float FindGroundZFor3DCoord(float x, float y, float z, bool *found); static float FindRoofZFor3DCoord(float x, float y, float z, bool *found); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index b2512ec2..c9e0da90 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -33,7 +33,7 @@ CPhysical::CPhysical(void) m_nCollisionRecords = 0; for(i = 0; i < 6; i++) - m_aCollisionRecords[0] = nil; + m_aCollisionRecords[i] = nil; field_EF = false; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 692fc4f2..cce5d6a9 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -23,6 +23,7 @@ #include "Lights.h" #include "PointLights.h" #include "Pad.h" +#include "Phones.h" WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); } WRAPPER void CPed::Say(uint16 audio) { EAXJMP(0x4E5A10); } @@ -42,6 +43,7 @@ WRAPPER void CPed::SetFollowRoute(int16, int16) { EAXJMP(0x4DD690); } WRAPPER void CPed::SetDuck(uint32) { EAXJMP(0x4E4920); } WRAPPER void CPed::RegisterThreatWithGangPeds(CEntity*) { EAXJMP(0x4E3870); } WRAPPER void CPed::MakeChangesForNewWeapon(int8) { EAXJMP(0x4F2560); } +WRAPPER bool CPed::Seek(void) { EAXJMP(0x4D1640); } bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44; bool &CPed::bPedCheat2 = *(bool*)0x95CD5A; @@ -1389,7 +1391,7 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg) if (ped->m_nPedState != PED_ARRESTED) { ped->m_nLastPedState = PED_NONE; if (dragAssoc) - dragAssoc->blendDelta = -1000.0; + dragAssoc->blendDelta = -1000.0f; } ped->RestartNonPartialAnims(); ped->m_pVehicleAnim = nil; @@ -2055,6 +2057,7 @@ CPed::SetupLighting(void) { ActivateDirectional(); SetAmbientColoursForPedsCarsAndObjects(); + if (bRenderScorched) { WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f); } else { @@ -2696,7 +2699,7 @@ CPed::QuitEnteringCar(void) if (veh->m_nNumGettingIn != 0) veh->m_nNumGettingIn--; - veh->m_nGettingInFlags = GetVehDoorFlag(m_vehEnterType); + veh->m_nGettingInFlags = ~GetVehDoorFlag(m_vehEnterType); } bUsesCollision = true; @@ -2869,6 +2872,38 @@ CPed::Chat(void) } } +void +CPed::CheckAroundForPossibleCollisions(void) +{ + CVector ourCentre, objCentre; + CEntity *objects[8]; + int16 maxObject; + + if (CTimer::GetTimeInMilliseconds() <= m_nPedStateTimer) + return; + + GetBoundCentre(ourCentre); + + CWorld::FindObjectsInRange(ourCentre, 10.0f, true, &maxObject, 6, objects, false, true, false, true, false); + for (int i = 0; i < maxObject; i++) { + CEntity *object = objects[i]; + if (field_31C) { + if (gPhoneInfo.PhoneAtThisPosition(object->GetPosition())) + break; + } + object->GetBoundCentre(objCentre); + float radius = object->GetBoundRadius(); + if (radius > 4.5f || radius < 1.0f) + radius = 1.0f; + + // According to code, developers gave up calculating Z diff. later. + float diff = CVector(ourCentre - objCentre).MagnitudeSqr2D(); + + if (sq(radius + 1.0f) > diff) + m_fRotationDest += DEGTORAD(22.5f); + } +} + WRAPPER void CPed::PedGetupCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE810); } WRAPPER void CPed::PedStaggerCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8D0); } WRAPPER void CPed::PedEvadeCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D36E0); } @@ -2961,4 +2996,5 @@ STARTPATCHES InjectHook(0x4D3C80, &CPed::ClearChat, PATCH_JUMP); InjectHook(0x4D1390, &CPed::TurnBody, PATCH_JUMP); InjectHook(0x4D3AC0, &CPed::Chat, PATCH_JUMP); + InjectHook(0x4D0490, &CPed::CheckAroundForPossibleCollisions, PATCH_JUMP); ENDPATCHES diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 2390d1d4..4909a583 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -13,7 +13,7 @@ struct CPathNode; -enum eWaitState : uint32 { +enum eWaitState { WAITSTATE_FALSE, WAITSTATE_TRAFFIC_LIGHTS, WAITSTATE_CROSS_ROAD, @@ -292,10 +292,10 @@ public: int32 m_nPrevActionState; eWaitState m_nWaitState; uint32 m_nWaitTimer; - void *m_pPathNodesStates[8]; + void *m_pPathNodesStates[8]; // seems unused CVector2D m_stPathNodeStates[10]; uint16 m_nPathNodes; - uint8 m_nCurPathNode; + int16 m_nCurPathNode; int8 m_nPathState; private: int8 _pad2B5[3]; @@ -324,7 +324,7 @@ public: CVehicle *m_pMyVehicle; bool bInVehicle; uint8 pad_315[3]; - uint32 field_318; + float field_318; uint8 field_31C; uint8 field_31D; int16 m_phoneId; @@ -457,7 +457,8 @@ public: bool TurnBody(void); void Chat(void); void MakeChangesForNewWeapon(int8); - + void CheckAroundForPossibleCollisions(void); + bool Seek(void); // Static methods static void GetLocalPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enterType, float offset); From 4a36d64f15f898854bb8a76be86ac9a8c536b291 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 10 Jul 2019 17:18:26 +0200 Subject: [PATCH 27/30] added wrappers around math functions --- src/audio/AudioManager.cpp | 2 +- src/control/PathFind.cpp | 14 +++++----- src/control/Replay.cpp | 6 ++-- src/core/Camera.cpp | 56 +++++++++++++++++++------------------- src/core/Collision.cpp | 20 +++++++------- src/core/FileLoader.cpp | 6 ++-- src/core/General.h | 24 ++++++++-------- src/core/Pad.cpp | 22 +++++++-------- src/core/Radar.cpp | 20 +++++++------- src/core/Streaming.cpp | 10 +++---- src/core/common.h | 1 + src/entities/Entity.cpp | 6 ++-- src/entities/Physical.cpp | 32 +++++++++++----------- src/math/Matrix.h | 24 ++++++++-------- src/math/Quaternion.h | 2 +- src/math/Vector.h | 6 ++-- src/math/Vector2D.h | 2 +- src/math/math.cpp | 6 ++-- src/math/maths.h | 12 ++++++++ src/peds/Ped.cpp | 18 ++++++------ src/peds/PedIK.cpp | 4 +-- src/render/Clouds.cpp | 14 +++++----- src/render/Coronas.cpp | 4 +-- src/render/Hud.cpp | 2 +- src/render/Particle.cpp | 8 +++--- src/render/PointLights.cpp | 14 +++++----- src/render/Sprite.cpp | 20 +++++++------- src/render/Timecycle.cpp | 4 +-- src/skel/win/win.cpp | 10 +++---- src/vehicles/Door.cpp | 8 +++--- src/vehicles/Vehicle.cpp | 18 ++++++------ 31 files changed, 204 insertions(+), 191 deletions(-) create mode 100644 src/math/maths.h diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 9e86aef0..51f45e16 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -445,7 +445,7 @@ void cAudioManager::CalculateDistance(bool *ptr, float dist) { if(*ptr == false) { - m_sQueueSample.m_fDistance = sqrt(dist); + m_sQueueSample.m_fDistance = Sqrt(dist); *ptr = true; } } diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index f9ce7f35..a92882db 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -146,8 +146,8 @@ CPathFind::PreparePathData(void) numExtern++; if(InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes > numLanes) numLanes = InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes; - maxX = max(maxX, fabs(InfoForTileCars[k].x)); - maxY = max(maxY, fabs(InfoForTileCars[k].y)); + maxX = max(maxX, Abs(InfoForTileCars[k].x)); + maxY = max(maxY, Abs(InfoForTileCars[k].y)); }else if(InfoForTileCars[k].type == NodeTypeIntern) numIntern++; } @@ -327,10 +327,10 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor if(tempnodes[k].linkState != 1) continue; dx = tempnodes[k].pos.x - CoorsXFormed.x; - if(fabs(dx) < nearestDist){ + if(Abs(dx) < nearestDist){ dy = tempnodes[k].pos.y - CoorsXFormed.y; - if(fabs(dy) < nearestDist){ - nearestDist = max(fabs(dx), fabs(dy)); + if(Abs(dy) < nearestDist){ + nearestDist = max(Abs(dx), Abs(dy)); nearestId = k; } } @@ -369,7 +369,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor dx = m_pathNodes[tempnodes[nearestId].link1].pos.x - m_pathNodes[tempnodes[nearestId].link2].pos.x; dy = m_pathNodes[tempnodes[nearestId].link1].pos.y - m_pathNodes[tempnodes[nearestId].link2].pos.y; tempnodes[nearestId].pos = (tempnodes[nearestId].pos + CoorsXFormed)*0.5f; - mag = sqrt(dx*dx + dy*dy); + mag = Sqrt(dx*dx + dy*dy); tempnodes[nearestId].dirX = dx/mag; tempnodes[nearestId].dirY = dy/mag; // do something when number of lanes doesn't agree @@ -464,7 +464,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor posy = (m_pathNodes[i].pos.y + m_pathNodes[j].pos.y)*0.5f; dx = m_pathNodes[j].pos.x - m_pathNodes[i].pos.x; dy = m_pathNodes[j].pos.y - m_pathNodes[i].pos.y; - mag = sqrt(dx*dx + dy*dy); + mag = Sqrt(dx*dx + dy*dy); dx /= mag; dy /= mag; if(i < j){ diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 2bdb9dfe..3ce9085f 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -1505,9 +1505,9 @@ void CReplay::ProcessLookAroundCam(void) else fAlphaAngleLookAroundCam = max(0.1f, min(1.5f, fAlphaAngleLookAroundCam + y_moved)); CVector camera_pt( - fDistanceLookAroundCam * sin(fBetaAngleLookAroundCam) * cos(fAlphaAngleLookAroundCam), - fDistanceLookAroundCam * cos(fBetaAngleLookAroundCam) * cos(fAlphaAngleLookAroundCam), - fDistanceLookAroundCam * sin(fAlphaAngleLookAroundCam) + fDistanceLookAroundCam * Sin(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam), + fDistanceLookAroundCam * Cos(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam), + fDistanceLookAroundCam * Sin(fAlphaAngleLookAroundCam) ); CVector focus = CVector(CameraFocusX, CameraFocusY, CameraFocusZ); camera_pt += focus; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 4f565897..4e988c15 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -170,9 +170,9 @@ WellBufferMe(float Target, float *CurrentValue, float *CurrentSpeed, float MaxSp float TargetSpeed = Delta * MaxSpeed; // Add or subtract absolute depending on sign, genius! // if(TargetSpeed - *CurrentSpeed > 0.0f) -// *CurrentSpeed += Acceleration * fabs(TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep(); +// *CurrentSpeed += Acceleration * Abs(TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep(); // else -// *CurrentSpeed -= Acceleration * fabs(TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep(); +// *CurrentSpeed -= Acceleration * Abs(TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep(); // this is simpler: *CurrentSpeed += Acceleration * (TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep(); @@ -249,14 +249,14 @@ CCam::GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaO for(a = 0.0f; a <= PI; a += DEGTORAD(5.0f)){ if(BetaOffset <= 0.0f){ - ToSource = CVector(cos(Beta + BetaOffset + a), sin(Beta + BetaOffset + a), 0.0f)*Dist; + ToSource = CVector(Cos(Beta + BetaOffset + a), Sin(Beta + BetaOffset + a), 0.0f)*Dist; if(!CWorld::ProcessLineOfSight(Target, Target + ToSource, point, ent, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, true, true)) return a; } if(BetaOffset >= 0.0f){ - ToSource = CVector(cos(Beta + BetaOffset - a), sin(Beta + BetaOffset - a), 0.0f)*Dist; + ToSource = CVector(Cos(Beta + BetaOffset - a), Sin(Beta + BetaOffset - a), 0.0f)*Dist; if(!CWorld::ProcessLineOfSight(Target, Target + ToSource, point, ent, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, true, true)) @@ -500,7 +500,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl CVector PlayerPos = FindPlayerPed()->GetPosition(); float RotationDist = (AngleToGoTo == Center ? CenterDist : LateralDist) * RealGroundDist; // What's going on here? - AngleToGoTo? - CVector RotatedSource = PlayerPos + CVector(cos(Beta - AngleToGoTo), sin(Beta - AngleToGoTo), 0.0f) * RotationDist; + CVector RotatedSource = PlayerPos + CVector(Cos(Beta - AngleToGoTo), Sin(Beta - AngleToGoTo), 0.0f) * RotationDist; CColPoint colpoint; CEntity *entity; @@ -584,9 +584,9 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl float ReqSpeed = DeltaBeta * MaxSpeed; // Add or subtract absolute depending on sign, genius! if(ReqSpeed - BetaSpeed > 0.0f) - BetaSpeed += SpeedStep * fabs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep(); + BetaSpeed += SpeedStep * Abs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep(); else - BetaSpeed -= SpeedStep * fabs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep(); + BetaSpeed -= SpeedStep * Abs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep(); // this would be simpler: // BetaSpeed += SpeedStep * (ReqSpeed - BetaSpeed) * CTimer::ms_fTimeStep; @@ -604,14 +604,14 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl BetaSpeed = 0.0f; } - Source.x = TargetCoors.x + Distance * cos(Beta); - Source.y = TargetCoors.y + Distance * sin(Beta); + Source.x = TargetCoors.x + Distance * Cos(Beta); + Source.y = TargetCoors.y + Distance * Sin(Beta); // Check if we can stop rotating DeltaBeta = FixedTargetOrientation - Beta; while(DeltaBeta >= PI) DeltaBeta -= 2*PI; while(DeltaBeta < -PI) DeltaBeta += 2*PI; - if(fabs(DeltaBeta) < DEGTORAD(1.0f) && !bBehindPlayerDesired){ + if(Abs(DeltaBeta) < DEGTORAD(1.0f) && !bBehindPlayerDesired){ // Stop rotation PickedASide = false; Rotating = false; @@ -624,18 +624,18 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl HackPlayerOnStoppingTrain || Rotating){ if(TheCamera.m_bCamDirectlyBehind){ Beta = TargetOrientation + PI; - Source.x = TargetCoors.x + Distance * cos(Beta); - Source.y = TargetCoors.y + Distance * sin(Beta); + Source.x = TargetCoors.x + Distance * Cos(Beta); + Source.y = TargetCoors.y + Distance * Sin(Beta); } if(TheCamera.m_bCamDirectlyInFront){ Beta = TargetOrientation; - Source.x = TargetCoors.x + Distance * cos(Beta); - Source.y = TargetCoors.y + Distance * sin(Beta); + Source.x = TargetCoors.x + Distance * Cos(Beta); + Source.y = TargetCoors.y + Distance * Sin(Beta); } if(HackPlayerOnStoppingTrain){ Beta = TargetOrientation + PI; - Source.x = TargetCoors.x + Distance * cos(Beta); - Source.y = TargetCoors.y + Distance * sin(Beta); + Source.x = TargetCoors.x + Distance * Cos(Beta); + Source.y = TargetCoors.y + Distance * Sin(Beta); m_fDimensionOfHighestNearCar = 0.0f; m_fCamBufferedHeight = 0.0f; m_fCamBufferedHeightSpeed = 0.0f; @@ -904,7 +904,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa while(deltaBeta >= PI) deltaBeta -= 2*PI; while(deltaBeta < -PI) deltaBeta += 2*PI; - float BehindCarNess = cos(deltaBeta); // 1 if behind car, 0 if side, -1 if in front + float BehindCarNess = Cos(deltaBeta); // 1 if behind car, 0 if side, -1 if in front CarAlpha = -CarAlpha * BehindCarNess; if(CarAlpha < -0.01f) CarAlpha = -0.01f; @@ -939,8 +939,8 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa Forward = CamTargetEntity->GetForward(); // we actually still have that... Forward.Normalise(); // shouldn't be necessary float CarSideAngle = CGeneral::GetATanOfXY(Forward.x, Forward.y) + PI/2.0f; - float SideX = 2.5f * cos(CarSideAngle); - float SideY = 2.5f * sin(CarSideAngle); + float SideX = 2.5f * Cos(CarSideAngle); + float SideY = 2.5f * Sin(CarSideAngle); CWorld::FindRoofZFor3DCoord(TargetCoors.x + SideX, TargetCoors.y + SideY, CarBottom, &FoundRoofSide1); CWorld::FindRoofZFor3DCoord(TargetCoors.x - SideX, TargetCoors.y - SideY, CarBottom, &FoundRoofSide2); @@ -1042,7 +1042,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa WellBufferMe(LastTargetAlphaWithCollisionOn, &Alpha, &AlphaSpeed, LastTopAlphaSpeed, LastAlphaSpeedStep, true); - Source.z = TargetCoors.z + sin(Alpha + ModeAlpha)*Length + m_fCloseInCarHeightOffset; + Source.z = TargetCoors.z + Sin(Alpha + ModeAlpha)*Length + m_fCloseInCarHeightOffset; } // Rotate cam behind the car when the car is moving forward @@ -1062,7 +1062,7 @@ CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation) while(DeltaBeta >= PI) DeltaBeta -= 2*PI; while(DeltaBeta < -PI) DeltaBeta += 2*PI; - if(fabs(DeltaBeta) > DEGTORAD(20.0f) && MovingForward && TheCamera.m_uiTransitionState == 0) + if(Abs(DeltaBeta) > DEGTORAD(20.0f) && MovingForward && TheCamera.m_uiTransitionState == 0) m_bFixingBeta = true; CPad *pad = CPad::GetPad(0); @@ -1088,14 +1088,14 @@ CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation) if(TheCamera.m_bUseTransitionBeta && &TheCamera.Cams[TheCamera.ActiveCam] == this) Beta = m_fTransitionBeta; - Source.x = TargetCoors.x - cos(Beta)*Dist; - Source.y = TargetCoors.y - sin(Beta)*Dist; + Source.x = TargetCoors.x - Cos(Beta)*Dist; + Source.y = TargetCoors.y - Sin(Beta)*Dist; // Check if we're done DeltaBeta = TargetOrientation - Beta; while(DeltaBeta >= PI) DeltaBeta -= 2*PI; while(DeltaBeta < -PI) DeltaBeta += 2*PI; - if(fabs(DeltaBeta) < DEGTORAD(2.0f)) + if(Abs(DeltaBeta) < DEGTORAD(2.0f)) m_bFixingBeta = false; } TheCamera.m_bCamDirectlyBehind = false; @@ -1157,14 +1157,14 @@ CCam::FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOri return false; if(Fix1){ - Source.x = Target.x - cos(Beta)*Dist1; - Source.y = Target.y - sin(Beta)*Dist1; + Source.x = Target.x - Cos(Beta)*Dist1; + Source.y = Target.y - Sin(Beta)*Dist1; if(Mode == MODE_BEHINDCAR) Source = colPoint.point; }else{ WellBufferMe(Dist2, &m_fDistanceBeforeChanges, &DistanceSpeed, 0.2f, 0.025f, false); - Source.x = Target.x - cos(Beta)*m_fDistanceBeforeChanges; - Source.y = Target.y - sin(Beta)*m_fDistanceBeforeChanges; + Source.x = Target.x - Cos(Beta)*m_fDistanceBeforeChanges; + Source.y = Target.y - Sin(Beta)*m_fDistanceBeforeChanges; } if(ResetStatics){ diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index 94da1338..6241b79a 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -457,7 +457,7 @@ CCollision::TestLineSphere(const CColLine &line, const CColSphere &sph) // I leave in the strange -2 factors even though they serve no real purpose float projline = -2.0f * DotProduct(v01, v0c); // project v0c onto line // Square of tangent from p0 multiplied by line length so we can compare with projline. - // The length of the tangent would be this: sqrt((c-p0)^2 - r^2). + // The length of the tangent would be this: Sqrt((c-p0)^2 - r^2). // Negative if p0 is inside the sphere! This breaks the test! float tansq = 4.0f * linesq * (sph.center.MagnitudeSqr() - 2.0f*DotProduct(sph.center, line.p0) + line.p0.MagnitudeSqr() - sph.radius*sph.radius); @@ -467,10 +467,10 @@ CCollision::TestLineSphere(const CColLine &line, const CColSphere &sph) return false; // projline (negative in GTA for some reason) is the point on the line // in the middle of the two intersection points (startin from p0). - // sqrt(diffsq) somehow works out to be the distance from that + // Sqrt(diffsq) somehow works out to be the distance from that // midpoint to the intersection points. // So subtract that and get rid of the awkward scaling: - float f = (-projline - sqrt(diffsq)) / (2.0f*linesq); + float f = (-projline - Sqrt(diffsq)) / (2.0f*linesq); // f should now be in range [0, 1] for [p0, p1] return f >= 0.0f && f <= 1.0f; } @@ -480,7 +480,7 @@ CCollision::TestSphereTriangle(const CColSphere &sphere, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane) { // If sphere and plane don't intersect, no collision - if(fabs(plane.CalcPoint(sphere.center)) > sphere.radius) + if(Abs(plane.CalcPoint(sphere.center)) > sphere.radius) return false; const CVector &va = verts[tri.a]; @@ -669,7 +669,7 @@ CCollision::ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoin dist = sph.center - p; float lensq = dist.MagnitudeSqr(); if(lensq < mindistsq){ - float len = sqrt(lensq); + float len = Sqrt(lensq); point.point = p; point.normal = dist * (1.0f/len); point.surfaceA = sph.surface; @@ -816,7 +816,7 @@ CCollision::ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CC if(diffsq < 0.0f) return false; // point of first intersection, in range [0,1] between p0 and p1 - float t = (projline - sqrt(diffsq)) / linesq; + float t = (projline - Sqrt(diffsq)) / linesq; // if not on line or beyond mindist, no intersection if(t < 0.0f || t > 1.0f || t >= mindist) return false; @@ -1010,7 +1010,7 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere, // If sphere and plane don't intersect, no collision float planedist = plane.CalcPoint(sphere.center); float distsq = planedist*planedist; - if(fabs(planedist) > sphere.radius || distsq > mindistsq) + if(Abs(planedist) > sphere.radius || distsq > mindistsq) return false; const CVector &va = verts[tri.a]; @@ -1057,7 +1057,7 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere, else assert(0); }else if(testcase == 3){ // center is in triangle - dist = fabs(planedist); + dist = Abs(planedist); p = sphere.center - normal*planedist; }else assert(0); // front fell off @@ -1333,7 +1333,7 @@ CCollision::DistToLine(const CVector *l0, const CVector *l1, const CVector *poin if(dot >= lensq) return (*point - *l1).Magnitude(); // distance to line - return sqrt((*point - *l0).MagnitudeSqr() - dot*dot/lensq); + return Sqrt((*point - *l0).MagnitudeSqr() - dot*dot/lensq); } // same as above but also return the point on the line @@ -1641,7 +1641,7 @@ CColTrianglePlane::Set(const CVector *v, CColTriangle &tri) normal = CrossProduct(vc-va, vb-va); normal.Normalise(); dist = DotProduct(normal, va); - CVector an(fabs(normal.x), fabs(normal.y), fabs(normal.z)); + CVector an(Abs(normal.x), Abs(normal.y), Abs(normal.z)); // find out largest component and its direction if(an.x > an.y && an.x > an.z) dir = normal.x < 0.0f ? DIR_X_NEG : DIR_X_POS; diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index b949eb98..0c53ae66 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -262,9 +262,9 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) model.vertices = (CVector*)RwMalloc(numVertices*sizeof(CVector)); for(i = 0; i < numVertices; i++){ model.vertices[i] = *(CVector*)buf; - if(fabs(model.vertices[i].x) >= 256.0f || - fabs(model.vertices[i].y) >= 256.0f || - fabs(model.vertices[i].z) >= 256.0f) + if(Abs(model.vertices[i].x) >= 256.0f || + Abs(model.vertices[i].y) >= 256.0f || + Abs(model.vertices[i].z) >= 256.0f) printf("%s:Collision volume too big\n", modelname); buf += 12; } diff --git a/src/core/General.h b/src/core/General.h index cae1caa0..a08b622b 100644 --- a/src/core/General.h +++ b/src/core/General.h @@ -6,32 +6,32 @@ public: static float GetATanOfXY(float x, float y){ if(x == 0.0f && y == 0.0f) return 0.0f; - float xabs = fabs(x); - float yabs = fabs(y); + float xabs = Abs(x); + float yabs = Abs(y); if(xabs < yabs){ if(y > 0.0f){ if(x > 0.0f) - return 0.5f*PI - atan2(x / y, 1.0f); + return 0.5f*PI - Atan2(x / y, 1.0f); else - return 0.5f*PI + atan2(-x / y, 1.0f); + return 0.5f*PI + Atan2(-x / y, 1.0f); }else{ if(x > 0.0f) - return 1.5f*PI + atan2(x / -y, 1.0f); + return 1.5f*PI + Atan2(x / -y, 1.0f); else - return 1.5f*PI - atan2(-x / -y, 1.0f); + return 1.5f*PI - Atan2(-x / -y, 1.0f); } }else{ if(y > 0.0f){ if(x > 0.0f) - return atan2(y / x, 1.0f); + return Atan2(y / x, 1.0f); else - return PI - atan2(y / -x, 1.0f); + return PI - Atan2(y / -x, 1.0f); }else{ if(x > 0.0f) - return 2.0f*PI - atan2(-y / x, 1.0f); + return 2.0f*PI - Atan2(-y / x, 1.0f); else - return PI + atan2(-y / -x, 1.0f); + return PI + Atan2(-y / -x, 1.0f); } } } @@ -68,12 +68,12 @@ public: if (x > 0.0f) { if (y > 0.0f) - return PI - atan2(x / y, 1.0f); + return PI - Atan2(x / y, 1.0f); else return -atan2(x / y, 1.0f); } else { if (y > 0.0f) - return -(PI + atan2(x / y, 1.0f)); + return -(PI + Atan2(x / y, 1.0f)); else return -atan2(x / y, 1.0f); } diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 002e7180..9c5e1c8a 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -670,7 +670,7 @@ int16 CPad::GetSteeringLeftRight(void) int16 axis = NewState.LeftStickX; int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2; - if ( abs(axis) > abs(dpad) ) + if ( Abs(axis) > Abs(dpad) ) return axis; else return dpad; @@ -703,7 +703,7 @@ int16 CPad::GetSteeringUpDown(void) int16 axis = NewState.LeftStickY; int16 dpad = (NewState.DPadUp - NewState.DPadDown) / 2; - if ( abs(axis) > abs(dpad) ) + if ( Abs(axis) > Abs(dpad) ) return axis; else return dpad; @@ -790,7 +790,7 @@ int16 CPad::GetPedWalkLeftRight(void) int16 axis = NewState.LeftStickX; int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2; - if ( abs(axis) > abs(dpad) ) + if ( Abs(axis) > Abs(dpad) ) return axis; else return dpad; @@ -824,7 +824,7 @@ int16 CPad::GetPedWalkUpDown(void) int16 axis = NewState.LeftStickY; int16 dpad = (NewState.DPadDown - NewState.DPadUp) / 2; - if ( abs(axis) > abs(dpad) ) + if ( Abs(axis) > Abs(dpad) ) return axis; else return dpad; @@ -854,7 +854,7 @@ int16 CPad::GetAnalogueUpDown(void) int16 axis = NewState.LeftStickY; int16 dpad = (NewState.DPadDown - NewState.DPadUp) / 2; - if ( abs(axis) > abs(dpad) ) + if ( Abs(axis) > Abs(dpad) ) return axis; else return dpad; @@ -1683,7 +1683,7 @@ int16 CPad::SniperModeLookLeftRight(void) int16 axis = NewState.LeftStickX; int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2; - if ( abs(axis) > abs(dpad) ) + if ( Abs(axis) > Abs(dpad) ) return axis; else return dpad; @@ -1694,7 +1694,7 @@ int16 CPad::SniperModeLookUpDown(void) int16 axis = NewState.LeftStickY; int16 dpad = (NewState.DPadUp - NewState.DPadDown) / 2; - if ( abs(axis) > abs(dpad) ) + if ( Abs(axis) > Abs(dpad) ) return axis; else return dpad; @@ -1704,11 +1704,11 @@ int16 CPad::LookAroundLeftRight(void) { float axis = GetPad(0)->NewState.RightStickX; - if ( fabs(axis) > 85 && !GetLookBehindForPed() ) + if ( Abs(axis) > 85 && !GetLookBehindForPed() ) return (int16) ( (axis + ( ( axis > 0 ) ? -85 : 85) ) * (127.0f / 32.0f) ); // 3.96875f - else if ( TheCamera.Cams[0].Using3rdPersonMouseCam() && fabs(axis) > 10 ) + else if ( TheCamera.Cams[0].Using3rdPersonMouseCam() && Abs(axis) > 10 ) return (int16) ( (axis + ( ( axis > 0 ) ? -10 : 10) ) * (127.0f / 64.0f) ); // 1.984375f @@ -1719,11 +1719,11 @@ int16 CPad::LookAroundUpDown(void) { int16 axis = GetPad(0)->NewState.RightStickY; - if ( abs(axis) > 85 && !GetLookBehindForPed() ) + if ( Abs(axis) > 85 && !GetLookBehindForPed() ) return (int16) ( (axis + ( ( axis > 0 ) ? -85 : 85) ) * (127.0f / 32.0f) ); // 3.96875f - else if ( TheCamera.Cams[0].Using3rdPersonMouseCam() && abs(axis) > 40 ) + else if ( TheCamera.Cams[0].Using3rdPersonMouseCam() && Abs(axis) > 40 ) return (int16) ( (axis + ( ( axis > 0 ) ? -40 : 40) ) * (127.0f / 64.0f) ); // 1.984375f diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index a071b96b..b634e4f5 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -469,8 +469,8 @@ void CRadar::DrawRadarMask() // Then generate a quarter of the circle for (int j = 0; j < 7; j++) { - in.x = corners[i].x * cos(j * (PI / 2.0f / 6.0f)); - in.y = corners[i].y * sin(j * (PI / 2.0f / 6.0f)); + in.x = corners[i].x * Cos(j * (PI / 2.0f / 6.0f)); + in.y = corners[i].y * Sin(j * (PI / 2.0f / 6.0f)); TransformRadarPointToScreenSpace(out[j + 1], in); }; @@ -562,8 +562,8 @@ void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float for (uint32 i = 0; i < 4; i++) { oldPosn[i] = curPosn[i]; - curPosn[i].x = x + (oldPosn[i].x - x) * cosf(angle) + (oldPosn[i].y - y) * sinf(angle); - curPosn[i].y = y - (oldPosn[i].x - x) * sinf(angle) + (oldPosn[i].y - y) * cosf(angle); + curPosn[i].x = x + (oldPosn[i].x - x) * Cos(angle) + (oldPosn[i].y - y) * Sin(angle); + curPosn[i].y = y - (oldPosn[i].x - x) * Sin(angle) + (oldPosn[i].y - y) * Cos(angle); } sprite->Draw(curPosn[2].x, curPosn[2].y, curPosn[3].x, curPosn[3].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha)); @@ -869,7 +869,7 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D float s, c; s = -sin(TheCamera.GetForward().Heading()); - c = cos(TheCamera.GetForward().Heading()); + c = Cos(TheCamera.GetForward().Heading()); if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1 || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWNPED) { s = 0.0f; @@ -886,7 +886,7 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind; s = -sin(forward.Heading()); - c = cos(forward.Heading()); + c = Cos(forward.Heading()); } out.x = s * in.y + c * in.x; @@ -915,8 +915,8 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D c = 1.0f; } else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) { - s = sin(TheCamera.GetForward().Heading()); - c = cos(TheCamera.GetForward().Heading()); + s = Sin(TheCamera.GetForward().Heading()); + c = Cos(TheCamera.GetForward().Heading()); } else { CVector forward; @@ -928,8 +928,8 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D else forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind; - s = sin(forward.Heading()); - c = cos(forward.Heading()); + s = Sin(forward.Heading()); + c = Cos(forward.Heading()); } float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_RadarRange); diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index f8ab19d4..a23e35be 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -2131,8 +2131,8 @@ CStreaming::DeleteRwObjectsAfterDeath(const CVector &pos) for(x = 0; x < NUMSECTORS_X; x++) for(y = 0; y < NUMSECTORS_Y; y++) - if(fabs(ix - x) > 3.0f && - fabs(iy - y) > 3.0f){ + if(Abs(ix - x) > 3.0f && + Abs(iy - y) > 3.0f){ sect = CWorld::GetSector(x, y); DeleteRwObjectsInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS]); DeleteRwObjectsInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]); @@ -2158,7 +2158,7 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem) ix = CWorld::GetSectorIndexX(TheCamera.GetPosition().x); iy = CWorld::GetSectorIndexX(TheCamera.GetPosition().y); - if(fabs(TheCamera.GetForward().x) > fabs(TheCamera.GetForward().y)){ + if(Abs(TheCamera.GetForward().x) > Abs(TheCamera.GetForward().y)){ // looking west/east ymin = max(iy - 10, 0); @@ -2312,13 +2312,13 @@ CStreaming::DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y) e = (CEntity*)node->item; if(e->m_rwObject && !e->bStreamingDontDelete && !e->bImBeingRendered){ // Now this is pretty weird... - if(fabs(CWorld::GetSectorIndexX(e->GetPosition().x) - x) >= 2.0f) + if(Abs(CWorld::GetSectorIndexX(e->GetPosition().x) - x) >= 2.0f) // { e->DeleteRwObject(); // return; // BUG? // } else // FIX? - if(fabs(CWorld::GetSectorIndexY(e->GetPosition().y) - y) >= 2.0f) + if(Abs(CWorld::GetSectorIndexY(e->GetPosition().y) - y) >= 2.0f) e->DeleteRwObject(); } } diff --git a/src/core/common.h b/src/core/common.h index 79626acb..e5702a2f 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -97,6 +97,7 @@ extern void **rwengine; #define SCREEN_SCALE_AR(a) (a) #endif +#include "math/maths.h" #include "math/Vector.h" #include "math/Vector2D.h" #include "math/Matrix.h" diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index d562ced5..10677bdf 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -806,12 +806,12 @@ CEntity::ModifyMatrixForTreeInWind(void) }else if(CWeather::Wind >= 0.2){ t = (uintptr)this + CTimer::GetTimeInMilliseconds(); f = (t & 0xFFF)/(float)0x1000; - flutter = sin(f * 6.28f); + flutter = Sin(f * 6.28f); strength = 0.008f; }else{ t = (uintptr)this + CTimer::GetTimeInMilliseconds(); f = (t & 0xFFF)/(float)0x1000; - flutter = sin(f * 6.28f); + flutter = Sin(f * 6.28f); strength = 0.005f; } @@ -857,7 +857,7 @@ CEntity::ModifyMatrixForBannerInWind(void) right.z = 0.0f; right.Normalise(); up = right * flutter; - up.z = sqrt(sq(1.0f) - sq(flutter)); + up.z = Sqrt(sq(1.0f) - sq(flutter)); GetRight() = CrossProduct(GetForward(), up); GetUp() = up; diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index 9cabb28b..55ed5380 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -476,7 +476,7 @@ CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &poin // what is this? float a = m_fTurnMass / ((point.MagnitudeSqr() + 1.0f) * 2.0f * m_fMass); a = min(a, 1.0f); - float b = fabs(impulse / (speedB * m_fMass)); + float b = Abs(impulse / (speedB * m_fMass)); if(a < b) impulse *= a/b; @@ -505,11 +505,11 @@ void CPhysical::ApplyAirResistance(void) { if(m_fAirResistance > 0.1f){ - float f = powf(m_fAirResistance, CTimer::GetTimeStep()); + float f = Pow(m_fAirResistance, CTimer::GetTimeStep()); m_vecMoveSpeed *= f; m_vecTurnSpeed *= f; }else{ - float f = powf(1.0f/(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep()); + float f = Pow(1.0f/(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep()); m_vecMoveSpeed *= f; m_vecTurnSpeed *= 0.99f; } @@ -719,7 +719,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(!B->bInfiniteMass){ if(fB.z < 0.0f){ fB.z = 0.0f; - if(fabs(speedA) < 0.01f) + if(Abs(speedA) < 0.01f) fB *= 0.5f; } if(ispedcontactA){ @@ -815,9 +815,9 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV float minspeed = 0.0104f * CTimer::GetTimeStep(); if((IsObject() || IsVehicle() && GetUp().z < -0.3f) && !bHasContacted && - fabs(m_vecMoveSpeed.x) < minspeed && - fabs(m_vecMoveSpeed.y) < minspeed && - fabs(m_vecMoveSpeed.z) < minspeed*2.0f) + Abs(m_vecMoveSpeed.x) < minspeed && + Abs(m_vecMoveSpeed.y) < minspeed && + Abs(m_vecMoveSpeed.z) < minspeed*2.0f) e = -1.0f; else e = -(m_fElasticity + 1.0f); @@ -1150,14 +1150,14 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) shift += dir * colpoints[mostColliding].depth * 0.5f; }else if(A->IsPed() && B->IsVehicle() && ((CVehicle*)B)->IsBoat()){ CVector dir = colpoints[mostColliding].normal; - float f = min(fabs(dir.z), 0.9f); + float f = min(Abs(dir.z), 0.9f); dir.z = 0.0f; dir.Normalise(); shift += dir * colpoints[mostColliding].depth / (1.0f - f); boat = B; }else if(B->IsPed() && A->IsVehicle() && ((CVehicle*)A)->IsBoat()){ CVector dir = colpoints[mostColliding].normal * -1.0f; - float f = min(fabs(dir.z), 0.9f); + float f = min(Abs(dir.z), 0.9f); dir.z = 0.0f; dir.Normalise(); B->GetPosition() += dir * colpoints[mostColliding].depth / (1.0f - f); @@ -1498,8 +1498,8 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) float imp = impulseA; if(A->IsVehicle() && A->GetUp().z < -0.6f && - fabs(A->m_vecMoveSpeed.x) < 0.05f && - fabs(A->m_vecMoveSpeed.y) < 0.05f) + Abs(A->m_vecMoveSpeed.x) < 0.05f && + Abs(A->m_vecMoveSpeed.y) < 0.05f) imp *= 0.1f; float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr(); @@ -1519,8 +1519,8 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) float imp = impulseA; if(A->IsVehicle() && A->GetUp().z < -0.6f && - fabs(A->m_vecMoveSpeed.x) < 0.05f && - fabs(A->m_vecMoveSpeed.y) < 0.05f) + Abs(A->m_vecMoveSpeed.x) < 0.05f && + Abs(A->m_vecMoveSpeed.y) < 0.05f) imp *= 0.1f; float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr(); @@ -1557,8 +1557,8 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) m_vecTurnSpeed += turnSpeed / numResponses; if(!CWorld::bNoMoreCollisionTorque && A->m_status == STATUS_PLAYER && A->IsVehicle() && - fabs(A->m_vecMoveSpeed.x) > 0.2f && - fabs(A->m_vecMoveSpeed.y) > 0.2f){ + Abs(A->m_vecMoveSpeed.x) > 0.2f && + Abs(A->m_vecMoveSpeed.y) > 0.2f){ A->m_vecMoveFriction.x += moveSpeed.x * -0.3f / numCollisions; A->m_vecMoveFriction.y += moveSpeed.y * -0.3f / numCollisions; A->m_vecTurnFriction += turnSpeed * -0.3f / numCollisions; @@ -1789,7 +1789,7 @@ CPhysical::ProcessShift(void) } // x is the number of units (m) we would like to step -#define NUMSTEPS(x) ceil(sqrt(distSq) * (1.0f/(x))) +#define NUMSTEPS(x) ceil(Sqrt(distSq) * (1.0f/(x))) void CPhysical::ProcessCollision(void) diff --git a/src/math/Matrix.h b/src/math/Matrix.h index b7d6c207..2c0108c1 100644 --- a/src/math/Matrix.h +++ b/src/math/Matrix.h @@ -127,8 +127,8 @@ public: } void SetRotateXOnly(float angle){ - float c = cos(angle); - float s = sin(angle); + float c = Cos(angle); + float s = Sin(angle); m_matrix.right.x = 1.0f; m_matrix.right.y = 0.0f; @@ -149,8 +149,8 @@ public: m_matrix.pos.z = 0.0f; } void SetRotateYOnly(float angle){ - float c = cos(angle); - float s = sin(angle); + float c = Cos(angle); + float s = Sin(angle); m_matrix.right.x = c; m_matrix.right.y = 0.0f; @@ -171,8 +171,8 @@ public: m_matrix.pos.z = 0.0f; } void SetRotateZOnly(float angle){ - float c = cos(angle); - float s = sin(angle); + float c = Cos(angle); + float s = Sin(angle); m_matrix.right.x = c; m_matrix.right.y = s; @@ -193,12 +193,12 @@ public: m_matrix.pos.z = 0.0f; } void SetRotate(float xAngle, float yAngle, float zAngle) { - float cX = cos(xAngle); - float sX = sin(xAngle); - float cY = cos(yAngle); - float sY = sin(yAngle); - float cZ = cos(zAngle); - float sZ = sin(zAngle); + float cX = Cos(xAngle); + float sX = Sin(xAngle); + float cY = Cos(yAngle); + float sY = Sin(yAngle); + float cZ = Cos(zAngle); + float sZ = Sin(zAngle); m_matrix.right.x = cZ * cY - (sZ * sX) * sY; m_matrix.right.y = (cZ * sX) * sY + sZ * cY; diff --git a/src/math/Quaternion.h b/src/math/Quaternion.h index 702fc72f..fb37dc10 100644 --- a/src/math/Quaternion.h +++ b/src/math/Quaternion.h @@ -8,7 +8,7 @@ public: CQuaternion(void) {} CQuaternion(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {} - float Magnitude(void) const { return sqrt(x*x + y*y + z*z + w*w); } + float Magnitude(void) const { return Sqrt(x*x + y*y + z*z + w*w); } float MagnitudeSqr(void) const { return x*x + y*y + z*z + w*w; } const CQuaternion &operator+=(CQuaternion const &right) { diff --git a/src/math/Vector.h b/src/math/Vector.h index b49f00f2..9a1dde7a 100644 --- a/src/math/Vector.h +++ b/src/math/Vector.h @@ -22,10 +22,10 @@ public: return *((RwV3d*)this); } #endif - float Heading(void) const { return atan2(-x, y); } - float Magnitude(void) const { return sqrt(x*x + y*y + z*z); } + float Heading(void) const { return Atan2(-x, y); } + float Magnitude(void) const { return Sqrt(x*x + y*y + z*z); } float MagnitudeSqr(void) const { return x*x + y*y + z*z; } - float Magnitude2D(void) const { return sqrt(x*x + y*y); } + float Magnitude2D(void) const { return Sqrt(x*x + y*y); } float MagnitudeSqr2D(void) const { return x*x + y*y; } void Normalise(void) { float sq = MagnitudeSqr(); diff --git a/src/math/Vector2D.h b/src/math/Vector2D.h index fa32bd9b..d0580545 100644 --- a/src/math/Vector2D.h +++ b/src/math/Vector2D.h @@ -7,7 +7,7 @@ public: CVector2D(void) {} CVector2D(float x, float y) : x(x), y(y) {} CVector2D(const CVector &v) : x(v.x), y(v.y) {} - float Magnitude(void) const { return sqrt(x*x + y*y); } + float Magnitude(void) const { return Sqrt(x*x + y*y); } float MagnitudeSqr(void) const { return x*x + y*y; } void Normalise(void){ diff --git a/src/math/math.cpp b/src/math/math.cpp index b76db4ae..b4ba9c98 100644 --- a/src/math/math.cpp +++ b/src/math/math.cpp @@ -13,11 +13,11 @@ CQuaternion::Slerp(const CQuaternion &q1, const CQuaternion &q2, float theta, fl float w1, w2; if(theta > PI/2){ theta = PI - theta; - w1 = sin((1.0f - t) * theta) * invSin; + w1 = Sin((1.0f - t) * theta) * invSin; w2 = -sin(t * theta) * invSin; }else{ - w1 = sin((1.0f - t) * theta) * invSin; - w2 = sin(t * theta) * invSin; + w1 = Sin((1.0f - t) * theta) * invSin; + w2 = Sin(t * theta) * invSin; } *this = w1*q1 + w2*q2; } diff --git a/src/math/maths.h b/src/math/maths.h new file mode 100644 index 00000000..49e39631 --- /dev/null +++ b/src/math/maths.h @@ -0,0 +1,12 @@ +#pragma once + +// wrapper around float versions of functions +// in gta they are in CMaths but that makes the code rather noisy + +inline float Sin(float x) { return sinf(x); } +inline float Cos(float x) { return cosf(x); } +inline float Abs(float x) { return fabs(x); } +inline float Sqrt(float x) { return sqrtf(x); } +inline float Atan2(float y, float x) { return atan2f(y, x); } +inline float RecipSqrt(float x) { return 1.0f/sqrtf(x); } +inline float Pow(float x, float y) { return powf(x, y); } diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 8ebe456f..c9a9cfb5 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -551,7 +551,7 @@ CheckForPedsOnGroundToAttack(CPlayerPed *player, CPed **pedOnGround) angleToFace = CGeneral::LimitRadianAngle(angleToFace); player->m_fRotationCur = CGeneral::LimitRadianAngle(player->m_fRotationCur); - angleDiff = fabs(angleToFace - player->m_fRotationCur); + angleDiff = Abs(angleToFace - player->m_fRotationCur); if (angleDiff > PI) angleDiff = 2 * PI - angleDiff; @@ -872,7 +872,7 @@ CPed::Avoid(void) // If so, we want to avoid it, so we turn our body 45 degree and look to somewhere else. // Game converts from radians to degress and back again here, doesn't make much sense - CVector2D forward(-sin(m_fRotationCur), cos(m_fRotationCur)); + CVector2D forward(-sin(m_fRotationCur), Cos(m_fRotationCur)); forward.Normalise(); // this is kinda pointless // Move forward 1.25 meters @@ -2151,10 +2151,10 @@ CPed::CalculateNewVelocity(void) } } - CVector2D forward(sin(m_fRotationCur), cos(m_fRotationCur)); + CVector2D forward(Sin(m_fRotationCur), Cos(m_fRotationCur)); - m_moved.x = CrossProduct2D(m_vecAnimMoveDelta, forward); // (m_vecAnimMoveDelta.x * cos(m_fRotationCur)) + -sin(m_fRotationCur) * m_vecAnimMoveDelta.y; - m_moved.y = DotProduct2D(m_vecAnimMoveDelta, forward); // m_vecAnimMoveDelta.y* cos(m_fRotationCur) + (m_vecAnimMoveDelta.x * sin(m_fRotationCur)); + m_moved.x = CrossProduct2D(m_vecAnimMoveDelta, forward); // (m_vecAnimMoveDelta.x * Cos(m_fRotationCur)) + -sin(m_fRotationCur) * m_vecAnimMoveDelta.y; + m_moved.y = DotProduct2D(m_vecAnimMoveDelta, forward); // m_vecAnimMoveDelta.y* Cos(m_fRotationCur) + (m_vecAnimMoveDelta.x * Sin(m_fRotationCur)); if (CTimer::GetTimeStep() >= 0.01f) { m_moved = m_moved * (1 / CTimer::GetTimeStep()); @@ -2179,7 +2179,7 @@ CPed::CalculateNewVelocity(void) // Interestingly this part is responsible for diagonal walking. if (localWalkAngle > -DEGTORAD(50.0f) && localWalkAngle < DEGTORAD(50.0f)) { TheCamera.Cams[TheCamera.ActiveCam].m_fPlayerVelocity = pedSpeed; - m_moved = CVector2D(-sin(walkAngle), cos(walkAngle)) * pedSpeed; + m_moved = CVector2D(-sin(walkAngle), Cos(walkAngle)) * pedSpeed; } CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_IDLE_STANCE); @@ -2239,7 +2239,7 @@ CPed::CanPedDriveOff(void) bool CPed::CanPedJumpThis(int32 unused) { - CVector2D forward(-sin(m_fRotationCur), cos(m_fRotationCur)); + CVector2D forward(-sin(m_fRotationCur), Cos(m_fRotationCur)); CVector pos = GetPosition(); // wat? CVector forwardPos( @@ -2276,7 +2276,7 @@ CPed::CanSeeEntity(CEntity *entity, float threshold) else if (ourAngle > 2 * PI) ourAngle -= 2 * PI; - float neededTurn = fabs(neededAngle - ourAngle); + float neededTurn = Abs(neededAngle - ourAngle); return neededTurn < threshold || 2 * PI - threshold < neededTurn; } @@ -2811,7 +2811,7 @@ CPed::TurnBody(void) float neededTurn = currentRot - limitedLookDir; m_fRotationDest = limitedLookDir; - if (fabs(neededTurn) > 0.05f) { + if (Abs(neededTurn) > 0.05f) { doneSmoothly = false; currentRot -= neededTurn * 0.2f; } diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp index b9baf49c..0bd49459 100644 --- a/src/peds/PedIK.cpp +++ b/src/peds/PedIK.cpp @@ -34,8 +34,8 @@ CPedIK::RotateTorso(AnimBlendFrameData *animBlend, LimbOrientation *limb, bool c // rotation == 0 -> looking in y direction // left? vector - float c = cos(m_ped->m_fRotationCur); - float s = sin(m_ped->m_fRotationCur); + float c = Cos(m_ped->m_fRotationCur); + float s = Sin(m_ped->m_fRotationCur); rightVector.x = -(c*mat->right.x + s*mat->right.y); rightVector.y = -(c*mat->up.x + s*mat->up.y); rightVector.z = -(c*mat->at.x + s*mat->at.y); diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp index d582bff8..2ead715b 100644 --- a/src/render/Clouds.cpp +++ b/src/render/Clouds.cpp @@ -53,7 +53,7 @@ CClouds::Shutdown(void) void CClouds::Update(void) { - float s = sin(TheCamera.Orientation - 0.85f); + float s = Sin(TheCamera.Orientation - 0.85f); CloudRotation += CWeather::Wind*s*0.0025f; IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep() + 0.3f) * 60.0f; } @@ -81,7 +81,7 @@ CClouds::Render(void) float coverage = CWeather::CloudCoverage <= CWeather::Foggyness ? CWeather::Foggyness : CWeather::CloudCoverage; // Moon - int moonfadeout = abs(minute - 180); // fully visible at 3AM + int moonfadeout = Abs(minute - 180); // fully visible at 3AM if(moonfadeout < 180){ // fade in/out 3 hours int brightness = (1.0f - coverage) * (180 - moonfadeout); RwV3d pos = { 0.0f, -100.0f, 15.0f }; @@ -169,8 +169,8 @@ CClouds::Render(void) } // Fluffy clouds - float rot_sin = sin(CloudRotation); - float rot_cos = cos(CloudRotation); + float rot_sin = Sin(CloudRotation); + float rot_cos = Cos(CloudRotation); int fluffyalpha = 160 * (1.0f - CWeather::Foggyness); if(fluffyalpha != 0){ static float CoorsOffsetX[37] = { @@ -210,7 +210,7 @@ CClouds::Render(void) worldpos.z = pos.z; if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){ - float sundist = sqrt(sq(screenpos.x-CCoronas::SunScreenX) + sq(screenpos.y-CCoronas::SunScreenY)); + float sundist = Sqrt(sq(screenpos.x-CCoronas::SunScreenX) + sq(screenpos.y-CCoronas::SunScreenY)); int tr = CTimeCycle::GetFluffyCloudsTopRed(); int tg = CTimeCycle::GetFluffyCloudsTopGreen(); int tb = CTimeCycle::GetFluffyCloudsTopBlue(); @@ -302,7 +302,7 @@ CClouds::RenderBackground(int16 topred, int16 topgreen, int16 topblue, int16 botred, int16 botgreen, int16 botblue, int16 alpha) { RwMatrix *mat = RwFrameGetLTM(RwCameraGetFrame(TheCamera.m_pRwCamera)); - float c = sqrt(mat->right.x * mat->right.x + mat->right.y * mat->right.y); + float c = Sqrt(mat->right.x * mat->right.x + mat->right.y * mat->right.y); if(c > 1.0f) c = 1.0f; ms_cameraRoll = acos(c); @@ -424,7 +424,7 @@ CClouds::RenderHorizon(void) SCREEN_HEIGHT/300.0f * max(TheCamera.GetPosition().z, 0.0f); float b = TheCamera.GetUp().z < 0.0f ? SCREEN_HEIGHT : - SCREEN_HEIGHT * fabs(TheCamera.GetRight().z); + SCREEN_HEIGHT * Abs(TheCamera.GetRight().z); float z2 = z1 + (a + b)*TheCamera.LODDistMultiplier; z2 = min(z2, SCREEN_HEIGHT); CSprite2d::DrawRect(CRect(0, z1, SCREEN_WIDTH, z2), diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp index 61fa1a5a..5ac9b149 100644 --- a/src/render/Coronas.cpp +++ b/src/render/Coronas.cpp @@ -286,8 +286,8 @@ CCoronas::Render(void) // if distance too big, break streak if(aCoronas[i].hasValue[1]){ - if(fabs(aCoronas[i].prevX[0] - aCoronas[i].prevX[1]) > 50.0f || - fabs(aCoronas[i].prevY[0] - aCoronas[i].prevY[1]) > 50.0f) + if(Abs(aCoronas[i].prevX[0] - aCoronas[i].prevX[1]) > 50.0f || + Abs(aCoronas[i].prevY[0] - aCoronas[i].prevY[1]) > 50.0f) aCoronas[i].hasValue[0] = false; } } diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index b3264dc7..81f27153 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -173,7 +173,7 @@ void CHud::Draw() RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); - float fStep = sin((CTimer::GetTimeInMilliseconds() & 1023) * 0.0061328127); + float fStep = Sin((CTimer::GetTimeInMilliseconds() & 1023) * 0.0061328127); float fMultBright = SpriteBrightness * 0.03f * (0.25f * fStep + 0.75f); CRect rect; #ifndef ASPECT_RATIO_SCALE diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp index 416e5af0..63545dff 100644 --- a/src/render/Particle.cpp +++ b/src/render/Particle.cpp @@ -299,8 +299,8 @@ void CParticle::Initialise() { float angle = DEGTORAD(float(i) * float(360.0f / SIN_COS_TABLE_SIZE)); - m_SinTable[i] = sin(angle); - m_CosTable[i] = cos(angle); + m_SinTable[i] = Sin(angle); + m_CosTable[i] = Cos(angle); } int32 slot = CTxdStore::FindTxdSlot("particle"); @@ -1599,7 +1599,7 @@ void CParticle::Render() fTrailLength = fDist; - //Float fRot = atan2( vecDist.x / fDist, sqrtf(1.0f - vecDist.x / fDist * (vecDist.x / fDist)) ); + //Float fRot = Atan2( vecDist.x / fDist, Sqrt(1.0f - vecDist.x / fDist * (vecDist.x / fDist)) ); float fRot = asinf(vecDist.x / fDist); fRotation = fRot; @@ -1651,7 +1651,7 @@ void CParticle::Render() fTrailLength = fDist; - //Float fRot = atan2(vecDist.x / fDist, sqrt(1.0f - vecDist.x / fDist * (vecDist.x / fDist))); + //Float fRot = Atan2(vecDist.x / fDist, Sqrt(1.0f - vecDist.x / fDist * (vecDist.x / fDist))); float fRot = asinf(vecDist.x / fDist); fRotation = fRot; diff --git a/src/render/PointLights.cpp b/src/render/PointLights.cpp index 9e98a327..b5d4ece1 100644 --- a/src/render/PointLights.cpp +++ b/src/render/PointLights.cpp @@ -33,7 +33,7 @@ CPointLights::AddLight(uint8 type, CVector coors, CVector dir, float radius, flo return; dist = coors - TheCamera.GetPosition(); - if(fabs(dist.x) < MAX_DIST && fabs(dist.y) < MAX_DIST){ + if(Abs(dist.x) < MAX_DIST && Abs(dist.y) < MAX_DIST){ distance = dist.Magnitude(); if(distance < MAX_DIST){ aLights[NumLights].type = type; @@ -73,9 +73,9 @@ CPointLights::GenerateLightsAffectingObject(CVector *objCoors) // same weird distance calculation. simplified here dist = aLights[i].coors - *objCoors; radius = aLights[i].radius; - if(fabs(dist.x) < radius && - fabs(dist.y) < radius && - fabs(dist.z) < radius){ + if(Abs(dist.x) < radius && + Abs(dist.y) < radius && + Abs(dist.z) < radius){ distance = dist.Magnitude(); if(distance < radius){ @@ -217,7 +217,7 @@ CPointLights::RenderFogEffect(void) // more intensity the closer to light source intensity *= 1.0f - sq(dot/FOG_AREA_LENGTH); // more intensity the closer to line - intensity *= 1.0f - sq(sqrt(linedistsq) / FOG_AREA_WIDTH); + intensity *= 1.0f - sq(Sqrt(linedistsq) / FOG_AREA_WIDTH); if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){ float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x1FFF; @@ -251,11 +251,11 @@ CPointLights::RenderFogEffect(void) float dx = xi - aLights[i].coors.x; float dy = yi - aLights[i].coors.y; - float lightdist = sqrt(sq(dx) + sq(dy)); + float lightdist = Sqrt(sq(dx) + sq(dy)); if(lightdist < FOG_AREA_RADIUS){ dx = xi - TheCamera.GetPosition().x; dy = yi - TheCamera.GetPosition().y; - float camdist = sqrt(sq(dx) + sq(dy)); + float camdist = Sqrt(sq(dx) + sq(dy)); if(camdist < MAX_DIST){ float intensity; // distance fade diff --git a/src/render/Sprite.cpp b/src/render/Sprite.cpp index d917117a..24577f41 100644 --- a/src/render/Sprite.cpp +++ b/src/render/Sprite.cpp @@ -135,8 +135,8 @@ CSprite::RenderOneXLUSprite(float x, float y, float z, float w, float h, uint8 r void CSprite::RenderOneXLUSprite_Rotate_Aspect(float x, float y, float z, float w, float h, uint8 r, uint8 g, uint8 b, int16 intens, float recipz, float rotation, uint8 a) { - float c = cos(DEGTORAD(rotation)); - float s = sin(DEGTORAD(rotation)); + float c = Cos(DEGTORAD(rotation)); + float s = Sin(DEGTORAD(rotation)); float xs[4]; float ys[4]; @@ -261,8 +261,8 @@ CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(float x, float y, float z, { m_bFlushSpriteBufferSwitchZTest = 0; // TODO: replace with lookup - float c = cos(DEGTORAD(rotation)); - float s = sin(DEGTORAD(rotation)); + float c = Cos(DEGTORAD(rotation)); + float s = Sin(DEGTORAD(rotation)); float xs[4]; float ys[4]; @@ -313,8 +313,8 @@ void CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(float x, float y, float z, float w, float h, uint8 r, uint8 g, uint8 b, int16 intens, float recipz, float rotation, uint8 a) { m_bFlushSpriteBufferSwitchZTest = 0; - float c = cos(DEGTORAD(rotation)); - float s = sin(DEGTORAD(rotation)); + float c = Cos(DEGTORAD(rotation)); + float s = Sin(DEGTORAD(rotation)); float xs[4]; float ys[4]; @@ -365,8 +365,8 @@ void CSprite::RenderBufferedOneXLUSprite_Rotate_2Colours(float x, float y, float z, float w, float h, uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2, float cx, float cy, float recipz, float rotation, uint8 a) { m_bFlushSpriteBufferSwitchZTest = 0; - float c = cos(DEGTORAD(rotation)); - float s = sin(DEGTORAD(rotation)); + float c = Cos(DEGTORAD(rotation)); + float s = Sin(DEGTORAD(rotation)); float xs[4]; float ys[4]; @@ -572,8 +572,8 @@ CSprite::RenderBufferedOneXLUSprite2D_Rotate_Dimension(float x, float y, float w { m_bFlushSpriteBufferSwitchZTest = 1; CRGBA col(intens * colour.red >> 8, intens * colour.green >> 8, intens * colour.blue >> 8, alpha); - float c = cos(DEGTORAD(rotation)); - float s = sin(DEGTORAD(rotation)); + float c = Cos(DEGTORAD(rotation)); + float s = Sin(DEGTORAD(rotation)); Set6Vertices2D(&SpriteBufferVerts[6 * nSpriteBufferIndex], x + c*w - s*h, diff --git a/src/render/Timecycle.cpp b/src/render/Timecycle.cpp index af154716..7ab3e91e 100644 --- a/src/render/Timecycle.cpp +++ b/src/render/Timecycle.cpp @@ -299,9 +299,9 @@ CTimeCycle::Update(void) float sunAngle = 2*PI*(CClock::GetMinutes() + CClock::GetHours()*60)/(24*60); CVector &sunPos = GetSunPosition(); - sunPos.x = sinf(sunAngle); + sunPos.x = Sin(sunAngle); sunPos.y = 1.0f; - sunPos.z = 0.2f - cosf(sunAngle); + sunPos.z = 0.2f - Cos(sunAngle); sunPos.Normalise(); CShadows::CalcPedShadowValues(sunPos, diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index 0481e104..9c7d0106 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -2340,7 +2340,7 @@ HRESULT CapturePad(RwInt32 padID) { float angle = DEGTORAD((float)js.rgdwPOV[0] / 100.0f); - leftStickPos.x = sin(angle); + leftStickPos.x = Sin(angle); leftStickPos.y = -cos(angle); } @@ -2365,16 +2365,16 @@ HRESULT CapturePad(RwInt32 padID) CPad *pad = CPad::GetPad(bs.padID); - if ( fabs(leftStickPos.x) > 0.3f ) + if ( Abs(leftStickPos.x) > 0.3f ) pad->PCTempJoyState.LeftStickX = (int32)(leftStickPos.x * 128.0f); - if ( fabs(leftStickPos.y) > 0.3f ) + if ( Abs(leftStickPos.y) > 0.3f ) pad->PCTempJoyState.LeftStickY = (int32)(leftStickPos.y * 128.0f); - if ( fabs(rightStickPos.x) > 0.3f ) + if ( Abs(rightStickPos.x) > 0.3f ) pad->PCTempJoyState.RightStickX = (int32)(rightStickPos.x * 128.0f); - if ( fabs(rightStickPos.y) > 0.3f ) + if ( Abs(rightStickPos.y) > 0.3f ) pad->PCTempJoyState.RightStickY = (int32)(rightStickPos.y * 128.0f); } diff --git a/src/vehicles/Door.cpp b/src/vehicles/Door.cpp index ec5eb223..25e87504 100644 --- a/src/vehicles/Door.cpp +++ b/src/vehicles/Door.cpp @@ -53,7 +53,7 @@ CDoor::Process(CVehicle *vehicle) break; } fSpeedDiff = clamp(fSpeedDiff, -0.2f, 0.2f); - if(fabs(fSpeedDiff) > 0.002f) + if(Abs(fSpeedDiff) > 0.002f) m_fAngVel += fSpeedDiff; m_fAngVel *= 0.945f; m_fAngVel = clamp(m_fAngVel, -0.3f, 0.3f); @@ -76,7 +76,7 @@ CDoor::Process(CVehicle *vehicle) float CDoor::RetAngleWhenClosed(void) { - if(fabs(m_fMaxAngle) < fabs(m_fMinAngle)) + if(Abs(m_fMaxAngle) < Abs(m_fMinAngle)) return m_fMaxAngle; else return m_fMinAngle; @@ -85,7 +85,7 @@ CDoor::RetAngleWhenClosed(void) float CDoor::RetAngleWhenOpen(void) { - if(fabs(m_fMaxAngle) < fabs(m_fMinAngle)) + if(Abs(m_fMaxAngle) < Abs(m_fMinAngle)) return m_fMinAngle; else return m_fMaxAngle; @@ -104,7 +104,7 @@ bool CDoor::IsFullyOpen(void) { // why -0.5? that's around 28 deg less than fully open - if(fabs(m_fAngle) < fabs(RetAngleWhenOpen()) - 0.5f) + if(Abs(m_fAngle) < Abs(RetAngleWhenOpen()) - 0.5f) return false; return true; } diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 13e02566..688496c1 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -213,7 +213,7 @@ CVehicle::FlyingControl(eFlightModel flightModel) ApplyTurnForce(impulse*GetUp(), 2.0f*GetUp() + com); - m_vecTurnSpeed.y *= powf(0.9f, CTimer::GetTimeStep()); + m_vecTurnSpeed.y *= Pow(0.9f, CTimer::GetTimeStep()); moveSpeed = m_vecMoveSpeed.MagnitudeSqr(); if(moveSpeed > 2.25f) m_vecMoveSpeed *= 1.5f/sqrt(moveSpeed); @@ -296,7 +296,7 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon } if(brake > adhesion){ - if(fabs(contactSpeedFwd) > 0.005f) + if(Abs(contactSpeedFwd) > 0.005f) *wheelState = WHEEL_STATE_STATIC; }else { if(fwd > 0.0f){ @@ -317,7 +317,7 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon *wheelState = WHEEL_STATE_2; } - float l = sqrt(sq(right) + sq(fwd)); + float l = Sqrt(sq(right) + sq(fwd)); float tractionLoss = bAlreadySkidding ? 1.0f : m_handling->fTractionLoss; right *= adhesion * tractionLoss / l; fwd *= adhesion * tractionLoss / l; @@ -552,9 +552,9 @@ CVehicle::CanPedExitCar(void) if(m_vecMoveSpeed.MagnitudeSqr() > 0.005f) return false; // if car is slow enough, check turn speed - if(fabs(m_vecTurnSpeed.x) > 0.01f || - fabs(m_vecTurnSpeed.y) > 0.01f || - fabs(m_vecTurnSpeed.z) > 0.01f) + if(Abs(m_vecTurnSpeed.x) > 0.01f || + Abs(m_vecTurnSpeed.y) > 0.01f || + Abs(m_vecTurnSpeed.z) > 0.01f) return false; return true; }else{ @@ -564,9 +564,9 @@ CVehicle::CanPedExitCar(void) if(m_vecMoveSpeed.MagnitudeSqr() >= 0.005f) return false; // if car is slow enough, check turn speed - if(fabs(m_vecTurnSpeed.x) >= 0.01f || - fabs(m_vecTurnSpeed.y) >= 0.01f || - fabs(m_vecTurnSpeed.z) >= 0.01f) + if(Abs(m_vecTurnSpeed.x) >= 0.01f || + Abs(m_vecTurnSpeed.y) >= 0.01f || + Abs(m_vecTurnSpeed.z) >= 0.01f) return false; return true; } From 90e093cd47fb2af10617b1d404fc65ca813782ec Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 10 Jul 2019 17:34:11 +0200 Subject: [PATCH 28/30] and of course the last commit didnt fix everything --- src/animation/AnimBlendNode.cpp | 4 ++-- src/animation/AnimBlendNode.h | 2 +- src/animation/FrameUpdate.cpp | 6 +++--- src/core/Camera.cpp | 14 +++++++------- src/core/Collision.cpp | 2 +- src/core/General.h | 4 ++-- src/core/Radar.cpp | 4 ++-- src/core/main.cpp | 2 +- src/math/Vector.h | 2 +- src/math/Vector2D.h | 2 +- src/math/math.cpp | 2 +- src/math/maths.h | 8 ++++++-- src/peds/Ped.cpp | 8 ++++---- src/peds/PedIK.cpp | 2 +- src/render/Clouds.cpp | 2 +- src/render/Draw.cpp | 4 ++-- src/render/PointLights.cpp | 2 +- src/skel/win/win.cpp | 2 +- src/vehicles/Vehicle.cpp | 4 ++-- 19 files changed, 40 insertions(+), 36 deletions(-) diff --git a/src/animation/AnimBlendNode.cpp b/src/animation/AnimBlendNode.cpp index 3d3d80ec..be5fcc9c 100644 --- a/src/animation/AnimBlendNode.cpp +++ b/src/animation/AnimBlendNode.cpp @@ -125,8 +125,8 @@ CAnimBlendNode::CalcDeltas(void) float cos = DotProduct(kfA->rotation, kfB->rotation); if(cos > 1.0f) cos = 1.0f; - theta = acos(cos); - invSin = theta == 0.0f ? 0.0f : 1.0f/sin(theta); + theta = Acos(cos); + invSin = theta == 0.0f ? 0.0f : 1.0f/Sin(theta); } void diff --git a/src/animation/AnimBlendNode.h b/src/animation/AnimBlendNode.h index ea75fbfa..361a4134 100644 --- a/src/animation/AnimBlendNode.h +++ b/src/animation/AnimBlendNode.h @@ -10,7 +10,7 @@ class CAnimBlendNode public: // for slerp float theta; // angle between quaternions - float invSin; // 1/sin(theta) + float invSin; // 1/Sin(theta) // indices into array in sequence int32 frameA; // next key frame int32 frameB; // previous key frame diff --git a/src/animation/FrameUpdate.cpp b/src/animation/FrameUpdate.cpp index 62300527..dcb71944 100644 --- a/src/animation/FrameUpdate.cpp +++ b/src/animation/FrameUpdate.cpp @@ -53,7 +53,7 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg) if(norm == 0.0f) rot.w = 1.0f; else - rot *= 1.0f/sqrt(norm); + rot *= 1.0f/Sqrt(norm); rot.Get(mat); } @@ -127,7 +127,7 @@ FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg) if(norm == 0.0f) rot.w = 1.0f; else - rot *= 1.0f/sqrt(norm); + rot *= 1.0f/Sqrt(norm); rot.Get(mat); } @@ -206,7 +206,7 @@ FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg if(norm == 0.0f) rot.w = 1.0f; else - rot *= 1.0f/sqrt(norm); + rot *= 1.0f/Sqrt(norm); rot.Get(mat); } diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 4e988c15..c06ee48b 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -355,8 +355,8 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl // TODO: what's transition beta? if(TheCamera.m_bUseTransitionBeta && ResetStatics){ CVector VecDistance; - IdealSource.x = TargetCoors.x + GroundDist*cos(m_fTransitionBeta); - IdealSource.y = TargetCoors.y + GroundDist*sin(m_fTransitionBeta); + IdealSource.x = TargetCoors.x + GroundDist*Cos(m_fTransitionBeta); + IdealSource.y = TargetCoors.y + GroundDist*Sin(m_fTransitionBeta); Beta = CGeneral::GetATanOfXY(IdealSource.x - TargetCoors.x, IdealSource.y - TargetCoors.y); }else Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y); @@ -799,7 +799,7 @@ CCam::WorkOutCamHeightWeeCar(CVector &TargetCoors, float TargetOrientation) if(CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) AlphaTarget = DEGTORAD(14.0f); WellBufferMe(AlphaTarget, &Alpha, &AlphaSpeed, 0.1f, 0.05f, true); - Source.z = TargetCoors.z + CA_MAX_DISTANCE*sin(Alpha); + Source.z = TargetCoors.z + CA_MAX_DISTANCE*Sin(Alpha); if(FindPlayerVehicle()){ m_fUnknownZOffSet = 0.0f; @@ -945,7 +945,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa CWorld::FindRoofZFor3DCoord(TargetCoors.x - SideX, TargetCoors.y - SideY, CarBottom, &FoundRoofSide2); // Now find out at what height we'd like to place the camera - float CamGround = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, TargetCoors.z + Length*sin(Alpha + ModeAlpha) + m_fCloseInCarHeightOffset, &FoundCamGround); + float CamGround = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, TargetCoors.z + Length*Sin(Alpha + ModeAlpha) + m_fCloseInCarHeightOffset, &FoundCamGround); float CamTargetZ = 0.0f; if(FoundCamGround){ // This is the normal case @@ -992,7 +992,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa } // Now do things if CamClear...but what is that anyway? - float CamZ = TargetCoors.z + Length*sin(Alpha + DeltaAlpha + ModeAlpha) + m_fCloseInCarHeightOffset; + float CamZ = TargetCoors.z + Length*Sin(Alpha + DeltaAlpha + ModeAlpha) + m_fCloseInCarHeightOffset; bool FoundGround, FoundRoof; float CamGround2 = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, CamZ, &FoundGround); if(FoundGround){ @@ -1138,8 +1138,8 @@ CCam::FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOri Obscured1 = CWorld::ProcessLineOfSight(EntityPos, TempSource, colPoint, ent, true, false, false, true, false, true, true); }else if(m_bFixingBeta){ float d = (TempSource - Target).Magnitude(); - TempSource.x = Target.x - d*cos(TargetOrientation); - TempSource.y = Target.y - d*sin(TargetOrientation); + TempSource.x = Target.x - d*Cos(TargetOrientation); + TempSource.y = Target.y - d*Sin(TargetOrientation); // same check again Obscured2 = CWorld::ProcessLineOfSight(Target, TempSource, colPoint, ent, true, false, false, true, false, true, true); diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index 6241b79a..1ed08867 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -627,7 +627,7 @@ CCollision::ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoin dist = sph.center - p; float lensq = dist.MagnitudeSqr(); if(lensq < mindistsq){ - point.normal = dist * (1.0f/sqrt(lensq)); + point.normal = dist * (1.0f/Sqrt(lensq)); point.point = sph.center - point.normal; point.surfaceA = sph.surface; point.pieceA = sph.piece; diff --git a/src/core/General.h b/src/core/General.h index a08b622b..64613478 100644 --- a/src/core/General.h +++ b/src/core/General.h @@ -70,12 +70,12 @@ public: if (y > 0.0f) return PI - Atan2(x / y, 1.0f); else - return -atan2(x / y, 1.0f); + return -Atan2(x / y, 1.0f); } else { if (y > 0.0f) return -(PI + Atan2(x / y, 1.0f)); else - return -atan2(x / y, 1.0f); + return -Atan2(x / y, 1.0f); } } diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index b634e4f5..ea7a7ffa 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -868,7 +868,7 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D { float s, c; - s = -sin(TheCamera.GetForward().Heading()); + s = -Sin(TheCamera.GetForward().Heading()); c = Cos(TheCamera.GetForward().Heading()); if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1 || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWNPED) { @@ -885,7 +885,7 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D else forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind; - s = -sin(forward.Heading()); + s = -Sin(forward.Heading()); c = Cos(forward.Heading()); } diff --git a/src/core/main.cpp b/src/core/main.cpp index 9ac271f9..ffde80bb 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -48,7 +48,7 @@ #include "RpAnimBlend.h" #include "Frontend.h" -#define DEFAULT_VIEWWINDOW (tan(DEGTORAD(CDraw::GetFOV() * 0.5f))) +#define DEFAULT_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f))) GlobalScene &Scene = *(GlobalScene*)0x726768; diff --git a/src/math/Vector.h b/src/math/Vector.h index 9a1dde7a..de8092eb 100644 --- a/src/math/Vector.h +++ b/src/math/Vector.h @@ -30,7 +30,7 @@ public: void Normalise(void) { float sq = MagnitudeSqr(); if(sq > 0.0f){ - float invsqrt = 1.0f/sqrt(sq); // CMaths::RecipSqrt + float invsqrt = 1.0f/Sqrt(sq); // CMaths::RecipSqrt x *= invsqrt; y *= invsqrt; z *= invsqrt; diff --git a/src/math/Vector2D.h b/src/math/Vector2D.h index d0580545..e6b04c14 100644 --- a/src/math/Vector2D.h +++ b/src/math/Vector2D.h @@ -13,7 +13,7 @@ public: void Normalise(void){ float sq = MagnitudeSqr(); if(sq > 0.0f){ - float invsqrt = 1.0f/sqrt(sq); + float invsqrt = 1.0f/Sqrt(sq); x *= invsqrt; y *= invsqrt; }else diff --git a/src/math/math.cpp b/src/math/math.cpp index b4ba9c98..c1199fcc 100644 --- a/src/math/math.cpp +++ b/src/math/math.cpp @@ -14,7 +14,7 @@ CQuaternion::Slerp(const CQuaternion &q1, const CQuaternion &q2, float theta, fl if(theta > PI/2){ theta = PI - theta; w1 = Sin((1.0f - t) * theta) * invSin; - w2 = -sin(t * theta) * invSin; + w2 = -Sin(t * theta) * invSin; }else{ w1 = Sin((1.0f - t) * theta) * invSin; w2 = Sin(t * theta) * invSin; diff --git a/src/math/maths.h b/src/math/maths.h index 49e39631..a1c3f109 100644 --- a/src/math/maths.h +++ b/src/math/maths.h @@ -4,9 +4,13 @@ // in gta they are in CMaths but that makes the code rather noisy inline float Sin(float x) { return sinf(x); } +inline float Asin(float x) { return asinf(x); } inline float Cos(float x) { return cosf(x); } +inline float Acos(float x) { return acosf(x); } +inline float Tan(float x) { return tanf(x); } +inline float Atan(float x) { return atanf(x); } +inline float Atan2(float y, float x) { return atan2f(y, x); } inline float Abs(float x) { return fabs(x); } inline float Sqrt(float x) { return sqrtf(x); } -inline float Atan2(float y, float x) { return atan2f(y, x); } -inline float RecipSqrt(float x) { return 1.0f/sqrtf(x); } +inline float RecipSqrt(float x) { return 1.0f/Sqrt(x); } inline float Pow(float x, float y) { return powf(x, y); } diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index c9a9cfb5..4ad4ac1b 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -872,7 +872,7 @@ CPed::Avoid(void) // If so, we want to avoid it, so we turn our body 45 degree and look to somewhere else. // Game converts from radians to degress and back again here, doesn't make much sense - CVector2D forward(-sin(m_fRotationCur), Cos(m_fRotationCur)); + CVector2D forward(-Sin(m_fRotationCur), Cos(m_fRotationCur)); forward.Normalise(); // this is kinda pointless // Move forward 1.25 meters @@ -2153,7 +2153,7 @@ CPed::CalculateNewVelocity(void) CVector2D forward(Sin(m_fRotationCur), Cos(m_fRotationCur)); - m_moved.x = CrossProduct2D(m_vecAnimMoveDelta, forward); // (m_vecAnimMoveDelta.x * Cos(m_fRotationCur)) + -sin(m_fRotationCur) * m_vecAnimMoveDelta.y; + m_moved.x = CrossProduct2D(m_vecAnimMoveDelta, forward); // (m_vecAnimMoveDelta.x * Cos(m_fRotationCur)) + -Sin(m_fRotationCur) * m_vecAnimMoveDelta.y; m_moved.y = DotProduct2D(m_vecAnimMoveDelta, forward); // m_vecAnimMoveDelta.y* Cos(m_fRotationCur) + (m_vecAnimMoveDelta.x * Sin(m_fRotationCur)); if (CTimer::GetTimeStep() >= 0.01f) { @@ -2179,7 +2179,7 @@ CPed::CalculateNewVelocity(void) // Interestingly this part is responsible for diagonal walking. if (localWalkAngle > -DEGTORAD(50.0f) && localWalkAngle < DEGTORAD(50.0f)) { TheCamera.Cams[TheCamera.ActiveCam].m_fPlayerVelocity = pedSpeed; - m_moved = CVector2D(-sin(walkAngle), Cos(walkAngle)) * pedSpeed; + m_moved = CVector2D(-Sin(walkAngle), Cos(walkAngle)) * pedSpeed; } CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_IDLE_STANCE); @@ -2239,7 +2239,7 @@ CPed::CanPedDriveOff(void) bool CPed::CanPedJumpThis(int32 unused) { - CVector2D forward(-sin(m_fRotationCur), Cos(m_fRotationCur)); + CVector2D forward(-Sin(m_fRotationCur), Cos(m_fRotationCur)); CVector pos = GetPosition(); // wat? CVector forwardPos( diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp index 0bd49459..9b3f401f 100644 --- a/src/peds/PedIK.cpp +++ b/src/peds/PedIK.cpp @@ -51,7 +51,7 @@ CPedIK::RotateTorso(AnimBlendFrameData *animBlend, LimbOrientation *limb, bool c float dotProduct = DotProduct(mat->at, inversedForward); if(dotProduct > 1.0f) dotProduct = 1.0f; if(dotProduct < -1.0f) dotProduct = -1.0f; - float alpha = acos(dotProduct); + float alpha = Acos(dotProduct); if(mat->at.z < 0.0f) alpha = -alpha; diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp index 2ead715b..2884894c 100644 --- a/src/render/Clouds.cpp +++ b/src/render/Clouds.cpp @@ -305,7 +305,7 @@ CClouds::RenderBackground(int16 topred, int16 topgreen, int16 topblue, float c = Sqrt(mat->right.x * mat->right.x + mat->right.y * mat->right.y); if(c > 1.0f) c = 1.0f; - ms_cameraRoll = acos(c); + ms_cameraRoll = Acos(c); if(mat->right.z < 0.0f) ms_cameraRoll = -ms_cameraRoll; diff --git a/src/render/Draw.cpp b/src/render/Draw.cpp index 5a377214..beb3443d 100644 --- a/src/render/Draw.cpp +++ b/src/render/Draw.cpp @@ -50,8 +50,8 @@ CDraw::ConvertFOV(float hfov) float ar1 = DEFAULT_ASPECT_RATIO; float ar2 = GetAspectRatio(); hfov = DEGTORAD(hfov); - float vfov = atan(tan(hfov/2) / ar1) *2; - hfov = atan(tan(vfov/2) * ar2) *2; + float vfov = Atan(tan(hfov/2) / ar1) *2; + hfov = Atan(tan(vfov/2) * ar2) *2; return RADTODEG(hfov); } #endif diff --git a/src/render/PointLights.cpp b/src/render/PointLights.cpp index b5d4ece1..a015ec54 100644 --- a/src/render/PointLights.cpp +++ b/src/render/PointLights.cpp @@ -213,7 +213,7 @@ CPointLights::RenderFogEffect(void) if(dot > 0.0f && dot < FOG_AREA_LENGTH && linedistsq < sq(FOG_AREA_WIDTH)){ float intensity = 158.0f * fogginess; // more intensity the smaller the angle - intensity *= dot/sqrt(distsq); + intensity *= dot/Sqrt(distsq); // more intensity the closer to light source intensity *= 1.0f - sq(dot/FOG_AREA_LENGTH); // more intensity the closer to line diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index 9c7d0106..ac0460f1 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -2341,7 +2341,7 @@ HRESULT CapturePad(RwInt32 padID) float angle = DEGTORAD((float)js.rgdwPOV[0] / 100.0f); leftStickPos.x = Sin(angle); - leftStickPos.y = -cos(angle); + leftStickPos.y = -Cos(angle); } if ( AllValidWinJoys.m_aJoys[bs.padID].m_bHasAxisR && AllValidWinJoys.m_aJoys[bs.padID].m_bHasAxisZ ) diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 688496c1..d8ed1a15 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -216,11 +216,11 @@ CVehicle::FlyingControl(eFlightModel flightModel) m_vecTurnSpeed.y *= Pow(0.9f, CTimer::GetTimeStep()); moveSpeed = m_vecMoveSpeed.MagnitudeSqr(); if(moveSpeed > 2.25f) - m_vecMoveSpeed *= 1.5f/sqrt(moveSpeed); + m_vecMoveSpeed *= 1.5f/Sqrt(moveSpeed); float turnSpeed = m_vecTurnSpeed.MagnitudeSqr(); if(turnSpeed > 0.04f) - m_vecTurnSpeed *= 0.2f/sqrt(turnSpeed); + m_vecTurnSpeed *= 0.2f/Sqrt(turnSpeed); } break; From 4f333d44a0c72cd3b8e34b76c8774717ee2a8994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Wed, 10 Jul 2019 23:07:41 +0300 Subject: [PATCH 29/30] Fix CPhone crash, more functions --- src/control/Phones.cpp | 91 +++++++++++++++++++++++++++++++++++++++++- src/control/Phones.h | 25 +++++++++++- 2 files changed, 112 insertions(+), 4 deletions(-) diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp index 1d3a9777..028d80a9 100644 --- a/src/control/Phones.cpp +++ b/src/control/Phones.cpp @@ -1,8 +1,13 @@ #include "common.h" #include "patcher.h" #include "Phones.h" +#include "Pools.h" -CPhoneInfo &gPhoneInfo = * (CPhoneInfo*) * (uintptr*)0x732A20; +CPhoneInfo &gPhoneInfo = *(CPhoneInfo*)0x732A20; + +bool &CPhoneInfo::isPhonePickedUp = *(bool*)0x6283AC; +bool &CPhoneInfo::isPhoneBeingPickedUp = *(bool*)0x6283B4; +CPhone *&CPhoneInfo::pickedUpPhone = *(CPhone**)0x6283B0; int CPhoneInfo::FindNearestFreePhone(CVector *pos) @@ -12,7 +17,7 @@ CPhoneInfo::FindNearestFreePhone(CVector *pos) for (int phoneId = 0; phoneId < m_nMax; phoneId++) { - if (gPhoneInfo.m_aPhones[phoneId].m_nState == 0) { + if (gPhoneInfo.m_aPhones[phoneId].m_nState == PHONE_STATE_FREE) { float phoneDist = (m_aPhones[phoneId].m_vecPos - *pos).Magnitude2D(); if (phoneDist < nearestPhoneDist) { @@ -34,9 +39,91 @@ CPhoneInfo::PhoneAtThisPosition(CVector pos) return false; } +bool +CPhoneInfo::HasMessageBeenDisplayed(int phoneId) +{ + if (isPhonePickedUp) + return false; + + int state = m_aPhones[phoneId].m_nState; + + return state == PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE || + state == PHONE_STATE_ONETIME_MESSAGE_SHOWN || + state == PHONE_STATE_REPEATED_MESSAGE_SHOWN; +} + +bool +CPhoneInfo::IsMessageBeingDisplayed(int phoneId) +{ + return pickedUpPhone == &m_aPhones[phoneId]; +} + +void +CPhoneInfo::Load(CPhoneInfo *source, uint8 buffer) +{ + // Buffer isn't used. + + m_nMax = source->m_nMax; + m_nNum = source->m_nNum; + for (int phoneId = 0; phoneId < 50; phoneId++) { + CPhone *phone = &source->m_aPhones[phoneId]; + + m_aPhones[phoneId].m_vecPos = phone->m_vecPos; + memcpy(m_aPhones[phoneId].m_apMessages, phone->m_apMessages, sizeof(uint16*) * 6); + m_aPhones[phoneId].m_pEntity = phone->m_pEntity; + m_aPhones[phoneId].m_nState = phone->m_nState; + m_aPhones[phoneId].field_30 = phone->field_30; + + if (phone->m_pEntity) { + // It's saved as building pool index in save file, convert it to true entity + CBuilding *actualEntity = CPools::GetBuildingPool()->GetSlot((int)phone->m_pEntity - 1); + m_aPhones[phoneId].m_pEntity = actualEntity; + } + } +} + +void +CPhoneInfo::SetPhoneMessage_JustOnce(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6) +{ + // If there is at least one message, it should be msg1. + if (msg1) { + m_aPhones[phoneId].m_apMessages[0] = msg1; + m_aPhones[phoneId].m_apMessages[1] = msg2; + m_aPhones[phoneId].m_apMessages[2] = msg3; + m_aPhones[phoneId].m_apMessages[3] = msg4; + m_aPhones[phoneId].m_apMessages[4] = msg5; + m_aPhones[phoneId].m_apMessages[5] = msg6; + m_aPhones[phoneId].m_nState = PHONE_STATE_ONETIME_MESSAGE_SET; + } else { + m_aPhones[phoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED; + } +} + +void +CPhoneInfo::SetPhoneMessage_Repeatedly(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6) +{ + // If there is at least one message, it should be msg1. + if (msg1) { + m_aPhones[phoneId].m_apMessages[0] = msg1; + m_aPhones[phoneId].m_apMessages[1] = msg2; + m_aPhones[phoneId].m_apMessages[2] = msg3; + m_aPhones[phoneId].m_apMessages[3] = msg4; + m_aPhones[phoneId].m_apMessages[4] = msg5; + m_aPhones[phoneId].m_apMessages[5] = msg6; + m_aPhones[phoneId].m_nState = PHONE_STATE_REPEATED_MESSAGE_SET; + } else { + m_aPhones[phoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED; + } +} + STARTPATCHES InjectHook(0x42F720, &CPhoneInfo::FindNearestFreePhone, PATCH_JUMP); InjectHook(0x42FD50, &CPhoneInfo::PhoneAtThisPosition, PATCH_JUMP); + InjectHook(0x42FFF0, &CPhoneInfo::HasMessageBeenDisplayed, PATCH_JUMP); + InjectHook(0x430030, &CPhoneInfo::IsMessageBeingDisplayed, PATCH_JUMP); + InjectHook(0x430120, &CPhoneInfo::Load, PATCH_JUMP); + InjectHook(0x42FF90, &CPhoneInfo::SetPhoneMessage_JustOnce, PATCH_JUMP); + InjectHook(0x42FF30, &CPhoneInfo::SetPhoneMessage_Repeatedly, PATCH_JUMP); ENDPATCHES WRAPPER void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x42F570); } diff --git a/src/control/Phones.h b/src/control/Phones.h index 7ac34c3a..74f24d25 100644 --- a/src/control/Phones.h +++ b/src/control/Phones.h @@ -3,12 +3,25 @@ #include "Physical.h" #include "AnimBlendAssociation.h" +enum { + PHONE_STATE_FREE, + PHONE_STATE_1, + PHONE_STATE_2, + PHONE_STATE_MESSAGE_REMOVED, + PHONE_STATE_ONETIME_MESSAGE_SET, + PHONE_STATE_REPEATED_MESSAGE_SET, + PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE, + PHONE_STATE_ONETIME_MESSAGE_SHOWN, + PHONE_STATE_REPEATED_MESSAGE_SHOWN, + PHONE_STATE_9 +}; + struct CPhone { CVector m_vecPos; uint16 *m_apMessages[6]; - int32 field_24; - CEntity *m_pEntity; + uint32 m_lastTimeRepeatedMsgShown; + CEntity *m_pEntity; // it's building pool index in save files int32 m_nState; uint8 field_30; }; @@ -16,6 +29,9 @@ struct CPhone static_assert(sizeof(CPhone) == 0x34, "CPhone: error"); class CPhoneInfo { + static bool &isPhonePickedUp; + static bool &isPhoneBeingPickedUp; + static CPhone *&pickedUpPhone; public: int32 m_nMax; int32 m_nNum; @@ -26,6 +42,11 @@ public: int FindNearestFreePhone(CVector*); bool PhoneAtThisPosition(CVector); + bool HasMessageBeenDisplayed(int); + bool IsMessageBeingDisplayed(int); + void Load(CPhoneInfo *source, uint8 buffer); + void SetPhoneMessage_JustOnce(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6); + void SetPhoneMessage_Repeatedly(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6); }; extern CPhoneInfo &gPhoneInfo; From f1951acd6ecb2bedf51ce748637ad28d0ad70d7c Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 10 Jul 2019 22:57:19 +0200 Subject: [PATCH 30/30] tried to fix CMenuManager::Process but still issues --- src/core/Frontend.cpp | 116 ++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index a846efc6..77666b12 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -64,15 +64,14 @@ CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8; float lodMultiplier = *(float*)0x5F726C; // Stuff not in CMenuManager: -uint32 VibrationTime; +uint32 &VibrationTime = *(uint32*)0x628CF8; char* pEditString = (char*)0x628D00; int32 *&pControlEdit = *(int32**)0x628D08; -int8 DisplayComboButtonErrMsg; -int8 MouseButtonJustClicked; -int8 JoyButtonJustClicked; +bool &DisplayComboButtonErrMsg = *(bool*)0x628D14; +int32 &MouseButtonJustClicked = *(int32*)0x628D0C; +int32 &JoyButtonJustClicked = *(int32*)0x628D10; int32 &nTimeForSomething = *(int32*)0x628D54; -int32 TypeOfControl = 0; -int32 *pControlTemp = 0; +//int32 *pControlTemp = 0; // Frontend inputs. @@ -164,7 +163,7 @@ void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* st else sprintf(gString2, " %d %s %d", *(int*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(int*)stat2); } - else if (stat2) { + else if (stat) { if (aFloat) sprintf(gString2, " %.2f", *stat); else @@ -1330,11 +1329,10 @@ void CMenuManager::Process(void) if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0) return; - //m_bLanguageLoaded = false; //XXX m_bStartGameLoading = false; InitialiseChangedLanguageSettings(); - if (GetPadExitEnter()) //XXX only escape + if (CPad::GetPad(0)->GetEscapeJustDown()) RequestFrontEndStartUp(); SwitchMenuOnAndOff(); @@ -1403,55 +1401,60 @@ void CMenuManager::Process(void) SaveSettings(); } - if (field_113 && !field_456) { - pControlEdit = CPad::EditCodesForControls(pControlEdit, 1); - JoyButtonJustClicked = 0; - MouseButtonJustClicked = 0; - - if (GetMouseClickLeft()) - MouseButtonJustClicked = 1; - else if (GetMouseClickRight()) - MouseButtonJustClicked = 3; - else if (GetMouseClickMiddle()) - MouseButtonJustClicked = 2; - else if (GetMouseWheelUp()) - MouseButtonJustClicked = 4; - else if (GetMouseWheelDown()) - MouseButtonJustClicked = 5; - //XXX two more buttons - - JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); - - if (JoyButtonJustClicked) - TypeOfControl = 3; - if (MouseButtonJustClicked) - TypeOfControl = 2; - if (*pControlEdit != rsNULL) - TypeOfControl = 0; - - if (!field_534) { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); - pControlEdit = nil; - field_113 = 0; - m_KeyPressedCode = -1; + if (field_113) { + if (field_456) field_456 = 0; - } - else if (!m_bKeyChangeNotProcessed) { - if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked) - CheckCodesForControls(TypeOfControl); - - field_535 = 1; - } else { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); - for (int i = 0; i < 4; i++) - ControlsManager.ClearSettingsAssociatedWithAction(m_CurrCntrlAction, i); - field_534 = false; - m_bKeyChangeNotProcessed = false; - pControlEdit = nil; - field_113 = 0; - m_KeyPressedCode = -1; - field_456 = 0; + pControlEdit = CPad::EditCodesForControls(pControlEdit, 1); + JoyButtonJustClicked = 0; + MouseButtonJustClicked = 0; + + if (GetMouseClickLeft()) + MouseButtonJustClicked = 1; + else if (GetMouseClickRight()) + MouseButtonJustClicked = 3; + else if (GetMouseClickMiddle()) + MouseButtonJustClicked = 2; + else if (GetMouseWheelUp()) + MouseButtonJustClicked = 4; + else if (GetMouseWheelDown()) + MouseButtonJustClicked = 5; + //XXX two more buttons + + JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); + + int32 TypeOfControl = 0; + if (JoyButtonJustClicked) + TypeOfControl = 3; + if (MouseButtonJustClicked) + TypeOfControl = 2; + if (*pControlEdit != rsNULL) + TypeOfControl = 0; + + if (!field_534) { + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); + pControlEdit = nil; + field_113 = 0; + m_KeyPressedCode = -1; + field_456 = 0; + } + else if (!m_bKeyChangeNotProcessed) { + if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked) + CheckCodesForControls(TypeOfControl); + + field_535 = 1; + } + else { + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); + for (int i = 0; i < 4; i++) + ControlsManager.ClearSettingsAssociatedWithAction(m_CurrCntrlAction, i); + field_534 = false; + m_bKeyChangeNotProcessed = false; + pControlEdit = nil; + field_113 = 0; + m_KeyPressedCode = -1; + field_456 = 0; + } } } @@ -1469,6 +1472,7 @@ void CMenuManager::Process(void) else { UnloadTextures(); field_452 = 0; + *(bool*)0x5F33E4 = true; // byte_5F33E4 = 1; // unused m_nPrevScreen = 0; m_nCurrScreen = m_nPrevScreen;