diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 631b7b329f..db7c7df1dd 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -222,6 +222,7 @@ CGameSA::CGameSA() CFxSystemSA::StaticSetHooks(); CFileLoaderSA::StaticSetHooks(); D3DResourceSystemSA::StaticSetHooks(); + CVehicleSA::StaticSetHooks(); } CGameSA::~CGameSA() @@ -603,6 +604,9 @@ bool CGameSA::IsCheatEnabled(const char* szCheatName) if (!strcmp(szCheatName, PROP_UNDERWORLD_WARP)) return IsUnderWorldWarpEnabled(); + if (!strcmp(szCheatName, PROP_VEHICLE_SUNGLARE)) + return IsVehicleSunGlareEnabled(); + std::map::iterator it = m_Cheats.find(szCheatName); if (it == m_Cheats.end()) return false; @@ -635,6 +639,12 @@ bool CGameSA::SetCheatEnabled(const char* szCheatName, bool bEnable) return true; } + if (!strcmp(szCheatName, PROP_VEHICLE_SUNGLARE)) + { + SetVehicleSunGlareEnabled(bEnable); + return true; + } + std::map::iterator it = m_Cheats.find(szCheatName); if (it == m_Cheats.end()) return false; @@ -724,6 +734,17 @@ void CGameSA::SetJetpackWeaponEnabled(eWeaponType weaponType, bool bEnabled) } } +void CGameSA::SetVehicleSunGlareEnabled(bool bEnabled) +{ + // State turning will be handled in hooks handler + CVehicleSA::SetVehiclesSunGlareEnable(bEnabled); +} + +bool CGameSA::IsVehicleSunGlareEnabled() +{ + return CVehicleSA::GetVehiclesSunGlareEnable(); +} + bool CGameSA::PerformChecks() { std::map::iterator it; diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index a3016a5aac..bc2a6dc615 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -85,6 +85,8 @@ extern unsigned int OBJECTDYNAMICINFO_MAX; // default: 160 #define PROP_SNIPER_MOON "snipermoon" #define PROP_EXTRA_AIR_RESISTANCE "extraairresistance" #define PROP_UNDERWORLD_WARP "underworldwarp" +#define PROP_VEHICLE_SUNGLARE "vehiclesunglare" + struct SCheatSA { @@ -391,6 +393,9 @@ class CGameSA : public CGame void SetJetpackWeaponEnabled(eWeaponType weaponType, bool bEnabled); bool GetJetpackWeaponEnabled(eWeaponType weaponType); + void SetVehicleSunGlareEnabled(bool bEnabled); + bool IsVehicleSunGlareEnabled(); + unsigned long GetMinuteDuration(); void SetMinuteDuration(unsigned long ulTime); diff --git a/Client/game_sa/CVehicleSA.cpp b/Client/game_sa/CVehicleSA.cpp index 16f454ae51..d371f3db2f 100644 --- a/Client/game_sa/CVehicleSA.cpp +++ b/Client/game_sa/CVehicleSA.cpp @@ -16,6 +16,30 @@ bool g_bVehiclePointerInvalid = false; #include "gamesa_renderware.h" +static BOOL m_bVehicleSunGlare = false; +_declspec(naked) void DoVehicleSunGlare(void* this_) +{ + _asm { + mov eax, FUNC_CVehicle_DoSunGlare + jmp eax + } +} + +void _declspec(naked) HOOK_Vehicle_PreRender(void) +{ + _asm { + mov ecx, m_bVehicleSunGlare + cmp ecx, 0 + jle noglare + mov ecx, esi + call DoVehicleSunGlare + noglare: + mov [esp+0D4h], edi + push 6ABD04h + retn + } +} + namespace { bool ClumpDumpCB(RpAtomic* pAtomic, void* data) @@ -2318,6 +2342,22 @@ void CVehicleSA::OnChangingPosition(const CVector& vecNewPosition) } } +void CVehicleSA::StaticSetHooks() +{ + // Setup vehicle sun glare hook + HookInstall(FUNC_CAutomobile_OnVehiclePreRender, (DWORD)HOOK_Vehicle_PreRender, 5); +} + +void CVehicleSA::SetVehiclesSunGlareEnable(bool bEnabled) +{ + m_bVehicleSunGlare = bEnabled; +} + +bool CVehicleSA::GetVehiclesSunGlareEnable() +{ + return m_bVehicleSunGlare; +} + namespace { VOID _MatrixConvertFromEulerAngles(CMatrix_Padded* matrixPadded, float fX, float fY, float fZ) diff --git a/Client/game_sa/CVehicleSA.h b/Client/game_sa/CVehicleSA.h index 0612e10a34..70ffd3df69 100644 --- a/Client/game_sa/CVehicleSA.h +++ b/Client/game_sa/CVehicleSA.h @@ -164,6 +164,10 @@ class CVehicleSA; #define VAR_CVehicle_Variation1 0x8A6458 #define VAR_CVehicle_Variation2 0x8A6459 +// for vehicle sun glare +#define FUNC_CAutomobile_OnVehiclePreRender 0x6ABCFD +#define FUNC_CVehicle_DoSunGlare 0x6DD6F0 + struct SRailNodeSA { short sX; // x coordinate times 8 @@ -769,6 +773,10 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA CVector* GetDummyPositions() { return m_dummyPositions.data(); } const CVector* GetDummyPositions() const override { return m_dummyPositions.data(); } + static void StaticSetHooks(); + static void SetVehiclesSunGlareEnable(bool bEnabled); + static bool GetVehiclesSunGlareEnable(); + private: static void SetAutomobileDummyPosition(CAutomobileSAInterface* automobile, eVehicleDummies dummy, const CVector& position);