mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-11-25 14:52:30 +01:00
parent
c6c9fe6013
commit
9f94595ee4
@ -5294,6 +5294,24 @@ void Patch_SA_10(HINSTANCE hInstance)
|
||||
InterceptCall(0x6A8BBE, orgWorldAdd, WorldAdd_SetLightObjectFlag);
|
||||
}
|
||||
|
||||
|
||||
// Fix the logic behind exploding cars losing wheels
|
||||
// Right now, they lose one wheel at random according to the damage manager, but they always lose the front left wheel visually.
|
||||
// This change matches the visuals to the physics
|
||||
// Also make it possible for the rear right wheel to be randomly picked
|
||||
{
|
||||
std::array<uint32_t, 4> spawnFlyingComponent = { 0x6B38CA, 0x6B3CCB, 0x6C6EBE, 0x6CCEF9 };
|
||||
CAutomobile::HookEach_SpawnFlyingComponent(spawnFlyingComponent, InterceptCall);
|
||||
|
||||
Nop(0x6B38E4, 5);
|
||||
Nop(0x6B3CF1, 5);
|
||||
Nop(0x6C6ED8, 5);
|
||||
Nop(0x6CCF17, 5);
|
||||
|
||||
static const float fRandomness = -4.0f;
|
||||
Patch(0x6C25F5 + 2, &fRandomness);
|
||||
}
|
||||
|
||||
#if FULL_PRECISION_D3D
|
||||
// Test - full precision D3D device
|
||||
Patch<uint8_t>( 0x7F672B+1, *(uint8_t*)(0x7F672B+1) | D3DCREATE_FPU_PRESERVE );
|
||||
@ -7028,6 +7046,36 @@ void Patch_SA_NewBinaries_Common(HINSTANCE hInstance)
|
||||
|
||||
InterceptCall(worldAdd, orgWorldAdd, WorldAdd_SetLightObjectFlag);
|
||||
}
|
||||
|
||||
|
||||
// Fix the logic behind exploding cars losing wheels
|
||||
// Right now, they lose one wheel at random according to the damage manager, but they always lose the front left wheel visually.
|
||||
// This change matches the visuals to the physics
|
||||
// Also make it possible for the rear right wheel to be randomly picked
|
||||
{
|
||||
auto automobileBlowUp = pattern("E8 ? ? ? ? 8B 8E ? ? ? ? 8D 45 08").get_one();
|
||||
auto automobileBlowUpCutscene = pattern("E8 ? ? ? ? 80 7D 10 00 C7 45").get_one();
|
||||
auto heliBlowUp = pattern("E8 ? ? ? ? 8B 86 ? ? ? ? 8D 55 08").get_one();
|
||||
auto planeBlowUp = pattern("E8 ? ? ? ? 8B 86 ? ? ? ? 85 C0 74 24").get_one();
|
||||
auto wheelDetachRandomness = get_pattern("DC 0D ? ? ? ? E8 ? ? ? ? 8B CE", 2);
|
||||
|
||||
std::array<void*, 4> spawnFlyingComponent = {
|
||||
automobileBlowUp.get<void>(),
|
||||
automobileBlowUpCutscene.get<void>(),
|
||||
heliBlowUp.get<void>(),
|
||||
planeBlowUp.get<void>(),
|
||||
};
|
||||
CAutomobile::HookEach_SpawnFlyingComponent(spawnFlyingComponent, InterceptCall);
|
||||
|
||||
Nop(automobileBlowUp.get<void>(0x1C), 5);
|
||||
Nop(automobileBlowUpCutscene.get<void>(0x22), 5);
|
||||
Nop(heliBlowUp.get<void>(0x1C), 5);
|
||||
Nop(planeBlowUp.get<void>(0x20), 5);
|
||||
|
||||
static const double fRandomness = -4.0;
|
||||
Patch(wheelDetachRandomness, &fRandomness);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -573,6 +573,69 @@ void CAutomobile::AfterPreRender()
|
||||
}
|
||||
}
|
||||
|
||||
void CAutomobile::HideDestroyedWheels_SilentPatch(void (CAutomobile::*spawnFlyingComponentCB)(int, unsigned int), int nodeID, unsigned int modelID)
|
||||
{
|
||||
auto hideWheel = [this](int nodeID)
|
||||
{
|
||||
bool bHasWheel = false;
|
||||
|
||||
RwFrame* wheelNode = m_pCarNode[nodeID];
|
||||
if (wheelNode != nullptr)
|
||||
{
|
||||
RwFrameForAllObjects(wheelNode, [&bHasWheel](RwObject* object)
|
||||
{
|
||||
if ((rwObjectGetFlags(object) & rpATOMICRENDER) != 0)
|
||||
{
|
||||
rwObjectSetFlags(object, 0);
|
||||
bHasWheel = true;
|
||||
}
|
||||
return object;
|
||||
});
|
||||
}
|
||||
return bHasWheel;
|
||||
};
|
||||
|
||||
|
||||
if (m_DamageManager.GetWheelStatus(0) == 2)
|
||||
{
|
||||
if (hideWheel(5))
|
||||
{
|
||||
std::invoke(spawnFlyingComponentCB, this, 5, modelID);
|
||||
}
|
||||
}
|
||||
if (m_DamageManager.GetWheelStatus(2) == 2)
|
||||
{
|
||||
if (hideWheel(2))
|
||||
{
|
||||
std::invoke(spawnFlyingComponentCB, this, 2, modelID);
|
||||
}
|
||||
}
|
||||
|
||||
// For rear wheels, also hide and spawn the middle wheel (if it exists)
|
||||
if (m_DamageManager.GetWheelStatus(1) == 2)
|
||||
{
|
||||
if (hideWheel(6))
|
||||
{
|
||||
std::invoke(spawnFlyingComponentCB, this, 6, modelID);
|
||||
}
|
||||
if (hideWheel(7))
|
||||
{
|
||||
std::invoke(spawnFlyingComponentCB, this, 7, modelID);
|
||||
}
|
||||
}
|
||||
if (m_DamageManager.GetWheelStatus(3) == 2)
|
||||
{
|
||||
if (hideWheel(3))
|
||||
{
|
||||
std::invoke(spawnFlyingComponentCB, this, 3, modelID);
|
||||
}
|
||||
if (hideWheel(4))
|
||||
{
|
||||
std::invoke(spawnFlyingComponentCB, this, 4, modelID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CAutomobile::Fix_SilentPatch()
|
||||
{
|
||||
ResetFrames();
|
||||
|
@ -135,6 +135,24 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CDamageManager
|
||||
{
|
||||
private:
|
||||
float WheelDamageEffect;
|
||||
uint8_t EngineStatus;
|
||||
uint8_t Wheel[4];
|
||||
uint8_t Door[6];
|
||||
uint32_t Lights;
|
||||
uint32_t Panels;
|
||||
|
||||
public:
|
||||
uint32_t GetWheelStatus(int wheelID) const
|
||||
{
|
||||
return Wheel[wheelID];
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(CDamageManager) == 0x18, "Wrong size: CDamageManager");
|
||||
|
||||
enum eRotAxis
|
||||
{
|
||||
ROT_AXIS_X = 0,
|
||||
@ -299,7 +317,7 @@ public:
|
||||
class NOVMT CAutomobile : public CVehicle
|
||||
{
|
||||
public:
|
||||
BYTE paddd[24];
|
||||
CDamageManager m_DamageManager;
|
||||
CDoor Door[NUM_DOORS];
|
||||
RwFrame* m_pCarNode[25];
|
||||
CBouncingPanel m_aBouncingPanel[3];
|
||||
@ -327,7 +345,20 @@ public:
|
||||
AfterPreRender();
|
||||
}
|
||||
|
||||
HOOK_EACH_FUNC_CTR(PreRender, 1, orgAutomobilePreRender, &PreRender_SilentPatch);
|
||||
HOOK_EACH_FUNC(PreRender, orgAutomobilePreRender, &PreRender_SilentPatch);
|
||||
|
||||
void HideDestroyedWheels_SilentPatch(void (CAutomobile::*spawnFlyingComponentCB)(int, unsigned int), int nodeID, unsigned int modelID);
|
||||
|
||||
template<std::size_t Index>
|
||||
static void (CAutomobile::*orgSpawnFlyingComponent)(int, unsigned int);
|
||||
|
||||
template<std::size_t Index>
|
||||
void SpawnFlyingComponent_HideWheels(int nodeID, unsigned int modelID)
|
||||
{
|
||||
HideDestroyedWheels_SilentPatch(orgSpawnFlyingComponent<Index>, nodeID, modelID);
|
||||
}
|
||||
|
||||
HOOK_EACH_FUNC(SpawnFlyingComponent, orgSpawnFlyingComponent, &SpawnFlyingComponent_HideWheels);
|
||||
|
||||
void Fix_SilentPatch();
|
||||
RwFrame* GetTowBarFrame() const;
|
||||
|
Loading…
Reference in New Issue
Block a user