mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-28 06:43:01 +05: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
4 changed files with 174 additions and 4 deletions
|
@ -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 )
|
||||
{
|
||||
using namespace Memory;
|
||||
|
@ -1254,6 +1278,29 @@ void Patch_III_Common()
|
|||
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)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
class CEntryExit;
|
||||
class CEvent;
|
||||
class CPed;
|
||||
class CVehicle;
|
||||
|
||||
// This structure is very incomplete, but it is good enough for now
|
||||
class __declspec(novtable) CTask
|
||||
|
@ -33,6 +34,9 @@ public:
|
|||
|
||||
class __declspec(novtable) CTaskComplex : public CTask
|
||||
{
|
||||
private:
|
||||
CTask* m_pSubTask;
|
||||
|
||||
public:
|
||||
virtual bool IsSimpleTask() const override { return false; }
|
||||
virtual void SetSubTask(CTask*);
|
||||
|
@ -54,12 +58,20 @@ public:
|
|||
bool Contains(int taskID) const;
|
||||
|
||||
public:
|
||||
std::byte __pad1[8];
|
||||
std::byte __pad1[4];
|
||||
CTask* m_taskSequence[8];
|
||||
std::byte __pad2[16];
|
||||
};
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -215,9 +227,6 @@ public:
|
|||
unsigned int bUsedForReplay : 1; // This ped is controlled by replay and should be removed when replay is done.
|
||||
};
|
||||
|
||||
class CVehicle;
|
||||
class CPed;
|
||||
|
||||
class CPlayerPedData
|
||||
{
|
||||
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 =============
|
||||
namespace LSRPMode
|
||||
{
|
||||
|
@ -5206,6 +5239,21 @@ void Patch_SA_10(HINSTANCE hInstance)
|
|||
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
|
||||
// Test - full precision D3D device
|
||||
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;
|
||||
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 )
|
||||
{
|
||||
using namespace Memory;
|
||||
|
@ -1158,6 +1183,27 @@ void Patch_VC_Common()
|
|||
Patch( getDriverOneShot.get<void>( -8 ), { 0x90, 0x89, 0xD9 } );
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue