diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 0542499f902..0e212090941 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -581,6 +581,9 @@ bool CGameSA::IsCheatEnabled(const char* szCheatName) if (!strcmp(szCheatName, PROP_EXTRA_AIR_RESISTANCE)) return IsExtraAirResistanceEnabled(); + if (!strcmp(szCheatName, PROP_UNDERWORLD_WARP)) + return IsUnderWorldWarpEnabled(); + std::map::iterator it = m_Cheats.find(szCheatName); if (it == m_Cheats.end()) return false; @@ -607,6 +610,12 @@ bool CGameSA::SetCheatEnabled(const char* szCheatName, bool bEnable) return true; } + if (!strcmp(szCheatName, PROP_UNDERWORLD_WARP)) + { + SetUnderWorldWarpEnabled(bEnable); + return true; + } + std::map::iterator it = m_Cheats.find(szCheatName); if (it == m_Cheats.end()) return false; @@ -622,6 +631,7 @@ void CGameSA::ResetCheats() SetRandomFoliageEnabled(true); SetMoonEasterEggEnabled(false); SetExtraAirResistanceEnabled(true); + SetUnderWorldWarpEnabled(true); std::map::iterator it; for (it = m_Cheats.begin(); it != m_Cheats.end(); it++) @@ -668,6 +678,16 @@ void CGameSA::SetExtraAirResistanceEnabled(bool bEnable) MemPut(0x72DDD9, bEnable ? 0x01 : 0x00); } +void CGameSA::SetUnderWorldWarpEnabled(bool bEnable) +{ + m_bUnderworldWarp = !bEnable; +} + +bool CGameSA::IsUnderWorldWarpEnabled() +{ + return !m_bUnderworldWarp; +} + bool CGameSA::GetJetpackWeaponEnabled(eWeaponType weaponType) { if (weaponType >= WEAPONTYPE_BRASSKNUCKLE && weaponType < WEAPONTYPE_LAST_WEAPONTYPE) diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index ffba31a4936..36424aa8278 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -83,6 +83,7 @@ #define PROP_RANDOM_FOLIAGE "randomfoliage" #define PROP_SNIPER_MOON "snipermoon" #define PROP_EXTRA_AIR_RESISTANCE "extraairresistance" +#define PROP_UNDERWORLD_WARP "underworldwarp" struct SCheatSA { @@ -399,6 +400,9 @@ class CGameSA : public CGame bool IsExtraAirResistanceEnabled(); void SetExtraAirResistanceEnabled(bool bEnable); + bool IsUnderWorldWarpEnabled(); + void SetUnderWorldWarpEnabled(bool bEnable); + bool VerifySADataFileNames(); bool PerformChecks(); int& GetCheckStatus(void) { return m_iCheckStatus; } @@ -489,6 +493,7 @@ class CGameSA : public CGame bool m_bAsyncScriptForced; bool m_bASyncLoadingSuspended; int m_iCheckStatus; + bool m_bUnderworldWarp; static unsigned long* VAR_SystemTime; static unsigned long* VAR_IsAtMenu; diff --git a/Client/game_sa/CWorldSA.cpp b/Client/game_sa/CWorldSA.cpp index 224e585a1d6..f21bd650097 100644 --- a/Client/game_sa/CWorldSA.cpp +++ b/Client/game_sa/CWorldSA.cpp @@ -15,6 +15,63 @@ CWorldSA::CWorldSA() m_pBuildingRemovals = new std::multimap; m_pDataBuildings = new std::multimap; m_pBinaryBuildings = new std::multimap; + + InstallHooks(); +} + +void HOOK_FallenPeds(); +void HOOK_FallenCars(); + +void CWorldSA::InstallHooks(void) +{ + HookInstall(0x565CB0, (DWORD)HOOK_FallenPeds, 5); + HookInstall(0x565E80, (DWORD)HOOK_FallenCars, 5); +} + +DWORD CONTINUE_CWorld_FallenPeds = 0x00565CBA; +DWORD CONTINUE_CWorld_FallenCars = 0x00565E8A; + +void _declspec(naked) HOOK_FallenPeds() +{ + if (pGame && pGame->IsUnderWorldWarpEnabled()) + { + _asm + { + sub esp, 2Ch + push ebx + mov ebx, ds:0B74490h + jmp CONTINUE_CWorld_FallenPeds + } + } + else + { + _asm + { + ret + } + } +} + + +void _declspec(naked) HOOK_FallenCars() +{ + if (pGame && !pGame->IsUnderWorldWarpEnabled()) + { + _asm + { + sub esp, 2Ch + push ebx + mov ebx, ds:0B74494h + jmp CONTINUE_CWorld_FallenCars + } + } + else + { + _asm + { + ret + } + } } void CWorldSA::Add(CEntity* pEntity, eDebugCaller CallerId) @@ -1298,4 +1355,4 @@ bool CWorldSA::CalculateImpactPosition(const CVector& vecInputStart, CVector& ve // Include dead peds MemPutFast(0xB7CD71, 0); return false; -} \ No newline at end of file +} diff --git a/Client/game_sa/CWorldSA.h b/Client/game_sa/CWorldSA.h index eac88247187..bc2a44fe262 100644 --- a/Client/game_sa/CWorldSA.h +++ b/Client/game_sa/CWorldSA.h @@ -55,6 +55,7 @@ class CWorldSA : public CWorld { public: CWorldSA(); + void InstallHooks(void); void Add(CEntity* entity, eDebugCaller CallerId); void Add(CEntitySAInterface* entityInterface, eDebugCaller CallerId); void Remove(CEntity* entity, eDebugCaller CallerId);