diff --git a/Client/core/CModelCacheManager.h b/Client/core/CModelCacheManager.h index 693a334d922..2134b51008c 100644 --- a/Client/core/CModelCacheManager.h +++ b/Client/core/CModelCacheManager.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * * Multi Theft Auto is available from http://www.multitheftauto.com/ diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index e65437ecda3..06bedb79d64 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -300,24 +300,18 @@ bool CGameSA::IsInForeground() return *VAR_IsForegroundWindow; } -CModelInfo* CGameSA::GetModelInfo(DWORD dwModelID) +CModelInfo* CGameSA::GetModelInfo(DWORD dwModelID, bool bCanBeInvalid) { - DEBUG_TRACE("CModelInfo * CGameSA::GetModelInfo(DWORD dwModelID )"); + DEBUG_TRACE("CModelInfo * CGameSA::GetModelInfo(DWORD dwModelID, bool bCanBeInvalid)"); if (dwModelID < MODELINFO_MAX) { - if (ModelInfo[dwModelID].IsValid()) + if (ModelInfo[dwModelID].IsValid() || bCanBeInvalid) { return &ModelInfo[dwModelID]; } - else - { - return NULL; - } - } - else - { - return NULL; + return nullptr; } + return nullptr; } /** diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index 592c0fa3285..a07092f4758 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -1,518 +1,518 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto v1.0 - * LICENSE: See LICENSE in the top level directory - * FILE: game_sa/CGameSA.h - * PURPOSE: Header file for base game logic handling class - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#pragma once - -#include "CModelInfoSA.h" -#include "CObjectGroupPhysicalPropertiesSA.h" -#include "CFxManagerSA.h" - -#define MAX_MEMORY_OFFSET_1_0 0xCAF008 - -#define CLASS_CPlayerInfo 0xB7CD98 // ##SA## -#define CLASS_CCamera 0xB6F028 // ##SA## -#define CLASS_CPad 0xB73458 // ##SA## -#define CLASS_CGarages 0x96C048 // ##SA## -#define CLASS_CFx 0xa9ae00 // ##SA## -#define CLASS_CFxManager 0xA9AE80 // ##SA## -#define CLASS_CMenuManager 0xBA6748 // ##SA## - -#define CLASS_RwCamera 0xB6F97C - -#define ARRAY_WeaponInfo 0xC8AAB8 // ##SA## -#define CLASSSIZE_WeaponInfo 112 // ##SA## -#define NUM_WeaponInfosStdSkill WEAPONTYPE_LAST_WEAPONTYPE -#define NUM_WeaponInfosOtherSkill 11 -#define NUM_WeaponInfosTotal (NUM_WeaponInfosStdSkill + (3*NUM_WeaponInfosOtherSkill)) // std, (poor, pro, special) - -#define MODELINFO_MAX 26000 // Actual max is 25755 -#define OBJECTDYNAMICINFO_MAX 160 - -#define FUNC_GetLevelFromPosition 0x4DD300 - -#define FUNC_CDebug_DebugDisplayTextBuffer 0x532260 -#define FUNC_JPegCompressScreenToFile 0x5D0820 - -#define VAR_FlyingCarsEnabled 0x969160 // ##SA## -#define VAR_ExtraBunnyhopEnabled 0x969161 // ##SA## -#define VAR_HoveringCarsEnabled 0x969152 // ##SA## -#define VAR_ExtraJumpEnabled 0x96916C // ##SA## -#define VAR_TankModeEnabled 0x969164 // ##SA## -#define VAR_NoReloadEnabled 0x969178 // ##SA## -#define VAR_PerfectHandling 0x96914C // ##SA## -#define VAR_AllCarsHaveNitro 0x969165 // ##SA## -#define VAR_BoatsCanFly 0x969153 // ##SA## -#define VAR_InfiniteOxygen 0x96916E // ##SA## -#define VAR_FasterClock 0x96913B // ##SA## -#define VAR_FasterGameplay 0x96913C // ##SA## -#define VAR_SlowerGameplay 0x96913D // ##SA## -#define VAR_AlwaysMidnight 0x969167 // ##SA## -#define VAR_FullWeaponAiming 0x969179 // ##SA## -#define VAR_InfiniteHealth 0x96916D // ##SA## -#define VAR_NeverWanted 0x969171 // ##SA## -#define VAR_HealthArmorMoney 0x969133 // ##SA## -#define VAR_WalkUnderwater 0x6C2759 - -#define CHEAT_HOVERINGCARS "hovercars" -#define CHEAT_FLYINGCARS "aircars" -#define CHEAT_EXTRABUNNYHOP "extrabunny" -#define CHEAT_EXTRAJUMP "extrajump" -#define CHEAT_TANKMODE "tankmode" -#define CHEAT_NORELOAD "noreload" -#define CHEAT_PERFECTHANDLING "perfecthandling" -#define CHEAT_ALLCARSHAVENITRO "allcarshavenitro" -#define CHEAT_BOATSCANFLY "airboats" -#define CHEAT_INFINITEOXYGEN "infiniteoxygen" -#define CHEAT_WALKUNDERWATER "walkunderwater" -#define CHEAT_FASTERCLOCK "fasterclock" -#define CHEAT_FASTERGAMEPLAY "fastergameplay" -#define CHEAT_SLOWERGAMEPLAY "slowergameplay" -#define CHEAT_ALWAYSMIDNIGHT "alwaysmidnight" -#define CHEAT_FULLWEAPONAIMING "fullweaponaiming" -#define CHEAT_INFINITEHEALTH "infinitehealth" -#define CHEAT_NEVERWANTED "neverwanted" -#define CHEAT_HEALTARMORMONEY "healtharmormoney" - -#define PROP_RANDOM_FOLIAGE "randomfoliage" -#define PROP_SNIPER_MOON "snipermoon" -#define PROP_EXTRA_AIR_RESISTANCE "extraairresistance" -#define PROP_UNDERWORLD_WARP "underworldwarp" - -struct SCheatSA -{ - BYTE* m_byAddress; // Cheat Address - bool m_bEnabled; // Cheat State - bool m_bCanBeSet; // Cheat can be set with setWorldSpecialPropertyEnabled - SCheatSA(BYTE* Address, bool bCanBeSet = true) - { - m_byAddress = Address; - m_bCanBeSet = bCanBeSet; - } -}; -class CGameSA : public CGame -{ - friend class COffsets; - typedef std::unique_ptr AssocGroup_type; - -private: - CWeaponInfo* WeaponInfos[NUM_WeaponInfosTotal]; - CModelInfoSA ModelInfo[MODELINFO_MAX]; - CObjectGroupPhysicalPropertiesSA ObjectGroupsInfo[OBJECTDYNAMICINFO_MAX]; - -public: - ZERO_ON_NEW - - CGameSA(); // constructor - ~CGameSA(); - - CPools* GetPools() - { - DEBUG_TRACE("CPools * GetPools()"); - return m_pPools; - }; - CPlayerInfo* GetPlayerInfo() - { - DEBUG_TRACE("CPlayerInfo * GetPlayerInfo()"); - return m_pPlayerInfo; - }; - CProjectileInfo* GetProjectileInfo() - { - DEBUG_TRACE("CProjectileInfo * GetProjectileInfo()"); - return m_pProjectileInfo; - }; - CRadar* GetRadar() - { - DEBUG_TRACE("CRadar * GetRadar()"); - return m_pRadar; - }; - CRestart* GetRestart() - { - DEBUG_TRACE("CRestart * GetRestart()"); - return m_pRestart; - }; - CClock* GetClock() - { - DEBUG_TRACE("CClock * GetClock()"); - return m_pClock; - }; - CCoronas* GetCoronas() - { - DEBUG_TRACE("CCoronas * GetCoronas()"); - return m_pCoronas; - }; - CCheckpoints* GetCheckpoints() - { - DEBUG_TRACE("CCheckpoints * GetCheckpoints()"); - return m_pCheckpoints; - }; - CEventList* GetEventList() - { - DEBUG_TRACE("CEventList * GetEventList()"); - return m_pEventList; - }; - CFireManager* GetFireManager() - { - DEBUG_TRACE("CFireManager * GetFireManager()"); - return m_pFireManager; - }; - CExplosionManager* GetExplosionManager() - { - DEBUG_TRACE("CExplosionManager * GetExplosionManager()"); - return m_pExplosionManager; - }; - CGarages* GetGarages() - { - DEBUG_TRACE("CGarages * GetGarages()"); - return m_pGarages; - }; - CHud* GetHud() - { - DEBUG_TRACE("CHud * GetHud()"); - return m_pHud; - }; - CWeather* GetWeather() - { - DEBUG_TRACE("CWeather * GetWeather()"); - return m_pWeather; - }; - CWorld* GetWorld() - { - DEBUG_TRACE("CWorld * GetWorld()"); - return m_pWorld; - }; - CCamera* GetCamera() - { - DEBUG_TRACE("CCamera * GetCamera()"); - return m_pCamera; - }; - CPickups* GetPickups() - { - DEBUG_TRACE("CPickups * GetPickups()"); - return m_pPickups; - }; - C3DMarkers* Get3DMarkers() - { - DEBUG_TRACE("C3DMarkers * Get3DMarkers()"); - return m_p3DMarkers; - }; - CPad* GetPad() - { - DEBUG_TRACE("CPad * GetPad()"); - return m_pPad; - }; - CTheCarGenerators* GetTheCarGenerators() - { - DEBUG_TRACE("CTheCarGenerators * GetTheCarGenerators()"); - return m_pTheCarGenerators; - }; - CAERadioTrackManager* GetAERadioTrackManager() - { - DEBUG_TRACE("CAERadioTrackManager * GetAERadioTrackManager()"); - return m_pCAERadioTrackManager; - }; - CAudioEngine* GetAudioEngine() - { - DEBUG_TRACE("CAudio * GetAudioEngine()"); - return m_pAudioEngine; - }; - CAEAudioHardware* GetAEAudioHardware() - { - DEBUG_TRACE("CAEAudioHardware * GetAEAudioHardware()"); - return m_pAEAudioHardware; - }; - CAESoundManager* GetAESoundManager() override { return m_pAESoundManager; } - CAudioContainer* GetAudioContainer() - { - DEBUG_TRACE("CAudio * GetAudioContainer()"); - return m_pAudioContainer; - }; - CMenuManager* GetMenuManager() - { - DEBUG_TRACE("CMenuManager * GetMenuManager()"); - return m_pMenuManager; - }; - CText* GetText() - { - DEBUG_TRACE("CText * GetText()"); - return m_pText; - }; - CStats* GetStats() - { - DEBUG_TRACE("CStats * GetStats()"); - return m_pStats; - }; - CFont* GetFont() - { - DEBUG_TRACE("CFont * GetFont()"); - return m_pFont; - }; - CPathFind* GetPathFind() - { - DEBUG_TRACE("CPathFind * GetPathFind()"); - return m_pPathFind; - }; - CPopulation* GetPopulation() - { - DEBUG_TRACE("CPopulation * GetPopulation()"); - return m_pPopulation; - }; - CTaskManagementSystem* GetTaskManagementSystem() - { - DEBUG_TRACE("CTaskManagementSystemSA * GetTaskManagementSystem()"); - return m_pTaskManagementSystem; - }; - CTasks* GetTasks() - { - DEBUG_TRACE("CTasks * GetTasks()"); - return m_pTasks; - }; - CGameSettings* GetSettings() - { - DEBUG_TRACE("CGameSettings * GetSettings()"); - return m_pSettings; - }; - CCarEnterExit* GetCarEnterExit() - { - DEBUG_TRACE("CCarEnterExit * GetCarEnterExit()"); - return m_pCarEnterExit; - }; - CControllerConfigManager* GetControllerConfigManager() - { - DEBUG_TRACE("CControllerConfigManager* GetControllerConfigManager()"); - return m_pControllerConfigManager; - }; - CRenderWare* GetRenderWare() - { - DEBUG_TRACE("CRenderWare * GetRenderWare()"); - return m_pRenderWare; - }; - CHandlingManager* GetHandlingManager() { return m_pHandlingManager; }; - CAnimManager* GetAnimManager() { return m_pAnimManager; } - CStreaming* GetStreaming() { return m_pStreaming; } - CVisibilityPlugins* GetVisibilityPlugins() { return m_pVisibilityPlugins; } - CKeyGen* GetKeyGen() { return m_pKeyGen; } - CRopes* GetRopes() { return m_pRopes; } - CFx* GetFx() { return m_pFx; } - CFxManager* GetFxManager() { return m_pFxManager; } - CWaterManager* GetWaterManager() { return m_pWaterManager; } - CWeaponStatManager* GetWeaponStatManager() { return m_pWeaponStatsManager; } - CPointLights* GetPointLights() { return m_pPointLights; } - CRenderWareSA* GetRenderWareSA() { return m_pRenderWare; } - CFxManagerSA* GetFxManagerSA() { return m_pFxManager; } - - CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD); - CModelInfo* GetModelInfo(DWORD dwModelID); - CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup); - - DWORD GetSystemTime() - { - DEBUG_TRACE("DWORD GetSystemTime ( )"); - return *VAR_SystemTime; - }; - BOOL IsAtMenu() - { - DEBUG_TRACE("BOOL IsAtMenu ( )"); - if (*VAR_IsAtMenu) - return TRUE; - else - return FALSE; - }; - BOOL IsGameLoaded() - { - DEBUG_TRACE("BOOL IsGameLoaded ( )"); - if (*VAR_IsGameLoaded) - return TRUE; - else - return FALSE; - }; - VOID StartGame(); - VOID SetSystemState(eSystemState State); - eSystemState GetSystemState(); - BOOL IsNastyGame() - { - DEBUG_TRACE("BOOL IsNastyGame ( )"); - return *VAR_IsNastyGame; - }; - VOID SetNastyGame(BOOL IsNasty) - { - DEBUG_TRACE("VOID SetNastyGame ( BOOL IsNasty )"); - *VAR_IsNastyGame = IsNasty ? true : false; - }; - VOID Pause(bool bPaused); - bool IsPaused(); - bool IsInForeground(); - VOID DisableRenderer(bool bDisabled); - VOID TakeScreenshot(char* szFileName); - DWORD* GetMemoryValue(DWORD dwOffset); - - VOID SetRenderHook(InRenderer* pInRenderer); - - void Initialize(); - void Reset(); - void Terminate(); - - eGameVersion GetGameVersion(); - eGameVersion FindGameVersion(); - - float GetFPS(); - float GetTimeStep(); - float GetOldTimeStep(); - float GetTimeScale(); - void SetTimeScale(float fTimeScale); - - BOOL InitLocalPlayer(class CClientPed* pClientPed); - - float GetGravity(); - void SetGravity(float fGravity); - - float GetGameSpeed(); - void SetGameSpeed(float fSpeed); - - unsigned char GetBlurLevel(); - void SetBlurLevel(unsigned char ucLevel); - - void SetJetpackWeaponEnabled(eWeaponType weaponType, bool bEnabled); - bool GetJetpackWeaponEnabled(eWeaponType weaponType); - - unsigned long GetMinuteDuration(); - void SetMinuteDuration(unsigned long ulTime); - - bool IsCheatEnabled(const char* szCheatName); - bool SetCheatEnabled(const char* szCheatName, bool bEnable); - void ResetCheats(); - - bool IsRandomFoliageEnabled(); - void SetRandomFoliageEnabled(bool bEnable); - - bool IsMoonEasterEggEnabled(); - void SetMoonEasterEggEnabled(bool bEnabled); - - bool IsExtraAirResistanceEnabled(); - void SetExtraAirResistanceEnabled(bool bEnable); - - bool IsUnderWorldWarpEnabled(); - void SetUnderWorldWarpEnabled(bool bEnable); - - bool VerifySADataFileNames(); - bool PerformChecks(); - int& GetCheckStatus() { return m_iCheckStatus; } - - void SetAsyncLoadingFromScript(bool bScriptEnabled, bool bScriptForced); - void SuspendASyncLoading(bool bSuspend, uint uiAutoUnsuspendDelay = 0); - bool IsASyncLoadingEnabled(bool bIgnoreSuspend = false); - - bool HasCreditScreenFadedOut(); - - void SetupSpecialCharacters(); - CWeapon* CreateWeapon(); - CWeaponStat* CreateWeaponStat(eWeaponType weaponType, eWeaponSkill weaponSkill); - void FlushPendingRestreamIPL(); - void ResetModelLodDistances(); - void ResetAlphaTransparencies(); - void DisableVSync(); - - void OnPedContextChange(CPed* pPedContext); - CPed* GetPedContext(); - - void GetShaderReplacementStats(SShaderReplacementStats& outStats); - - void SetPreWeaponFireHandler(PreWeaponFireHandler* pPreWeaponFireHandler) { m_pPreWeaponFireHandler = pPreWeaponFireHandler; } - void SetPostWeaponFireHandler(PostWeaponFireHandler* pPostWeaponFireHandler) { m_pPostWeaponFireHandler = pPostWeaponFireHandler; } - void SetTaskSimpleBeHitHandler(TaskSimpleBeHitHandler* pTaskSimpleBeHitHandler) { m_pTaskSimpleBeHitHandler = pTaskSimpleBeHitHandler; } - - PreWeaponFireHandler* m_pPreWeaponFireHandler; - PostWeaponFireHandler* m_pPostWeaponFireHandler; - TaskSimpleBeHitHandler* m_pTaskSimpleBeHitHandler; - -private: - CPools* m_pPools; - CPlayerInfo* m_pPlayerInfo; - CProjectileInfo* m_pProjectileInfo; - CRadar* m_pRadar; - CRestart* m_pRestart; - CClock* m_pClock; - CCoronas* m_pCoronas; - CCheckpoints* m_pCheckpoints; - CEventList* m_pEventList; - CFireManager* m_pFireManager; - CGarages* m_pGarages; - CHud* m_pHud; - CWanted* m_pWanted; - CWeather* m_pWeather; - CWorld* m_pWorld; - CCamera* m_pCamera; - CModelInfo* m_pModelInfo; - CPickups* m_pPickups; - CWeaponInfo* m_pWeaponInfo; - CExplosionManager* m_pExplosionManager; - C3DMarkers* m_p3DMarkers; - CRenderWareSA* m_pRenderWare; - CHandlingManager* m_pHandlingManager; - CAnimManager* m_pAnimManager; - CStreaming* m_pStreaming; - CVisibilityPlugins* m_pVisibilityPlugins; - CKeyGen* m_pKeyGen; - CRopes* m_pRopes; - CFx* m_pFx; - CFxManagerSA* m_pFxManager; - CWaterManager* m_pWaterManager; - CWeaponStatManager* m_pWeaponStatsManager; - CPointLights* m_pPointLights; - CObjectGroupPhysicalProperties* m_pObjectGroupPhysicalProperties; - - CPad* m_pPad; - CTheCarGenerators* m_pTheCarGenerators; - CAERadioTrackManager* m_pCAERadioTrackManager; - CAudioEngine* m_pAudioEngine; - CAEAudioHardware* m_pAEAudioHardware; - CAESoundManager* m_pAESoundManager; - CAudioContainer* m_pAudioContainer; - CMenuManager* m_pMenuManager; - CText* m_pText; - CStats* m_pStats; - CFont* m_pFont; - CPathFind* m_pPathFind; - CPopulation* m_pPopulation; - CTaskManagementSystem* m_pTaskManagementSystem; // not used outside the game_sa - CTasks* m_pTasks; - CGameSettings* m_pSettings; - CCarEnterExit* m_pCarEnterExit; - CControllerConfigManager* m_pControllerConfigManager; - - eGameVersion m_eGameVersion; - bool m_bAsyncScriptEnabled; - bool m_bAsyncScriptForced; - bool m_bASyncLoadingSuspended; - int m_iCheckStatus; - bool m_bUnderworldWarp; - - static unsigned long* VAR_SystemTime; - static unsigned long* VAR_IsAtMenu; - static unsigned long* VAR_IsGameLoaded; - static bool* VAR_GamePaused; - static bool* VAR_IsForegroundWindow; - ; - static unsigned long* VAR_SystemState; - static void* VAR_StartGame; - static bool* VAR_IsNastyGame; - static float* VAR_TimeScale; - static float* VAR_FPS; - static float* VAR_OldTimeStep; - static float* VAR_TimeStep; - static unsigned long* VAR_Framelimiter; - - std::map m_Cheats; - - SFixedArray m_JetpackWeapons; - - CPed* m_pPedContext; - CTickCount m_llASyncLoadingAutoUnsuspendTime; -}; +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CGameSA.h + * PURPOSE: Header file for base game logic handling class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "CModelInfoSA.h" +#include "CObjectGroupPhysicalPropertiesSA.h" +#include "CFxManagerSA.h" + +#define MAX_MEMORY_OFFSET_1_0 0xCAF008 + +#define CLASS_CPlayerInfo 0xB7CD98 // ##SA## +#define CLASS_CCamera 0xB6F028 // ##SA## +#define CLASS_CPad 0xB73458 // ##SA## +#define CLASS_CGarages 0x96C048 // ##SA## +#define CLASS_CFx 0xa9ae00 // ##SA## +#define CLASS_CFxManager 0xA9AE80 // ##SA## +#define CLASS_CMenuManager 0xBA6748 // ##SA## + +#define CLASS_RwCamera 0xB6F97C + +#define ARRAY_WeaponInfo 0xC8AAB8 // ##SA## +#define CLASSSIZE_WeaponInfo 112 // ##SA## +#define NUM_WeaponInfosStdSkill WEAPONTYPE_LAST_WEAPONTYPE +#define NUM_WeaponInfosOtherSkill 11 +#define NUM_WeaponInfosTotal (NUM_WeaponInfosStdSkill + (3*NUM_WeaponInfosOtherSkill)) // std, (poor, pro, special) + +#define MODELINFO_MAX 26000 // Actual max is 25755 +#define OBJECTDYNAMICINFO_MAX 160 + +#define FUNC_GetLevelFromPosition 0x4DD300 + +#define FUNC_CDebug_DebugDisplayTextBuffer 0x532260 +#define FUNC_JPegCompressScreenToFile 0x5D0820 + +#define VAR_FlyingCarsEnabled 0x969160 // ##SA## +#define VAR_ExtraBunnyhopEnabled 0x969161 // ##SA## +#define VAR_HoveringCarsEnabled 0x969152 // ##SA## +#define VAR_ExtraJumpEnabled 0x96916C // ##SA## +#define VAR_TankModeEnabled 0x969164 // ##SA## +#define VAR_NoReloadEnabled 0x969178 // ##SA## +#define VAR_PerfectHandling 0x96914C // ##SA## +#define VAR_AllCarsHaveNitro 0x969165 // ##SA## +#define VAR_BoatsCanFly 0x969153 // ##SA## +#define VAR_InfiniteOxygen 0x96916E // ##SA## +#define VAR_FasterClock 0x96913B // ##SA## +#define VAR_FasterGameplay 0x96913C // ##SA## +#define VAR_SlowerGameplay 0x96913D // ##SA## +#define VAR_AlwaysMidnight 0x969167 // ##SA## +#define VAR_FullWeaponAiming 0x969179 // ##SA## +#define VAR_InfiniteHealth 0x96916D // ##SA## +#define VAR_NeverWanted 0x969171 // ##SA## +#define VAR_HealthArmorMoney 0x969133 // ##SA## +#define VAR_WalkUnderwater 0x6C2759 + +#define CHEAT_HOVERINGCARS "hovercars" +#define CHEAT_FLYINGCARS "aircars" +#define CHEAT_EXTRABUNNYHOP "extrabunny" +#define CHEAT_EXTRAJUMP "extrajump" +#define CHEAT_TANKMODE "tankmode" +#define CHEAT_NORELOAD "noreload" +#define CHEAT_PERFECTHANDLING "perfecthandling" +#define CHEAT_ALLCARSHAVENITRO "allcarshavenitro" +#define CHEAT_BOATSCANFLY "airboats" +#define CHEAT_INFINITEOXYGEN "infiniteoxygen" +#define CHEAT_WALKUNDERWATER "walkunderwater" +#define CHEAT_FASTERCLOCK "fasterclock" +#define CHEAT_FASTERGAMEPLAY "fastergameplay" +#define CHEAT_SLOWERGAMEPLAY "slowergameplay" +#define CHEAT_ALWAYSMIDNIGHT "alwaysmidnight" +#define CHEAT_FULLWEAPONAIMING "fullweaponaiming" +#define CHEAT_INFINITEHEALTH "infinitehealth" +#define CHEAT_NEVERWANTED "neverwanted" +#define CHEAT_HEALTARMORMONEY "healtharmormoney" + +#define PROP_RANDOM_FOLIAGE "randomfoliage" +#define PROP_SNIPER_MOON "snipermoon" +#define PROP_EXTRA_AIR_RESISTANCE "extraairresistance" +#define PROP_UNDERWORLD_WARP "underworldwarp" + +struct SCheatSA +{ + BYTE* m_byAddress; // Cheat Address + bool m_bEnabled; // Cheat State + bool m_bCanBeSet; // Cheat can be set with setWorldSpecialPropertyEnabled + SCheatSA(BYTE* Address, bool bCanBeSet = true) + { + m_byAddress = Address; + m_bCanBeSet = bCanBeSet; + } +}; +class CGameSA : public CGame +{ + friend class COffsets; + typedef std::unique_ptr AssocGroup_type; + +private: + CWeaponInfo* WeaponInfos[NUM_WeaponInfosTotal]; + CModelInfoSA ModelInfo[MODELINFO_MAX]; + CObjectGroupPhysicalPropertiesSA ObjectGroupsInfo[OBJECTDYNAMICINFO_MAX]; + +public: + ZERO_ON_NEW + + CGameSA(); // constructor + ~CGameSA(); + + CPools* GetPools() + { + DEBUG_TRACE("CPools * GetPools()"); + return m_pPools; + }; + CPlayerInfo* GetPlayerInfo() + { + DEBUG_TRACE("CPlayerInfo * GetPlayerInfo()"); + return m_pPlayerInfo; + }; + CProjectileInfo* GetProjectileInfo() + { + DEBUG_TRACE("CProjectileInfo * GetProjectileInfo()"); + return m_pProjectileInfo; + }; + CRadar* GetRadar() + { + DEBUG_TRACE("CRadar * GetRadar()"); + return m_pRadar; + }; + CRestart* GetRestart() + { + DEBUG_TRACE("CRestart * GetRestart()"); + return m_pRestart; + }; + CClock* GetClock() + { + DEBUG_TRACE("CClock * GetClock()"); + return m_pClock; + }; + CCoronas* GetCoronas() + { + DEBUG_TRACE("CCoronas * GetCoronas()"); + return m_pCoronas; + }; + CCheckpoints* GetCheckpoints() + { + DEBUG_TRACE("CCheckpoints * GetCheckpoints()"); + return m_pCheckpoints; + }; + CEventList* GetEventList() + { + DEBUG_TRACE("CEventList * GetEventList()"); + return m_pEventList; + }; + CFireManager* GetFireManager() + { + DEBUG_TRACE("CFireManager * GetFireManager()"); + return m_pFireManager; + }; + CExplosionManager* GetExplosionManager() + { + DEBUG_TRACE("CExplosionManager * GetExplosionManager()"); + return m_pExplosionManager; + }; + CGarages* GetGarages() + { + DEBUG_TRACE("CGarages * GetGarages()"); + return m_pGarages; + }; + CHud* GetHud() + { + DEBUG_TRACE("CHud * GetHud()"); + return m_pHud; + }; + CWeather* GetWeather() + { + DEBUG_TRACE("CWeather * GetWeather()"); + return m_pWeather; + }; + CWorld* GetWorld() + { + DEBUG_TRACE("CWorld * GetWorld()"); + return m_pWorld; + }; + CCamera* GetCamera() + { + DEBUG_TRACE("CCamera * GetCamera()"); + return m_pCamera; + }; + CPickups* GetPickups() + { + DEBUG_TRACE("CPickups * GetPickups()"); + return m_pPickups; + }; + C3DMarkers* Get3DMarkers() + { + DEBUG_TRACE("C3DMarkers * Get3DMarkers()"); + return m_p3DMarkers; + }; + CPad* GetPad() + { + DEBUG_TRACE("CPad * GetPad()"); + return m_pPad; + }; + CTheCarGenerators* GetTheCarGenerators() + { + DEBUG_TRACE("CTheCarGenerators * GetTheCarGenerators()"); + return m_pTheCarGenerators; + }; + CAERadioTrackManager* GetAERadioTrackManager() + { + DEBUG_TRACE("CAERadioTrackManager * GetAERadioTrackManager()"); + return m_pCAERadioTrackManager; + }; + CAudioEngine* GetAudioEngine() + { + DEBUG_TRACE("CAudio * GetAudioEngine()"); + return m_pAudioEngine; + }; + CAEAudioHardware* GetAEAudioHardware() + { + DEBUG_TRACE("CAEAudioHardware * GetAEAudioHardware()"); + return m_pAEAudioHardware; + }; + CAESoundManager* GetAESoundManager() override { return m_pAESoundManager; } + CAudioContainer* GetAudioContainer() + { + DEBUG_TRACE("CAudio * GetAudioContainer()"); + return m_pAudioContainer; + }; + CMenuManager* GetMenuManager() + { + DEBUG_TRACE("CMenuManager * GetMenuManager()"); + return m_pMenuManager; + }; + CText* GetText() + { + DEBUG_TRACE("CText * GetText()"); + return m_pText; + }; + CStats* GetStats() + { + DEBUG_TRACE("CStats * GetStats()"); + return m_pStats; + }; + CFont* GetFont() + { + DEBUG_TRACE("CFont * GetFont()"); + return m_pFont; + }; + CPathFind* GetPathFind() + { + DEBUG_TRACE("CPathFind * GetPathFind()"); + return m_pPathFind; + }; + CPopulation* GetPopulation() + { + DEBUG_TRACE("CPopulation * GetPopulation()"); + return m_pPopulation; + }; + CTaskManagementSystem* GetTaskManagementSystem() + { + DEBUG_TRACE("CTaskManagementSystemSA * GetTaskManagementSystem()"); + return m_pTaskManagementSystem; + }; + CTasks* GetTasks() + { + DEBUG_TRACE("CTasks * GetTasks()"); + return m_pTasks; + }; + CGameSettings* GetSettings() + { + DEBUG_TRACE("CGameSettings * GetSettings()"); + return m_pSettings; + }; + CCarEnterExit* GetCarEnterExit() + { + DEBUG_TRACE("CCarEnterExit * GetCarEnterExit()"); + return m_pCarEnterExit; + }; + CControllerConfigManager* GetControllerConfigManager() + { + DEBUG_TRACE("CControllerConfigManager* GetControllerConfigManager()"); + return m_pControllerConfigManager; + }; + CRenderWare* GetRenderWare() + { + DEBUG_TRACE("CRenderWare * GetRenderWare()"); + return m_pRenderWare; + }; + CHandlingManager* GetHandlingManager() { return m_pHandlingManager; }; + CAnimManager* GetAnimManager() { return m_pAnimManager; } + CStreaming* GetStreaming() { return m_pStreaming; } + CVisibilityPlugins* GetVisibilityPlugins() { return m_pVisibilityPlugins; } + CKeyGen* GetKeyGen() { return m_pKeyGen; } + CRopes* GetRopes() { return m_pRopes; } + CFx* GetFx() { return m_pFx; } + CFxManager* GetFxManager() { return m_pFxManager; } + CWaterManager* GetWaterManager() { return m_pWaterManager; } + CWeaponStatManager* GetWeaponStatManager() { return m_pWeaponStatsManager; } + CPointLights* GetPointLights() { return m_pPointLights; } + CRenderWareSA* GetRenderWareSA() { return m_pRenderWare; } + CFxManagerSA* GetFxManagerSA() { return m_pFxManager; } + + CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD); + CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false); + CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup); + + DWORD GetSystemTime() + { + DEBUG_TRACE("DWORD GetSystemTime ( )"); + return *VAR_SystemTime; + }; + BOOL IsAtMenu() + { + DEBUG_TRACE("BOOL IsAtMenu ( )"); + if (*VAR_IsAtMenu) + return TRUE; + else + return FALSE; + }; + BOOL IsGameLoaded() + { + DEBUG_TRACE("BOOL IsGameLoaded ( )"); + if (*VAR_IsGameLoaded) + return TRUE; + else + return FALSE; + }; + VOID StartGame(); + VOID SetSystemState(eSystemState State); + eSystemState GetSystemState(); + BOOL IsNastyGame() + { + DEBUG_TRACE("BOOL IsNastyGame ( )"); + return *VAR_IsNastyGame; + }; + VOID SetNastyGame(BOOL IsNasty) + { + DEBUG_TRACE("VOID SetNastyGame ( BOOL IsNasty )"); + *VAR_IsNastyGame = IsNasty ? true : false; + }; + VOID Pause(bool bPaused); + bool IsPaused(); + bool IsInForeground(); + VOID DisableRenderer(bool bDisabled); + VOID TakeScreenshot(char* szFileName); + DWORD* GetMemoryValue(DWORD dwOffset); + + VOID SetRenderHook(InRenderer* pInRenderer); + + void Initialize(); + void Reset(); + void Terminate(); + + eGameVersion GetGameVersion(); + eGameVersion FindGameVersion(); + + float GetFPS(); + float GetTimeStep(); + float GetOldTimeStep(); + float GetTimeScale(); + void SetTimeScale(float fTimeScale); + + BOOL InitLocalPlayer(class CClientPed* pClientPed); + + float GetGravity(); + void SetGravity(float fGravity); + + float GetGameSpeed(); + void SetGameSpeed(float fSpeed); + + unsigned char GetBlurLevel(); + void SetBlurLevel(unsigned char ucLevel); + + void SetJetpackWeaponEnabled(eWeaponType weaponType, bool bEnabled); + bool GetJetpackWeaponEnabled(eWeaponType weaponType); + + unsigned long GetMinuteDuration(); + void SetMinuteDuration(unsigned long ulTime); + + bool IsCheatEnabled(const char* szCheatName); + bool SetCheatEnabled(const char* szCheatName, bool bEnable); + void ResetCheats(); + + bool IsRandomFoliageEnabled(); + void SetRandomFoliageEnabled(bool bEnable); + + bool IsMoonEasterEggEnabled(); + void SetMoonEasterEggEnabled(bool bEnabled); + + bool IsExtraAirResistanceEnabled(); + void SetExtraAirResistanceEnabled(bool bEnable); + + bool IsUnderWorldWarpEnabled(); + void SetUnderWorldWarpEnabled(bool bEnable); + + bool VerifySADataFileNames(); + bool PerformChecks(); + int& GetCheckStatus() { return m_iCheckStatus; } + + void SetAsyncLoadingFromScript(bool bScriptEnabled, bool bScriptForced); + void SuspendASyncLoading(bool bSuspend, uint uiAutoUnsuspendDelay = 0); + bool IsASyncLoadingEnabled(bool bIgnoreSuspend = false); + + bool HasCreditScreenFadedOut(); + + void SetupSpecialCharacters(); + CWeapon* CreateWeapon(); + CWeaponStat* CreateWeaponStat(eWeaponType weaponType, eWeaponSkill weaponSkill); + void FlushPendingRestreamIPL(); + void ResetModelLodDistances(); + void ResetAlphaTransparencies(); + void DisableVSync(); + + void OnPedContextChange(CPed* pPedContext); + CPed* GetPedContext(); + + void GetShaderReplacementStats(SShaderReplacementStats& outStats); + + void SetPreWeaponFireHandler(PreWeaponFireHandler* pPreWeaponFireHandler) { m_pPreWeaponFireHandler = pPreWeaponFireHandler; } + void SetPostWeaponFireHandler(PostWeaponFireHandler* pPostWeaponFireHandler) { m_pPostWeaponFireHandler = pPostWeaponFireHandler; } + void SetTaskSimpleBeHitHandler(TaskSimpleBeHitHandler* pTaskSimpleBeHitHandler) { m_pTaskSimpleBeHitHandler = pTaskSimpleBeHitHandler; } + + PreWeaponFireHandler* m_pPreWeaponFireHandler; + PostWeaponFireHandler* m_pPostWeaponFireHandler; + TaskSimpleBeHitHandler* m_pTaskSimpleBeHitHandler; + +private: + CPools* m_pPools; + CPlayerInfo* m_pPlayerInfo; + CProjectileInfo* m_pProjectileInfo; + CRadar* m_pRadar; + CRestart* m_pRestart; + CClock* m_pClock; + CCoronas* m_pCoronas; + CCheckpoints* m_pCheckpoints; + CEventList* m_pEventList; + CFireManager* m_pFireManager; + CGarages* m_pGarages; + CHud* m_pHud; + CWanted* m_pWanted; + CWeather* m_pWeather; + CWorld* m_pWorld; + CCamera* m_pCamera; + CModelInfo* m_pModelInfo; + CPickups* m_pPickups; + CWeaponInfo* m_pWeaponInfo; + CExplosionManager* m_pExplosionManager; + C3DMarkers* m_p3DMarkers; + CRenderWareSA* m_pRenderWare; + CHandlingManager* m_pHandlingManager; + CAnimManager* m_pAnimManager; + CStreaming* m_pStreaming; + CVisibilityPlugins* m_pVisibilityPlugins; + CKeyGen* m_pKeyGen; + CRopes* m_pRopes; + CFx* m_pFx; + CFxManagerSA* m_pFxManager; + CWaterManager* m_pWaterManager; + CWeaponStatManager* m_pWeaponStatsManager; + CPointLights* m_pPointLights; + CObjectGroupPhysicalProperties* m_pObjectGroupPhysicalProperties; + + CPad* m_pPad; + CTheCarGenerators* m_pTheCarGenerators; + CAERadioTrackManager* m_pCAERadioTrackManager; + CAudioEngine* m_pAudioEngine; + CAEAudioHardware* m_pAEAudioHardware; + CAESoundManager* m_pAESoundManager; + CAudioContainer* m_pAudioContainer; + CMenuManager* m_pMenuManager; + CText* m_pText; + CStats* m_pStats; + CFont* m_pFont; + CPathFind* m_pPathFind; + CPopulation* m_pPopulation; + CTaskManagementSystem* m_pTaskManagementSystem; // not used outside the game_sa + CTasks* m_pTasks; + CGameSettings* m_pSettings; + CCarEnterExit* m_pCarEnterExit; + CControllerConfigManager* m_pControllerConfigManager; + + eGameVersion m_eGameVersion; + bool m_bAsyncScriptEnabled; + bool m_bAsyncScriptForced; + bool m_bASyncLoadingSuspended; + int m_iCheckStatus; + bool m_bUnderworldWarp; + + static unsigned long* VAR_SystemTime; + static unsigned long* VAR_IsAtMenu; + static unsigned long* VAR_IsGameLoaded; + static bool* VAR_GamePaused; + static bool* VAR_IsForegroundWindow; + ; + static unsigned long* VAR_SystemState; + static void* VAR_StartGame; + static bool* VAR_IsNastyGame; + static float* VAR_TimeScale; + static float* VAR_FPS; + static float* VAR_OldTimeStep; + static float* VAR_TimeStep; + static unsigned long* VAR_Framelimiter; + + std::map m_Cheats; + + SFixedArray m_JetpackWeapons; + + CPed* m_pPedContext; + CTickCount m_llASyncLoadingAutoUnsuspendTime; +}; diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 4127ed60b05..09faadd2006 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -250,10 +250,7 @@ BOOL CModelInfoSA::IsVehicle() bool CModelInfoSA::IsPlayerModel() { - return (m_dwModelID == 0 || m_dwModelID == 1 || m_dwModelID == 2 || m_dwModelID == 7 || - (m_dwModelID >= 9 && m_dwModelID != 208 && m_dwModelID != 149 && m_dwModelID != 119 && m_dwModelID != 86 && m_dwModelID != 74 && - m_dwModelID != 65 && m_dwModelID != 42 && m_dwModelID <= 272) || - (m_dwModelID >= 274 && m_dwModelID <= 288) || (m_dwModelID >= 290 && m_dwModelID <= 312)); + return (GetInterface() && GetInterface()->pColModel && GetInterface()->pColModel == (CColModelSAInterface*)VAR_CTempColModels_ModelPed1); } BOOL CModelInfoSA::IsUpgrade() @@ -1210,6 +1207,11 @@ void CModelInfoSA::MakePedModel(char* szTexture) pGame->GetStreaming()->RequestSpecialModel(m_dwModelID, szTexture, 0); } +void CModelInfoSA::DeallocateModel(void) +{ + Remove(); + ppModelInfo[m_dwModelID] = nullptr; +} ////////////////////////////////////////////////////////////////////////////////////////// // // Hook for NodeNameStreamRead diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index b7b024d14ed..51fd93a9bc3 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -361,6 +361,7 @@ class CModelInfoSA : public CModelInfo // CModelInfoSA methods void MakePedModel(char* szTexture); + void DeallocateModel(void); SVehicleSupportedUpgrades GetVehicleSupportedUpgrades() { return m_ModelSupportedUpgrades; } diff --git a/Client/mods/deathmatch/StdInc.h b/Client/mods/deathmatch/StdInc.h index d7697d9a41e..75cb77d42b1 100644 --- a/Client/mods/deathmatch/StdInc.h +++ b/Client/mods/deathmatch/StdInc.h @@ -94,6 +94,7 @@ #include #include #include +#include #include #include #include diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 5d565bfe6dc..d3fff842845 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -3564,6 +3564,9 @@ void CClientGame::Event_OnIngame() g_pGame->GetWaterManager()->SetWaterDrawnLast(true); m_pCamera->SetCameraClip(true, true); + // Deallocate all custom models + m_pManager->GetModelManager()->RemoveAll(); + // Create a local player for us m_pLocalPlayer = new CClientPlayer(m_pManager, m_LocalID, true); diff --git a/Client/mods/deathmatch/logic/CClientManager.cpp b/Client/mods/deathmatch/logic/CClientManager.cpp index 43c6e674efd..2f2683a7584 100644 --- a/Client/mods/deathmatch/logic/CClientManager.cpp +++ b/Client/mods/deathmatch/logic/CClientManager.cpp @@ -52,6 +52,7 @@ CClientManager::CClientManager() m_pWeaponManager = new CClientWeaponManager(this); m_pEffectManager = new CClientEffectManager(this); m_pPointLightsManager = new CClientPointLightsManager(this); + m_pModelManager = new CClientModelManager(this); m_pPacketRecorder = new CClientPacketRecorder(this); m_bBeingDeleted = false; @@ -173,6 +174,9 @@ CClientManager::~CClientManager() delete m_pPointLightsManager; m_pPointLightsManager = NULL; + + delete m_pModelManager; + m_pModelManager = nullptr; } // diff --git a/Client/mods/deathmatch/logic/CClientManager.h b/Client/mods/deathmatch/logic/CClientManager.h index ce7135ebea4..6cde4c247ac 100644 --- a/Client/mods/deathmatch/logic/CClientManager.h +++ b/Client/mods/deathmatch/logic/CClientManager.h @@ -42,6 +42,7 @@ class CClientManager; #include "CClientWeaponManager.h" #include "CClientEffectManager.h" #include "CClientPointLightsManager.h" +#include "CClientModelManager.h" class CClientProjectileManager; class CClientExplosionManager; @@ -65,6 +66,7 @@ class CClientManager CClientGUIManager* GetGUIManager() { return m_pGUIManager; } CClientMarkerManager* GetMarkerManager() { return m_pMarkerManager; } CClientStreamer* GetMarkerStreamer() { return m_pMarkerStreamer; } + CClientModelManager* GetModelManager() { return m_pModelManager; } CClientModelRequestManager* GetModelRequestManager() { return m_pModelRequestManager; } CClientObjectManager* GetObjectManager() { return m_pObjectManager; } CClientStreamer* GetObjectStreamer() { return m_pObjectStreamer; } @@ -144,6 +146,7 @@ class CClientManager CClientWeaponManager* m_pWeaponManager; CClientEffectManager* m_pEffectManager; CClientPointLightsManager* m_pPointLightsManager; + CClientModelManager* m_pModelManager; CClientPacketRecorder* m_pPacketRecorder; bool m_bBeingDeleted; bool m_bGameUnloadedFlag; diff --git a/Client/mods/deathmatch/logic/CClientModel.cpp b/Client/mods/deathmatch/logic/CClientModel.cpp new file mode 100644 index 00000000000..7aca127086b --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientModel.cpp @@ -0,0 +1,89 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CClientModel.h + * PURPOSE: Model handling class + * + *****************************************************************************/ + +#include "StdInc.h" + +CClientModel::CClientModel(CClientManager* pManager, int iModelID, eClientModelType eModelType) +{ + // Init + m_pManager = pManager; + m_pModelManager = pManager->GetModelManager(); + m_iModelID = iModelID; + m_eModelType = eModelType; + + m_pModelManager->Add(this); +} + +CClientModel::~CClientModel(void) +{ + Deallocate(); + + m_pModelManager->Remove(this); +} + +bool CClientModel::Allocate(void) +{ + m_bAllocatedByUs = true; + + CModelInfo* pModelInfo = g_pGame->GetModelInfo(m_iModelID, true); + + // Allocate only on free IDs + if (!pModelInfo->IsValid()) + { + pModelInfo->MakePedModel("PSYCHO"); + return true; + } + return false; +} + +bool CClientModel::Deallocate(void) +{ + if (!m_bAllocatedByUs) + return false; + + CModelInfo* pModelInfo = g_pGame->GetModelInfo(m_iModelID, true); + + // ModelInfo must be valid + if (pModelInfo->IsValid()) + { + if (m_eModelType == CCLIENTMODELPED) + { + // If some ped is using this ID, change him to CJ + CClientPedManager* pPedManager = g_pClientGame->GetManager()->GetPedManager(); + std::vector::const_iterator iter = pPedManager->IterBegin(); + for (; iter != pPedManager->IterEnd(); iter++) + { + if ((*iter)->GetModel() == m_iModelID) + { + if ((*iter)->IsStreamedIn()) + { + (*iter)->StreamOutForABit(); + } + (*iter)->SetModel(0); + } + } + } + + // Restore DFF/TXD + g_pClientGame->GetManager()->GetDFFManager()->RestoreModel(m_iModelID); + + // Restore COL (for non ped models) + if (m_eModelType != CCLIENTMODELPED) + { + g_pClientGame->GetManager()->GetColModelManager()->RestoreModel(m_iModelID); + } + + pModelInfo->DeallocateModel(); + + this->SetParentResource(nullptr); + return true; + } + return false; +} diff --git a/Client/mods/deathmatch/logic/CClientModel.h b/Client/mods/deathmatch/logic/CClientModel.h new file mode 100644 index 00000000000..a39d36f954c --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientModel.h @@ -0,0 +1,47 @@ +/***************************************************************************** +* +* PROJECT: Multi Theft Auto +* (Shared logic for modifications) +* LICENSE: See LICENSE in the top level directory +* FILE: mods/deathmatch/logic/CClientModel.h +* PURPOSE: Model handling class +* +*****************************************************************************/ + +class CClientModel; + +#pragma once + +#include +#include "CClientModelManager.h" + +enum eClientModelType +{ + CCLIENTMODELPED +}; + +class CClientModel +{ + friend class CClientModelManager; + +public: + CClientModel(CClientManager* pManager, int iModelID, eClientModelType eModelType); + ~CClientModel(void); + + int GetModelID(void) { return m_iModelID; }; + eClientModelType GetModelType(void) { return m_eModelType; }; + bool Allocate(void); + bool Deallocate(void); + void SetParentResource(CResource* pResource) { m_pParentResource = pResource; } + CResource* GetParentResource(void) { return m_pParentResource; } + +protected: + CClientManager* m_pManager; + class CClientModelManager* m_pModelManager; + + int m_iModelID; + eClientModelType m_eModelType; + bool m_bAllocatedByUs; + + CResource* m_pParentResource; // Resource that allocated model +}; diff --git a/Client/mods/deathmatch/logic/CClientModelManager.cpp b/Client/mods/deathmatch/logic/CClientModelManager.cpp new file mode 100644 index 00000000000..745479acad1 --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientModelManager.cpp @@ -0,0 +1,87 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CClientModelManager.cpp + * PURPOSE: Model manager class + * + *****************************************************************************/ + +#include "StdInc.h" + +CClientModelManager::CClientModelManager(CClientManager* pManager) +{ + for (ushort i = 0; i < MAX_MODEL_ID; i++) + { + m_Models[i] = nullptr; + } +} + +CClientModelManager::~CClientModelManager(void) +{ + // Delete all our models + RemoveAll(); +} + +void CClientModelManager::RemoveAll(void) +{ + for (int i = 0; i < MAX_MODEL_ID; i++) + { + Remove(m_Models[i]); + } +} + +void CClientModelManager::Add(CClientModel* pModel) +{ + if (m_Models[pModel->GetModelID()] == nullptr) + { + m_Models[pModel->GetModelID()] = pModel; + } +} + +bool CClientModelManager::Remove(CClientModel* pModel) +{ + if (pModel && m_Models[pModel->GetModelID()] != nullptr) + { + m_Models[pModel->GetModelID()] = nullptr; + return true; + } + return false; +} + +int CClientModelManager::GetFirstFreeModelID(void) +{ + for (int i = 0; i < MAX_MODEL_ID; i++) + { + CModelInfo* pModelInfo = g_pGame->GetModelInfo(i, true); + if (!pModelInfo->IsValid()) + { + return i; + } + } + return INVALID_MODEL_ID; +} + +CClientModel* CClientModelManager::FindModelByID(int iModelID) +{ + if (iModelID < MAX_MODEL_ID) + { + return m_Models[iModelID]; + } + return nullptr; +} + +void CClientModelManager::DeallocateModelsAllocatedByResource(CResource* pResource) +{ + for (ushort i = 0; i < MAX_MODEL_ID; i++) + { + if (m_Models[i] != nullptr) + { + if (m_Models[i]->GetParentResource() == pResource) + { + m_Models[i]->Deallocate(); + } + } + } +} diff --git a/Client/mods/deathmatch/logic/CClientModelManager.h b/Client/mods/deathmatch/logic/CClientModelManager.h new file mode 100644 index 00000000000..664caf875eb --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientModelManager.h @@ -0,0 +1,41 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CClientModelManager.h + * PURPOSE: Model manager class + * + *****************************************************************************/ + +class CClientModelManager; + +#pragma once + +#include +#include "CClientModel.h" + +#define MAX_MODEL_ID 20000 + +class CClientModelManager +{ + friend class CClientModel; + +public: + CClientModelManager(class CClientManager* pManager); + ~CClientModelManager(void); + + void RemoveAll(void); + + void Add(CClientModel* pModel); + bool Remove(CClientModel* pModel); + + int GetFirstFreeModelID(void); + + CClientModel* FindModelByID(int iModelID); + + void DeallocateModelsAllocatedByResource(CResource* pResource); + +private: + CClientModel* m_Models[MAX_MODEL_ID]; +}; diff --git a/Client/mods/deathmatch/logic/CClientPlayerManager.cpp b/Client/mods/deathmatch/logic/CClientPlayerManager.cpp index 83a0bb31d7e..bc78a006201 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerManager.cpp +++ b/Client/mods/deathmatch/logic/CClientPlayerManager.cpp @@ -178,10 +178,12 @@ bool CClientPlayerManager::IsPlayerLimitReached() bool CClientPlayerManager::IsValidModel(unsigned long ulModel) { - return (ulModel == 0 || ulModel == 1 || ulModel == 2 || ulModel == 7 || - ulModel >= 9 && ulModel != 208 && ulModel != 149 && ulModel != 119 && ulModel != 86 && ulModel != 74 && ulModel != 65 && ulModel != 42 && - ulModel <= 272 || - ulModel >= 274 && ulModel <= 288 || ulModel >= 290 && ulModel <= 312); + if (ulModel < MAX_MODEL_ID) + { + CModelInfo* pModelInfo = g_pGame->GetModelInfo(ulModel); + return pModelInfo && pModelInfo->IsPlayerModel(); + } + return false; } void CClientPlayerManager::ResetAll() diff --git a/Client/mods/deathmatch/logic/CResource.cpp b/Client/mods/deathmatch/logic/CResource.cpp index d33a9be985d..bd6686bf700 100644 --- a/Client/mods/deathmatch/logic/CResource.cpp +++ b/Client/mods/deathmatch/logic/CResource.cpp @@ -121,6 +121,9 @@ CResource::~CResource() g_pClientGame->GetElementDeleter()->DeleteRecursive(m_pResourceGUIEntity); m_pResourceGUIEntity = NULL; + // Deallocate all models that this resource allocated earlier + g_pClientGame->GetManager()->GetModelManager()->DeallocateModelsAllocatedByResource(this); + // Undo all changes to water g_pGame->GetWaterManager()->UndoChanges(this); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 400f9ae3ab3..26f9e826804 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -14,6 +14,7 @@ void CLuaEngineDefs::LoadFunctions() { std::map functions{ + {"engineFreeModel", EngineFreeModel}, {"engineLoadTXD", EngineLoadTXD}, {"engineLoadCOL", EngineLoadCOL}, {"engineLoadDFF", EngineLoadDFF}, @@ -25,6 +26,7 @@ void CLuaEngineDefs::LoadFunctions() {"engineRestoreModel", EngineRestoreModel}, {"engineReplaceAnimation", EngineReplaceAnimation}, {"engineRestoreAnimation", EngineRestoreAnimation}, + {"engineRequestModel", EngineRequestModel}, {"engineGetModelLODDistance", EngineGetModelLODDistance}, {"engineSetModelLODDistance", EngineSetModelLODDistance}, {"engineSetAsynchronousLoading", EngineSetAsynchronousLoading}, @@ -500,6 +502,73 @@ int CLuaEngineDefs::EngineRestoreModel(lua_State* luaVM) return 1; } +int CLuaEngineDefs::EngineRequestModel(lua_State* luaVM) +{ + SString strModelType; + + CScriptArgReader argStream(luaVM); + argStream.ReadString(strModelType); + + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CResource* pResource = pLuaMain->GetResource(); + if (pResource) + { + if (!argStream.HasErrors()) + { + eClientModelType eModelType; + if (strModelType == "ped") + { + eModelType = CCLIENTMODELPED; + } + else + { + lua_pushboolean(luaVM, false); + return 1; + } + + int iModelID = m_pManager->GetModelManager()->GetFirstFreeModelID(); + if (iModelID != INVALID_MODEL_ID) { + CClientModel* pModel = new CClientModel(m_pManager, iModelID, eModelType); + pModel->Allocate(); + pModel->SetParentResource(pResource); + + lua_pushinteger(luaVM, iModelID); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + } + } + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaEngineDefs::EngineFreeModel(lua_State* luaVM) +{ + int iModelID; + + CScriptArgReader argStream(luaVM); + argStream.ReadNumber(iModelID); + + if (!argStream.HasErrors()) + { + CClientModel* pModel = m_pManager->GetModelManager()->FindModelByID(iModelID); + + if (pModel && pModel->Deallocate()) + lua_pushboolean(luaVM, true); + + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaEngineDefs::EngineReplaceAnimation(lua_State* luaVM) { CClientEntity* pEntity = nullptr; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index bb978c28ac8..fb1a594494e 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -27,6 +27,8 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineRestoreCOL); LUA_DECLARE(EngineReplaceModel); LUA_DECLARE(EngineRestoreModel); + LUA_DECLARE(EngineRequestModel); + LUA_DECLARE(EngineFreeModel); LUA_DECLARE(EngineReplaceAnimation); LUA_DECLARE(EngineRestoreAnimation); LUA_DECLARE(EngineReplaceMatchingAtomics); diff --git a/Client/sdk/game/CGame.h b/Client/sdk/game/CGame.h index b1991a9aed5..1ab81fdd37c 100644 --- a/Client/sdk/game/CGame.h +++ b/Client/sdk/game/CGame.h @@ -169,7 +169,7 @@ class __declspec(novtable) CGame virtual CPointLights* GetPointLights() = 0; virtual CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD) = 0; - virtual CModelInfo* GetModelInfo(DWORD dwModelID) = 0; + virtual CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false) = 0; virtual DWORD GetSystemTime() = 0; virtual BOOL IsAtMenu() = 0; diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index 74fd16f7986..262b33a600a 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -102,6 +102,7 @@ class CModelInfo virtual class CBaseModelInfoSAInterface* GetInterface() = 0; virtual DWORD GetModel() = 0; + virtual bool IsPlayerModel() = 0; virtual BOOL IsBoat() = 0; virtual BOOL IsCar() = 0; virtual BOOL IsTrain() = 0; @@ -132,6 +133,7 @@ class CModelInfo virtual void RemoveRef(bool bRemoveExtraGTARef = false) = 0; virtual int GetRefCount() = 0; virtual bool ForceUnload() = 0; + virtual void DeallocateModel() = 0; virtual float GetDistanceFromCentreOfMassToBaseOfModel() = 0; @@ -169,6 +171,7 @@ class CModelInfo // Call this to make sure the custom vehicle models are being used after a load. virtual void MakeCustomModel() = 0; virtual RwObject* GetRwObject() = 0; + virtual void MakePedModel(char* szTexture) = 0; virtual SVehicleSupportedUpgrades GetVehicleSupportedUpgrades() = 0; virtual void ResetSupportedUpgrades() = 0;