diff --git a/SilentPatchSA/GeneralSA.cpp b/SilentPatchSA/GeneralSA.cpp index 5a55ce5..d0f22ff 100644 --- a/SilentPatchSA/GeneralSA.cpp +++ b/SilentPatchSA/GeneralSA.cpp @@ -76,6 +76,7 @@ void CObject::Render() m_nCarColor[1].Get(), m_nCarColor[2].Get(), m_nCarColor[3].Get() ); SetEditableMaterialsCB(reinterpret_cast(m_pRwObject), &pData); + assert( pData >= std::begin(materialRestoreData) && pData < std::end(materialRestoreData) ); pData->first = nullptr; // Disable backface culling for the part diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index 272f3e9..ffbfea6 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -3982,6 +3982,17 @@ void Patch_SA_10() // Car generators placed in interiors visible everywhere InjectHook( 0x6F3B30, &CEntity::SetPositionAndAreaCode ); + + + // Fixed bomb ownership/bombs saving for bikes + { + void* pRestoreCar; + ReadCall( 0x44856A, pRestoreCar ); + CStoredCar::orgRestoreCar = *(decltype(CStoredCar::orgRestoreCar)*)&pRestoreCar; + InjectHook( 0x44856A, &CStoredCar::RestoreCar_SilentPatch ); + InjectHook( 0x4485DB, &CStoredCar::RestoreCar_SilentPatch ); + } + } void Patch_SA_11() diff --git a/SilentPatchSA/VehicleSA.cpp b/SilentPatchSA/VehicleSA.cpp index 66fa3b9..6cd84ec 100644 --- a/SilentPatchSA/VehicleSA.cpp +++ b/SilentPatchSA/VehicleSA.cpp @@ -5,6 +5,7 @@ #include #include "VehicleSA.h" #include "TimerSA.h" +#include "PedSA.h" #include "DelimStringReader.h" static constexpr float PHOENIX_FLUTTER_PERIOD = 70.0f; @@ -27,9 +28,12 @@ WRAPPER void CVehicle::Render() { VARJMP(varVehicleRender); } static void* varIsLawEnforcementVehicle = AddressByVersion(0x6D2370, 0x6D2BA0, 0x70D8C0); WRAPPER bool CVehicle::IsLawEnforcementVehicle() { VARJMP(varIsLawEnforcementVehicle); } +auto FindPlayerPed = AddressByVersion( 0x56E210, 0, 0 ); // TODO: DO + void (CVehicle::*CVehicle::orgVehiclePreRender)(); void (CAutomobile::*CAutomobile::orgAutomobilePreRender)(); void (CPlane::*CPlane::orgPlanePreRender)(); +CVehicle* (CStoredCar::*CStoredCar::orgRestoreCar)(); static int32_t random(int32_t from, int32_t to) { @@ -457,4 +461,18 @@ void CAutomobile::ProcessNewsvan() if ( m_fGunOrientation > 2.0f * PI ) m_fGunOrientation -= 2.0f * PI; SetComponentRotation( m_pCarNode[20], ROT_AXIS_Z, m_fGunOrientation ); } +} + +CVehicle* CStoredCar::RestoreCar_SilentPatch() +{ + CVehicle* vehicle = (this->*(orgRestoreCar))(); + + // Fixup bomb stuff + if ( vehicle->GetClass() == VEHICLE_AUTOMOBILE || vehicle->GetClass() == VEHICLE_BIKE ) + { + vehicle->SetBombOnBoard( m_bombType ); + vehicle->SetBombOwner( FindPlayerPed(-1) ); + } + + return vehicle; } \ No newline at end of file diff --git a/SilentPatchSA/VehicleSA.h b/SilentPatchSA/VehicleSA.h index a314c13..fd2c37a 100644 --- a/SilentPatchSA/VehicleSA.h +++ b/SilentPatchSA/VehicleSA.h @@ -127,7 +127,10 @@ protected: BYTE __pad2[108]; float m_fGasPedal; float m_fBrakePedal; - BYTE __pad6[44]; + uint8_t m_VehicleCreatedBy; + uint32_t m_BombOnBoard : 3; + BYTE __pad6[32]; + CEntity* m_pBombOwner; signed int m_nTimeTillWeNeedThisCar; BYTE __pad4[56]; CEntity* pDamagingEntity; @@ -135,13 +138,23 @@ protected: char padpad, padpad2, padpad3; int8_t PlateDesign; RwTexture* PlateTexture; - BYTE __pad5[20]; + BYTE __pad78[4]; + uint32_t m_dwVehicleClass; + uint32_t m_dwVehicleSubClass; + BYTE __pad5[8]; public: CVehicleFlags& GetVehicleFlags() { return m_nVehicleFlags; } CEntity* GetDamagingEntity() { return pDamagingEntity; } + uint32_t GetClass() const + { return m_dwVehicleClass; } + + void SetBombOnBoard( uint32_t bombOnBoard ) + { m_BombOnBoard = bombOnBoard; } + void SetBombOwner( CEntity* owner ) + { m_pBombOwner = owner; } virtual void Render() override; virtual void PreRender() override; @@ -229,10 +242,33 @@ public: void PreRender_SilentPatch(); }; +class CStoredCar +{ +private: + CVector m_position; + uint32_t m_handlingFlags; + uint8_t m_flags; + uint16_t m_modelIndex; + uint16_t m_carMods[15]; + uint8_t m_colour[4]; + uint8_t m_radioStation; + uint8_t m_extra[2]; + uint8_t m_bombType; + uint8_t m_remapIndex; + uint8_t m_nitro; + int8_t m_angleX, m_angleY, m_angleZ; + +public: + static CVehicle* (CStoredCar::*orgRestoreCar)(); + + CVehicle* RestoreCar_SilentPatch(); +}; + void ReadRotorFixExceptions(const wchar_t* pPath); static_assert(sizeof(CBouncingPanel) == 0x20, "Wrong size: CBouncingPanel"); static_assert(sizeof(CVehicle) == 0x5A0, "Wrong size: CVehicle"); static_assert(sizeof(CAutomobile) == 0x988, "Wrong size: CAutomobile"); +static_assert(sizeof(CStoredCar) == 0x40, "Wrong size: CStoredCar"); #endif \ No newline at end of file