mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-29 15:23:02 +05:00
parent
c6c9fe6013
commit
9f94595ee4
3 changed files with 144 additions and 2 deletions
|
@ -5294,6 +5294,24 @@ void Patch_SA_10(HINSTANCE hInstance)
|
||||||
InterceptCall(0x6A8BBE, orgWorldAdd, WorldAdd_SetLightObjectFlag);
|
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
|
#if FULL_PRECISION_D3D
|
||||||
// Test - full precision D3D device
|
// Test - full precision D3D device
|
||||||
Patch<uint8_t>( 0x7F672B+1, *(uint8_t*)(0x7F672B+1) | D3DCREATE_FPU_PRESERVE );
|
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);
|
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()
|
void CAutomobile::Fix_SilentPatch()
|
||||||
{
|
{
|
||||||
ResetFrames();
|
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
|
enum eRotAxis
|
||||||
{
|
{
|
||||||
ROT_AXIS_X = 0,
|
ROT_AXIS_X = 0,
|
||||||
|
@ -299,7 +317,7 @@ public:
|
||||||
class NOVMT CAutomobile : public CVehicle
|
class NOVMT CAutomobile : public CVehicle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BYTE paddd[24];
|
CDamageManager m_DamageManager;
|
||||||
CDoor Door[NUM_DOORS];
|
CDoor Door[NUM_DOORS];
|
||||||
RwFrame* m_pCarNode[25];
|
RwFrame* m_pCarNode[25];
|
||||||
CBouncingPanel m_aBouncingPanel[3];
|
CBouncingPanel m_aBouncingPanel[3];
|
||||||
|
@ -327,7 +345,20 @@ public:
|
||||||
AfterPreRender();
|
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();
|
void Fix_SilentPatch();
|
||||||
RwFrame* GetTowBarFrame() const;
|
RwFrame* GetTowBarFrame() const;
|
||||||
|
|
Loading…
Reference in a new issue