mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-11-24 22:32:29 +01:00
Fixed vehicles exploding twice if the driver leaves the car while it's exploding
Fixes #13
This commit is contained in:
parent
1d2f0014f1
commit
f025dff42d
@ -506,6 +506,30 @@ namespace SirenSwitchingFix
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ============= Fixed vehicles exploding twice if the driver leaves the car while it's exploding =============
|
||||||
|
namespace RemoveDriverStatusFix
|
||||||
|
{
|
||||||
|
__declspec(naked) void RemoveDriver_SetStatus()
|
||||||
|
{
|
||||||
|
// if (m_nStatus != STATUS_WRECKED)
|
||||||
|
// m_nStatus = STATUS_ABANDONED;
|
||||||
|
_asm
|
||||||
|
{
|
||||||
|
mov ah, [ecx+50h]
|
||||||
|
mov al, ah
|
||||||
|
and ah, 0F8h
|
||||||
|
cmp ah, 28h
|
||||||
|
je DontSetStatus
|
||||||
|
and al, 7
|
||||||
|
or al, 20h
|
||||||
|
|
||||||
|
DontSetStatus:
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
||||||
{
|
{
|
||||||
using namespace Memory;
|
using namespace Memory;
|
||||||
@ -1254,6 +1278,29 @@ void Patch_III_Common()
|
|||||||
Patch( initHelis.get<void>( 9 + 3 ), &colModelChopper );
|
Patch( initHelis.get<void>( 9 + 3 ), &colModelChopper );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fixed vehicles exploding twice if the driver leaves the car while it's exploding
|
||||||
|
{
|
||||||
|
using namespace RemoveDriverStatusFix;
|
||||||
|
|
||||||
|
auto removeDriver = pattern("8A 41 50 24 07 0C 20 88 41 50 C7 81").get_one();
|
||||||
|
auto processCommands1 = get_pattern("88 41 50 8B 87");
|
||||||
|
auto processCommands2 = get_pattern("88 41 50 8B 2B");
|
||||||
|
auto processCommands3 = get_pattern("0C 20 88 42 50", 2);
|
||||||
|
auto processCommands4 = get_pattern("88 41 50 8B BE");
|
||||||
|
auto pedSetOutCar = get_pattern("88 41 50 8B 85");
|
||||||
|
|
||||||
|
Nop(removeDriver.get<void>(), 2);
|
||||||
|
InjectHook(removeDriver.get<void>(2), RemoveDriver_SetStatus, HookType::Call);
|
||||||
|
|
||||||
|
// CVehicle::RemoveDriver already sets the status to STATUS_ABANDONED, these are redundant
|
||||||
|
Nop(processCommands1, 3);
|
||||||
|
Nop(processCommands2, 3);
|
||||||
|
Nop(processCommands3, 3);
|
||||||
|
Nop(processCommands4, 3);
|
||||||
|
Nop(pedSetOutCar, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
class CEntryExit;
|
class CEntryExit;
|
||||||
class CEvent;
|
class CEvent;
|
||||||
class CPed;
|
class CPed;
|
||||||
|
class CVehicle;
|
||||||
|
|
||||||
// This structure is very incomplete, but it is good enough for now
|
// This structure is very incomplete, but it is good enough for now
|
||||||
class __declspec(novtable) CTask
|
class __declspec(novtable) CTask
|
||||||
@ -33,6 +34,9 @@ public:
|
|||||||
|
|
||||||
class __declspec(novtable) CTaskComplex : public CTask
|
class __declspec(novtable) CTaskComplex : public CTask
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
CTask* m_pSubTask;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool IsSimpleTask() const override { return false; }
|
virtual bool IsSimpleTask() const override { return false; }
|
||||||
virtual void SetSubTask(CTask*);
|
virtual void SetSubTask(CTask*);
|
||||||
@ -54,12 +58,20 @@ public:
|
|||||||
bool Contains(int taskID) const;
|
bool Contains(int taskID) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::byte __pad1[8];
|
std::byte __pad1[4];
|
||||||
CTask* m_taskSequence[8];
|
CTask* m_taskSequence[8];
|
||||||
std::byte __pad2[16];
|
std::byte __pad2[16];
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CTaskComplexSequence) == 0x40, "Wrong size: CTaskComplexSequence");
|
static_assert(sizeof(CTaskComplexSequence) == 0x40, "Wrong size: CTaskComplexSequence");
|
||||||
|
|
||||||
|
class __declspec(novtable) CTaskComplexCarSlowBeDraggedOut : public CTaskComplex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CVehicle* m_pVehicle;
|
||||||
|
int m_status;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CTaskComplexCarSlowBeDraggedOut) == 0x14, "Wrong size: CTaskComplexCarSlowBeDraggedOut");
|
||||||
|
|
||||||
class CTaskManager
|
class CTaskManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -215,9 +227,6 @@ public:
|
|||||||
unsigned int bUsedForReplay : 1; // This ped is controlled by replay and should be removed when replay is done.
|
unsigned int bUsedForReplay : 1; // This ped is controlled by replay and should be removed when replay is done.
|
||||||
};
|
};
|
||||||
|
|
||||||
class CVehicle;
|
|
||||||
class CPed;
|
|
||||||
|
|
||||||
class CPlayerPedData
|
class CPlayerPedData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -2455,6 +2455,39 @@ namespace RiotDontTargetPlayerGroupDuringMissions
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============= Fixed vehicles exploding twice if the driver leaves the car while it's exploding =============
|
||||||
|
namespace RemoveDriverStatusFix
|
||||||
|
{
|
||||||
|
__declspec(naked) void RemoveDriver_SetStatus()
|
||||||
|
{
|
||||||
|
// if (m_nStatus != STATUS_WRECKED)
|
||||||
|
// m_nStatus = STATUS_ABANDONED;
|
||||||
|
_asm
|
||||||
|
{
|
||||||
|
mov bl, [edi+36h]
|
||||||
|
mov al, bl
|
||||||
|
and bl, 0F8h
|
||||||
|
cmp bl, 28h
|
||||||
|
je DontSetStatus
|
||||||
|
and al, 7
|
||||||
|
or al, 20h
|
||||||
|
|
||||||
|
DontSetStatus:
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void (__thiscall *orgPrepareVehicleForPedExit)(CTaskComplexCarSlowBeDraggedOut* task, CPed* ped);
|
||||||
|
static void __fastcall PrepareVehicleForPedExit_WreckedCheck(CTaskComplexCarSlowBeDraggedOut* task, void*, CPed* ped)
|
||||||
|
{
|
||||||
|
if (task->m_pVehicle->GetStatus() != STATUS_WRECKED)
|
||||||
|
{
|
||||||
|
orgPrepareVehicleForPedExit(task, ped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============= LS-RP Mode stuff =============
|
// ============= LS-RP Mode stuff =============
|
||||||
namespace LSRPMode
|
namespace LSRPMode
|
||||||
{
|
{
|
||||||
@ -5206,6 +5239,21 @@ void Patch_SA_10(HINSTANCE hInstance)
|
|||||||
Patch<const void*>(0x6D5612 + 2, &LightStatusRandomnessThreshold);
|
Patch<const void*>(0x6D5612 + 2, &LightStatusRandomnessThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fixed vehicles exploding twice if the driver leaves the car while it's exploding
|
||||||
|
{
|
||||||
|
using namespace RemoveDriverStatusFix;
|
||||||
|
|
||||||
|
Nop(0x6D1955, 2);
|
||||||
|
InjectHook(0x6D1955 + 2, RemoveDriver_SetStatus, HookType::Call);
|
||||||
|
|
||||||
|
InterceptCall(0x64C8CE, orgPrepareVehicleForPedExit, PrepareVehicleForPedExit_WreckedCheck);
|
||||||
|
|
||||||
|
// CVehicle::RemoveDriver already sets the status to STATUS_ABANDONED, these are redundant
|
||||||
|
Nop(0x48628D, 3);
|
||||||
|
Nop(0x647E21, 3);
|
||||||
|
}
|
||||||
|
|
||||||
#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 );
|
||||||
@ -6900,6 +6948,26 @@ void Patch_SA_NewBinaries_Common(HINSTANCE hInstance)
|
|||||||
static const double LightStatusRandomnessThreshold = 25000.0;
|
static const double LightStatusRandomnessThreshold = 25000.0;
|
||||||
Patch<const void*>(getVehicleLightsStatus, &LightStatusRandomnessThreshold);
|
Patch<const void*>(getVehicleLightsStatus, &LightStatusRandomnessThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fixed vehicles exploding twice if the driver leaves the car while it's exploding
|
||||||
|
{
|
||||||
|
using namespace RemoveDriverStatusFix;
|
||||||
|
|
||||||
|
auto removeDriver = pattern("8A 47 36 24 07 0C 20 80 7D 08 00").get_one();
|
||||||
|
auto removeThisPed = get_pattern("80 C9 20 88 48 36 8B 96", 3);
|
||||||
|
auto taskSimpleCarSetPedOut = get_pattern("80 C9 20 88 48 36 8B 86", 3);
|
||||||
|
auto prepareVehicleForPedExit = get_pattern("57 E8 ? ? ? ? 57 8B CE E8 ? ? ? ? 57", 1);
|
||||||
|
|
||||||
|
Nop(removeDriver.get<void>(), 2);
|
||||||
|
InjectHook(removeDriver.get<void>(2), RemoveDriver_SetStatus, HookType::Call);
|
||||||
|
|
||||||
|
InterceptCall(prepareVehicleForPedExit, orgPrepareVehicleForPedExit, PrepareVehicleForPedExit_WreckedCheck);
|
||||||
|
|
||||||
|
// CVehicle::RemoveDriver already sets the status to STATUS_ABANDONED, these are redundant
|
||||||
|
Nop(removeThisPed, 3);
|
||||||
|
Nop(taskSimpleCarSetPedOut, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -449,6 +449,31 @@ namespace FBISirenCoronaFix
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============= Fixed vehicles exploding twice if the driver leaves the car while it's exploding =============
|
||||||
|
namespace RemoveDriverStatusFix
|
||||||
|
{
|
||||||
|
__declspec(naked) void RemoveDriver_SetStatus()
|
||||||
|
{
|
||||||
|
// if (m_nStatus != STATUS_WRECKED)
|
||||||
|
// m_nStatus = STATUS_ABANDONED;
|
||||||
|
_asm
|
||||||
|
{
|
||||||
|
mov cl, [ebx+50h]
|
||||||
|
mov al, cl
|
||||||
|
and cl, 0F8h
|
||||||
|
cmp cl, 28h
|
||||||
|
je DontSetStatus
|
||||||
|
and al, 7
|
||||||
|
or al, 20h
|
||||||
|
|
||||||
|
DontSetStatus:
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModulePath )
|
||||||
{
|
{
|
||||||
using namespace Memory;
|
using namespace Memory;
|
||||||
@ -1158,6 +1183,27 @@ void Patch_VC_Common()
|
|||||||
Patch( getDriverOneShot.get<void>( -8 ), { 0x90, 0x89, 0xD9 } );
|
Patch( getDriverOneShot.get<void>( -8 ), { 0x90, 0x89, 0xD9 } );
|
||||||
InjectHook( getDriverOneShot.get<void>( -5 ), &CVehicle::GetOneShotOwnerID_SilentPatch, HookType::Call );
|
InjectHook( getDriverOneShot.get<void>( -5 ), &CVehicle::GetOneShotOwnerID_SilentPatch, HookType::Call );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fixed vehicles exploding twice if the driver leaves the car while it's exploding
|
||||||
|
{
|
||||||
|
using namespace RemoveDriverStatusFix;
|
||||||
|
|
||||||
|
auto removeDriver = pattern("8A 43 50 24 07 0C 20 88 43 50 E8").get_one();
|
||||||
|
auto processCommands1 = get_pattern("88 42 50 8B 33");
|
||||||
|
auto processCommands2 = get_pattern("88 42 50 8B AE");
|
||||||
|
auto removeThisPed = get_pattern("88 42 50 8B 85");
|
||||||
|
auto pedSetOutCar = get_pattern("0C 20 88 47 50 8B 85", 2);
|
||||||
|
|
||||||
|
Nop(removeDriver.get<void>(), 2);
|
||||||
|
InjectHook(removeDriver.get<void>(2), RemoveDriver_SetStatus, HookType::Call);
|
||||||
|
|
||||||
|
// CVehicle::RemoveDriver already sets the status to STATUS_ABANDONED, these are redundant
|
||||||
|
Nop(processCommands1, 3);
|
||||||
|
Nop(processCommands2, 3);
|
||||||
|
Nop(removeThisPed, 3);
|
||||||
|
Nop(pedSetOutCar, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
|
Loading…
Reference in New Issue
Block a user