Files
SA-MP/saco/game/hooks.cpp
T

2783 lines
64 KiB
C++

#include "../main.h"
#include "game.h"
#include "util.h"
#include "keystuff.h"
#include "aimstuff.h"
extern int iGtaVersion;
extern CNetGame* pNetGame;
extern CGame* pGame;
extern CChatWindow *pChatWindow;
extern CObjectPool *unnamed_1014FFAC; // 0x1014FFAC, lives in another translation unit
extern DWORD dwGraphicsLoop; // Used for the external dll game loop.
extern CObjectPool *unnamed_1014FFAC; // second object pool, see .text:100A5090
#define NUDE void _declspec(naked)
//-----------------------------------------------------------
// Globals which are used to avoid stack frame alteration
// inside the following hook procedures.
DWORD dwFarClipHookAddr=0;
DWORD dwFarClipReturnAddr=0;
// used generically
PED_TYPE *_pPlayer;
BOOL bIgnoreNextEntry=FALSE;
BOOL bIgnoreNextExit=FALSE;
BYTE byteSavedCameraMode;
DWORD dwCurPlayerActor=0;
BYTE *pbyteCameraMode = (BYTE *)0xB6F1A8;
BYTE *pbyteCurrentPlayer = (BYTE *)0xB7CD74;
WORD *wCameraMode2 = (WORD *)0xB6F858;
PED_TYPE pedCrimeReportTemp; // pay attention! used in 0x100A1790 ; void __thiscall CGame::PlayCrimeReport as pedCrimeReportTemp 0x10150D00
int iRadarColor1=0;
DWORD dwSavedCheatFn=0;
BOOL bAllowVehicleCreation=FALSE;
float fFarClip=1400.0f;
DWORD dwParam1;
DWORD dwParam2;
DWORD dwParamThis;
DWORD unnamed_10113AD8 = 1;
DWORD unnamed_10113ADC = 0x7FB270; // RwRasterCreate
WORD unnamed_10113B2C;
BYTE unnamed_10113AE8[3] = {0xFF,0x52,0x20}; // original `call dword ptr [edx+20h]` at 0x4096AA
PCHAR unnamed_10150734;
DWORD unnamed_10150960;
PCHAR unnamed_10151628; // gxt key, also reused as the ped a use-gun task runs on
DWORD unnamed_101516C8;
DWORD unnamed_101516D0;
DWORD unnamed_101516D4;
DWORD unnamed_101516D8; // vehicle being rendered
DWORD unnamed_10151710;
DWORD unnamed_1015172C;
DWORD unnamed_10151804;
bool unnamed_10151808;
DWORD unnamed_1015180C;
DWORD unnamed_10151810;
DWORD unnamed_10151814;
DWORD unnamed_10151818;
DWORD unnamed_10151824;
CObjectPool *unnamed_1015177C;
WORD wLastRendObj=0;
BYTE Unk1_JmpCode[] = {0xFF,0x19,0xD1,0xBE,0x35,0x00};
BYTE TaskEnterVehicleDriver_HookJmpCode[] = {0xFF,0x25,0xBB,0x19,0x69,0x00,0x90};
BYTE TaskExitVehicle_HookJmpCode[] = {0xFF,0x25,0xBA,0xB8,0x63,0x00,0x90};
BYTE RadarTranslateColor_HookJmpCode[] = {0xFF,0x25,0x79,0x4A,0x58,0x00,0x90};
BYTE CheatProcessHook_JmpCode[] = {0xFF,0x25,0xAA,0x85,0x43,0x00,0x90};
BYTE Unk2_JmpCode[] = {0xFF,0x25,0x33,0x14,0x42,0x00};
BYTE Unk3_JmpCode[] = {0xFF,0x25,0x61,0x36,0x53,0x00,0x90,0x90,0x90};
BYTE CGameShutdown_HookJmpCode[] = {0xFF,0x25,0xF1,0xC8,0x53,0x00,0x90};
BYTE PedDamage_HookJmpCode[] = {0xFF,0x25,0xBC,0x5A,0x4B,0x00};
BYTE Unk4_JmpCode[] = {0xFF,0x25,0x74,0x22,0x50,0x00,0x90,0x90,0x90,0x90};
BYTE Unk5_JmpCode[] = {0xFF,0x25,0x61,0x38,0x4C,0x00};
BYTE GetText_HookJmpCode[] = {0xFF,0x25,0x43,0x00,0x6A,0x00,0x90,0x90,0x90};
BYTE Unk6_JmpCode[] = {0xFF,0x25,0xD8,0xFF,0x5E,0x00,0x90};
BYTE CProjectileInfo_Update_HookJmpCode[] = {0xFF,0x25,0x1B,0x8B,0x73,0x00};
BYTE CWeapon__Satchel__Activate_HookJmpCode[] = {0xFF,0x25,0x5B,0x88,0x73,0x00};
BYTE Unk7_JmpCode[] = {0xFF,0x25,0x36,0xA0,0x63,0x00,0x90};
BYTE Unk8_JmpCode[] = {0xFF,0x25,0x77,0xAB,0x5E,0x00,0x90};
BYTE Unk9_JmpCode[] = {0xFF,0x25,0x39,0x88,0x4C,0x00,0x90,0x90};
BYTE CAnimManager__AddAnimation_Hook_HookJmpCode[] = {0xFF,0x25,0x34,0x39,0x4D,0x00,0x90,0x90,0x90,0x90};
BYTE CAnimManager__BlendAnimation_HookJmpCode[] = {0xFF,0x25,0x09,0x46,0x4D,0x00,0x90};
BYTE Unk10_JmpCode[] = {0xFF,0x25,0xE5,0x42,0x4D,0x00,0x90};
BYTE Unk11_JmpCode[] = {0xFF,0x25,0x29,0x3B,0x4D,0x00};
BYTE RwRasterDestroy_HookJmpCode[] = {0xFF,0x25,0x21,0xC7,0x59,0x00};
BYTE CFileLoader__LoadObjectInstance_HookJmpCode[] = {0xFF,0x25,0x84,0x80,0x53,0x00,0x90};
BYTE CRenderer__AddEntityToRenderList_HookJmpCode[] = {0xFF,0x25,0xA6,0x34,0x55,0x00,0x90,0x90,0x90};
BYTE CEventDamage__AffectsPed_HookJmpCode[] = {0xFF,0x25,0x33,0x34,0x4B,0x00};
BYTE Unk12_JmpCode[] = {0xFF,0x25,0xC6,0x84,0x6D,0x00,0x90,0x90};
BYTE CStreaming__RequestModel_HookJmpCode[] = {0xFF,0x25,0xD7,0x87,0x40,0x00};
BYTE CWorld__ProcessVerticalLine_HookJmpCode[] = {0xFF,0x25,0xDB,0x74,0x56,0x00};
//-----------------------------------------------------------
// TODO: implement functions
// radar scale/shape fix
bool bHudScaleFix = true;
DWORD dwHudScaleX = 0;
DWORD dwHudScaleY = 0;
float fMaximumWidth;
float fMaximumHeight;
bool bSomeHudScaleFixFlag = false;
float* CRadar__radarHeight = (float*)0x866B74;
float* CRadar__radarWidth = (float*)0x866B78;
void ProcessHudScaleFix()
{
if ( bHudScaleFix )
{
dwHudScaleX = *(DWORD*)0x859520;
dwHudScaleY = *(DWORD*)0x859524;
fMaximumWidth = (float)pGame->GetScreenWidth();
fMaximumHeight = (float)pGame->GetScreenHeight();
if ( pGame->GetScreenWidth() > 0 && pGame->GetScreenHeight() > 0 )
{
if ( fMaximumWidth / fMaximumHeight >= 1.6f )
{
*CRadar__radarHeight = 82.0f;
*CRadar__radarWidth = 96.0f;
*(float*)0x859524 = 0.00242f;
*(float*)0x859520 = 0.00222f / (fMaximumWidth / fMaximumHeight);
bSomeHudScaleFixFlag = true;
}
else
{
*CRadar__radarHeight = 76.0f;
*CRadar__radarWidth = 94.0f;
}
}
}
}
void FUNC_100A24C0()
{
if(bSomeHudScaleFixFlag == true)
{
*(DWORD*)0x859520 = dwHudScaleX;
*(DWORD*)0x859524 = dwHudScaleY;
*CRadar__radarHeight = 76.0f;
*CRadar__radarWidth = 94.0f;
bSomeHudScaleFixFlag = false;
}
}
NUDE CHud__DrawRadar_Hook()
{
__asm pushad
ProcessHudScaleFix();
__asm
{
popad
// call original CHud::DrawRadar
mov edx, 0x58A330
call edx
pushad
}
FUNC_100A24C0();
__asm
{
popad
retn
}
}
bool bSomeFlag = false;
NUDE CHud__DrawCrossHairs_Hook()
{
__asm pushad
bSomeFlag = false;
if ( pGame && pGame->FindPlayerPed() )
{
if ( pGame->FindPlayerPed()->GetCameraMode() == 53 )
{
ProcessHudScaleFix();
bSomeFlag = true;
}
}
__asm
{
popad
// call original CHud::DrawCrossHairs
mov edx, 0x58E020
call edx
pushad
}
if (bSomeFlag)
{
FUNC_100A24C0();
bSomeFlag = false;
}
__asm
{
popad
retn
}
}
//-----------------------------------------------------------
NUDE CCamera__Process_Hook()
{
_asm pushad
if(pGame) {
pGame->GetCamera()->FUNC_1009D6B0();
}
_asm popad
_asm mov eax, 0x52B730
_asm jmp eax
}
//-----------------------------------------------------------
NUDE CGame__Process_Hook()
{
// TODO: CGame__Process_Hook
}
//-----------------------------------------------------------
void FUNC_100C3D30(BOOL bFogEnable); // todo: implement `FUNC_100C3D30`, lives in another file
extern DWORD GLOBAL_1026EBDC; // todo: define, lives in another file
NUDE CPed_Render_Hook()
{
__asm pushad
FUNC_100C3D30(FALSE);
__asm
{
popad
// call original CPed::Render
mov edx, 0x5E7680
call edx
pushad
}
if (GLOBAL_1026EBDC) FUNC_100C3D30(TRUE);
else FUNC_100C3D30(FALSE);
__asm
{
popad
retn
}
}
//-----------------------------------------------------------
// saved return address, shared by the task and anim hooks below
DWORD dwHookRetnAddr;
// animation the local player got told to play, picked up for sync
DWORD dwAnimClump;
DWORD dwAnimGroup;
DWORD dwAnimID;
DWORD dwAnimBlend;
DWORD dwLocalPlayerClump;
DWORD dwSyncAnimType;
DWORD dwSyncAnimGroup;
DWORD dwSyncAnimID;
DWORD dwSyncAnimBlend;
DWORD dwAddAnimationRetAddr = 0x4D3AAA;
DWORD dwBlendAnimationRetAddr = 0x4D4617;
NUDE CAnimManager__AddAnimation_Hook()
{
_asm mov edx, [esp]
_asm mov dwHookRetnAddr, edx
_asm mov edx, [esp+4]
_asm mov dwAnimClump, edx
_asm mov edx, [esp+8]
_asm mov dwAnimGroup, edx
_asm mov edx, [esp+12]
_asm mov dwAnimID, edx
_asm pushad
_pPlayer = GamePool_FindPlayerPed();
if(_pPlayer) dwLocalPlayerClump = (DWORD)_pPlayer->entity.pdwRenderWare;
else dwLocalPlayerClump = 0;
if(dwAnimClump == dwLocalPlayerClump && (dwAnimGroup || dwAnimID != 0xA0))
{
dwSyncAnimType = 1;
dwSyncAnimGroup = dwAnimGroup;
dwSyncAnimID = dwAnimID;
}
_asm popad
_asm mov eax, [esp+12]
_asm mov edx, ds:0xB4EA34
_asm jmp dwAddAnimationRetAddr
}
//-----------------------------------------------------------
NUDE CAnimManager__BlendAnimation_Hook()
{
_asm mov edx, [esp]
_asm mov dwHookRetnAddr, edx
_asm mov edx, [esp+4]
_asm mov dwAnimClump, edx
_asm mov edx, [esp+8]
_asm mov dwAnimGroup, edx
_asm mov edx, [esp+12]
_asm mov dwAnimID, edx
_asm mov edx, [esp+16]
_asm mov dwAnimBlend, edx
_asm pushad
_pPlayer = GamePool_FindPlayerPed();
if(_pPlayer) dwLocalPlayerClump = (DWORD)_pPlayer->entity.pdwRenderWare;
else dwLocalPlayerClump = 0;
if(dwAnimClump == dwLocalPlayerClump && (dwAnimGroup || dwAnimID != 0xA0))
{
dwSyncAnimType = 2;
dwSyncAnimGroup = dwAnimGroup;
dwSyncAnimID = dwAnimID;
dwSyncAnimBlend = dwAnimBlend;
}
_asm popad
_asm sub esp, 0x14
_asm mov ecx, [esp+0x18]
_asm jmp dwBlendAnimationRetAddr
}
//-----------------------------------------------------------
DWORD dwProcessControlPed;
PED_TYPE *_pProcessControlPed;
BYTE byteSavedCurrentPlayer;
BYTE byteProcessControlPlayerID;
WORD wSavedCameraMode2;
DWORD dwSavedPedHealth;
GTA_CONTROLSET *pProcessControlKeys;
// `fst [esi+0x55C]` heading writes at 0x6884C4 and 0x688200, only enabled for the local player
BYTE PedHeadingCode1[] = {0xD9,0x96,0x5C,0x05,0x00,0x00};
BYTE PedHeadingCode2[] = {0xD9,0x96,0x5C,0x05,0x00,0x00};
// `call 0x5E1B10` at 0x5E92F4, nopped out while a remote ped processes
BYTE RemotePedProcessCode[] = {0xE8,0x17,0x88,0xFF,0xFF};
// runs the original CPlayerPed::ProcessControl for a remote ped under SEH
void ProcessControlRemotePed(); // .text:100A27C0
NUDE CPlayerPed_ProcessControl_Hook()
{
_asm mov dwProcessControlPed, ecx
_asm pushad
_pProcessControlPed = (PED_TYPE *)dwProcessControlPed;
byteSavedCurrentPlayer = *pbyteCurrentPlayer;
byteProcessControlPlayerID = FindPlayerNumFromPedPtr(dwProcessControlPed);
if(dwProcessControlPed && byteProcessControlPlayerID && !byteSavedCurrentPlayer)
{
GameStoreLocalPlayerKeys();
GameSetRemotePlayerKeys(byteProcessControlPlayerID);
byteSavedCameraMode = *pbyteCameraMode;
*pbyteCameraMode = GameGetPlayerCameraMode(byteProcessControlPlayerID);
wSavedCameraMode2 = *wCameraMode2;
*wCameraMode2 = GameGetPlayerCameraMode(byteProcessControlPlayerID);
if(*wCameraMode2 == 4) *wCameraMode2 = 0;
GameStoreLocalPlayerCameraExtZoom();
GameSetRemotePlayerCameraExtZoom(byteProcessControlPlayerID);
GameStoreLocalPlayerAim();
GameSetRemotePlayerAim(byteProcessControlPlayerID);
GameStoreLocalPlayerWeaponSkills();
GameSetRemotePlayerWeaponSkills(byteProcessControlPlayerID);
*pbyteCurrentPlayer = byteProcessControlPlayerID;
dwSavedPedHealth = *(DWORD *)&_pProcessControlPed->fHealth;
UnFuck(0x5E92F4, 5);
memset((void *)0x5E92F4, 0x90, 5);
ProcessControlRemotePed();
memcpy((void *)0x5E92F4, RemotePedProcessCode, 5);
GameSetLocalPlayerWeaponSkills();
*pbyteCameraMode = byteSavedCameraMode;
*wCameraMode2 = wSavedCameraMode2;
GameSetLocalPlayerCameraExtZoom();
*pbyteCurrentPlayer = 0;
GameSetLocalPlayerKeys();
GameSetLocalPlayerAim();
}
else
{
if(pNetGame && pNetGame->GetPlayerPool()->GetLocalPlayer()->GetField_F0())
{
struc_41 *pSettings = pNetGame->GetSettings();
if(pGame->FindPlayerPed()->HasExceededWorldBoundries(pSettings->fWorldBoundryPX,
pSettings->fWorldBoundryZX, pSettings->fWorldBoundryPY, pSettings->fWorldBoundryNY))
{
if(!pGame->GetActiveInterior())
{
DWORD dwStateFlags = _pProcessControlPed->dwStateFlags;
if(!(dwStateFlags & 0x100) && (dwStateFlags & 3))
{
pProcessControlKeys = GameGetInternalKeys();
pProcessControlKeys->wKeys1[14] = 255;
pProcessControlKeys->wKeys2[14] = 0;
}
}
}
}
if(pGame->FindPlayerPed())
{
if(pGame->FindPlayerPed()->field_2F7)
{
pProcessControlKeys = GameGetInternalKeys();
pProcessControlKeys->wKeys1[18] = 0;
pProcessControlKeys->wKeys2[18] = 0;
}
if(pGame->FindPlayerPed()->field_2F6)
{
pProcessControlKeys = GameGetInternalKeys();
pProcessControlKeys->wKeys1[14] = 0;
pProcessControlKeys->wKeys2[14] = 0;
}
if(pGame->FindPlayerPed()->field_2F8)
{
pProcessControlKeys = GameGetInternalKeys();
pProcessControlKeys->wKeys1[16] = 0;
pProcessControlKeys->wKeys2[16] = 0;
}
}
memcpy((void *)0x6884C4, PedHeadingCode1, 6);
memcpy((void *)0x688200, PedHeadingCode2, 6);
_asm mov ecx, dwProcessControlPed
_asm mov edx, 0x60EA90
_asm call edx
memset((void *)0x6884C4, 0x90, 6);
memset((void *)0x688200, 0x90, 6);
}
_asm popad
_asm retn
}
//-----------------------------------------------------------
MATRIX4X4 unnamed_10150A48; // ped matrix saved across ProcessControl
float unnamed_10150C1C;
float unnamed_10150C20;
float unnamed_10150C24;
NUDE CCivillianPed__ProcessControl_Hook()
{
_asm mov dwProcessControlPed, ecx
_asm pushad
_pProcessControlPed = (PED_TYPE *)dwProcessControlPed;
// hold attached/frozen peds still while the game processes them
if((_pProcessControlPed->entity.dwPhysFlags & 0x40000) &&
(_pProcessControlPed->entity.dwPhysFlags & 0x800000) &&
(_pProcessControlPed->entity.dwPhysFlags & 0x200000))
{
_pProcessControlPed->entity.vecMoveSpeed.X = 0.0f;
_pProcessControlPed->entity.vecMoveSpeed.Y = 0.0f;
}
if(_pProcessControlPed->entity.mat)
{
unnamed_10150A48 = *_pProcessControlPed->entity.mat;
unnamed_10150C1C = _pProcessControlPed->entity.vecMoveSpeed.X;
unnamed_10150C20 = _pProcessControlPed->entity.vecMoveSpeed.Y;
unnamed_10150C24 = _pProcessControlPed->entity.vecMoveSpeed.Z;
}
_asm mov ecx, dwProcessControlPed
_asm mov edx, 0x5DDBF0 ;// CCivilianPed::ProcessControl
_asm call edx
if((_pProcessControlPed->entity.dwPhysFlags & 0x40000) &&
(_pProcessControlPed->entity.dwPhysFlags & 0x800000) &&
(_pProcessControlPed->entity.dwPhysFlags & 0x200000))
{
if(_pProcessControlPed->entity.mat)
{
_pProcessControlPed->entity.mat->pos.X = unnamed_10150A48.pos.X;
_pProcessControlPed->entity.mat->pos.Y = unnamed_10150A48.pos.Y;
_pProcessControlPed->entity.mat->pos.Z = unnamed_10150A48.pos.Z;
}
_pProcessControlPed->entity.vecMoveSpeed.X = 0.0f;
_pProcessControlPed->entity.vecMoveSpeed.Y = 0.0f;
}
_asm popad
_asm retn
}
//-----------------------------------------------------------
WORD unnamed_10150730;
BYTE unnamed_10150BC0;
DWORD unnamed_1015168C;
NUDE TaskUseGun_Hook()
{
_asm mov unnamed_10151628, ecx
_asm mov eax, [esp+4]
_asm mov dwProcessControlPed, eax
byteSavedCurrentPlayer = *pbyteCurrentPlayer;
byteProcessControlPlayerID = FindPlayerNumFromPedPtr(dwProcessControlPed);
if(dwProcessControlPed && byteProcessControlPlayerID && !byteSavedCurrentPlayer)
{
// run the task with the remote player's keys, camera and skills in place
GameStoreLocalPlayerKeys();
GameSetRemotePlayerKeys(byteProcessControlPlayerID);
unnamed_10150BC0 = *pbyteCameraMode;
*pbyteCameraMode = GameGetPlayerCameraMode(byteProcessControlPlayerID);
unnamed_10150730 = *wCameraMode2;
*wCameraMode2 = GameGetPlayerCameraMode(byteProcessControlPlayerID);
if(*wCameraMode2 == 4) *wCameraMode2 = 0;
GameStoreLocalPlayerCameraExtZoom();
GameSetRemotePlayerCameraExtZoom(byteProcessControlPlayerID);
GameStoreLocalPlayerAim();
GameSetRemotePlayerAim(byteProcessControlPlayerID);
GameStoreLocalPlayerWeaponSkills();
GameSetRemotePlayerWeaponSkills(byteProcessControlPlayerID);
*pbyteCurrentPlayer = byteProcessControlPlayerID;
_asm mov ecx, unnamed_10151628
_asm push dwProcessControlPed
_asm mov eax, 0x624ED0 ;// CTaskSimpleUseGun::ProcessPed
_asm call eax
*pbyteCameraMode = unnamed_10150BC0;
*wCameraMode2 = unnamed_10150730;
GameSetLocalPlayerWeaponSkills();
GameSetLocalPlayerCameraExtZoom();
*pbyteCurrentPlayer = 0;
GameSetLocalPlayerAim();
GameSetLocalPlayerKeys();
}
else
{
unnamed_1015168C = 1;
_asm mov ecx, unnamed_10151628
_asm push dwProcessControlPed
_asm mov eax, 0x624ED0
_asm call eax
unnamed_1015168C = 0;
}
_asm retn 4
}
//-----------------------------------------------------------
DWORD unnamed_10151684;
DWORD unnamed_10151688;
NUDE WeaponRender__GetWeaponSkill_Hook()
{
_asm mov dwProcessControlPed, ecx
_pProcessControlPed = (PED_TYPE *)dwProcessControlPed;
byteSavedCurrentPlayer = *pbyteCurrentPlayer;
byteProcessControlPlayerID = FindPlayerNumFromPedPtr(dwProcessControlPed);
if(dwProcessControlPed && byteProcessControlPlayerID && !byteSavedCurrentPlayer)
{
// render a remote player with his own skill level
GameStoreLocalPlayerWeaponSkills();
GameSetRemotePlayerWeaponSkills(byteProcessControlPlayerID);
unnamed_10151688 = 1;
}
_asm mov ecx, dwProcessControlPed
_asm movsx eax, byte ptr [ecx+0x718]
_asm imul eax, 0x1C
_asm mov eax, [eax+ecx+0x5A0]
_asm push eax
_asm mov edx, 0x5E3B60 ;// CPed::GetWeaponSkill
_asm call edx
_asm mov unnamed_10151684, eax
if(unnamed_10151688)
{
GameSetLocalPlayerWeaponSkills();
unnamed_10151688 = 0;
}
_asm mov eax, unnamed_10151684
_asm retn
}
//-----------------------------------------------------------
NUDE CWorld__ProcessAttachedEntities_Hook()
{
// TODO: CWorld__ProcessAttachedEntities_Hook
}
//-----------------------------------------------------------
NUDE CWorld__ProcessPedsAfterPreRender_Hook()
{
__asm
{
// call original CWorld::ProcessPedsAfterPreRender
mov edx, 0x563430
call edx
pushad
}
if (pNetGame && pNetGame->GetPlayerPool())
pNetGame->GetPlayerPool()->FUNC_10013960();
__asm
{
popad
retn
}}
//-----------------------------------------------------------
NUDE AllVehicles_ProcessControl_Hook()
{
// TODO: AllVehicles_ProcessControl_Hook
}
//-----------------------------------------------------------
// fix horn processing
VEHICLE_TYPE *_pHornVehicle;
int _iHasSetHornHookFix = 0;
BYTE _byteSavedControlFlags = 0;
DWORD _dwVehicleParams = 0;
DWORD _dwAudioClass = 0;
NUDE VehicleHorn_Hook()
{
_asm mov _dwAudioClass, ecx
_asm mov edx, [esp+4]
_asm mov _dwVehicleParams, edx
_asm mov eax, [edx+16]
_asm mov _pHornVehicle, eax
_byteSavedControlFlags = _pHornVehicle->entity.nControlFlags;
if( _pHornVehicle->pDriver &&
IN_VEHICLE(_pHornVehicle->pDriver) )
{
_pHornVehicle->entity.nControlFlags = 0x02;
//_iHasSetHornHookFix = 1;
} else {
_pHornVehicle->entity.nControlFlags = 0x22;
//_iHasSetHornHookFix = 0;
}
_asm push _dwVehicleParams
_asm mov ecx, _dwAudioClass
_asm mov edx, 0x5002C0
_asm call edx
_pHornVehicle->entity.nControlFlags = _byteSavedControlFlags;
_asm retn 4
}
//-----------------------------------------------------------
DWORD dwSayParam1;
DWORD dwSayParam2;
float fSayParam3;
DWORD dwSayParam4;
DWORD dwSayParam5;
DWORD dwSayParam6;
NUDE CPed_Say_Hook()
{
_asm mov eax, [esp+4]
_asm mov dwSayParam1, eax
_asm mov eax, [esp+8]
_asm mov dwSayParam2, eax
_asm mov eax, [esp+12]
_asm mov fSayParam3, eax
_asm mov eax, [esp+16]
_asm mov dwSayParam4, eax
_asm mov eax, [esp+20]
_asm mov dwSayParam5, eax
_asm mov eax, [esp+24]
_asm mov dwSayParam6, eax
_asm pushad
if(dwSayParam1 != 45) {
if(pChatWindow) pChatWindow->AddDebugMessage("CPed::Say(%u,%u,%f,%u,%u,%u)",
dwSayParam1,dwSayParam2,fSayParam3,dwSayParam4,dwSayParam5,dwSayParam6);
}
_asm popad
_asm mov eax, [esp+4]
_asm test ax, ax
_asm mov edx, 0x5EFFE7
_asm jmp edx
}
//-----------------------------------------------------------
NUDE ZoneOverlay_Hook()
{
_asm pushad
if (pNetGame && pNetGame->GetGangZonePool()) pNetGame->GetGangZonePool()->Draw();
_asm popad
_asm ret
}
//-----------------------------------------------------------
NUDE PlayerWalk_Hook()
{
_asm pushad
if (pNetGame && pNetGame->GetWalkStyle())
{
_asm popad
_asm mov [esi + 0x4D4], eax
}
else
{
_asm popad
}
_asm ret
}
//-----------------------------------------------------------
NUDE PickUpPickup_Hook()
{
_asm mov unnamed_10150960, esi
_asm pushad
if (pNetGame && pNetGame->GetPickupPool())
pNetGame->GetPickupPool()->sub_10013440((unnamed_10150960 - 0x9788C0) >> 5);
_asm popad
_asm mov al, [esi+0x1C]
_asm cmp al, 6
_asm push 0x4579CB
_asm ret
}
//-----------------------------------------------------------
NUDE CWeapon_FireCamera_Hook()
{
_asm mov ebx, [esp+8]
_asm mov dwCurPlayerActor, ebx
_asm pushad
if (dwCurPlayerActor == (DWORD)GamePool_FindPlayerPed()) {
*(BYTE*)0xC8A7C0 = 1;
*(BYTE*)0xC8A7C1 = 1;
}
_asm popad
_asm mov ebx, 0x73C260
_asm jmp ebx
}
//-----------------------------------------------------------
NUDE CCameraCamShake_Sniper_Hook()
{
_asm ret
}
//-----------------------------------------------------------
NUDE CTrain_ProcessControl_Derailment()
{
_asm {
mov eax, [esi+1444]; // get the speed
and eax, 0x80000000; // get the upper bit
or eax, 0x3F800000; // or it with 1.0f (it'll be -ve if bit is set)
mov [esi+1444], eax; // set the new speed
ret;
}
}
//-----------------------------------------------------------
int FUNC_100A36C0(); // todo: implement `FUNC_100A36C0`
DWORD dwEnterExitVehicle;
NUDE TaskEnterVehicleDriver_Hook()
{
_asm mov eax, [esp]
_asm mov dwHookRetnAddr, eax
_asm mov eax, [esp+4]
_asm mov dwEnterExitVehicle, eax
_asm pushad
if((dwHookRetnAddr == 0x570A20 || dwHookRetnAddr == 0x570A99) && !FUNC_100A36C0())
{
_asm
{
popad
// kill the task, we're not letting them in
mov ebx, [ecx]
test ebx, ebx
jz noTaskDelete
push 1
call dword ptr [ebx]
noTaskDelete:
pop eax
pop eax
mov eax, 0x570A9E
jmp eax
}
}
_asm popad
_asm mov eax, [esp+4]
_asm push esi
_asm push 0
_asm mov ebx, 0x6402F7
_asm jmp ebx
}
//-----------------------------------------------------------
DWORD dwExitTaskThis;
DWORD dwPutOutOfVehicle = 0xFFFFFFFF;
CVehiclePool *pExitVehiclePool;
WORD wExitVehicleID;
CVehicle *pExitVehicle;
CLocalPlayer *pExitLocalPlayer;
MATRIX4X4 matExitVehicle;
NUDE TaskExitVehicle()
{
_asm mov ebp, esp
_asm mov dwExitTaskThis, ecx
_asm mov eax, [ebp]
_asm mov dwHookRetnAddr, eax
_asm mov eax, [ebp+4]
_asm mov dwEnterExitVehicle, eax
dwPutOutOfVehicle = 0xFFFFFFFF;
if(!bIgnoreNextExit &&
(dwHookRetnAddr == 0x5704A1 || dwHookRetnAddr == 0x5703FC))
{
if(pNetGame)
{
if(GamePool_FindPlayerPed()->pVehicle == dwEnterExitVehicle)
{
pExitVehiclePool = pNetGame->GetVehiclePool();
wExitVehicleID = pExitVehiclePool->FUNC_1001EB90((int)GamePool_FindPlayerPed()->pVehicle);
if(wExitVehicleID != 0xFFFF)
{
pExitVehicle = (CVehicle *)pExitVehiclePool->FUNC_10001120(wExitVehicleID);
pExitLocalPlayer = pNetGame->GetPlayerPool()->GetLocalPlayer();
if(pExitVehicle && pExitLocalPlayer)
{
if(pExitVehicle->IsATrainPart())
{
// exiting a train part normally doesn't work, dump them next to it
dwPutOutOfVehicle = 1;
pExitVehicle->GetMatrix(&matExitVehicle);
pExitLocalPlayer->GetPlayerPed()->RemoveFromVehicleAndPutAt(
matExitVehicle.pos.X + 2.5f,
matExitVehicle.pos.Y + 2.5f,
matExitVehicle.pos.Z);
}
else
{
pExitLocalPlayer->FUNC_10005BF0(wExitVehicleID);
}
}
}
}
}
}
else
{
bIgnoreNextExit = FALSE;
}
_asm push dwPutOutOfVehicle
_asm push 0x841618
_asm mov ecx, dwExitTaskThis
_asm mov edx, 0x63B8C0
_asm add edx, 7
_asm jmp edx
}
//-----------------------------------------------------------
NUDE AddVehicleHook()
{
_asm pushad
if(!bAllowVehicleCreation) {
_asm popad
_asm xor eax, eax
_asm ret
}
_asm popad
_asm mov eax, 0x421446
_asm jmp eax
}
//-----------------------------------------------------------
// disable cheat code processing
NUDE CheatProcessorHook()
{
__asm
{
mov dwSavedCheatFn, eax
pushad
// CCheat::m_bHasPlayerCheated = true
mov edx, 0x96918C
mov byte ptr [edx], 1
popad
// dont process cheat
mov edx, 0x438581
cmp eax, 0
jmp edx
}
}
//-----------------------------------------------------------
NUDE RadarTranslateColor()
{
_asm mov eax, [esp+4]
_asm mov iRadarColor1, eax
TranslateColorCodeToRGBA(iRadarColor1); // return will still be in eax.
_asm ret
}
//-----------------------------------------------------------
NUDE SetFarClipHook()
{
_asm fld fFarClip
_asm push esi
_asm mov esi, [esp+8]
_asm mov edx, dwFarClipReturnAddr
_asm jmp edx
}
//-----------------------------------------------------------
// We use this to trap and exit the game
DWORD dwShutDownTick;
void QuitGame(); // todo: implement `QuitGame`
NUDE CGameShutdownHook()
{
dwShutDownTick = GetTickCount() + 2000;
QuitGame();
while(GetTickCount() < dwShutDownTick) {
Sleep(100);
}
ExitProcess(0);
}
//-----------------------------------------------------------
DWORD unnamed_101516A0; // CEventDamage *
DWORD unnamed_101516A4; // CPed * taking the damage
int __stdcall FUNC_100A3BB0(DWORD *pEventDamage, PED_TYPE *pPed); // todo: implement `FUNC_100A3BB0`
NUDE PedDamage_Hook()
{
__asm
{
mov eax, fs:0
test ecx, ecx
jz computeResponse
mov unnamed_101516A0, ecx
mov ebx, [esp+4]
test ebx, ebx
jz computeResponse
mov unnamed_101516A4, ebx
pushad
mov eax, unnamed_101516A4
push eax
mov ecx, unnamed_101516A0
push ecx
call FUNC_100A3BB0
test eax, eax
jz computeResponseAfterSync
// the netcode dealt with it, don't let the game apply the damage
popad
retn 0Ch
computeResponseAfterSync:
popad
computeResponse:
mov edx, 0x4B5AC6 ;// CEventDamage::ComputeDamageResponse + 6
jmp edx
}
}
//-----------------------------------------------------------
NUDE AnimCrashFixHook()
{
__asm
{
push edi
mov edi, [esp+8] ;// arg0
test edi, edi
jz exitFn
mov eax, 0x4D41C5 ;// CAnimManager::UncompressAnimation
jmp eax
exitFn:
pop edi
ret
}
}
//-----------------------------------------------------------
NUDE SetForegroundWindowCrashFixHook()
{
__asm
{
mov eax, ds:0xC17054;
test eax, eax;
jz exitFn;
push 0x746929; // return address;
ret;
exitFn:
xor eax, eax;
ret;
}
}
//-----------------------------------------------------------
NUDE GenTaskAlloc_Hook()
{
_asm mov edi, [esp+4]
_asm mov dwParam1, edi
//_asm mov edx, [esp+8]
//_asm mov dwParam2, edx
_asm mov dwParamThis, ecx
_asm pushad
_asm mov edx, [edi]
_asm mov ecx, edi
_asm call dword ptr [edx+4]
_asm mov dwParam2, eax
//pChatWindow->AddDebugMessage("TaskAlloc: 0x%X, 0x%X, 0x%X",dwParamThis,dwParam1,dwParam2);
_asm popad
_asm mov eax, fs:0
_asm mov edx, 0x4C3876
_asm jmp edx
}
//-----------------------------------------------------------
// used for correct report message using 100A1790 ; void __thiscall CGame::PlayCrimeReport
NUDE PoliceScannerAudio_FindPlayerPed_Hook()
{
__asm
{
mov eax, offset pedCrimeReportTemp
retn
}
}
//-----------------------------------------------------------
// delete satchel projectile if the owner is dead (not sure if this code will work properly)
DWORD dwProjectileObject = 0;
DWORD dwProjectileInfo = 0;
NUDE CProjectile_Update_Hook()
{
__asm
{
mov dwProjectileObject, esi
mov dwProjectileInfo, ebx
pushad
mov eax, dwProjectileInfo
mov ecx, [eax+4] ;// dwProjectileInfo->pOwner
test ecx, ecx //
jnz dont_delete // if the owner == nullptr, delete the projectile
// delete projectile CProjectileInfo::RemoveIfThisIsAProjectile
push dwProjectileObject
mov eax, 0x739A40
call eax
// correct stack
add esp, 4
popad
mov dl, 0x0FF
jmp end_hook
dont_delete:
popad
// original code
mov ecx, [ebx+4]
mov dl, [ecx+36h]
end_hook:
push 0x738F40
retn
}
}
//-----------------------------------------------------------
NUDE CWeapon__Satchel__Activate_Hook()
{
__asm
{
CMP DWORD PTR DS:[ESI-0x20], 0x27
MOV EDI, DWORD PTR SS:[EBP]
JNZ skip
MOV EAX, [ESP]
CMP DWORD PTR DS:[ESI-0x1C], EAX
JNZ skip
MOV EAX, 0x738880
JMP EAX
skip:
MOV EAX, 0x7388DB
JMP EAX
}
}
//-----------------------------------------------------------
NUDE PathProcessingCrashFixHook()
{
__asm
{
push esi
test ecx, ecx;
jz exitFn
mov esi,dword ptr ss:[esp+8]
mov eax,dword ptr ds:[esi]
mov edx, 0x63A047;
jmp edx;
exitFn:
mov esi, 0x63a04d;
jmp esi;
}
}
//-----------------------------------------------------------
NUDE SetCarColorCrashFix()
{
__asm
{
test eax, eax;
jz exitFn; // CPool_CVehicle_GetAt(scmParam1) == NULL
mov ecx, 0x47eab8;
mov cl,byte ptr ds:[0xA43C7C]; // get color1 (was replaced by jmpcode)
jmp ecx; // continue function
exitFn:
mov esi, 0x47eaca;
jmp esi;
}
}
//-----------------------------------------------------------
NUDE GetText_Hook()
{
__asm
{
// stolen prologue from CText::Get
sub esp, 0x20
push esi
push edi
mov edi, [esp+0x2C]
pushad
mov unnamed_10151628, edi
}
unnamed_10150734 = 0;
// SAMP prefixed keys are server menu text, not gxt entries
if(pNetGame && unnamed_10151628[0] == 'S' && unnamed_10151628[1] == 'A' &&
unnamed_10151628[2] == 'M' && unnamed_10151628[3] == 'P' && pNetGame->GetMenuPool())
{
unnamed_10150734 = pNetGame->GetMenuPool()->GetTextPointer(unnamed_10151628 + 4);
}
__asm
{
popad
cmp unnamed_10150734, 0
jz callOriginal
mov eax, unnamed_10150734
pop edi
pop esi
add esp, 0x20
retn 4
callOriginal:
mov eax, 0x6A0059
jmp eax
}
}
//-----------------------------------------------------------
NUDE CCustomCarPlateMgr__CreatePlateTexture__RwRasterCreate_Hook()
{
__asm
{
// only ever create the plate raster once
mov eax, unnamed_101516C8
test eax, eax
jnz exitFn
cmp iGtaVersion, GTASA_VERSION_USA10
jnz createRaster
mov unnamed_10113ADC, 0x7FB230
createRaster:
push 0x604
push 0x20
push 0x10
push 0x40
mov ebx, unnamed_10113ADC
call ebx
mov unnamed_101516C8, eax
pop ebx
pop ebx
pop ebx
pop ebx
exitFn:
mov eax, unnamed_101516C8
retn
}
}
//-----------------------------------------------------------
NUDE RwRasterDestroy_Hook()
{
__asm
{
mov eax, [esp+4] ;// arg0 (RwRaster *)
mov unnamed_101516D0, eax
pushad
// never let the game destroy our cached plate raster
cmp unnamed_10113AD8, 0
jz destroyRaster
cmp unnamed_101516C8, 0
jz destroyRaster
mov eax, unnamed_101516D0
cmp eax, unnamed_101516C8
jnz destroyRaster
popad
mov eax, 1
retn
destroyRaster:
popad
push esi
mov esi, [esp+8]
push esi
mov edx, unnamed_101516D4
jmp edx
}
}
//-----------------------------------------------------------
NUDE CVehicle__Render_Hook()
{
_asm mov unnamed_101516D8, esi
_asm ret
}
//-----------------------------------------------------------
// todo: implement `CObject` (samp object, holds the material/text data)
class CObject
{
public:
char _gap0[84];
float field_54;
char _gap58[4403];
int field_118B;
char _gap118F[10];
BYTE field_1199;
public:
void FUNC_100A7E20();
void FUNC_100A9E30();
void FUNC_100A9E70();
};
extern CObjectPool *GLOBAL_1014FFAC; // todo: define, lives in another file
DWORD dwRenderObjectRet = 0;
ENTITY_TYPE *_pRenderEntity;
CObject *_pRenderNetObject;
CPlayerPool *_pRenderPlayerPool;
NUDE CObject__Render_Hook()
{
_asm mov eax, [esp]
_asm mov dwRenderObjectRet, eax
_asm mov _pRenderEntity, ecx
_asm pushad
if (_pRenderEntity) wLastRendObj = _pRenderEntity->nModelIndex;
_pRenderNetObject = NULL;
if (pNetGame && _pRenderEntity && (_pRenderEntity->dwProcessingFlags & 0x80000000))
{
if ((_pRenderNetObject = pNetGame->GetObjectPool()->FUNC_100129D0(_pRenderEntity)) != NULL ||
((_pRenderPlayerPool = pNetGame->GetPlayerPool()) != NULL &&
(_pRenderNetObject = _pRenderPlayerPool->FUNC_10013B70(_pRenderEntity)) != NULL))
{
_pRenderNetObject->FUNC_100A9E30();
}
}
if (GLOBAL_1014FFAC && _pRenderEntity && (_pRenderEntity->dwProcessingFlags & 0x80000000))
{
_pRenderNetObject = GLOBAL_1014FFAC->FUNC_100129D0(_pRenderEntity);
if (_pRenderNetObject) _pRenderNetObject->FUNC_100A9E30();
}
_asm
{
popad
// call original CObject::Render
mov eax, 0x59F180
call eax
pushad
}
if (pNetGame && _pRenderNetObject) _pRenderNetObject->FUNC_100A9E70();
if (GLOBAL_1014FFAC && _pRenderNetObject) _pRenderNetObject->FUNC_100A9E70();
_asm popad
_asm retn
}
//-----------------------------------------------------------
NUDE CRadar__DrawMap__FindPlayerSpeed_Hook()
{
// keep the map still while the local player is a vehicle passenger
if(pGame && pGame->FindPlayerPed() && pGame->FindPlayerPed()->IsInVehicle() &&
pGame->FindPlayerPed()->sub_100ABFC0())
{
_asm lea eax, unnamed_10151710
_asm ret
}
_asm mov edx, 0x56E090 ;// FindPlayerSpeed
_asm jmp edx
}
//-----------------------------------------------------------
DWORD dwObjectInstance = 0;
DWORD dwObjectInstanceUnused = 0;
BOOL bReplaceAllObjects = FALSE;
int FUNC_1009D050(int iModelID, float fX, float fY, float fZ); // todo: implement `IsObjectRemoved`
NUDE CFileLoader__LoadObjectInstance_Hook()
{
_asm mov eax, [esp+4]
_asm mov dwObjectInstance, eax
_asm mov eax, [esp+8]
_asm mov dwObjectInstanceUnused, eax
_asm pushad
// replace removed objects with an invisible model
if (dwObjectInstance && FUNC_1009D050(*(int *)(dwObjectInstance + 0x1C), *(float *)dwObjectInstance,
*(float *)(dwObjectInstance + 4), *(float *)(dwObjectInstance + 8)))
{
*(int *)(dwObjectInstance + 0x1C) = 19300;
}
if (bReplaceAllObjects) *(int *)(dwObjectInstance + 0x1C) = 19300;
_asm
{
popad
push -1
push 0x83C931
mov eax, 0x538097
jmp eax
}
}
//-----------------------------------------------------------
float fEscalatorCheck1;
float fEscalatorCheck2;
NUDE CEscalator__Update_Hook()
{
__asm pushad
UnFuck(0x858BA4, 4);
UnFuck(0x858F84, 4);
fEscalatorCheck1 = *(float*)0x858BA4;
fEscalatorCheck2 = *(float*)0x858F84;
*(float*)0x858BA4 = 40.0f;
*(float*)0x858F84 = 50.0f;
__asm
{
popad
mov eax, 0x717D30 // CEscalator::Update
call eax
pushad
}
*(float*)0x858BA4 = fEscalatorCheck1;
*(float*)0x858F84 = fEscalatorCheck2;
__asm popad
__asm ret
}
//-----------------------------------------------------------
NUDE CObject__CreateRwObject_Hook()
{
_asm mov eax, [esp]
_asm mov unnamed_1015172C, eax
_asm pushad
// stop the original from calling the roadsign/plate atomic setup
UnFuck(0x4096AA, 3);
memset((void *)0x4096AA, 0x90, 3);
__asm
{
popad
mov eax, 0x533D30 // CObject::CreateRwObject
call eax
pushad
}
memcpy((void *)0x4096AA, unnamed_10113AE8, 3);
__asm popad
__asm ret
}
//-----------------------------------------------------------
DWORD dwDeleteRwObjectRet = 0;
ENTITY_TYPE *_pDeleteRwObjectEntity;
BYTE byteSavedRoadsignCode[5] = {0xE8,0x3C,0xFF,0xFF,0xFF};
NUDE CEntity__DeleteRwObject_Hook()
{
_asm mov eax, [esp]
_asm mov dwDeleteRwObjectRet, eax
_asm mov _pDeleteRwObjectEntity, ecx
_asm pushad
if (_pDeleteRwObjectEntity->nModelIndex == 3586 || _pDeleteRwObjectEntity->nModelIndex == 3743 ||
_pDeleteRwObjectEntity->nModelIndex == 8980 || _pDeleteRwObjectEntity->nModelIndex == 8979)
{
// nop the CCustomRoadsignMgr call these models crash in
UnFuck(0x71791F, 5);
memset((void *)0x71791F, 0x90, 5);
_asm
{
popad
// call original CEntity::DeleteRwObject
mov eax, 0x534030
call eax
pushad
}
memcpy((void *)0x71791F, byteSavedRoadsignCode, 5);
_asm popad
_asm retn
}
_asm popad
_asm mov eax, 0x534030
_asm jmp eax
}
//-----------------------------------------------------------
VEHICLE_TYPE *_pBreakTowLinkVehicle;
VEHICLEID _BreakTowLinkTractorId;
CVehiclePool *_pBreakTowLinkPool;
// set while samp detaches a trailer itself, so gta gets to break the link
BOOL bIgnoreBreakTowLinkHook;
CVehicle *_pBreakTowLinkTractor;
NUDE CAutomobile__BreakTowLink_Hook()
{
__asm
{
mov _pBreakTowLinkVehicle, ecx
pushad
}
if (pNetGame && !bIgnoreBreakTowLinkHook && _pBreakTowLinkVehicle &&
_pBreakTowLinkVehicle->fHealth > 0.0f)
{
_pBreakTowLinkPool = pNetGame->FUNC_10001180();
_BreakTowLinkTractorId = _pBreakTowLinkPool->FUNC_1001EB90(_pBreakTowLinkVehicle->dwTractor);
if (_BreakTowLinkTractorId != 0xFFFF)
{
_pBreakTowLinkTractor = (CVehicle *)_pBreakTowLinkPool->FUNC_10001120(_BreakTowLinkTractorId);
if (_pBreakTowLinkTractor && !_pBreakTowLinkTractor->IsDriverLocalPlayer() &&
*(DWORD *)_pBreakTowLinkTractor->_gap48)
{
__asm
{
popad
retn
}
}
}
}
__asm
{
popad
// call original CAutomobile::BreakTowLink
mov eax, 0x6A4400
jmp eax
}
}
//-----------------------------------------------------------
ENTITY_TYPE *_pAttachedEntity;
CObject *_pAttachedObject;
DWORD _dwAttachedEntityEsp;
DWORD _dwAttachedEntityResult;
NUDE CWorld__ProcessAttachedEntities__PositionAttachedEntity_Hook()
{
__asm
{
mov _dwAttachedEntityEsp, esp
mov _pAttachedEntity, ecx
pushad
// call original CEntity::PositionAttachedEntity
mov ecx, _pAttachedEntity
mov ebx, 0x546FF0
call ebx
mov _dwAttachedEntityResult, eax
}
if (pNetGame && pNetGame->GetObjectPool())
{
_pAttachedObject = pNetGame->GetObjectPool()->FUNC_100129D0(_pAttachedEntity);
if (_pAttachedObject) _pAttachedObject->FUNC_100A7E20();
}
__asm
{
popad
mov eax, _dwAttachedEntityResult
retn
}}
//-----------------------------------------------------------
NUDE CRenderer__RenderEverythingBarRoads_Hook()
{
_asm mov eax, 0x553AA0 ;// CRenderer::RenderEverythingBarRoads
_asm call eax
if(pNetGame) {
unnamed_1015177C = pNetGame->GetObjectPool();
if(unnamed_1015177C) {
unnamed_1015177C->FUNC_10012B90();
}
}
if(unnamed_1014FFAC) {
unnamed_1014FFAC->FUNC_10012B90();
}
_asm ret
}
//-----------------------------------------------------------
NUDE CRenderer__RenderFadingInEntities_Hook()
{
_asm mov eax, 0x5531E0 ;// CRenderer::RenderFadingInEntities
_asm call eax
if(pNetGame) {
unnamed_1015177C = pNetGame->GetObjectPool();
if(unnamed_1015177C) {
unnamed_1015177C->FUNC_10012BD0();
}
}
if(unnamed_1014FFAC) {
unnamed_1014FFAC->FUNC_10012BD0();
}
_asm ret
}
//-----------------------------------------------------------
ENTITY_TYPE *_pRenderListEntity;
NUDE CRenderer__AddEntityToRenderList_Hook()
{
_asm push esi
_asm mov esi, [esp+8]
_asm mov _pRenderListEntity, esi
_asm pushad
// keep objects out of the render list once they are past their draw distance
if (pNetGame && _pRenderListEntity && _pRenderListEntity->vtable == 0x866F60 &&
(_pRenderListEntity->dwProcessingFlags & 0x80000000))
{
_pRenderNetObject = pNetGame->FUNC_10002E10()->FUNC_100129D0(_pRenderListEntity);
if (_pRenderNetObject && (_pRenderNetObject->field_118B != 0 ||
_pRenderNetObject->field_54 > 300.0f || _pRenderNetObject->field_1199 != 0))
{
_asm popad
_asm pop esi
_asm retn
}
}
if (GLOBAL_1014FFAC && _pRenderListEntity && _pRenderListEntity->vtable == 0x866F60 &&
(_pRenderListEntity->dwProcessingFlags & 0x80000000))
{
_pRenderNetObject = GLOBAL_1014FFAC->FUNC_100129D0(_pRenderListEntity);
if (_pRenderNetObject && (_pRenderNetObject->field_118B != 0 ||
_pRenderNetObject->field_54 > 300.0f))
{
_asm popad
_asm pop esi
_asm retn
}
}
_asm
{
popad
// original code
mov esi, _pRenderListEntity
movsx eax, word ptr [esi+22h]
mov edx, 0x5534B9
jmp edx
}
}
//-----------------------------------------------------------
NUDE CEntity__RenderEffects__RenderRoadsignAtomic_Hook()
{
__asm
{
mov eax, [esp+4] ;// arg0 (RpAtomic *)
test eax, eax
jz exitFn
mov eax, 0x6FF350 ;// CCustomRoadsignMgr::RenderRoadsignAtomic
jmp eax
exitFn:
ret
}
}
//-----------------------------------------------------------
DWORD dwEventDamageThis;
DWORD dwEventDamagePed;
NUDE CEventDamage__AffectsPed_Hook()
{
__asm
{
mov dwEventDamageThis, ecx
mov eax, [esp+4]
mov dwEventDamagePed, eax
pushad
cmp pNetGame, 0
jz do_affects_ped
call GamePool_FindPlayerPed
cmp dwEventDamagePed, eax
jnz do_affects_ped
mov eax, pbyteCurrentPlayer
movzx ecx, byte ptr [eax]
test ecx, ecx
jz do_affects_ped
popad
// inside a remote player context: always report the event as affecting the ped
xor eax, eax
mov al, 1
retn 4
do_affects_ped:
popad
sub esp, 0xC
push esi
mov esi, ecx
mov eax, 0x4B35A6 // CEventDamage::AffectsPed + 6
jmp eax
}
}
//-----------------------------------------------------------
// the game hands two 20 byte blocks (a position plus two more floats) to
// CCollision::BuildCacheOfCameraCollision
typedef struct _CAMCOL_POINT
{
VECTOR vecPos;
float field_C;
float field_10;
} CAMCOL_POINT;
CAMCOL_POINT _camColStart;
CAMCOL_POINT _camColEnd;
BYTE _byteCamColResult;
BYTE CCollision__BuildCacheOfCameraCollision_Hook(CAMCOL_POINT *pStart, CAMCOL_POINT *pEnd)
{
_camColStart = *pStart;
_camColEnd = *pEnd;
_byteCamColResult = 0;
__asm
{
push pEnd
push pStart
// call original CCollision::BuildCacheOfCameraCollision
mov edx, 0x41AC40
call edx
mov _byteCamColResult, al
pop edx
pop edx
}
// gta only caches collision inside the map bounds, so samp entities placed
// outside of them have to be checked by hand
if (pEnd->vecPos.X > 3000.0f || pEnd->vecPos.X < -3000.0f ||
pEnd->vecPos.Y > 3000.0f || pEnd->vecPos.Y < -3000.0f)
{
if (pNetGame && !_byteCamColResult &&
pNetGame->GetObjectPool()->FUNC_10012DE0(&_camColStart.vecPos, &_camColEnd.vecPos))
_byteCamColResult = 1;
if (unnamed_1014FFAC && !_byteCamColResult &&
unnamed_1014FFAC->FUNC_10012DE0(&_camColStart.vecPos, &_camColEnd.vecPos))
_byteCamColResult = 1;
if (pNetGame && !pNetGame->GetField232() && !_byteCamColResult &&
pNetGame->GetVehiclePool()->FUNC_1001EE20(&_camColStart.vecPos, &_camColEnd.vecPos))
_byteCamColResult = 1;
}
return _byteCamColResult;
}
//-----------------------------------------------------------
NUDE CCollision__CheckCameraCollisionVehicles_Hook()
{
__asm
{
pushad
cmp pNetGame, 0
jz do_check
mov eax, pNetGame
movzx ecx, byte ptr [eax+0x232] // pNetGame->field_232
test ecx, ecx
jz do_check
popad
xor eax, eax
retn
do_check:
popad
mov eax, 0x41A990 // CCollision::CheckCameraCollisionVehicles
jmp eax
}
}
//-----------------------------------------------------------
NUDE CWorld__CameraToIgnoreThisObject_Hook()
{
__asm
{
mov eax, [esp+4] // pEntity
test eax, eax
jz ignore_this_object
mov ecx, [eax+0xFC]
cmp ecx, 0
jnz ignore_this_object
mov edx, 0x563F40 // CWorld::CameraToIgnoreThisObject
jmp edx
ignore_this_object:
mov eax, 1
retn
}
}
//-----------------------------------------------------------
// shared by the four ProcessEntityCollision hooks below
DWORD dwCollisionThis;
DWORD dwCollisionEntity;
DWORD dwCollisionRetAddr;
NUDE CAutomobile__ProcessEntityCollision_Hook()
{
__asm
{
mov dwCollisionThis, ecx
mov edx, [esp]
mov dwCollisionRetAddr, edx
mov edx, [esp+4]
mov dwCollisionEntity, edx
pushad
cmp pNetGame, 0
jz process_collision
mov eax, pNetGame
movzx ecx, byte ptr [eax+0x232] // pNetGame->field_232
test ecx, ecx
jz process_collision
cmp dwCollisionThis, 0
jz process_collision
cmp dwCollisionEntity, 0
jz process_collision
mov edx, dwCollisionEntity
movzx eax, word ptr [edx+0x22] // entity.nModelIndex
cmp eax, 400
jl process_collision
mov ecx, dwCollisionEntity
movzx edx, word ptr [ecx+0x22]
cmp edx, 611 // only vehicle models pass
jg process_collision
mov eax, dwCollisionThis
cmp dword ptr [eax+0x460], 0 // pVehicle->pDriver
jz process_collision
mov ecx, dwCollisionEntity
cmp dword ptr [ecx+0x460], 0
jz process_collision
popad
// both vehicles are being driven, so don't collide them
mov eax, 0
retn 8
process_collision:
popad
mov edx, 0x6ACE70 // CAutomobile::ProcessEntityCollision
jmp edx
}
}
//-----------------------------------------------------------
NUDE CBike__ProcessEntityCollision_Hook()
{
__asm
{
mov dwCollisionThis, ecx
mov edx, [esp]
mov dwCollisionRetAddr, edx
mov edx, [esp+4]
mov dwCollisionEntity, edx
pushad
cmp pNetGame, 0
jz process_collision
mov eax, pNetGame
movzx ecx, byte ptr [eax+0x232] // pNetGame->field_232
test ecx, ecx
jz process_collision
cmp dwCollisionThis, 0
jz process_collision
cmp dwCollisionEntity, 0
jz process_collision
mov edx, dwCollisionEntity
movzx eax, word ptr [edx+0x22] // entity.nModelIndex
cmp eax, 400
jl process_collision
mov ecx, dwCollisionEntity
movzx edx, word ptr [ecx+0x22]
cmp edx, 611 // only vehicle models pass
jg process_collision
mov eax, dwCollisionThis
cmp dword ptr [eax+0x460], 0 // pVehicle->pDriver
jz process_collision
mov ecx, dwCollisionEntity
cmp dword ptr [ecx+0x460], 0
jz process_collision
popad
// both vehicles are being driven, so don't collide them
mov eax, 0
retn 8
process_collision:
popad
mov edx, 0x6BDEA0 // CBike::ProcessEntityCollision
jmp edx
}
}
//-----------------------------------------------------------
NUDE CMonsterTruck__ProcessEntityCollision_Hook()
{
__asm
{
mov dwCollisionThis, ecx
mov edx, [esp]
mov dwCollisionRetAddr, edx
mov edx, [esp+4]
mov dwCollisionEntity, edx
pushad
cmp pNetGame, 0
jz process_collision
mov eax, pNetGame
movzx ecx, byte ptr [eax+0x232] // pNetGame->field_232
test ecx, ecx
jz process_collision
cmp dwCollisionThis, 0
jz process_collision
cmp dwCollisionEntity, 0
jz process_collision
mov edx, dwCollisionEntity
movzx eax, word ptr [edx+0x22] // entity.nModelIndex
cmp eax, 400
jl process_collision
mov ecx, dwCollisionEntity
movzx edx, word ptr [ecx+0x22]
cmp edx, 611 // only vehicle models pass
jg process_collision
mov eax, dwCollisionThis
cmp dword ptr [eax+0x460], 0 // pVehicle->pDriver
jz process_collision
mov ecx, dwCollisionEntity
cmp dword ptr [ecx+0x460], 0
jz process_collision
popad
// both vehicles are being driven, so don't collide them
mov eax, 0
retn 8
process_collision:
popad
mov edx, 0x6C8AE0 // CMonsterTruck::ProcessEntityCollision
jmp edx
}
}
//-----------------------------------------------------------
NUDE CPhysical__ProcessEntityCollision_Hook()
{
__asm
{
mov dwCollisionThis, ecx
mov edx, [esp]
mov dwCollisionRetAddr, edx
mov edx, [esp+4]
mov dwCollisionEntity, edx
pushad
cmp pNetGame, 0
jz process_collision
mov eax, pNetGame
movzx ecx, byte ptr [eax+0x232] // pNetGame->field_232
test ecx, ecx
jz process_collision
cmp dwCollisionThis, 0
jz process_collision
cmp dwCollisionEntity, 0
jz process_collision
mov edx, dwCollisionEntity
movzx eax, word ptr [edx+0x22] // entity.nModelIndex
cmp eax, 400
jl process_collision
mov ecx, dwCollisionEntity
movzx edx, word ptr [ecx+0x22]
cmp edx, 611 // only vehicle models pass
jg process_collision
mov eax, dwCollisionThis
cmp dword ptr [eax+0x460], 0 // pVehicle->pDriver
jz process_collision
mov ecx, dwCollisionEntity
cmp dword ptr [ecx+0x460], 0
jz process_collision
popad
// both vehicles are being driven, so don't collide them
mov eax, 0
retn 8
process_collision:
popad
mov edx, 0x546D00 // CPhysical::ProcessEntityCollision
jmp edx
}
}
//-----------------------------------------------------------
NUDE CVehicle__UsesSiren_Hook()
{
__asm
{
// the streamed in check below already answered for this vehicle
mov eax, unnamed_1015180C
test eax, eax
jz usesSiren
mov unnamed_1015180C, 0
mov al, 1
retn
usesSiren:
mov unnamed_10151804, ecx
mov edx, 0x6D8470 // CVehicle::UsesSiren
call edx
mov unnamed_10151808, al
}
if(!unnamed_10151808)
{
_asm pushad
// the game doesn't know about server sided sirens, ask our own vehicle
if(pNetGame)
{
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
if(pVehiclePool)
{
unnamed_10113B2C = pVehiclePool->FUNC_1001EB90(unnamed_10151804);
if(unnamed_10113B2C != 0xFFFF)
{
CVehicle *pVehicle = (CVehicle *)pNetGame->GetVehiclePool()->FUNC_10001120(unnamed_10113B2C);
if(pVehicle->FUNC_100B8330()) unnamed_10151808 = 1;
}
}
}
_asm popad
}
_asm mov al, unnamed_10151808
_asm retn
}
//-----------------------------------------------------------
NUDE CAEWeatherAudioEntity__UpdateParameters_Hook()
{
_asm mov edx, [esp+4]
_asm mov unnamed_10151814, edx
_asm mov edx, [esp+8]
_asm mov unnamed_10151818, edx
unnamed_10151810 = *(DWORD *)0xB72914;
// mute the rain/wind audio while the outdoor ambience track is disabled
if(pGame)
{
CAudio *pAudio = pGame->m_pGameAudio;
if(pAudio->field_4) *(DWORD *)0xB72914 = 1;
}
_asm push unnamed_10151818
_asm push unnamed_10151814
_asm mov edx, 0x505A00
_asm call edx
*(DWORD *)0xB72914 = unnamed_10151810;
_asm ret 8
}
//-----------------------------------------------------------
NUDE CWorld__ProcessVerticalLine_Hook()
{
__asm
{
mov eax, [esp] ;// caller
mov unnamed_10151824, eax
cmp eax, 0x59E8F9
jz callFn
mov eax, [esp+0x14]
test eax, eax
jz callFn
mov byte ptr [esp+0x20], 1
callFn:
sub esp, 0x2C
mov eax, 0x407C37 ;// CWorld::ProcessVerticalLine
jmp eax
}
}
//-----------------------------------------------------------
NUDE CStreaming__RequestModel_Hook()
{
__asm
{
cmp ebp, 0 ;// model id
jl exitFn
push esi
push edi
lea edi, [ebp+ebp*4]
mov eax, 0x4087F0 ;// CStreaming::RequestModel
jmp eax
exitFn:
pop ebp
pop ebx
ret
}
}
//-----------------------------------------------------------
// todo: implement fully
ENTITY_TYPE* pFiringEntity = 0;
VECTOR* pPosn = 0;
VECTOR* pEffectPosn = 0;
ENTITY_TYPE* pTargetEntity = 0;
VECTOR* pTarget = 0;
VECTOR* pPosnForDriveBy = 0;
DWORD dwUnknown8 = 0;
DWORD dwAdditionalEffects = 0;
NUDE CWeapon__FireInstantHit_Hook()
{
__asm
{
mov eax, [esp+0x4]
mov pFiringEntity, eax
mov eax, [esp+0x8]
mov pPosn, eax
mov eax, [esp+0xC]
mov pEffectPosn, eax
mov eax, [esp+0x10]
mov pTargetEntity, eax
mov eax, [esp+0x14]
mov pTarget, eax
mov eax, [esp+0x18]
mov pPosnForDriveBy, eax
mov eax, [esp+0x1C]
mov dwUnknown8, eax
mov eax, [esp+0x20]
mov dwAdditionalEffects, eax
pushad
}
if(pFiringEntity != (ENTITY_TYPE*)GamePool_FindPlayerPed())
{
__asm
{
popad
retn 0x20
}
}
// todo: implement sub_10013C90
/*if ( pNetGame && pNetGame->m_pPools->pPlayerPool )
sub_10013C90();*/
_asm popad
_asm ret 0x20
}
//-----------------------------------------------------------
NUDE CWorld__ProcessLineOfSight_Hook()
{
// TODO: CWorld__ProcessLineOfSight_Hook
}
//-----------------------------------------------------------
ENTITY_TYPE* pSniperFiringEntity = 0;
NUDE CWeapon__FireSniper_Hook()
{
_asm mov eax, [esp+0x4]
_asm mov pSniperFiringEntity, eax
_asm pushad
if(pSniperFiringEntity != (ENTITY_TYPE*)GamePool_FindPlayerPed())
{
__asm
{
popad
retn 0xC
}
}
if(pGame && pGame->FindPlayerPed())
pGame->FindPlayerPed()->FUNC_100AFA70();
_asm popad
_asm ret 0xC
}
//-----------------------------------------------------------
// bullets get a 50x velocity so the shot lands on the frame it was fired
const float fBulletVelocityScale = 50.0f;
NUDE CBulletInfo__AddBullet_Hook()
{
__asm
{
push ebp
mov ebp, esp
fld dword ptr [ebp+0x1C]
fmul fBulletVelocityScale
fstp dword ptr [ebp+0x1C]
fld dword ptr [ebp+0x20]
fmul fBulletVelocityScale
fstp dword ptr [ebp+0x20]
fld dword ptr [ebp+0x24]
fmul fBulletVelocityScale
fstp dword ptr [ebp+0x24]
push dword ptr [ebp+0x24]
push dword ptr [ebp+0x20]
push dword ptr [ebp+0x1C]
push dword ptr [ebp+0x18]
push dword ptr [ebp+0x14]
push dword ptr [ebp+0x10]
push dword ptr [ebp+0xC]
push dword ptr [ebp+0x8]
mov edx, 0x736010 ;// CBulletInfo::AddBullet
call edx
add esp, 0x20
mov edx, 0x7360D0 ;// CBulletInfo::Update
call edx
pop ebp
retn
}
}
//-----------------------------------------------------------
// todo: implement sub_100A5240, it tells whether the damage came from a team mate
BOOL sub_100A5240(DWORD dwVehicle, DWORD dwInflictor, DWORD dwWeapon);
DWORD dwDamageInflictor = 0;
DWORD dwDamagedVehicle = 0;
DWORD dwDamageWeapon = 0;
BOOL bIgnoreVehicleDamage = 0;
DWORD dwInflictDamageRetAddr = 0;
NUDE CVehicle__InflictDamage_Hook()
{
_asm mov dwDamagedVehicle, ecx
_asm mov eax, [esp]
_asm mov dwInflictDamageRetAddr, eax
_asm mov eax, [esp+0x4]
_asm mov dwDamageInflictor, eax
_asm mov eax, [esp+0x8]
_asm mov dwDamageWeapon, eax
_asm pushad
bIgnoreVehicleDamage = sub_100A5240(dwDamagedVehicle, dwDamageInflictor, dwDamageWeapon);
_asm popad
if(bIgnoreVehicleDamage)
{
_asm xor eax, eax
_asm retn 0x18
}
if(iGtaVersion == 1)
{
_asm push 0xFFFFFFFF
_asm mov eax, 0x404CDC
_asm jmp eax
}
else
{
_asm push 0xFFFFFFFF
_asm mov eax, 0x404CE3
_asm jmp eax
}
}
//-----------------------------------------------------------
// fps-related hook
NUDE CTimer__GetCurrentTimeInCycles_Hook()
{
Sleep(1);
_asm mov edx, 0x561A80
_asm jmp edx
}
//-----------------------------------------------------------
DWORD dwRandCaller;
NUDE Rand_Hook()
{
_asm mov eax, [esp+0]
_asm mov dwRandCaller, eax
/*
if(dwRandCaller > 0x73FB10 && dwRandCaller < 0x74132E) {
_asm mov eax, iSyncedRandomNumber
_asm ret
}*/
rand();
_asm ret
}
//-----------------------------------------------------------
// We use a special bit (32) on dwProcFlags (+28) to indicate
// whether we should process gravity/collisions on this PlayerPed.
NUDE CPlayerPed_ProcessCollision_Hook()
{
_asm test ecx, ecx
_asm jnz ptr_is_ok
_asm ret
ptr_is_ok:
_asm mov eax, [ecx+28]
_asm shr eax, 31
_asm cmp eax, 1
_asm jne do_process_cols
_asm ret // we set top bit so don't process this
do_process_cols:
_asm mov edx, 0x54DFB0
_asm jmp edx
}
//-----------------------------------------------------------
DWORD dwMat;
DWORD dwMatEffects;
DWORD dwDataParam;
NUDE VehicleModel_SetEnvironmentMapHook()
{
_asm mov eax, [esp+4]
_asm mov dwMat, eax
_asm mov eax, [esp+8]
_asm mov dwDataParam, eax
UnFuck(0x6D64F0,1);
*(PBYTE)0x6D64F0 = 0xC3;
/*
_asm push dwMat
_asm mov edx, 0x812140 // _RpMatFXMaterialGetEffects
_asm call edx
_asm pop edx
_asm mov dwMatEffects, eax*/
_asm push 0
_asm push dwMat
_asm mov edx, 0x811C80 // _RpMatFXMaterialSetEffects
_asm call edx
_asm pop edx
_asm pop edx
//pChatWindow->AddDebugMessage("SetEnvironmentMapCB(0x%X,0x%X,%d)",dwMat,dwDataParam,dwMatEffects);
_asm mov edx, 0x4C8848
_asm cmp [esp+8], 0FFFFh
_asm jmp edx
}
//-----------------------------------------------------------
NUDE FUNC_100A5FF0()
{
_asm mov edx, 0x550F10
_asm call edx
_asm ret
}
//-----------------------------------------------------------
void InstallMethodHook( DWORD dwInstallAddress,
DWORD dwHookFunction )
{
DWORD oldProt, oldProt2;
VirtualProtect((LPVOID)dwInstallAddress,4,PAGE_EXECUTE_READWRITE,&oldProt);
*(PDWORD)dwInstallAddress = (DWORD)dwHookFunction;
VirtualProtect((LPVOID)dwInstallAddress,4,oldProt,&oldProt2);
}
//-----------------------------------------------------------
void InstallHook( DWORD dwInstallAddress,
DWORD dwHookFunction,
DWORD dwHookStorage,
BYTE * pbyteJmpCode,
int iJmpCodeSize )
{
DWORD oldProt, oldProt2;
// Install the pointer to procaddr.
VirtualProtect((PVOID)dwHookStorage,4,PAGE_EXECUTE_READWRITE,&oldProt);
*(PDWORD)dwHookStorage = (DWORD)dwHookFunction;
VirtualProtect((PVOID)dwHookStorage,4,oldProt,&oldProt2);
// Install the Jmp code.
VirtualProtect((PVOID)dwInstallAddress,iJmpCodeSize,PAGE_EXECUTE_READWRITE,&oldProt);
memcpy((PVOID)dwInstallAddress,pbyteJmpCode,iJmpCodeSize);
VirtualProtect((PVOID)dwInstallAddress,iJmpCodeSize,oldProt,&oldProt2);
}
//-----------------------------------------------------------
void InstallCallHook(DWORD dwInstallAddress, DWORD dwHookFunction, BYTE byteJumpCode = 0xE8)
{
DWORD oldProt, oldProt2;
DWORD disp = dwHookFunction - (dwInstallAddress + 5);
VirtualProtect((LPVOID)dwInstallAddress,5,PAGE_EXECUTE_READWRITE,&oldProt);
*(PBYTE)(dwInstallAddress) = byteJumpCode;
*(PDWORD)(dwInstallAddress+1) = (DWORD)disp;
VirtualProtect((LPVOID)dwInstallAddress,5,oldProt,&oldProt2);
}
//-----------------------------------------------------------
void InstallGameAndGraphicsLoopHooks()
{
UnFuck(0x53EB13,4);
*(int *)0x53EB13 = dwGraphicsLoop - 0x53EB12 - 5; // relative addr
InstallCallHook(0x58FC53,(DWORD)CHud__DrawRadar_Hook);
InstallCallHook(0x58FBBF,(DWORD)CHud__DrawCrossHairs_Hook);
InstallCallHook(0x53C104,(DWORD)CCamera__Process_Hook);
InstallCallHook(0x53E981,(DWORD)CGame__Process_Hook);
// For fixing fogging issues (needed for both debug and net)
InstallMethodHook(0x86D1B0,(DWORD)CPed_Render_Hook); // This is PlayerPed
InstallMethodHook(0x86C0F0,(DWORD)CPed_Render_Hook);
InstallMethodHook(0x86C168,(DWORD)CPed_Render_Hook);
InstallMethodHook(0x86C248,(DWORD)CPed_Render_Hook);
InstallMethodHook(0x86C3A0,(DWORD)CPed_Render_Hook);
InstallCallHook(0x53E930,(DWORD)CTimer__GetCurrentTimeInCycles_Hook);
}
//-----------------------------------------------------------
void GameInstallHooks()
{
InstallGameAndGraphicsLoopHooks();
InstallHook(0x4D3AA0,(DWORD)CAnimManager__AddAnimation_Hook,0x4D3934,CAnimManager__AddAnimation_Hook_HookJmpCode,sizeof(CAnimManager__AddAnimation_Hook_HookJmpCode));
InstallHook(0x4D4610,(DWORD)CAnimManager__BlendAnimation_Hook,0x4D4609,CAnimManager__BlendAnimation_HookJmpCode,sizeof(CAnimManager__BlendAnimation_HookJmpCode));
InstallMethodHook(0x86D190,(DWORD)CPlayerPed_ProcessControl_Hook);
InstallMethodHook(0x86C0D0,(DWORD)CCivillianPed__ProcessControl_Hook);
InstallMethodHook(0x86D744,(DWORD)TaskUseGun_Hook);
InstallCallHook(0x7330A2,(DWORD)WeaponRender__GetWeaponSkill_Hook);
InstallMethodHook(0x86D194,(DWORD)CPlayerPed_ProcessCollision_Hook);
InstallCallHook(0x5689FD,(DWORD)CWorld__ProcessAttachedEntities_Hook);
InstallCallHook(0x53EA03,(DWORD)CWorld__ProcessPedsAfterPreRender_Hook);
InstallMethodHook(0x871148,(DWORD)AllVehicles_ProcessControl_Hook); // Automobile
InstallMethodHook(0x8721C8,(DWORD)AllVehicles_ProcessControl_Hook); // boat
InstallMethodHook(0x871388,(DWORD)AllVehicles_ProcessControl_Hook); // motorbike1
InstallMethodHook(0x871970,(DWORD)AllVehicles_ProcessControl_Hook); // plane
InstallMethodHook(0x8716A8,(DWORD)AllVehicles_ProcessControl_Hook); // heli
InstallMethodHook(0x871550,(DWORD)AllVehicles_ProcessControl_Hook); // pushbike
InstallMethodHook(0x871800,(DWORD)AllVehicles_ProcessControl_Hook); // truck
InstallMethodHook(0x871B10,(DWORD)AllVehicles_ProcessControl_Hook); // quad
InstallMethodHook(0x872398,(DWORD)AllVehicles_ProcessControl_Hook); // train
InstallMethodHook(0x871C50,(DWORD)AllVehicles_ProcessControl_Hook);
InstallCallHook(0x501B1D,(DWORD)VehicleHorn_Hook);
InstallCallHook(0x501B42,(DWORD)VehicleHorn_Hook);
InstallCallHook(0x501FC2,(DWORD)VehicleHorn_Hook);
InstallCallHook(0x502067,(DWORD)VehicleHorn_Hook);
InstallCallHook(0x5021AE,(DWORD)VehicleHorn_Hook);
// Radar and map hooks for gang zones
InstallCallHook(0x5869BF,(DWORD)ZoneOverlay_Hook);
InstallCallHook(0x5759E4,(DWORD)ZoneOverlay_Hook);
InstallCallHook(0x609A4E,(DWORD)PlayerWalk_Hook);
InstallCallHook(0x4579C6,(DWORD)PickUpPickup_Hook, 0xE9);
InstallCallHook(0x73C252,(DWORD)CWeapon_FireCamera_Hook, 0xE9);
// Hook the call to CCamera::CamShake when called for sniper fire
InstallCallHook(0x73ACE2,(DWORD)CCameraCamShake_Sniper_Hook);
// Hook the train derailment code
InstallCallHook(0x6F8CF8,(DWORD)CTrain_ProcessControl_Derailment);
InstallHook(0x6402F0,(DWORD)TaskEnterVehicleDriver_Hook,
0x6919BB,TaskEnterVehicleDriver_HookJmpCode,sizeof(TaskEnterVehicleDriver_HookJmpCode));
InstallHook(0x63B8C0,(DWORD)TaskExitVehicle,
0x63B8BA,TaskExitVehicle_HookJmpCode,sizeof(TaskExitVehicle_HookJmpCode));
InstallHook(0x438576,(DWORD)CheatProcessorHook,
0x4385AA,CheatProcessHook_JmpCode,sizeof(CheatProcessHook_JmpCode));
InstallHook(0x584770,(DWORD)RadarTranslateColor,0x584A79,
RadarTranslateColor_HookJmpCode,sizeof(RadarTranslateColor_HookJmpCode));
InstallHook(0x53C900,(DWORD)CGameShutdownHook,0x53C8F1,
CGameShutdown_HookJmpCode,sizeof(CGameShutdown_HookJmpCode));
InstallHook(0x4B5AC0,(DWORD)PedDamage_Hook,0x4B5ABC,
PedDamage_HookJmpCode,sizeof(PedDamage_HookJmpCode));
// Fix for 0x004D41C5 crash
InstallCallHook(0x4D41C0, (DWORD)AnimCrashFixHook, 0xE9);
InstallCallHook(0x4E7427,(DWORD)PoliceScannerAudio_FindPlayerPed_Hook);
// Fix for crash when the player who threw the satchel died
InstallHook(0x738F3A, (DWORD)CProjectile_Update_Hook, 0x738B1B, CProjectileInfo_Update_HookJmpCode, sizeof(CProjectileInfo_Update_HookJmpCode));
// Fix for all satchels blowing up when someone activated their satchel
InstallHook(0x738877, (DWORD)CWeapon__Satchel__Activate_Hook, 0x73885B, CWeapon__Satchel__Activate_HookJmpCode, sizeof(CWeapon__Satchel__Activate_HookJmpCode));
InstallHook(0x6A0050, (DWORD)GetText_Hook, 0x6A0043, GetText_HookJmpCode, sizeof (GetText_HookJmpCode));
InstallCallHook(0x6FDED6,(DWORD)CCustomCarPlateMgr__CreatePlateTexture__RwRasterCreate_Hook);
if(iGtaVersion == GTASA_VERSION_USA10)
{
InstallHook(0x7FB020,(DWORD)RwRasterDestroy_Hook,0x59C721,RwRasterDestroy_HookJmpCode,sizeof(RwRasterDestroy_HookJmpCode));
unnamed_101516D4 = 0x7FB026;
}
else
{
InstallHook(0x7FB060,(DWORD)RwRasterDestroy_Hook,0x59C721,RwRasterDestroy_HookJmpCode,sizeof(RwRasterDestroy_HookJmpCode));
unnamed_101516D4 = 0x7FB066;
}
InstallCallHook(0x6D0E7E,(DWORD)CVehicle__Render_Hook);
InstallMethodHook(0x866FA8,(DWORD)CObject__Render_Hook);
InstallCallHook(0x586C0A,(DWORD)CRadar__DrawMap__FindPlayerSpeed_Hook);
InstallHook(0x538090,(DWORD)CFileLoader__LoadObjectInstance_Hook,0x538084,CFileLoader__LoadObjectInstance_HookJmpCode,sizeof(CFileLoader__LoadObjectInstance_HookJmpCode));
InstallCallHook(0x718599,(DWORD)CEscalator__Update_Hook);
InstallMethodHook(0x866F7C,(DWORD)CObject__CreateRwObject_Hook);
InstallMethodHook(0x866F80,(DWORD)CEntity__DeleteRwObject_Hook);
InstallMethodHook(0x8585E8,(DWORD)CEntity__DeleteRwObject_Hook);
InstallMethodHook(0x871218,(DWORD)CAutomobile__BreakTowLink_Hook);
InstallMethodHook(0x871778,(DWORD)CAutomobile__BreakTowLink_Hook);
InstallMethodHook(0x8718D0,(DWORD)CAutomobile__BreakTowLink_Hook);
InstallMethodHook(0x871A40,(DWORD)CAutomobile__BreakTowLink_Hook);
InstallMethodHook(0x871BE0,(DWORD)CAutomobile__BreakTowLink_Hook);
InstallCallHook(0x5648D3,(DWORD)CWorld__ProcessAttachedEntities__PositionAttachedEntity_Hook);
InstallCallHook(0x53DFDD,(DWORD)CRenderer__RenderEverythingBarRoads_Hook);
InstallCallHook(0x53E019,(DWORD)CRenderer__RenderFadingInEntities_Hook);
InstallHook(0x5534B0,(DWORD)CRenderer__AddEntityToRenderList_Hook,0x5534A6,CRenderer__AddEntityToRenderList_HookJmpCode,sizeof(CRenderer__AddEntityToRenderList_HookJmpCode));
InstallCallHook(0x5342F9,(DWORD)CEntity__RenderEffects__RenderRoadsignAtomic_Hook);
InstallHook(0x4B35A0,(DWORD)CEventDamage__AffectsPed_Hook,0x4B3433,CEventDamage__AffectsPed_HookJmpCode,sizeof(CEventDamage__AffectsPed_HookJmpCode));
InstallCallHook(0x41B02E,(DWORD)CCollision__BuildCacheOfCameraCollision_Hook);
InstallCallHook(0x41AF80,(DWORD)CCollision__CheckCameraCollisionVehicles_Hook);
InstallCallHook(0x41AB78,(DWORD)CWorld__CameraToIgnoreThisObject_Hook);
InstallMethodHook(0x871178,(DWORD)CAutomobile__ProcessEntityCollision_Hook);
InstallMethodHook(0x8716D8,(DWORD)CAutomobile__ProcessEntityCollision_Hook);
InstallMethodHook(0x8719A0,(DWORD)CAutomobile__ProcessEntityCollision_Hook);
InstallMethodHook(0x871B40,(DWORD)CAutomobile__ProcessEntityCollision_Hook);
InstallMethodHook(0x8713B8,(DWORD)CBike__ProcessEntityCollision_Hook);
InstallMethodHook(0x871580,(DWORD)CBike__ProcessEntityCollision_Hook);
InstallMethodHook(0x871830,(DWORD)CMonsterTruck__ProcessEntityCollision_Hook);
InstallMethodHook(0x8721F8,(DWORD)CPhysical__ProcessEntityCollision_Hook);
InstallCallHook(0x6E0954,(DWORD)CVehicle__UsesSiren_Hook);
InstallCallHook(0x6B2BCB,(DWORD)CVehicle__UsesSiren_Hook);
InstallCallHook(0x4F77DA,(DWORD)CVehicle__UsesSiren_Hook);
InstallMethodHook(0x872A74,(DWORD)CAEWeatherAudioEntity__UpdateParameters_Hook);
InstallHook(0x5674E0,(DWORD)CWorld__ProcessVerticalLine_Hook,0x5674DB,CWorld__ProcessVerticalLine_HookJmpCode,sizeof(CWorld__ProcessVerticalLine_HookJmpCode));
}
//-----------------------------------------------------------
void InstallModelInfoHackHooks()
{
InstallHook(0x4087EA,(DWORD)CStreaming__RequestModel_Hook,0x4087D7,CStreaming__RequestModel_HookJmpCode,sizeof(CStreaming__RequestModel_HookJmpCode));
}
//-----------------------------------------------------------
void InstallShotSyncHooks()
{
InstallCallHook(0x742495,(DWORD)CWeapon__FireInstantHit_Hook);
InstallCallHook(0x7424EC,(DWORD)CWeapon__FireInstantHit_Hook);
InstallCallHook(0x742548,(DWORD)CWeapon__FireInstantHit_Hook);
InstallCallHook(0x740721,(DWORD)CWorld__ProcessLineOfSight_Hook);
InstallCallHook(0x740B69,(DWORD)CWorld__ProcessLineOfSight_Hook);
InstallCallHook(0x736247,(DWORD)CWorld__ProcessLineOfSight_Hook);
InstallCallHook(0x7424CB,(DWORD)CWeapon__FireSniper_Hook);
InstallCallHook(0x73AC4B,(DWORD)CBulletInfo__AddBullet_Hook);
}
//-----------------------------------------------------------
void InstallVehicleFriendyFireHooks()
{
InstallCallHook(0x6D7C90,(DWORD)CVehicle__InflictDamage_Hook,0xE9);
}
//-----------------------------------------------------------