diff --git a/Client/cefweb/CWebView.cpp b/Client/cefweb/CWebView.cpp index ef3f016e7c..744247599f 100644 --- a/Client/cefweb/CWebView.cpp +++ b/Client/cefweb/CWebView.cpp @@ -936,10 +936,10 @@ void CWebView::OnBeforeClose(CefRefPtr browser) // // // // //////////////////////////////////////////////////////////////////// -bool CWebView::OnBeforePopup(CefRefPtr browser, CefRefPtr frame, const CefString& target_url, const CefString& target_frame_name, - CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, const CefPopupFeatures& popupFeatures, - CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, CefRefPtr& extra_info, - bool* no_javascript_access) +bool CWebView::OnBeforePopup(CefRefPtr browser, CefRefPtr frame, int popup_id, const CefString& target_url, + const CefString& target_frame_name, CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, + const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, + CefRefPtr& extra_info, bool* no_javascript_access) { // ATTENTION: This method is called on the IO thread diff --git a/Client/cefweb/CWebView.h b/Client/cefweb/CWebView.h index 0c9589d6c9..59cd64f381 100644 --- a/Client/cefweb/CWebView.h +++ b/Client/cefweb/CWebView.h @@ -152,10 +152,10 @@ class CWebView : public CWebViewInterface, // CefLifeSpawnHandler methods virtual void OnBeforeClose(CefRefPtr browser) override; - virtual bool OnBeforePopup(CefRefPtr browser, CefRefPtr frame, const CefString& target_url, const CefString& target_frame_name, - CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, const CefPopupFeatures& popupFeatures, - CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, CefRefPtr& extra_info, - bool* no_javascript_access) override; + virtual bool OnBeforePopup(CefRefPtr browser, CefRefPtr frame, int popup_id, const CefString& target_url, + const CefString& target_frame_name, CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture, + const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings, + CefRefPtr& extra_info, bool* no_javascript_access) override; virtual void OnAfterCreated(CefRefPtr browser) override; // CefJSDialogHandler methods diff --git a/Client/core/CConsole.h b/Client/core/CConsole.h index 5899fa645d..677e1133ff 100644 --- a/Client/core/CConsole.h +++ b/Client/core/CConsole.h @@ -41,7 +41,6 @@ class CConsole : public CConsoleInterface bool IsInputActive(); void ActivateInput(); - void HandleTextAccepted(bool bHandled); void GetCommandInfo(const std::string& strIn, std::string& strCmdOut, std::string& strCmdLineOut); void ResetHistoryChanges(); diff --git a/Client/core/CQueryReceiver.cpp b/Client/core/CQueryReceiver.cpp index 559691bcb3..4d1e516de9 100644 --- a/Client/core/CQueryReceiver.cpp +++ b/Client/core/CQueryReceiver.cpp @@ -183,7 +183,7 @@ SQueryInfo CQueryReceiver::GetServerResponse() // Recover server ping status if present const SString strPingStatus = strBuildNumber.Right(strBuildNumber.length() - strlen(strBuildNumber) - 1); - CCore::GetSingleton().GetNetwork()->UpdatePingStatus(*strPingStatus, info.players, info.isStatusVerified); + CCore::GetSingleton().GetNetwork()->UpdatePingStatus(strPingStatus.c_str(), strPingStatus.length(), info.players, info.isStatusVerified); // Recover server http port if present const SString strNetRoute = strPingStatus.Right(strPingStatus.length() - strlen(strPingStatus) - 1); diff --git a/Client/game_sa/CBuildingsPoolSA.cpp b/Client/game_sa/CBuildingsPoolSA.cpp index 50ae14bb3c..7cd8e887ae 100644 --- a/Client/game_sa/CBuildingsPoolSA.cpp +++ b/Client/game_sa/CBuildingsPoolSA.cpp @@ -53,6 +53,13 @@ CBuilding* CBuildingsPoolSA::AddBuilding(CClientBuilding* pClientBuilding, uint1 if (!HasFreeBuildingSlot()) return nullptr; + auto modelInfo = pGame->GetModelInfo(modelId); + + // Change the properties group to force dynamic models to be created as buildings instead of dummies + auto prevGroup = modelInfo->GetObjectPropertiesGroup(); + if (prevGroup != MODEL_PROPERTIES_GROUP_STATIC) + modelInfo->SetObjectPropertiesGroup(MODEL_PROPERTIES_GROUP_STATIC); + // Load building SFileObjectInstance instance; instance.modelID = modelId; @@ -70,9 +77,12 @@ CBuilding* CBuildingsPoolSA::AddBuilding(CClientBuilding* pClientBuilding, uint1 pBuilding->m_pLod = nullptr; pBuilding->m_iplIndex = 0; + // Restore changed properties group + if (prevGroup != MODEL_PROPERTIES_GROUP_STATIC) + modelInfo->SetObjectPropertiesGroup(prevGroup); + // Always stream model collosion // TODO We can setup collison bounding box and use GTA streamer for it - auto modelInfo = pGame->GetModelInfo(modelId); modelInfo->AddColRef(); // Add building in world diff --git a/Client/game_sa/CEntitySA.cpp b/Client/game_sa/CEntitySA.cpp index 02a9f00380..9053910737 100644 --- a/Client/game_sa/CEntitySA.cpp +++ b/Client/game_sa/CEntitySA.cpp @@ -679,7 +679,7 @@ bool CEntitySA::GetBonePosition(eBone boneId, CVector& position) return false; const RwV3d& pos = rwBoneMatrix->pos; - position = {pos.x, pos.y, pos.z}; + position = CVector(pos.x, pos.y, pos.z); return true; } diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 07ac611c09..dffc159313 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -104,7 +104,7 @@ CGameSA::CGameSA() m_pAESoundManager = new CAESoundManagerSA((CAESoundManagerSAInterface*)CLASS_CAESoundManager); m_pAudioContainer = new CAudioContainerSA(); m_pWorld = new CWorldSA(); - m_pPools = new CPoolsSA(); + m_Pools = std::make_unique(); m_pClock = new CClockSA(); m_pRadar = new CRadarSA(); m_pCamera = new CCameraSA((CCameraSAInterface*)CLASS_CCamera); @@ -125,7 +125,7 @@ CGameSA::CGameSA() m_pControllerConfigManager = new CControllerConfigManagerSA(); m_pProjectileInfo = new CProjectileInfoSA(); m_pRenderWare = new CRenderWareSA(); - m_pHandlingManager = new CHandlingManagerSA(); + m_HandlingManager = std::make_unique(); m_pEventList = new CEventListSA(); m_pGarages = new CGaragesSA((CGaragesSAInterface*)CLASS_CGarages); m_pTasks = new CTasksSA((CTaskManagementSystemSA*)m_pTaskManagementSystem); @@ -208,17 +208,17 @@ CGameSA::CGameSA() m_Cheats[CHEAT_HEALTARMORMONEY] = new SCheatSA((BYTE*)VAR_HealthArmorMoney, false); // Change pool sizes here - m_pPools->SetPoolCapacity(TASK_POOL, 5000); // Default is 500 - m_pPools->SetPoolCapacity(OBJECT_POOL, MAX_OBJECTS); // Default is 350 - m_pPools->SetPoolCapacity(EVENT_POOL, 5000); // Default is 200 - m_pPools->SetPoolCapacity(COL_MODEL_POOL, 12000); // Default is 10150 - m_pPools->SetPoolCapacity(ENV_MAP_MATERIAL_POOL, 16000); // Default is 4096 - m_pPools->SetPoolCapacity(ENV_MAP_ATOMIC_POOL, 4000); // Default is 1024 - m_pPools->SetPoolCapacity(SPEC_MAP_MATERIAL_POOL, 16000); // Default is 4096 - m_pPools->SetPoolCapacity(ENTRY_INFO_NODE_POOL, MAX_ENTRY_INFO_NODES); // Default is 500 - m_pPools->SetPoolCapacity(POINTER_SINGLE_LINK_POOL, MAX_POINTER_SINGLE_LINKS); // Default is 70000 - m_pPools->SetPoolCapacity(POINTER_DOUBLE_LINK_POOL, MAX_POINTER_DOUBLE_LINKS); // Default is 3200 - dassert(m_pPools->GetPoolCapacity(POINTER_SINGLE_LINK_POOL) == MAX_POINTER_SINGLE_LINKS); + m_Pools->SetPoolCapacity(TASK_POOL, 5000); // Default is 500 + m_Pools->SetPoolCapacity(OBJECT_POOL, MAX_OBJECTS); // Default is 350 + m_Pools->SetPoolCapacity(EVENT_POOL, 5000); // Default is 200 + m_Pools->SetPoolCapacity(COL_MODEL_POOL, 12000); // Default is 10150 + m_Pools->SetPoolCapacity(ENV_MAP_MATERIAL_POOL, 16000); // Default is 4096 + m_Pools->SetPoolCapacity(ENV_MAP_ATOMIC_POOL, 4000); // Default is 1024 + m_Pools->SetPoolCapacity(SPEC_MAP_MATERIAL_POOL, 16000); // Default is 4096 + m_Pools->SetPoolCapacity(ENTRY_INFO_NODE_POOL, MAX_ENTRY_INFO_NODES); // Default is 500 + m_Pools->SetPoolCapacity(POINTER_SINGLE_LINK_POOL, MAX_POINTER_SINGLE_LINKS); // Default is 70000 + m_Pools->SetPoolCapacity(POINTER_DOUBLE_LINK_POOL, MAX_POINTER_DOUBLE_LINKS); // Default is 3200 + dassert(m_Pools->GetPoolCapacity(POINTER_SINGLE_LINK_POOL) == MAX_POINTER_SINGLE_LINKS); // Increase streaming object instances list size MemPut(0x05B8E55, MAX_RWOBJECT_INSTANCES * 12); // Default is 1000 * 12 @@ -261,7 +261,6 @@ CGameSA::~CGameSA() delete reinterpret_cast(m_pAnimManager); delete reinterpret_cast(m_pTasks); delete reinterpret_cast(m_pTaskManagementSystem); - delete reinterpret_cast(m_pHandlingManager); delete reinterpret_cast(m_pStats); delete reinterpret_cast(m_pWeather); delete reinterpret_cast(m_pCAERadioTrackManager); @@ -276,7 +275,6 @@ CGameSA::~CGameSA() delete reinterpret_cast(m_pCamera); delete reinterpret_cast(m_pRadar); delete reinterpret_cast(m_pClock); - delete reinterpret_cast(m_pPools); delete reinterpret_cast(m_pWorld); delete reinterpret_cast(m_pAudioEngine); delete reinterpret_cast(m_pAEAudioHardware); @@ -848,6 +846,34 @@ void CGameSA::SetRoadSignsTextEnabled(bool isEnabled) m_isRoadSignsTextEnabled = isEnabled; } +void CGameSA::SetIgnoreFireStateEnabled(bool isEnabled) +{ + if (isEnabled == m_isIgnoreFireStateEnabled) + return; + + if (isEnabled) + { + MemSet((void*)0x6511B9, 0x90, 10); // CCarEnterExit::IsVehicleStealable + MemSet((void*)0x643A95, 0x90, 14); // CTaskComplexEnterCar::CreateFirstSubTask + MemSet((void*)0x6900B5, 0x90, 14); // CTaskComplexCopInCar::ControlSubTask + MemSet((void*)0x64F3DB, 0x90, 14); // CCarEnterExit::IsPlayerToQuitCarEnter + + MemSet((void*)0x685A7F, 0x90, 14); // CTaskSimplePlayerOnFoot::ProcessPlayerWeapon + } + else + { + // Restore original bytes + MemCpy((void*)0x6511B9, "\x88\x86\x90\x04\x00\x00\x85\xC0\x75\x3E", 10); + MemCpy((void*)0x643A95, "\x8B\x88\x90\x04\x00\x00\x85\xC9\x0F\x85\x99\x01\x00\x00", 14); + MemCpy((void*)0x6900B5, "\x8B\x81\x90\x04\x00\x00\x85\xC0\x0F\x85\x1A\x01\x00\x00", 14); + MemCpy((void*)0x64F3DB, "\x8B\x85\x90\x04\x00\x00\x85\xC0\x0F\x85\x1B\x01\x00\x00", 14); + + MemCpy((void*)0x685A7F, "\x8B\x86\x30\x07\x00\x00\x85\xC0\x0F\x85\x1D\x01\x00\x00", 14); + } + + m_isIgnoreFireStateEnabled = isEnabled; +} + bool CGameSA::PerformChecks() { std::map::iterator it; @@ -1011,8 +1037,8 @@ void CGameSA::RemoveAllBuildings() { m_pIplStore->SetDynamicIplStreamingEnabled(false); - m_pPools->GetDummyPool().RemoveAllBuildingLods(); - m_pPools->GetBuildingsPool().RemoveAllBuildings(); + m_Pools->GetDummyPool().RemoveAllBuildingLods(); + m_Pools->GetBuildingsPool().RemoveAllBuildings(); auto pBuildingRemoval = static_cast(m_pBuildingRemoval); pBuildingRemoval->DropCaches(); @@ -1022,8 +1048,8 @@ void CGameSA::RemoveAllBuildings() void CGameSA::RestoreGameBuildings() { - m_pPools->GetBuildingsPool().RestoreAllBuildings(); - m_pPools->GetDummyPool().RestoreAllBuildingsLods(); + m_Pools->GetBuildingsPool().RestoreAllBuildings(); + m_Pools->GetDummyPool().RestoreAllBuildingsLods(); m_pIplStore->SetDynamicIplStreamingEnabled(true, [](CIplSAInterface* ipl) { return memcmp("barriers", ipl->name, 8) != 0; }); m_isBuildingsRemoved = false; @@ -1041,7 +1067,7 @@ bool CGameSA::SetBuildingPoolSize(size_t size) static_cast(m_pBuildingRemoval)->DropCaches(); } - bool status = m_pPools->GetBuildingsPool().Resize(size); + bool status = m_Pools->GetBuildingsPool().Resize(size); if (shouldRemoveBuilding) { diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index cf4788d953..2133d7d9a5 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -125,7 +125,7 @@ class CGameSA : public CGame CGameSA(); ~CGameSA(); - CPools* GetPools() { return m_pPools; } + CPools* GetPools() const noexcept { return m_Pools.get(); } CPlayerInfo* GetPlayerInfo() { return m_pPlayerInfo; } CProjectileInfo* GetProjectileInfo() { return m_pProjectileInfo; } CRadar* GetRadar() { return m_pRadar; } @@ -155,7 +155,7 @@ class CGameSA : public CGame CCarEnterExit* GetCarEnterExit() { return m_pCarEnterExit; } CControllerConfigManager* GetControllerConfigManager() { return m_pControllerConfigManager; } CRenderWare* GetRenderWare() { return m_pRenderWare; } - CHandlingManager* GetHandlingManager() { return m_pHandlingManager; } + CHandlingManager* GetHandlingManager() const noexcept { return m_HandlingManager.get(); } CAnimManager* GetAnimManager() { return m_pAnimManager; } CStreaming* GetStreaming() { return m_pStreaming; } CVisibilityPlugins* GetVisibilityPlugins() { return m_pVisibilityPlugins; } @@ -249,6 +249,8 @@ class CGameSA : public CGame bool IsTunnelWeatherBlendEnabled() const noexcept override { return m_isTunnelWeatherBlendEnabled; } void SetTunnelWeatherBlendEnabled(bool isEnabled) override; + bool IsIgnoreFireStateEnabled() const noexcept override { return m_isIgnoreFireStateEnabled; } + void SetIgnoreFireStateEnabled(bool isEnabled) override; unsigned long GetMinuteDuration(); void SetMinuteDuration(unsigned long ulTime); @@ -311,42 +313,42 @@ class CGameSA : public CGame bool SetBuildingPoolSize(size_t size); private: - CPools* m_pPools; - CPlayerInfo* m_pPlayerInfo; - CProjectileInfo* m_pProjectileInfo; - CRadar* m_pRadar; - CClock* m_pClock; - CCoronas* m_pCoronas; - CCheckpoints* m_pCheckpoints; - CEventList* m_pEventList; - CFireManager* m_pFireManager; - CGarages* m_pGarages; - CHud* m_pHud; - 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; - CColStore* m_collisionStore; - CObjectGroupPhysicalProperties* m_pObjectGroupPhysicalProperties; - CCoverManagerSA* m_pCoverManager; - CPlantManagerSA* m_pPlantManager; - CBuildingRemoval* m_pBuildingRemoval; + std::unique_ptr m_Pools; + CPlayerInfo* m_pPlayerInfo; + CProjectileInfo* m_pProjectileInfo; + CRadar* m_pRadar; + CClock* m_pClock; + CCoronas* m_pCoronas; + CCheckpoints* m_pCheckpoints; + CEventList* m_pEventList; + CFireManager* m_pFireManager; + CGarages* m_pGarages; + CHud* m_pHud; + 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; + std::unique_ptr m_HandlingManager; + 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; + CColStore* m_collisionStore; + CObjectGroupPhysicalProperties* m_pObjectGroupPhysicalProperties; + CCoverManagerSA* m_pCoverManager; + CPlantManagerSA* m_pPlantManager; + CBuildingRemoval* m_pBuildingRemoval; std::unique_ptr m_pRenderer; @@ -378,6 +380,7 @@ class CGameSA : public CGame bool m_isRoadSignsTextEnabled{true}; bool m_isBuildingsRemoved{false}; bool m_isExtendedWaterCannonsEnabled{false}; + bool m_isIgnoreFireStateEnabled{false}; static unsigned int& ClumpOffset; diff --git a/Client/game_sa/CHandlingEntrySA.cpp b/Client/game_sa/CHandlingEntrySA.cpp index 1ebb1471e3..3cc2987f82 100644 --- a/Client/game_sa/CHandlingEntrySA.cpp +++ b/Client/game_sa/CHandlingEntrySA.cpp @@ -19,47 +19,48 @@ extern CGameSA* pGame; CHandlingEntrySA::CHandlingEntrySA() { // Create a new interface and zero it - m_pHandlingSA = new tHandlingDataSA; - memset(m_pHandlingSA, 0, sizeof(tHandlingDataSA)); - m_bDeleteInterface = true; + if (m_HandlingSA = std::make_unique()) + { + MemSet(m_HandlingSA.get(), 0, sizeof(tHandlingDataSA)); + } } -CHandlingEntrySA::CHandlingEntrySA(tHandlingDataSA* pOriginal) +CHandlingEntrySA::CHandlingEntrySA(const tHandlingDataSA* const pOriginal) { // Store gta's pointer - m_pHandlingSA = nullptr; - m_bDeleteInterface = false; - memcpy(&m_Handling, pOriginal, sizeof(tHandlingDataSA)); -} - -CHandlingEntrySA::~CHandlingEntrySA() -{ - if (m_bDeleteInterface) + m_HandlingSA = nullptr; + if (pOriginal) { - SAFE_DELETE(m_pHandlingSA); + MemCpy(&m_Handling, pOriginal, sizeof(tHandlingDataSA)); } } // Apply the handlingdata from another data -void CHandlingEntrySA::Assign(const CHandlingEntry* pEntry) +void CHandlingEntrySA::Assign(const CHandlingEntry* const pEntry) noexcept { if (!pEntry) return; // Copy the data - const CHandlingEntrySA* pEntrySA = static_cast(pEntry); + const CHandlingEntrySA* const pEntrySA = static_cast(pEntry); m_Handling = pEntrySA->m_Handling; } -void CHandlingEntrySA::Recalculate() +void CHandlingEntrySA::Recalculate() noexcept { // Real GTA class? - if (!m_pHandlingSA) + if (!m_HandlingSA) return; - // Copy our stored field to GTA's - memcpy(m_pHandlingSA, &m_Handling, sizeof(m_Handling)); - ((void(_stdcall*)(tHandlingDataSA*))FUNC_HandlingDataMgr_ConvertDataToGameUnits)(m_pHandlingSA); + try + { + // Copy our stored field to GTA's + MemCpy(m_HandlingSA.get(), &m_Handling, sizeof(m_Handling)); + ((void(_stdcall*)(tHandlingDataSA*))FUNC_HandlingDataMgr_ConvertDataToGameUnits)(m_HandlingSA.get()); + } + catch (...) + { + } } void CHandlingEntrySA::SetSuspensionForceLevel(float fForce) noexcept @@ -104,7 +105,7 @@ void CHandlingEntrySA::SetSuspensionAntiDiveMultiplier(float fAntidive) noexcept m_Handling.fSuspensionAntiDiveMultiplier = fAntidive; } -void CHandlingEntrySA::CheckSuspensionChanges() noexcept +void CHandlingEntrySA::CheckSuspensionChanges() const noexcept { pGame->GetHandlingManager()->CheckSuspensionChanges(this); } diff --git a/Client/game_sa/CHandlingEntrySA.h b/Client/game_sa/CHandlingEntrySA.h index d1836f461e..bab11335be 100644 --- a/Client/game_sa/CHandlingEntrySA.h +++ b/Client/game_sa/CHandlingEntrySA.h @@ -91,83 +91,83 @@ class CHandlingEntrySA : public CHandlingEntry CHandlingEntrySA(); // Constructor for original entries - CHandlingEntrySA(tHandlingDataSA* pOriginal); + CHandlingEntrySA(const tHandlingDataSA* const pOriginal); - virtual ~CHandlingEntrySA(); + virtual ~CHandlingEntrySA(){}; // Use this to copy data from an another handling class to this - void Assign(const CHandlingEntry* pEntry); + void Assign(const CHandlingEntry* const pEntry) noexcept; // Get functions - float GetMass() const { return m_Handling.fMass; } - float GetTurnMass() const { return m_Handling.fTurnMass; } - float GetDragCoeff() const { return m_Handling.fDragCoeff; } - const CVector& GetCenterOfMass() const { return m_Handling.vecCenterOfMass; } + float GetMass() const noexcept { return m_Handling.fMass; } + float GetTurnMass() const noexcept { return m_Handling.fTurnMass; } + float GetDragCoeff() const noexcept { return m_Handling.fDragCoeff; } + const CVector& GetCenterOfMass() const noexcept { return m_Handling.vecCenterOfMass; } - unsigned int GetPercentSubmerged() const { return m_Handling.uiPercentSubmerged; } - float GetTractionMultiplier() const { return m_Handling.fTractionMultiplier; } + unsigned int GetPercentSubmerged() const noexcept { return m_Handling.uiPercentSubmerged; } + float GetTractionMultiplier() const noexcept { return m_Handling.fTractionMultiplier; } - eDriveType GetCarDriveType() const { return static_cast(m_Handling.Transmission.ucDriveType); } - eEngineType GetCarEngineType() const { return static_cast(m_Handling.Transmission.ucEngineType); } - unsigned char GetNumberOfGears() const { return m_Handling.Transmission.ucNumberOfGears; } + eDriveType GetCarDriveType() const noexcept { return static_cast(m_Handling.Transmission.ucDriveType); } + eEngineType GetCarEngineType() const noexcept { return static_cast(m_Handling.Transmission.ucEngineType); } + unsigned char GetNumberOfGears() const noexcept { return m_Handling.Transmission.ucNumberOfGears; } - float GetEngineAcceleration() const { return m_Handling.Transmission.fEngineAcceleration; } - float GetEngineInertia() const { return m_Handling.Transmission.fEngineInertia; } - float GetMaxVelocity() const { return m_Handling.Transmission.fMaxVelocity; } + float GetEngineAcceleration() const noexcept { return m_Handling.Transmission.fEngineAcceleration; } + float GetEngineInertia() const noexcept { return m_Handling.Transmission.fEngineInertia; } + float GetMaxVelocity() const noexcept { return m_Handling.Transmission.fMaxVelocity; } - float GetBrakeDeceleration() const { return m_Handling.fBrakeDeceleration; } - float GetBrakeBias() const { return m_Handling.fBrakeBias; } - bool GetABS() const { return m_Handling.bABS; } + float GetBrakeDeceleration() const noexcept { return m_Handling.fBrakeDeceleration; } + float GetBrakeBias() const noexcept { return m_Handling.fBrakeBias; } + bool GetABS() const noexcept { return m_Handling.bABS; } - float GetSteeringLock() const { return m_Handling.fSteeringLock; } - float GetTractionLoss() const { return m_Handling.fTractionLoss; } - float GetTractionBias() const { return m_Handling.fTractionBias; } + float GetSteeringLock() const noexcept { return m_Handling.fSteeringLock; } + float GetTractionLoss() const noexcept { return m_Handling.fTractionLoss; } + float GetTractionBias() const noexcept { return m_Handling.fTractionBias; } - float GetSuspensionForceLevel() const { return m_Handling.fSuspensionForceLevel; } - float GetSuspensionDamping() const { return m_Handling.fSuspensionDamping; } - float GetSuspensionHighSpeedDamping() const { return m_Handling.fSuspensionHighSpdDamping; } - float GetSuspensionUpperLimit() const { return m_Handling.fSuspensionUpperLimit; } - float GetSuspensionLowerLimit() const { return m_Handling.fSuspensionLowerLimit; } - float GetSuspensionFrontRearBias() const { return m_Handling.fSuspensionFrontRearBias; } - float GetSuspensionAntiDiveMultiplier() const { return m_Handling.fSuspensionAntiDiveMultiplier; } + float GetSuspensionForceLevel() const noexcept { return m_Handling.fSuspensionForceLevel; } + float GetSuspensionDamping() const noexcept { return m_Handling.fSuspensionDamping; } + float GetSuspensionHighSpeedDamping() const noexcept { return m_Handling.fSuspensionHighSpdDamping; } + float GetSuspensionUpperLimit() const noexcept { return m_Handling.fSuspensionUpperLimit; } + float GetSuspensionLowerLimit() const noexcept { return m_Handling.fSuspensionLowerLimit; } + float GetSuspensionFrontRearBias() const noexcept { return m_Handling.fSuspensionFrontRearBias; } + float GetSuspensionAntiDiveMultiplier() const noexcept { return m_Handling.fSuspensionAntiDiveMultiplier; } - float GetCollisionDamageMultiplier() const { return m_Handling.fCollisionDamageMultiplier; } + float GetCollisionDamageMultiplier() const noexcept { return m_Handling.fCollisionDamageMultiplier; } - unsigned int GetHandlingFlags() const { return m_Handling.uiHandlingFlags; } - unsigned int GetModelFlags() const { return m_Handling.uiModelFlags; } - float GetSeatOffsetDistance() const { return m_Handling.fSeatOffsetDistance; } - unsigned int GetMonetary() const { return m_Handling.uiMonetary; } + unsigned int GetHandlingFlags() const noexcept { return m_Handling.uiHandlingFlags; } + unsigned int GetModelFlags() const noexcept { return m_Handling.uiModelFlags; } + float GetSeatOffsetDistance() const noexcept { return m_Handling.fSeatOffsetDistance; } + unsigned int GetMonetary() const noexcept { return m_Handling.uiMonetary; } - eLightType GetHeadLight() const { return static_cast(m_Handling.ucHeadLight); } - eLightType GetTailLight() const { return static_cast(m_Handling.ucTailLight); } - unsigned char GetAnimGroup() const { return m_Handling.ucAnimGroup; } + eLightType GetHeadLight() const noexcept { return static_cast(m_Handling.ucHeadLight); } + eLightType GetTailLight() const noexcept { return static_cast(m_Handling.ucTailLight); } + unsigned char GetAnimGroup() const noexcept { return m_Handling.ucAnimGroup; } - std::uint16_t GetVehicleID() const { return static_cast(m_Handling.iVehicleID); } + eHandlingTypes GetVehicleID() const noexcept { return static_cast(m_Handling.iVehicleID); } // Set functions - void SetMass(float fMass) { m_Handling.fMass = fMass; } - void SetTurnMass(float fTurnMass) { m_Handling.fTurnMass = fTurnMass; } - void SetDragCoeff(float fDrag) { m_Handling.fDragCoeff = fDrag; } - void SetCenterOfMass(const CVector& vecCenter) { m_Handling.vecCenterOfMass = vecCenter; } + void SetMass(float fMass) noexcept { m_Handling.fMass = fMass; } + void SetTurnMass(float fTurnMass) noexcept { m_Handling.fTurnMass = fTurnMass; } + void SetDragCoeff(float fDrag) noexcept { m_Handling.fDragCoeff = fDrag; } + void SetCenterOfMass(const CVector& vecCenter) noexcept { m_Handling.vecCenterOfMass = vecCenter; } - void SetPercentSubmerged(unsigned int uiPercent) { m_Handling.uiPercentSubmerged = uiPercent; } - void SetTractionMultiplier(float fTractionMultiplier) { m_Handling.fTractionMultiplier = fTractionMultiplier; } + void SetPercentSubmerged(unsigned int uiPercent) noexcept { m_Handling.uiPercentSubmerged = uiPercent; } + void SetTractionMultiplier(float fTractionMultiplier) noexcept { m_Handling.fTractionMultiplier = fTractionMultiplier; } - void SetCarDriveType(eDriveType Type) { m_Handling.Transmission.ucDriveType = Type; } - void SetCarEngineType(eEngineType Type) { m_Handling.Transmission.ucEngineType = Type; } - void SetNumberOfGears(unsigned char ucNumber) { m_Handling.Transmission.ucNumberOfGears = ucNumber; } + void SetCarDriveType(eDriveType Type) noexcept { m_Handling.Transmission.ucDriveType = Type; } + void SetCarEngineType(eEngineType Type) noexcept { m_Handling.Transmission.ucEngineType = Type; } + void SetNumberOfGears(unsigned char ucNumber) noexcept { m_Handling.Transmission.ucNumberOfGears = ucNumber; } - void SetEngineAcceleration(float fAcceleration) { m_Handling.Transmission.fEngineAcceleration = fAcceleration; } - void SetEngineInertia(float fInertia) { m_Handling.Transmission.fEngineInertia = fInertia; } - void SetMaxVelocity(float fVelocity) { m_Handling.Transmission.fMaxVelocity = fVelocity; } + void SetEngineAcceleration(float fAcceleration) noexcept { m_Handling.Transmission.fEngineAcceleration = fAcceleration; } + void SetEngineInertia(float fInertia) noexcept { m_Handling.Transmission.fEngineInertia = fInertia; } + void SetMaxVelocity(float fVelocity) noexcept { m_Handling.Transmission.fMaxVelocity = fVelocity; } - void SetBrakeDeceleration(float fDeceleration) { m_Handling.fBrakeDeceleration = fDeceleration; } - void SetBrakeBias(float fBias) { m_Handling.fBrakeBias = fBias; } - void SetABS(bool bABS) { m_Handling.bABS = bABS; } + void SetBrakeDeceleration(float fDeceleration) noexcept { m_Handling.fBrakeDeceleration = fDeceleration; } + void SetBrakeBias(float fBias) noexcept { m_Handling.fBrakeBias = fBias; } + void SetABS(bool bABS) noexcept { m_Handling.bABS = bABS; } - void SetSteeringLock(float fSteeringLock) { m_Handling.fSteeringLock = fSteeringLock; } - void SetTractionLoss(float fTractionLoss) { m_Handling.fTractionLoss = fTractionLoss; } - void SetTractionBias(float fTractionBias) { m_Handling.fTractionBias = fTractionBias; } + void SetSteeringLock(float fSteeringLock) noexcept { m_Handling.fSteeringLock = fSteeringLock; } + void SetTractionLoss(float fTractionLoss) noexcept { m_Handling.fTractionLoss = fTractionLoss; } + void SetTractionBias(float fTractionBias) noexcept { m_Handling.fTractionBias = fTractionBias; } void SetSuspensionForceLevel(float fForce) noexcept; void SetSuspensionDamping(float fDamping) noexcept; @@ -177,26 +177,24 @@ class CHandlingEntrySA : public CHandlingEntry void SetSuspensionFrontRearBias(float fBias) noexcept; void SetSuspensionAntiDiveMultiplier(float fAntidive) noexcept; - void SetCollisionDamageMultiplier(float fMultiplier) { m_Handling.fCollisionDamageMultiplier = fMultiplier; } + void SetCollisionDamageMultiplier(float fMultiplier) noexcept { m_Handling.fCollisionDamageMultiplier = fMultiplier; } - void SetHandlingFlags(unsigned int uiFlags) { m_Handling.uiHandlingFlags = uiFlags; } - void SetModelFlags(unsigned int uiFlags) { m_Handling.uiModelFlags = uiFlags; } - void SetSeatOffsetDistance(float fDistance) { m_Handling.fSeatOffsetDistance = fDistance; } - void SetMonetary(unsigned int uiMonetary) { m_Handling.uiMonetary = uiMonetary; } + void SetHandlingFlags(unsigned int uiFlags) noexcept { m_Handling.uiHandlingFlags = uiFlags; } + void SetModelFlags(unsigned int uiFlags) noexcept { m_Handling.uiModelFlags = uiFlags; } + void SetSeatOffsetDistance(float fDistance) noexcept { m_Handling.fSeatOffsetDistance = fDistance; } + void SetMonetary(unsigned int uiMonetary) noexcept { m_Handling.uiMonetary = uiMonetary; } - void SetHeadLight(eLightType Style) { m_Handling.ucHeadLight = Style; } - void SetTailLight(eLightType Style) { m_Handling.ucTailLight = Style; } - void SetAnimGroup(unsigned char ucGroup) { m_Handling.ucAnimGroup = ucGroup; } + void SetHeadLight(eLightType Style) noexcept { m_Handling.ucHeadLight = Style; } + void SetTailLight(eLightType Style) noexcept { m_Handling.ucTailLight = Style; } + void SetAnimGroup(unsigned char ucGroup) noexcept { m_Handling.ucAnimGroup = ucGroup; } - void CheckSuspensionChanges() noexcept; + void CheckSuspensionChanges() const noexcept; - void Recalculate(); + void Recalculate() noexcept; - tHandlingDataSA* GetInterface() const { return m_pHandlingSA; } + tHandlingDataSA* GetInterface() const noexcept { return m_HandlingSA.get(); } private: - tHandlingDataSA* m_pHandlingSA; - bool m_bDeleteInterface; - - tHandlingDataSA m_Handling; + std::unique_ptr m_HandlingSA; + tHandlingDataSA m_Handling; }; diff --git a/Client/game_sa/CHandlingManagerSA.cpp b/Client/game_sa/CHandlingManagerSA.cpp index 8bbfb348b1..d967bec968 100644 --- a/Client/game_sa/CHandlingManagerSA.cpp +++ b/Client/game_sa/CHandlingManagerSA.cpp @@ -27,19 +27,19 @@ extern CGameSA* pGame; #define DUMP_HANDLING_DATA 0 // Original handling data unaffected by handling.cfg changes -tHandlingDataSA m_OriginalHandlingData[HT_MAX]; -CHandlingEntrySA* m_pOriginalEntries[HT_MAX]; +static tHandlingDataSA m_OriginalHandlingData[HT_MAX]; +static std::unique_ptr m_OriginalEntries[HT_MAX]; -tFlyingHandlingDataSA m_OriginalFlyingHandlingData[24]; -CFlyingHandlingEntrySA* m_pOriginalFlyingEntries[24]; +static tFlyingHandlingDataSA m_OriginalFlyingHandlingData[24]; +static std::unique_ptr m_OriginalFlyingEntries[24]; -tBoatHandlingDataSA m_OriginalBoatHandlingData[12]; -CBoatHandlingEntrySA* m_pOriginalBoatEntries[12]; +static tBoatHandlingDataSA m_OriginalBoatHandlingData[12]; +static std::unique_ptr m_OriginalBoatEntries[12]; -tBikeHandlingDataSA m_OriginalBikeHandlingData[14]; -CBikeHandlingEntrySA* m_pOriginalBikeEntries[14]; +static tBikeHandlingDataSA m_OriginalBikeHandlingData[14]; +static std::unique_ptr m_OriginalBikeEntries[14]; -std::map m_HandlingNames; +static std::map m_HandlingNames; // TODO We need install a hook in 0x6F52D0 to make some stuff work corrently @@ -120,12 +120,6 @@ static __declspec(naked) void Hook_Calculate() } } -static bool IsVehicleModel(eVehicleTypes eModel) -{ - const auto pModelInfo = pGame->GetModelInfo(eModel); - return pModelInfo && pModelInfo->IsVehicle(); -} - CHandlingManagerSA::CHandlingManagerSA() { // Initialize all default handlings @@ -134,22 +128,22 @@ CHandlingManagerSA::CHandlingManagerSA() // Create a handling entry for every original handling data. for (std::size_t i = 0; i < HT_MAX; i++) { - m_pOriginalEntries[i] = new CHandlingEntrySA(&m_OriginalHandlingData[i]); + m_OriginalEntries[i] = std::make_unique(&m_OriginalHandlingData[i]); } for (std::size_t i = 0; i < 24; i++) { - m_pOriginalFlyingEntries[i] = new CFlyingHandlingEntrySA(&m_OriginalFlyingHandlingData[i]); + m_OriginalFlyingEntries[i] = std::make_unique(&m_OriginalFlyingHandlingData[i]); } for (std::size_t i = 0; i < 12; i++) { - m_pOriginalBoatEntries[i] = new CBoatHandlingEntrySA(&m_OriginalBoatHandlingData[i]); + m_OriginalBoatEntries[i] = std::make_unique(&m_OriginalBoatHandlingData[i]); } for (std::size_t i = 0; i < 14; i++) { - m_pOriginalBikeEntries[i] = new CBikeHandlingEntrySA(&m_OriginalBikeHandlingData[i]); + m_OriginalBikeEntries[i] = std::make_unique(&m_OriginalBikeHandlingData[i]); } #if DUMP_HANDLING_DATA @@ -193,116 +187,96 @@ CHandlingManagerSA::CHandlingManagerSA() CHandlingManagerSA::~CHandlingManagerSA() { - // Destroy all original handling entries - for (std::size_t i = 0; i < HT_MAX; i++) - { - delete m_pOriginalEntries[i]; - } - - for (std::size_t i = 0; i < 24; i++) - { - delete m_pOriginalFlyingEntries[i]; - } - - for (std::size_t i = 0; i < 12; i++) - { - delete m_pOriginalBoatEntries[i]; - } - - for (std::size_t i = 0; i < 14; i++) - { - delete m_pOriginalBikeEntries[i]; - } } -eHandlingProperty CHandlingManagerSA::GetPropertyEnumFromName(const std::string& strName) const +eHandlingProperty CHandlingManagerSA::GetPropertyEnumFromName(const std::string& name) const noexcept { - const auto it = m_HandlingNames.find(strName); + const auto it = m_HandlingNames.find(name); return it != m_HandlingNames.end() ? it->second : HANDLING_MAX; } -CHandlingEntry* CHandlingManagerSA::CreateHandlingData() +std::unique_ptr CHandlingManagerSA::CreateHandlingData() const noexcept { - return new CHandlingEntrySA; + return std::make_unique(); } -CFlyingHandlingEntry* CHandlingManagerSA::CreateFlyingHandlingData() +std::unique_ptr CHandlingManagerSA::CreateFlyingHandlingData() const noexcept { - return new CFlyingHandlingEntrySA; + return std::make_unique(); } -CBoatHandlingEntry* CHandlingManagerSA::CreateBoatHandlingData() +std::unique_ptr CHandlingManagerSA::CreateBoatHandlingData() const noexcept { - return new CBoatHandlingEntrySA; + return std::make_unique(); } -CBikeHandlingEntry* CHandlingManagerSA::CreateBikeHandlingData() +std::unique_ptr CHandlingManagerSA::CreateBikeHandlingData() const noexcept { - return new CBikeHandlingEntrySA; + return std::make_unique(); } -const CHandlingEntry* CHandlingManagerSA::GetOriginalHandlingData(eVehicleTypes eModel) const +const CHandlingEntry* CHandlingManagerSA::GetOriginalHandlingData(std::uint32_t model) const noexcept { // Vehicle? - if (!IsVehicleModel(eModel)) + if (!CModelInfoSA::IsVehicleModel(model)) return nullptr; // Get our Handling ID, the default value will be HT_LANDSTAL - const eHandlingTypes eHandling = GetHandlingID(eModel); + const eHandlingTypes eHandling = GetHandlingID(model); // Return it - return m_pOriginalEntries[eHandling]; + return m_OriginalEntries[eHandling].get(); } -const CFlyingHandlingEntry* CHandlingManagerSA::GetOriginalFlyingHandlingData(eVehicleTypes eModel) const +const CFlyingHandlingEntry* CHandlingManagerSA::GetOriginalFlyingHandlingData(std::uint32_t model) const noexcept { // Vehicle? - if (!IsVehicleModel(eModel)) + if (!CModelInfoSA::IsVehicleModel(model)) return nullptr; // Get our Handling ID, the default value will be HT_LANDSTAL - const eHandlingTypes eHandling = GetHandlingID(eModel); + const eHandlingTypes eHandling = GetHandlingID(model); // Original GTA:SA behavior if (eHandling < HT_SEAPLANE || eHandling > HT_RCRAIDER) - return m_pOriginalFlyingEntries[0]; + return m_OriginalFlyingEntries[0].get(); else - return m_pOriginalFlyingEntries[eHandling - HT_SEAPLANE]; + return m_OriginalFlyingEntries[eHandling - HT_SEAPLANE].get(); } -const CBoatHandlingEntry* CHandlingManagerSA::GetOriginalBoatHandlingData(eVehicleTypes eModel) const +const CBoatHandlingEntry* CHandlingManagerSA::GetOriginalBoatHandlingData(std::uint32_t model) const noexcept { // Vehicle? - if (!IsVehicleModel(eModel)) + if (!CModelInfoSA::IsVehicleModel(model)) return nullptr; // Get our Handling ID, the default value will be HT_LANDSTAL - const eHandlingTypes eHandling = GetHandlingID(eModel); + const eHandlingTypes eHandling = GetHandlingID(model); // Original GTA:SA behavior if (eHandling < HT_PREDATOR || eHandling > HT_SEAPLANE) - return m_pOriginalBoatEntries[0]; + return m_OriginalBoatEntries[0].get(); else - return m_pOriginalBoatEntries[eHandling - HT_PREDATOR]; + return m_OriginalBoatEntries[eHandling - HT_PREDATOR].get(); } -const CBikeHandlingEntry* CHandlingManagerSA::GetOriginalBikeHandlingData(eVehicleTypes eModel) const +const CBikeHandlingEntry* CHandlingManagerSA::GetOriginalBikeHandlingData(std::uint32_t model) const noexcept { // Vehicle? - if (!IsVehicleModel(eModel)) + if (!CModelInfoSA::IsVehicleModel(model)) return nullptr; // Get our Handling ID, the default value will be HT_LANDSTAL - const eHandlingTypes eHandling = GetHandlingID(eModel); + const eHandlingTypes eHandling = GetHandlingID(model); if (eHandling >= HT_BIKE && eHandling <= HT_FREEWAY) - return m_pOriginalBikeEntries[eHandling - HT_BIKE]; + return m_OriginalBikeEntries[eHandling - HT_BIKE].get(); else if (eHandling == HT_FAGGIO) - return m_pOriginalBikeEntries[13]; + return m_OriginalBikeEntries[13].get(); else return nullptr; } // Return the handling manager id -eHandlingTypes CHandlingManagerSA::GetHandlingID(eVehicleTypes eModel) const +eHandlingTypes CHandlingManagerSA::GetHandlingID(std::uint32_t model) const noexcept { - switch (eModel) + switch (model) { case VT_LANDSTAL: return HT_LANDSTAL; @@ -732,11 +706,8 @@ eHandlingTypes CHandlingManagerSA::GetHandlingID(eVehicleTypes eModel) const return HT_LANDSTAL; } -void CHandlingManagerSA::InitializeDefaultHandlings() +void CHandlingManagerSA::InitializeDefaultHandlings() noexcept { - // Reset - MemSetFast(m_OriginalHandlingData, 0, sizeof(m_OriginalHandlingData)); - // NB: Don't waste your time changing this manually. Use the dumping code // commented out at the bottom :) m_OriginalHandlingData[0].iVehicleID = 0; @@ -9154,53 +9125,53 @@ void CHandlingManagerSA::InitializeDefaultHandlings() m_OriginalBikeHandlingData[13].iVehicleID = 214; } -void CHandlingManagerSA::CheckSuspensionChanges(CHandlingEntry* pEntry) noexcept +void CHandlingManagerSA::CheckSuspensionChanges(const CHandlingEntry* const pEntry) const noexcept { - // Valid? - if (!pEntry) - return; - - // Grab us a multiplayer_sa pointer - CMultiplayer* const pMultiplayer = g_pCore->GetMultiplayer(); - if (!pMultiplayer) - return; - - // Get Handling ID - const eHandlingTypes eHandling = static_cast(pEntry->GetVehicleID()); - if (eHandling >= HT_MAX) - return; - - const CHandlingEntrySA* pOriginal = m_pOriginalEntries[eHandling]; - if (!pOriginal) - return; - - // Default bChanged to false - bool bChanged = false; - - // Set bChanged to true if we find ANY change. - if (pEntry->GetSuspensionAntiDiveMultiplier() != pOriginal->GetSuspensionAntiDiveMultiplier()) - bChanged = true; - - if (pEntry->GetSuspensionDamping() != pOriginal->GetSuspensionDamping()) - bChanged = true; - - if (pEntry->GetSuspensionForceLevel() != pOriginal->GetSuspensionForceLevel()) - bChanged = true; - - if (pEntry->GetSuspensionFrontRearBias() != pOriginal->GetSuspensionFrontRearBias()) - bChanged = true; - - if (pEntry->GetSuspensionHighSpeedDamping() != pOriginal->GetSuspensionHighSpeedDamping()) - bChanged = true; - - if (pEntry->GetSuspensionLowerLimit() != pOriginal->GetSuspensionLowerLimit()) - bChanged = true; - - if (pEntry->GetSuspensionUpperLimit() != pOriginal->GetSuspensionUpperLimit()) - bChanged = true; - - if (!bChanged) - return; - - pMultiplayer->UpdateVehicleSuspension(); + try + { + // Valid? + if (!pEntry) + return; + + // Grab us a multiplayer_sa pointer + const CMultiplayer* const pMultiplayer = g_pCore->GetMultiplayer(); + if (!pMultiplayer) + return; + + // Get Handling ID + const eHandlingTypes eHandling = pEntry->GetVehicleID(); + if (eHandling >= HT_MAX) + return; + + const auto& entries = m_OriginalEntries[eHandling]; + if (!entries) + return; + + // Default bChanged to false + bool bChanged = false; + + // Set bChanged to true if we find ANY change. + if (pEntry->GetSuspensionAntiDiveMultiplier() != entries->GetSuspensionAntiDiveMultiplier()) + bChanged = true; + else if (pEntry->GetSuspensionDamping() != entries->GetSuspensionDamping()) + bChanged = true; + else if (pEntry->GetSuspensionForceLevel() != entries->GetSuspensionForceLevel()) + bChanged = true; + else if (pEntry->GetSuspensionFrontRearBias() != entries->GetSuspensionFrontRearBias()) + bChanged = true; + else if (pEntry->GetSuspensionHighSpeedDamping() != entries->GetSuspensionHighSpeedDamping()) + bChanged = true; + else if (pEntry->GetSuspensionLowerLimit() != entries->GetSuspensionLowerLimit()) + bChanged = true; + else if (pEntry->GetSuspensionUpperLimit() != entries->GetSuspensionUpperLimit()) + bChanged = true; + + if (!bChanged) + return; + + pMultiplayer->UpdateVehicleSuspension(); + } + catch (...) + { + } } diff --git a/Client/game_sa/CHandlingManagerSA.h b/Client/game_sa/CHandlingManagerSA.h index 52ce90c9f3..d27ec2459f 100644 --- a/Client/game_sa/CHandlingManagerSA.h +++ b/Client/game_sa/CHandlingManagerSA.h @@ -23,22 +23,22 @@ class CHandlingManagerSA : public CHandlingManager CHandlingManagerSA(); ~CHandlingManagerSA(); - CHandlingEntry* CreateHandlingData(); - CFlyingHandlingEntry* CreateFlyingHandlingData(); - CBoatHandlingEntry* CreateBoatHandlingData(); - CBikeHandlingEntry* CreateBikeHandlingData(); + std::unique_ptr CreateHandlingData() const noexcept; + std::unique_ptr CreateFlyingHandlingData() const noexcept; + std::unique_ptr CreateBoatHandlingData() const noexcept; + std::unique_ptr CreateBikeHandlingData() const noexcept; - const CHandlingEntry* GetOriginalHandlingData(eVehicleTypes eModel) const; - const CFlyingHandlingEntry* GetOriginalFlyingHandlingData(eVehicleTypes eModel) const; - const CBoatHandlingEntry* GetOriginalBoatHandlingData(eVehicleTypes eModel) const; - const CBikeHandlingEntry* GetOriginalBikeHandlingData(eVehicleTypes eModel) const; + const CHandlingEntry* GetOriginalHandlingData(std::uint32_t model) const noexcept; + const CFlyingHandlingEntry* GetOriginalFlyingHandlingData(std::uint32_t model) const noexcept; + const CBoatHandlingEntry* GetOriginalBoatHandlingData(std::uint32_t model) const noexcept; + const CBikeHandlingEntry* GetOriginalBikeHandlingData(std::uint32_t model) const noexcept; - eHandlingProperty GetPropertyEnumFromName(const std::string& strName) const; + eHandlingProperty GetPropertyEnumFromName(const std::string& name) const noexcept; - void CheckSuspensionChanges(CHandlingEntry* pEntry) noexcept; + void CheckSuspensionChanges(const CHandlingEntry* const pEntry) const noexcept; private: - void InitializeDefaultHandlings(); + void InitializeDefaultHandlings() noexcept; - eHandlingTypes GetHandlingID(eVehicleTypes eModel) const; + eHandlingTypes GetHandlingID(std::uint32_t uiModel) const noexcept; }; diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 4bf3146d7f..0b5ff312b3 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -270,20 +270,14 @@ bool CModelInfoSA::IsTrailer() return bReturn; } -BYTE CModelInfoSA::GetVehicleType() +BYTE CModelInfoSA::GetVehicleType() const noexcept { // This function will return a vehicle type for vehicles or 0xFF on failure - DWORD dwFunction = FUNC_IsVehicleModelType; - DWORD ModelID = m_dwModelID; - BYTE bReturn = -1; - _asm - { - push ModelID - call dwFunction - mov bReturn, al - add esp, 4 - } - return bReturn; + if (!IsVehicle()) + return -1; + + auto GetVehicleModelType = reinterpret_cast(FUNC_IsVehicleModelType); + return GetVehicleModelType(m_dwModelID); } bool CModelInfoSA::IsVehicle() const @@ -292,9 +286,25 @@ bool CModelInfoSA::IsVehicle() const if (m_dwModelID >= 20000) return false; + if (!IsAllocatedInArchive()) + return false; + // NOTE(botder): m_pInterface might be a nullptr here, we can't use it CBaseModelInfoSAInterface* model = ppModelInfo[m_dwModelID]; - return model != nullptr && reinterpret_cast(model->VFTBL) == vftable_CVehicleModelInfo; + return model && reinterpret_cast(model->VFTBL) == vftable_CVehicleModelInfo; +} + +bool CModelInfoSA::IsVehicleModel(std::uint32_t model) noexcept +{ + try + { + const auto* const modelInfo = pGame->GetModelInfo(model); + return modelInfo && modelInfo->IsVehicle(); + } + catch (...) + { + return false; + } } bool CModelInfoSA::IsPlayerModel() @@ -754,9 +764,16 @@ bool CModelInfoSA::IsValid() return true; } -bool CModelInfoSA::IsAllocatedInArchive() +bool CModelInfoSA::IsAllocatedInArchive() const noexcept { - return pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)->sizeInBlocks > 0; + try + { + return pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)->sizeInBlocks > 0; + } + catch (...) + { + return false; + } } float CModelInfoSA::GetDistanceFromCentreOfMassToBaseOfModel() diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index b261bcc04a..6fc7b04811 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -359,7 +359,7 @@ class CModelInfoSA : public CModelInfo char* GetNameIfVehicle(); - BYTE GetVehicleType(); + BYTE GetVehicleType() const noexcept; void Request(EModelRequestType requestType, const char* szTag); void Remove(); bool UnloadUnused(); @@ -374,7 +374,7 @@ class CModelInfoSA : public CModelInfo static void StaticResetFlags(); CBoundingBox* GetBoundingBox(); bool IsValid(); - bool IsAllocatedInArchive(); + bool IsAllocatedInArchive() const noexcept; float GetDistanceFromCentreOfMassToBaseOfModel(); unsigned short GetTextureDictionaryID(); void SetTextureDictionaryID(unsigned short usID); @@ -466,7 +466,9 @@ class CModelInfoSA : public CModelInfo // Vehicle towing functions bool IsTowableBy(CModelInfo* towingModel) override; - bool IsDynamic() { return m_pInterface ? m_pInterface->usDynamicIndex != 0xffff : false; }; + bool IsDynamic() { return m_pInterface ? m_pInterface->usDynamicIndex != MODEL_PROPERTIES_GROUP_STATIC : false; }; + + static bool IsVehicleModel(std::uint32_t model) noexcept; private: void CopyStreamingInfoFromModel(ushort usCopyFromModelID); diff --git a/Client/game_sa/CPhysicalSA.cpp b/Client/game_sa/CPhysicalSA.cpp index d13513a414..ec05a42225 100644 --- a/Client/game_sa/CPhysicalSA.cpp +++ b/Client/game_sa/CPhysicalSA.cpp @@ -39,7 +39,7 @@ void CPhysicalSA::RestoreLastGoodPhysicsState() CVector vecDefault; SetTurnSpeed(&vecDefault); - SetMoveSpeed(&vecDefault); + SetMoveSpeed(vecDefault); CPhysicalSAInterface* pInterface = (CPhysicalSAInterface*)GetInterface(); pInterface->m_pad4d = 0; @@ -100,24 +100,30 @@ CVector* CPhysicalSA::GetTurnSpeedInternal(CVector* vecTurnSpeed) return vecTurnSpeed; } -void CPhysicalSA::SetMoveSpeed(CVector* vecMoveSpeed) +void CPhysicalSA::SetMoveSpeed(const CVector& vecMoveSpeed) noexcept { - DWORD dwFunc = FUNC_GetMoveSpeed; - DWORD dwThis = (DWORD)((CPhysicalSAInterface*)GetInterface()); - DWORD dwReturn = 0; - - _asm + try { - mov ecx, dwThis - call dwFunc - mov dwReturn, eax + DWORD dwFunc = FUNC_GetMoveSpeed; + DWORD dwThis = (DWORD)((CPhysicalSAInterface*)GetInterface()); + DWORD dwReturn = 0; + + __asm + { + mov ecx, dwThis + call dwFunc + mov dwReturn, eax + } + MemCpyFast((void*)dwReturn, &vecMoveSpeed, sizeof(CVector)); + + if (GetInterface()->nType == ENTITY_TYPE_OBJECT) + { + AddToMovingList(); + SetStatic(false); + } } - MemCpyFast((void*)dwReturn, vecMoveSpeed, sizeof(CVector)); - - if (GetInterface()->nType == ENTITY_TYPE_OBJECT) + catch (...) { - AddToMovingList(); - SetStatic(false); } } diff --git a/Client/game_sa/CPhysicalSA.h b/Client/game_sa/CPhysicalSA.h index 2b1234150c..eb5a2a4515 100644 --- a/Client/game_sa/CPhysicalSA.h +++ b/Client/game_sa/CPhysicalSA.h @@ -121,7 +121,7 @@ class CPhysicalSA : public virtual CPhysical, public virtual CEntitySA CVector* GetTurnSpeed(CVector* vecTurnSpeed); CVector* GetMoveSpeedInternal(CVector* vecMoveSpeed); CVector* GetTurnSpeedInternal(CVector* vecTurnSpeed); - void SetMoveSpeed(CVector* vecMoveSpeed); + void SetMoveSpeed(const CVector& vecMoveSpeed) noexcept; void SetTurnSpeed(CVector* vecTurnSpeed); float GetMass(); diff --git a/Client/game_sa/CPlayerPedSA.cpp b/Client/game_sa/CPlayerPedSA.cpp index 534f8376c6..cf8a03faea 100644 --- a/Client/game_sa/CPlayerPedSA.cpp +++ b/Client/game_sa/CPlayerPedSA.cpp @@ -18,6 +18,7 @@ #include "CPlayerInfoSA.h" #include "CPlayerPedSA.h" #include "CWorldSA.h" +#include "CProjectileInfoSA.h" extern CCoreInterface* g_pCore; extern CGameSA* pGame; @@ -137,6 +138,7 @@ CPlayerPedSA::~CPlayerPedSA() if ((DWORD)GetInterface()->vtbl != VTBL_CPlaceable) { CWorldSA* world = (CWorldSA*)pGame->GetWorld(); + pGame->GetProjectileInfo()->RemoveEntityReferences(this); world->Remove(m_pInterface, CPlayerPed_Destructor); DWORD dwThis = (DWORD)m_pInterface; diff --git a/Client/game_sa/CPoolsSA.cpp b/Client/game_sa/CPoolsSA.cpp index 1aaac0b40d..bd7a5f9c96 100644 --- a/Client/game_sa/CPoolsSA.cpp +++ b/Client/game_sa/CPoolsSA.cpp @@ -71,70 +71,76 @@ inline bool CPoolsSA::AddVehicleToPool(CClientVehicle* pClientVehicle, CVehicleS return true; } -CVehicle* CPoolsSA::AddVehicle(CClientVehicle* pClientVehicle, eVehicleTypes eVehicleType, unsigned char ucVariation, unsigned char ucVariation2) +CVehicle* CPoolsSA::AddVehicle(CClientVehicle* pClientVehicle, std::uint16_t model, std::uint8_t variation, std::uint8_t variation2) noexcept { - CVehicleSA* pVehicle = nullptr; - - if (m_vehiclePool.ulCount < MAX_VEHICLES) + try { - MemSetFast((void*)VAR_CVehicle_Variation1, ucVariation, 1); - MemSetFast((void*)VAR_CVehicle_Variation2, ucVariation2, 1); + if (m_vehiclePool.ulCount >= MAX_VEHICLES) + return nullptr; + + MemSetFast((void*)VAR_CVehicle_Variation1, variation, 1); + MemSetFast((void*)VAR_CVehicle_Variation2, variation2, 1); // CCarCtrl::CreateCarForScript - CVehicleSAInterface* pInterface = - ((CVehicleSAInterface * (__cdecl*)(int, CVector, unsigned char)) FUNC_CCarCtrlCreateCarForScript)(eVehicleType, CVector(0, 0, 0), 0); + auto* pInterface = ((CVehicleSAInterface*(__cdecl*)(int, CVector, std::uint8_t))FUNC_CCarCtrlCreateCarForScript)(model, CVector(), 0); + if (!pInterface) + return nullptr; - auto vehicleClass = static_cast(pGame->GetModelInfo(eVehicleType)->GetVehicleType()); + // Valid model? + if (!CModelInfoSA::IsVehicleModel(model)) + return nullptr; + auto vehicleClass = static_cast(pGame->GetModelInfo(model)->GetVehicleType()); + + std::unique_ptr vehicle = nullptr; switch (vehicleClass) { case VehicleClass::MONSTER_TRUCK: - pVehicle = new CMonsterTruckSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; case VehicleClass::QUAD: - pVehicle = new CQuadBikeSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; case VehicleClass::HELI: - pVehicle = new CHeliSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; case VehicleClass::PLANE: - pVehicle = new CPlaneSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; case VehicleClass::BOAT: - pVehicle = new CBoatSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; case VehicleClass::TRAIN: - pVehicle = new CTrainSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; case VehicleClass::BIKE: - pVehicle = new CBikeSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; case VehicleClass::BMX: - pVehicle = new CBmxSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; case VehicleClass::TRAILER: - pVehicle = new CTrailerSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; default: - pVehicle = new CAutomobileSA(reinterpret_cast(pInterface)); + vehicle = std::make_unique(reinterpret_cast(pInterface)); break; } - if (pVehicle && AddVehicleToPool(pClientVehicle, pVehicle)) - { - pVehicle->m_ucVariant = ucVariation; - pVehicle->m_ucVariant2 = ucVariation2; + if (!vehicle || !AddVehicleToPool(pClientVehicle, vehicle.get())) + return nullptr; - pVehicle->DumpVehicleFrames(); - } - else - { - delete pVehicle; - pVehicle = nullptr; - } - } + vehicle->m_ucVariant = variation; + vehicle->m_ucVariant2 = variation2; - return pVehicle; + vehicle->DumpVehicleFrames(); + + return vehicle.release(); + } + catch (...) + { + return nullptr; + } } void CPoolsSA::RemoveVehicle(CVehicle* pVehicle, bool bDelete) @@ -564,108 +570,89 @@ CClientEntity* CPoolsSA::GetClientEntity(DWORD* pGameInterface) return NULL; } -CVehicle* CPoolsSA::AddTrain(CClientVehicle* pClientVehicle, CVector* vecPosition, DWORD dwModels[], int iSize, bool bDirection, uchar ucTrackId) +static void CreateMissionTrain(const CVector& vecPos, bool bDirection, std::uint32_t uiTrainType, CTrainSAInterface** ppTrainBeginning, + CTrainSAInterface** ppTrainEnd, int iNodeIndex, int iTrackId, bool bMissionTrain) noexcept +{ + try + { + auto createMissionTrain = reinterpret_cast(FUNC_CTrain_CreateMissionTrain); + + createMissionTrain(vecPos, bDirection, uiTrainType, ppTrainBeginning, ppTrainEnd, iNodeIndex, iTrackId, bMissionTrain); + } + catch (...) + { + } +} + +CVehicle* CPoolsSA::AddTrain(CClientVehicle* pClientVehicle, const CVector& vecPosition, std::vector models, bool bDirection, + std::uint8_t ucTrackId) noexcept { // clean the existing array MemSetFast((void*)VAR_TrainModelArray, 0, 32 * sizeof(DWORD)); // now load the models we're going to use and add them to the array - for (int i = 0; i < iSize; i++) + std::size_t count = 0; + for (const auto model : models) { - if (dwModels[i] == 449 || dwModels[i] == 537 || dwModels[i] == 538 || dwModels[i] == 569 || dwModels[i] == 590 || dwModels[i] == 570) + // Valid model? + if (!CModelInfoSA::IsVehicleModel(model)) + return nullptr; + + if (model == 449 || model == 537 || model == 538 || model == 569 || model == 590 || model == 570) { - MemPutFast(VAR_TrainModelArray + i * 4, dwModels[i]); + MemPutFast(VAR_TrainModelArray + count * 4, model); + count += 1; } } - CTrainSAInterface* pTrainBeginning = nullptr; - CTrainSAInterface* pTrainEnd = nullptr; - - float fX = vecPosition->fX; - float fY = vecPosition->fY; - float fZ = vecPosition->fZ; - // Disable GetVehicle because CreateMissionTrain calls it before our CVehicleSA instance is inited m_bGetVehicleEnabled = false; // Find closest track node float fRailDistance; - int iNodeId = pGame->GetWorld()->FindClosestRailTrackNode(*vecPosition, ucTrackId, fRailDistance); + int iNodeId = pGame->GetWorld()->FindClosestRailTrackNode(vecPosition, ucTrackId, fRailDistance); int iDesiredTrackId = ucTrackId; - DWORD dwFunc = FUNC_CTrain_CreateMissionTrain; - _asm - { - push 0 // place as close to point as possible (rather than at node)? (maybe) (actually seems to have an effect on the speed, so changed from - // 1 to 0) - push iDesiredTrackId // track ID - push iNodeId // node to start at (-1 for closest node) - lea ecx, pTrainEnd - push ecx // end of train - lea ecx, pTrainBeginning - push ecx // begining of train - push 0 // train type (always use 0 as thats where we're writing to) - push bDirection // direction - push fZ // z - push fY // y - push fX // x - call dwFunc - add esp, 0x28 - } + CTrainSAInterface* pTrainBeginning = nullptr; + CTrainSAInterface* pTrainEnd = nullptr; + + CreateMissionTrain(vecPosition, bDirection, 0, &pTrainBeginning, &pTrainEnd, iNodeId, iDesiredTrackId, false); // Enable GetVehicle m_bGetVehicleEnabled = true; - CVehicleSA* trainHead = NULL; - if (pTrainBeginning) - { - DWORD vehicleIndex = 0; + if (!pTrainBeginning || m_vehiclePool.ulCount >= MAX_VEHICLES) + return nullptr; - if (m_vehiclePool.ulCount < MAX_VEHICLES) - { - trainHead = new CTrainSA(pTrainBeginning); - if (!AddVehicleToPool(pClientVehicle, trainHead)) - { - delete trainHead; - trainHead = NULL; - } - else - ++vehicleIndex; - } + std::size_t vehicleIndex = 0; + + std::unique_ptr train = std::make_unique(pTrainBeginning); + if (!train || !AddVehicleToPool(pClientVehicle, train.get())) + return nullptr; - CVehicleSA* carriage = trainHead; + ++vehicleIndex; - while (carriage) + CVehicleSA* pCarriage = train.get(); + while (m_vehiclePool.ulCount < MAX_VEHICLES && pCarriage && pCarriage->GetNextCarriageInTrain()) + { + CTrainSAInterface* pVehCarriage = pCarriage->GetNextCarriageInTrain(); + if (!pVehCarriage) + break; + + auto newCarriage = std::make_unique(pVehCarriage); + if (!newCarriage || !AddVehicleToPool(pClientVehicle, newCarriage.get())) { - if (m_vehiclePool.ulCount < MAX_VEHICLES) - { - CTrainSAInterface* vehCarriage = carriage->GetNextCarriageInTrain(); - if (vehCarriage) - { - carriage = new CTrainSA(vehCarriage); - if (!AddVehicleToPool(pClientVehicle, carriage)) - { - delete carriage; - carriage = NULL; - } - else - ++vehicleIndex; - } - else - carriage = NULL; - } + newCarriage.reset(); + break; } - } - // Stops the train from moving at ludacrist speeds right after creation - // due to some glitch in the node finding in CreateMissionTrain - CVector vec(0, 0, 0); - if (trainHead) - { - trainHead->SetMoveSpeed(&vec); + pCarriage = newCarriage.release(); + ++vehicleIndex; } - return trainHead; + train->SetMoveSpeed(CVector()); + return train.release(); } DWORD CPoolsSA::GetPedPoolIndex(std::uint8_t* pInterface) diff --git a/Client/game_sa/CPoolsSA.h b/Client/game_sa/CPoolsSA.h index 5718421d6c..27eeec68bc 100644 --- a/Client/game_sa/CPoolsSA.h +++ b/Client/game_sa/CPoolsSA.h @@ -30,7 +30,7 @@ class CPoolsSA : public CPools ~CPoolsSA(); // Vehicles pool - CVehicle* AddVehicle(CClientVehicle* pClientVehicle, eVehicleTypes eVehicleType, unsigned char ucVariation, unsigned char ucVariation2); + CVehicle* AddVehicle(CClientVehicle* pClientVehicle, std::uint16_t model, std::uint8_t variation, std::uint8_t variation2) noexcept; private: bool AddVehicleToPool(CClientVehicle* pClientVehicle, CVehicleSA* pVehicle); @@ -76,7 +76,8 @@ class CPoolsSA : public CPools uint GetModelIdFromClump(RpClump* pRpClump); // Others - CVehicle* AddTrain(CClientVehicle* pClientVehicle, CVector* vecPosition, DWORD dwModels[], int iSize, bool bDirection, uchar ucTrackId = 0xFF); + CVehicle* AddTrain(CClientVehicle* pClientVehicle, const CVector& vecPosition, std::vector models, bool bDirection, + std::uint8_t ucTrackId = 255) noexcept; DWORD GetPedPoolIndex(std::uint8_t* pInterface); DWORD GetVehiclePoolIndex(std::uint8_t* pInterfacee); diff --git a/Client/game_sa/CProjectileInfoSA.cpp b/Client/game_sa/CProjectileInfoSA.cpp index 439553941d..843f029462 100644 --- a/Client/game_sa/CProjectileInfoSA.cpp +++ b/Client/game_sa/CProjectileInfoSA.cpp @@ -180,3 +180,18 @@ DWORD CProjectileInfoSA::GetCounter() { return internalInterface->dwCounter - pGame->GetSystemTime(); } + +void CProjectileInfoSA::RemoveEntityReferences(CEntity* entity) +{ + const CEntitySAInterface* entityInterface = entity->GetInterface(); + for (int i = 0; i < PROJECTILE_INFO_COUNT; i++) + { + auto projectileInterface = projectileInfo[i]->internalInterface; + + if (projectileInterface->pEntProjectileOwner == entityInterface) + projectileInterface->pEntProjectileOwner = nullptr; + + if (projectileInterface->pEntProjectileTarget == entityInterface) + projectileInterface->pEntProjectileTarget = nullptr; + } +} diff --git a/Client/game_sa/CProjectileInfoSA.h b/Client/game_sa/CProjectileInfoSA.h index 2d8ba9cb32..73b69f74e2 100644 --- a/Client/game_sa/CProjectileInfoSA.h +++ b/Client/game_sa/CProjectileInfoSA.h @@ -42,7 +42,8 @@ class CProjectileInfoSAInterface }; // #pragma pack(pop) -class CProjectileInfoSA : public CProjectileInfo +// TODO extract manager class +class CProjectileInfoSA final : public CProjectileInfo { private: CProjectileInfoSA* projectileInfo[PROJECTILE_INFO_COUNT]; @@ -65,6 +66,7 @@ class CProjectileInfoSA : public CProjectileInfo CProjectileInfo* GetProjectileInfo(DWORD dwIndex); bool AddProjectile(CEntity* creator, eWeaponType eWeapon, CVector vecOrigin, float fForce, CVector* target, CEntity* targetEntity); CProjectile* GetProjectile(void* projectilePointer); + void RemoveEntityReferences(CEntity* entity); CEntity* GetTarget(); void SetTarget(CEntity* pEntity); diff --git a/Client/game_sa/CVehicleSA.cpp b/Client/game_sa/CVehicleSA.cpp index 9d4a02598e..296ddb9e47 100644 --- a/Client/game_sa/CVehicleSA.cpp +++ b/Client/game_sa/CVehicleSA.cpp @@ -224,6 +224,7 @@ CVehicleSA::~CVehicleSA() } CWorldSA* pWorld = (CWorldSA*)pGame->GetWorld(); + pGame->GetProjectileInfo()->RemoveEntityReferences(this); pWorld->Remove(m_pInterface, CVehicle_Destructor); pWorld->RemoveReferencesToDeletedObject(m_pInterface); @@ -240,18 +241,24 @@ CVehicleSA::~CVehicleSA() } } -void CVehicleSA::SetMoveSpeed(CVector* vecMoveSpeed) +void CVehicleSA::SetMoveSpeed(const CVector& vecMoveSpeed) noexcept { - DWORD dwFunc = FUNC_GetMoveSpeed; - DWORD dwThis = (DWORD)GetInterface(); - DWORD dwReturn = 0; - _asm + try + { + DWORD dwFunc = FUNC_GetMoveSpeed; + DWORD dwThis = (DWORD)GetInterface(); + DWORD dwReturn = 0; + _asm + { + mov ecx, dwThis + call dwFunc + mov dwReturn, eax + } + MemCpyFast((void*)dwReturn, &vecMoveSpeed, sizeof(CVector)); + } + catch (...) { - mov ecx, dwThis - call dwFunc - mov dwReturn, eax } - MemCpyFast((void*)dwReturn, vecMoveSpeed, sizeof(CVector)); // INACCURATE. Use Get/SetTrainSpeed instead of Get/SetMoveSpeed. (Causes issue #4829). #if 0 diff --git a/Client/game_sa/CVehicleSA.h b/Client/game_sa/CVehicleSA.h index 9674a165cd..1bf81d63b4 100644 --- a/Client/game_sa/CVehicleSA.h +++ b/Client/game_sa/CVehicleSA.h @@ -437,7 +437,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA virtual void OnChangingPosition(const CVector& vecNewPosition); // Override of CPhysicalSA::SetMoveSpeed to take trains into account - void SetMoveSpeed(CVector* vecMoveSpeed); + void SetMoveSpeed(const CVector& vecMoveSpeed) noexcept; bool AddProjectile(eWeaponType eWeapon, CVector vecOrigin, float fForce, CVector* target, CEntity* targetEntity); diff --git a/Client/game_sa/CWorldSA.cpp b/Client/game_sa/CWorldSA.cpp index a60e360464..72befc316e 100644 --- a/Client/game_sa/CWorldSA.cpp +++ b/Client/game_sa/CWorldSA.cpp @@ -528,6 +528,23 @@ bool CWorldSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd return bReturn; } +CEntity* CWorldSA::TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) +{ + auto entity = ((CEntitySAInterface*(__cdecl*)(CVector, float, CEntitySAInterface*, bool, bool, bool, bool, bool, bool))FUNC_CWorld_TestSphereAgainstWorld)(sphereCenter, radius, ignoredEntity ? ignoredEntity->GetInterface() : nullptr, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, cameraIgnore); + if (!entity) + return nullptr; + + result.collisionDetected = true; + result.modelID = entity->m_nModelIndex; + result.entityPosition = entity->Placeable.matrix->vPos; + ConvertMatrixToEulerAngles(*entity->Placeable.matrix, result.entityRotation.fX, result.entityRotation.fY, result.entityRotation.fZ); + result.entityRotation = -result.entityRotation; + result.lodID = entity->m_pLod ? entity->m_pLod->m_nModelIndex : 0; + result.type = static_cast(entity->nType); + + return pGame->GetPools()->GetEntity(reinterpret_cast(entity)); +} + void CWorldSA::IgnoreEntity(CEntity* pEntity) { CEntitySA* pEntitySA = dynamic_cast(pEntity); diff --git a/Client/game_sa/CWorldSA.h b/Client/game_sa/CWorldSA.h index 340db3ef5d..5da287a1a6 100644 --- a/Client/game_sa/CWorldSA.h +++ b/Client/game_sa/CWorldSA.h @@ -25,6 +25,7 @@ #define VAR_COcclusion_NumActiveOccluders 0xC73CC0 #define CALL_CCullZones_FindTunnelAttributesForCoors 0x55570D #define FUNC_CWorld_FindPositionForTrackPosition 0x6F59E0 +#define FUNC_CWorld_TestSphereAgainstWorld 0x569E20 #define VAR_IgnoredEntity 0xB7CD68 #define VAR_currArea 0xB72914 @@ -74,6 +75,8 @@ class CWorldSA : public CWorld void ResetAllSurfaceInfo() override; bool ResetSurfaceInfo(short sSurfaceID) override; + CEntity* TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) override; + private: float m_fAircraftMaxHeight; CSurfaceType* m_pSurfaceInfo; diff --git a/Client/loader/Utils.cpp b/Client/loader/Utils.cpp index 9d3ead9eba..7dae8ce439 100644 --- a/Client/loader/Utils.cpp +++ b/Client/loader/Utils.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #pragma comment (lib, "wintrust") namespace fs = std::filesystem; @@ -527,30 +528,26 @@ bool LookForGtaProcess(SString& strOutPathFilename) // // /////////////////////////////////////////////////////////////// -SString DoUserAssistedSearch() +static const SString DoUserAssistedSearch() noexcept { - SString strResult; + SString result; - ShowProgressDialog(g_hInstance, _("Searching for Grand Theft Auto San Andreas"), true); + MessageBox(nullptr, _("Start Grand Theft Auto: San Andreas.\nEnsure the game is placed in the 'Program Files (x86)' folder."), _("Searching for GTA: San Andreas"), MB_OK | MB_ICONINFORMATION); - while (!UpdateProgress(0, 100, _("Please start Grand Theft Auto San Andreas"))) + while (true) { - SString strPathFilename; - // Check if user has started GTA - if (LookForGtaProcess(strPathFilename)) + SString path; + + if (LookForGtaProcess(path)) { - // If so, get the exe path - ExtractFilename(strPathFilename, &strResult, NULL); - // And then stop it + ExtractFilename(path, &result, nullptr); TerminateGTAIfRunning(); - break; + return result; } - Sleep(200); + if (MessageBox(nullptr, _("Sorry, game not found.\nStart Grand Theft Auto: San Andreas and click retry.\nEnsure the game is placed in the 'Program Files (x86)' folder."), _("Searching for GTA: San Andreas"), MB_RETRYCANCEL | MB_ICONWARNING) == IDCANCEL) + return result; } - - HideProgressDialog(); - return strResult; } /////////////////////////////////////////////////////////////// diff --git a/Client/mods/deathmatch/logic/CClientBuildingManager.cpp b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp index 243917b89f..a09df6a226 100644 --- a/Client/mods/deathmatch/logic/CClientBuildingManager.cpp +++ b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp @@ -73,11 +73,6 @@ bool CClientBuildingManager::IsValidModel(uint16_t modelId) if (!pModelInfo->IsAllocatedInArchive()) return false; - if (pModelInfo->IsDynamic()) - { - return false; - } - eModelInfoType eType = pModelInfo->GetModelType(); return (eType == eModelInfoType::CLUMP || eType == eModelInfoType::ATOMIC || eType == eModelInfoType::WEAPON || eType == eModelInfoType::TIME); } @@ -106,29 +101,9 @@ void CClientBuildingManager::RestoreDestroyed() { const CClientBuilding* highLodBuilding = building->GetHighLodBuilding(); if (highLodBuilding && !highLodBuilding->IsValid()) - { hasInvalidLods = true; - } else - { - CModelInfo* modelInfo = building->GetModelInfo(); - const uint16_t physicalGroup = modelInfo->GetObjectPropertiesGroup(); - - if (physicalGroup == -1) - { - building->Create(); - } - else - { - // GTA creates dynamic models as dummies. - // It's possible that the physical group was changes after - // creating a new building. We can avoid crashes in this case. - modelInfo->SetObjectPropertiesGroup(-1); - building->Create(); - modelInfo->SetObjectPropertiesGroup(physicalGroup); - } - - } + building->Create(); } } } diff --git a/Client/mods/deathmatch/logic/CClientGUIManager.cpp b/Client/mods/deathmatch/logic/CClientGUIManager.cpp index b2eb23322c..8b3db9650a 100644 --- a/Client/mods/deathmatch/logic/CClientGUIManager.cpp +++ b/Client/mods/deathmatch/logic/CClientGUIManager.cpp @@ -43,7 +43,7 @@ void CClientGUIManager::DeleteAll() bool CClientGUIManager::Exists(CClientGUIElement* pGUIElement) { - return m_Elements.Contains(pGUIElement); + return pGUIElement ? m_Elements.Contains(pGUIElement) : false; } bool CClientGUIManager::Exists(CGUIElement* pCGUIElement) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index a6348f4381..eedd7cfd7a 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -34,6 +34,7 @@ #include #include #include "game/CClock.h" +#include #include #include "CServerInfo.h" @@ -135,6 +136,7 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; m_Glitches[GLITCH_QUICKSTAND] = false; m_Glitches[GLITCH_KICKOUTOFVEHICLE_ONMODELREPLACE] = false; + g_pMultiplayer->DisableBadDrivebyHitboxes(true); // Remove Night & Thermal vision view (if enabled). @@ -402,6 +404,10 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) CClientGame::~CClientGame() { m_bBeingDeleted = true; + // Remove active projectile references to local player + if (auto pLocalPlayer = g_pClientGame->GetLocalPlayer()) + g_pGame->GetProjectileInfo()->RemoveEntityReferences(pLocalPlayer->GetGameEntity()); + // Stop all explosions. Unfortunately this doesn't fix the crash // if a vehicle is destroyed while it explodes. g_pGame->GetExplosionManager()->RemoveAllExplosions(); @@ -5982,7 +5988,7 @@ bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; } -bool CClientGame::SetWorldSpecialProperty(WorldSpecialProperty property, bool isEnabled) +bool CClientGame::SetWorldSpecialProperty(WorldSpecialProperty property, bool isEnabled) noexcept { switch (property) { @@ -5990,44 +5996,60 @@ bool CClientGame::SetWorldSpecialProperty(WorldSpecialProperty property, bool is case WorldSpecialProperty::AIRCARS: case WorldSpecialProperty::EXTRABUNNY: case WorldSpecialProperty::EXTRAJUMP: - return g_pGame->SetCheatEnabled(EnumToString(property), isEnabled); + g_pGame->SetCheatEnabled(EnumToString(property), isEnabled); + break; case WorldSpecialProperty::RANDOMFOLIAGE: g_pGame->SetRandomFoliageEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::SNIPERMOON: g_pGame->SetMoonEasterEggEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::EXTRAAIRRESISTANCE: g_pGame->SetExtraAirResistanceEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::UNDERWORLDWARP: g_pGame->SetUnderWorldWarpEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::VEHICLESUNGLARE: g_pGame->SetVehicleSunGlareEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::CORONAZTEST: g_pGame->SetCoronaZTestEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::WATERCREATURES: g_pGame->SetWaterCreaturesEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::BURNFLIPPEDCARS: g_pGame->SetBurnFlippedCarsEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::FIREBALLDESTRUCT: g_pGame->SetFireballDestructEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::EXTENDEDWATERCANNONS: g_pGame->SetExtendedWaterCannonsEnabled(isEnabled); + break; case WorldSpecialProperty::ROADSIGNSTEXT: g_pGame->SetRoadSignsTextEnabled(isEnabled); - return true; + break; case WorldSpecialProperty::TUNNELWEATHERBLEND: g_pGame->SetTunnelWeatherBlendEnabled(isEnabled); - return true; + break; + case WorldSpecialProperty::IGNOREFIRESTATE: + g_pGame->SetIgnoreFireStateEnabled(isEnabled); + break; + default: + return false; } - return false; + + if (g_pNet->CanServerBitStream(eBitStreamVersion::WorldSpecialPropertyEvent)) { + NetBitStreamInterface* stream = g_pNet->AllocateNetBitStream(); + stream->WriteString(EnumToString(property)); + stream->WriteBit(isEnabled); + g_pNet->SendPacket(PACKET_ID_PLAYER_WORLD_SPECIAL_PROPERTY, stream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(stream); + } + + return true; } bool CClientGame::IsWorldSpecialProperty(WorldSpecialProperty property) @@ -6063,6 +6085,8 @@ bool CClientGame::IsWorldSpecialProperty(WorldSpecialProperty property) return g_pGame->IsRoadSignsTextEnabled(); case WorldSpecialProperty::TUNNELWEATHERBLEND: return g_pGame->IsTunnelWeatherBlendEnabled(); + case WorldSpecialProperty::IGNOREFIRESTATE: + return g_pGame->IsIgnoreFireStateEnabled(); } return false; } @@ -6476,7 +6500,7 @@ void CClientGame::OutputServerInfo() { SString strEnabledGlitches; const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", - "Bad driveby hitboxes", "Quick stand"}; + "Bad driveby hitboxes", "Quick stand", "Kickout of vehicle on model replace"}; for (uint i = 0; i < NUM_GLITCHES; i++) { if (IsGlitchEnabled(i)) diff --git a/Client/mods/deathmatch/logic/CClientGame.h b/Client/mods/deathmatch/logic/CClientGame.h index ba6bc29334..4423f35cf2 100644 --- a/Client/mods/deathmatch/logic/CClientGame.h +++ b/Client/mods/deathmatch/logic/CClientGame.h @@ -410,7 +410,7 @@ class CClientGame bool SetGlitchEnabled(unsigned char cGlitch, bool bEnabled); bool IsGlitchEnabled(unsigned char cGlitch); - bool SetWorldSpecialProperty(WorldSpecialProperty property, bool isEnabled); + bool SetWorldSpecialProperty(WorldSpecialProperty property, bool isEnabled) noexcept; bool IsWorldSpecialProperty(WorldSpecialProperty property); bool SetCloudsEnabled(bool bEnabled); diff --git a/Client/mods/deathmatch/logic/CClientObject.cpp b/Client/mods/deathmatch/logic/CClientObject.cpp index 7d34045f1b..de1cdaad50 100644 --- a/Client/mods/deathmatch/logic/CClientObject.cpp +++ b/Client/mods/deathmatch/logic/CClientObject.cpp @@ -668,7 +668,7 @@ void CClientObject::SetMoveSpeed(const CVector& vecMoveSpeed) { if (m_pObject) { - m_pObject->SetMoveSpeed(const_cast(&vecMoveSpeed)); + m_pObject->SetMoveSpeed(vecMoveSpeed); } m_vecMoveSpeed = vecMoveSpeed; } diff --git a/Client/mods/deathmatch/logic/CClientPed.cpp b/Client/mods/deathmatch/logic/CClientPed.cpp index f4c9ba5ee6..533d63975f 100644 --- a/Client/mods/deathmatch/logic/CClientPed.cpp +++ b/Client/mods/deathmatch/logic/CClientPed.cpp @@ -831,7 +831,7 @@ void CClientPed::SetMoveSpeed(const CVector& vecMoveSpeed) { if (m_pPlayerPed) { - m_pPlayerPed->SetMoveSpeed(const_cast(&vecMoveSpeed)); + m_pPlayerPed->SetMoveSpeed(vecMoveSpeed); } m_vecMoveSpeed = vecMoveSpeed; } @@ -2754,7 +2754,7 @@ void CClientPed::StreamedInPulse(bool bDoStandardPulses) { CVector vecTemp; m_pPlayerPed->SetMatrix(&m_matFrozen); - m_pPlayerPed->SetMoveSpeed(&vecTemp); + m_pPlayerPed->SetMoveSpeed(vecTemp); } // Is our health locked? @@ -3612,7 +3612,7 @@ void CClientPed::_CreateModel() m_pPlayerPed->SetMatrix(&m_Matrix); m_pPlayerPed->SetCurrentRotation(m_fCurrentRotation); m_pPlayerPed->SetTargetRotation(m_fTargetRotation); - m_pPlayerPed->SetMoveSpeed(&m_vecMoveSpeed); + m_pPlayerPed->SetMoveSpeed(m_vecMoveSpeed); m_pPlayerPed->SetTurnSpeed(&m_vecTurnSpeed); Duck(m_bDucked); SetWearingGoggles(m_bWearingGoggles); diff --git a/Client/mods/deathmatch/logic/CClientProjectile.cpp b/Client/mods/deathmatch/logic/CClientProjectile.cpp index 43f2d1930d..048334da6a 100644 --- a/Client/mods/deathmatch/logic/CClientProjectile.cpp +++ b/Client/mods/deathmatch/logic/CClientProjectile.cpp @@ -289,7 +289,7 @@ void CClientProjectile::GetVelocity(CVector& vecVelocity) void CClientProjectile::SetVelocity(CVector& vecVelocity) { if (m_pProjectile) - m_pProjectile->SetMoveSpeed(&vecVelocity); + m_pProjectile->SetMoveSpeed(vecVelocity); } unsigned short CClientProjectile::GetModel() diff --git a/Client/mods/deathmatch/logic/CClientVehicle.cpp b/Client/mods/deathmatch/logic/CClientVehicle.cpp index 537f9457dd..8cd4d2761a 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.cpp +++ b/Client/mods/deathmatch/logic/CClientVehicle.cpp @@ -55,30 +55,30 @@ CClientVehicle::CClientVehicle(CClientManager* pManager, ElementID ID, unsigned m_pModelInfo = g_pGame->GetModelInfo(usModel); // Apply handling - ushort usHandlingModelID = m_usModel; + std::uint16_t usHandlingModelID = m_usModel; if (m_usModel < 400 || m_usModel > 611) usHandlingModelID = m_pModelInfo->GetParentID(); - m_pOriginalHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(static_cast(usHandlingModelID)); - m_pHandlingEntry = g_pGame->GetHandlingManager()->CreateHandlingData(); - m_pHandlingEntry->Assign(m_pOriginalHandlingEntry); + m_pOriginalHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(usHandlingModelID); + m_HandlingEntry = g_pGame->GetHandlingManager()->CreateHandlingData(); + m_HandlingEntry->Assign(m_pOriginalHandlingEntry); - m_pOriginalFlyingHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalFlyingHandlingData(static_cast(usHandlingModelID)); - m_pFlyingHandlingEntry = g_pGame->GetHandlingManager()->CreateFlyingHandlingData(); - m_pFlyingHandlingEntry->Assign(m_pOriginalFlyingHandlingEntry); + m_pOriginalFlyingHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalFlyingHandlingData(usHandlingModelID); + m_FlyingHandlingEntry = g_pGame->GetHandlingManager()->CreateFlyingHandlingData(); + m_FlyingHandlingEntry->Assign(m_pOriginalFlyingHandlingEntry); - m_pOriginalBoatHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalBoatHandlingData(static_cast(usHandlingModelID)); + m_pOriginalBoatHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalBoatHandlingData(usHandlingModelID); if (m_pOriginalBoatHandlingEntry) { - m_pBoatHandlingEntry = g_pGame->GetHandlingManager()->CreateBoatHandlingData(); - m_pBoatHandlingEntry->Assign(m_pOriginalBoatHandlingEntry); + m_BoatHandlingEntry = g_pGame->GetHandlingManager()->CreateBoatHandlingData(); + m_BoatHandlingEntry->Assign(m_pOriginalBoatHandlingEntry); } - m_pOriginalBikeHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalBikeHandlingData(static_cast(usHandlingModelID)); + m_pOriginalBikeHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalBikeHandlingData(usHandlingModelID); if (m_pOriginalBikeHandlingEntry) { - m_pBikeHandlingEntry = g_pGame->GetHandlingManager()->CreateBikeHandlingData(); - m_pBikeHandlingEntry->Assign(m_pOriginalBikeHandlingEntry); + m_BikeHandlingEntry = g_pGame->GetHandlingManager()->CreateBikeHandlingData(); + m_BikeHandlingEntry->Assign(m_pOriginalBikeHandlingEntry); } SetTypeName("vehicle"); @@ -277,10 +277,6 @@ CClientVehicle::~CClientVehicle() Unlink(); delete m_pUpgrades; - delete m_pHandlingEntry; - delete m_pFlyingHandlingEntry; - delete m_pBoatHandlingEntry; - delete m_pBikeHandlingEntry; delete m_LastSyncedData; CClientEntityRefManager::RemoveEntityRefs(0, &m_pDriver, &m_pOccupyingDriver, &m_pPreviousLink, &m_pNextLink, &m_pTowedVehicle, &m_pTowedByVehicle, &m_pPickedUpWinchEntity, NULL); @@ -361,7 +357,7 @@ void CClientVehicle::SetPosition(const CVector& vecPosition, bool bResetInterpol if (vecMoveSpeed.fX == 0.0f && vecMoveSpeed.fY == 0.0f && vecMoveSpeed.fZ == 0.0f) { vecMoveSpeed.fZ -= 0.01f; - m_pVehicle->SetMoveSpeed(&vecMoveSpeed); + m_pVehicle->SetMoveSpeed(vecMoveSpeed); } } } @@ -564,7 +560,7 @@ void CClientVehicle::SetMoveSpeed(const CVector& vecMoveSpeed) if (!m_bIsFrozen) { if (m_pVehicle) - m_pVehicle->SetMoveSpeed(const_cast(&vecMoveSpeed)); + m_pVehicle->SetMoveSpeed(vecMoveSpeed); m_vecMoveSpeed = vecMoveSpeed; @@ -1055,32 +1051,32 @@ void CClientVehicle::SetModelBlocking(unsigned short usModel, unsigned char ucVa // Reset handling to fit the vehicle if (IsLocalEntity() || !(usModel < 400 || usModel > 611)) { - ushort usHandlingModelID = usModel; + std::uint16_t usHandlingModelID = usModel; if (usHandlingModelID < 400 || usHandlingModelID > 611) usHandlingModelID = m_pModelInfo->GetParentID(); - m_pOriginalHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData((eVehicleTypes)usHandlingModelID); - m_pHandlingEntry->Assign(m_pOriginalHandlingEntry); + m_pOriginalHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(usHandlingModelID); + m_HandlingEntry->Assign(m_pOriginalHandlingEntry); - m_pOriginalFlyingHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalFlyingHandlingData((eVehicleTypes)usHandlingModelID); - m_pFlyingHandlingEntry->Assign(m_pOriginalFlyingHandlingEntry); + m_pOriginalFlyingHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalFlyingHandlingData(usHandlingModelID); + m_FlyingHandlingEntry->Assign(m_pOriginalFlyingHandlingEntry); - m_pOriginalBoatHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalBoatHandlingData((eVehicleTypes)usHandlingModelID); + m_pOriginalBoatHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalBoatHandlingData(usHandlingModelID); if (m_pOriginalBoatHandlingEntry) { - if (!m_pBoatHandlingEntry) - m_pBoatHandlingEntry = g_pGame->GetHandlingManager()->CreateBoatHandlingData(); + if (!m_BoatHandlingEntry) + m_BoatHandlingEntry = g_pGame->GetHandlingManager()->CreateBoatHandlingData(); - m_pBoatHandlingEntry->Assign(m_pOriginalBoatHandlingEntry); + m_BoatHandlingEntry->Assign(m_pOriginalBoatHandlingEntry); } - m_pOriginalBikeHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalBikeHandlingData((eVehicleTypes)usHandlingModelID); + m_pOriginalBikeHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalBikeHandlingData(usHandlingModelID); if (m_pOriginalBikeHandlingEntry) { - if (!m_pBikeHandlingEntry) - m_pBikeHandlingEntry = g_pGame->GetHandlingManager()->CreateBikeHandlingData(); + if (!m_BikeHandlingEntry) + m_BikeHandlingEntry = g_pGame->GetHandlingManager()->CreateBikeHandlingData(); - m_pBikeHandlingEntry->Assign(m_pOriginalBikeHandlingEntry); + m_BikeHandlingEntry->Assign(m_pOriginalBikeHandlingEntry); } } @@ -1802,7 +1798,7 @@ void CClientVehicle::SetFrozen(bool bFrozen) if (m_pVehicle) { m_pVehicle->GetMatrix(&m_matFrozen); - m_pVehicle->SetMoveSpeed(&vecTemp); + m_pVehicle->SetMoveSpeed(vecTemp); m_pVehicle->SetTurnSpeed(&vecTemp); } else @@ -1822,7 +1818,7 @@ void CClientVehicle::SetFrozen(bool bFrozen) if (m_pVehicle) { m_pVehicle->GetMatrix(&m_matFrozen); - m_pVehicle->SetMoveSpeed(&vecTemp); + m_pVehicle->SetMoveSpeed(vecTemp); m_pVehicle->SetTurnSpeed(&vecTemp); } else @@ -1863,7 +1859,7 @@ void CClientVehicle::SetFrozenWaitingForGroundToLoad(bool bFrozen, bool bSuspend if (m_pVehicle) { m_pVehicle->GetMatrix(&m_matFrozen); - m_pVehicle->SetMoveSpeed(&vecTemp); + m_pVehicle->SetMoveSpeed(vecTemp); m_pVehicle->SetTurnSpeed(&vecTemp); } else @@ -1887,7 +1883,7 @@ void CClientVehicle::SetFrozenWaitingForGroundToLoad(bool bFrozen, bool bSuspend m_vecTurnSpeed = m_vecWaitingForGroundSavedTurnSpeed; if (m_pVehicle) { - m_pVehicle->SetMoveSpeed(&m_vecMoveSpeed); + m_pVehicle->SetMoveSpeed(m_vecMoveSpeed); m_pVehicle->SetTurnSpeed(&m_vecTurnSpeed); } m_bAsyncLoadingDisabled = false; @@ -2227,7 +2223,7 @@ void CClientVehicle::StreamedInPulse() { CVector vecTemp; m_pVehicle->SetMatrix(&m_matFrozen); - m_pVehicle->SetMoveSpeed(&vecTemp); + m_pVehicle->SetMoveSpeed(vecTemp); m_pVehicle->SetTurnSpeed(&vecTemp); } else @@ -2249,7 +2245,7 @@ void CClientVehicle::StreamedInPulse() { m_pVehicle->SetMatrix(&m_matFrozen); CVector vec(0.0f, 0.0f, 0.0f); - m_pVehicle->SetMoveSpeed(&vec); + m_pVehicle->SetMoveSpeed(vec); } // Added by ChrML 27. Nov: Shouldn't cause any problems m_pVehicle->SetUsesCollision(false); @@ -2480,13 +2476,12 @@ void CClientVehicle::Create() // Create the vehicle if (CClientVehicleManager::IsTrainModel(m_usModel)) { - DWORD dwModels[1]; - dwModels[0] = m_usModel; - m_pVehicle = g_pGame->GetPools()->AddTrain(this, &m_Matrix.vPos, dwModels, 1, m_bTrainDirection, m_ucTrackID); + std::vector Models{m_usModel}; + m_pVehicle = g_pGame->GetPools()->AddTrain(this, m_Matrix.vPos, Models, m_bTrainDirection, m_ucTrackID); } else { - m_pVehicle = g_pGame->GetPools()->AddVehicle(this, static_cast(m_usModel), m_ucVariation, m_ucVariation2); + m_pVehicle = g_pGame->GetPools()->AddVehicle(this, m_usModel, m_ucVariation, m_ucVariation2); } // Failed. Remove our reference to the vehicle model and return @@ -2722,7 +2717,7 @@ void CClientVehicle::Create() m_vecMoveSpeed.fZ > -0.01f) { m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.01f); - m_pVehicle->SetMoveSpeed(&m_vecMoveSpeed); + m_pVehicle->SetMoveSpeed(m_vecMoveSpeed); } // Validate @@ -2742,19 +2737,19 @@ void CClientVehicle::Create() SetWindowOpen(i, m_bWindowOpen[i]); // Re-apply handling entry - if (m_pHandlingEntry) + if (m_HandlingEntry) { - m_pVehicle->SetHandlingData(m_pHandlingEntry); - m_pVehicle->SetFlyingHandlingData(m_pFlyingHandlingEntry); + m_pVehicle->SetHandlingData(m_HandlingEntry.get()); + m_pVehicle->SetFlyingHandlingData(m_FlyingHandlingEntry.get()); switch (m_eVehicleType) { case CLIENTVEHICLE_BOAT: - dynamic_cast(m_pVehicle)->SetBoatHandlingData(m_pBoatHandlingEntry); + dynamic_cast(m_pVehicle)->SetBoatHandlingData(m_BoatHandlingEntry.get()); break; case CLIENTVEHICLE_BIKE: case CLIENTVEHICLE_BMX: - dynamic_cast(m_pVehicle)->SetBikeHandlingData(m_pBikeHandlingEntry); + dynamic_cast(m_pVehicle)->SetBikeHandlingData(m_BikeHandlingEntry.get()); break; } @@ -2919,17 +2914,17 @@ void CClientVehicle::Destroy() m_bIsOnGround = IsOnGround(); m_fHeliRotorSpeed = GetHeliRotorSpeed(); m_bHeliSearchLightVisible = IsHeliSearchLightVisible(); - m_pHandlingEntry = m_pVehicle->GetHandlingData(); - m_pFlyingHandlingEntry = m_pVehicle->GetFlyingHandlingData(); + m_HandlingEntry->Assign(m_pVehicle->GetHandlingData()); + m_FlyingHandlingEntry->Assign(m_pVehicle->GetFlyingHandlingData()); switch (m_eVehicleType) { case CLIENTVEHICLE_BOAT: - m_pBoatHandlingEntry = dynamic_cast(m_pVehicle)->GetBoatHandlingData(); + m_BoatHandlingEntry->Assign(dynamic_cast(m_pVehicle)->GetBoatHandlingData()); break; case CLIENTVEHICLE_BIKE: case CLIENTVEHICLE_BMX: - m_pBikeHandlingEntry = dynamic_cast(m_pVehicle)->GetBikeHandlingData(); + m_BikeHandlingEntry->Assign(dynamic_cast(m_pVehicle)->GetBikeHandlingData()); break; default: break; @@ -3759,12 +3754,12 @@ void CClientVehicle::UpdateTargetPosition() if (m_eVehicleType != CLIENTVEHICLE_HELI && m_eVehicleType != CLIENTVEHICLE_BOAT) { // Ghostmode upwards movement compensation - CVector MoveSpeed; - m_pVehicle->GetMoveSpeed(&MoveSpeed); - float SpeedXY = CVector(MoveSpeed.fX, MoveSpeed.fY, 0).Length(); - if (MoveSpeed.fZ > 0.00 && MoveSpeed.fZ < 0.02 && MoveSpeed.fZ > SpeedXY) - MoveSpeed.fZ = SpeedXY; - m_pVehicle->SetMoveSpeed(&MoveSpeed); + CVector vecMoveSpeed; + m_pVehicle->GetMoveSpeed(&vecMoveSpeed); + float SpeedXY = CVector(vecMoveSpeed.fX, vecMoveSpeed.fY, 0).Length(); + if (vecMoveSpeed.fZ > 0.00 && vecMoveSpeed.fZ < 0.02 && vecMoveSpeed.fZ > SpeedXY) + vecMoveSpeed.fZ = SpeedXY; + m_pVehicle->SetMoveSpeed(vecMoveSpeed); } } @@ -4252,8 +4247,8 @@ CHandlingEntry* CClientVehicle::GetHandlingData() { if (m_pVehicle) return m_pVehicle->GetHandlingData(); - else if (m_pHandlingEntry) - return m_pHandlingEntry; + else if (m_HandlingEntry) + return m_HandlingEntry.get(); return nullptr; } @@ -4262,8 +4257,8 @@ CFlyingHandlingEntry* CClientVehicle::GetFlyingHandlingData() { if (m_pVehicle) return m_pVehicle->GetFlyingHandlingData(); - else if (m_pFlyingHandlingEntry) - return m_pFlyingHandlingEntry; + else if (m_FlyingHandlingEntry) + return m_FlyingHandlingEntry.get(); return nullptr; } @@ -4275,8 +4270,8 @@ CBoatHandlingEntry* CClientVehicle::GetBoatHandlingData() if (m_pVehicle) return reinterpret_cast(m_pVehicle)->GetBoatHandlingData(); - else if (m_pBoatHandlingEntry) - return m_pBoatHandlingEntry; + else if (m_BoatHandlingEntry) + return m_BoatHandlingEntry.get(); return nullptr; } @@ -4288,8 +4283,8 @@ CBikeHandlingEntry* CClientVehicle::GetBikeHandlingData() if (m_pVehicle) return reinterpret_cast(m_pVehicle)->GetBikeHandlingData(); - else if (m_pBikeHandlingEntry) - return m_pBikeHandlingEntry; + else if (m_BikeHandlingEntry) + return m_BikeHandlingEntry.get(); return nullptr; } @@ -4342,7 +4337,7 @@ void CClientVehicle::HandleWaitingForGroundToLoad() // Reset position CVector vecTemp; m_pVehicle->SetMatrix(&m_matFrozen); - m_pVehicle->SetMoveSpeed(&vecTemp); + m_pVehicle->SetMoveSpeed(vecTemp); m_pVehicle->SetTurnSpeed(&vecTemp); m_vecMoveSpeed = vecTemp; m_vecTurnSpeed = vecTemp; diff --git a/Client/mods/deathmatch/logic/CClientVehicle.h b/Client/mods/deathmatch/logic/CClientVehicle.h index 76ec08eff1..a56a7cd5e2 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.h +++ b/Client/mods/deathmatch/logic/CClientVehicle.h @@ -653,13 +653,13 @@ class CClientVehicle : public CClientStreamElement float m_fHeliRotorSpeed; float m_fPlaneRotorSpeed; const CHandlingEntry* m_pOriginalHandlingEntry = nullptr; - CHandlingEntry* m_pHandlingEntry = nullptr; + std::unique_ptr m_HandlingEntry = nullptr; const CFlyingHandlingEntry* m_pOriginalFlyingHandlingEntry = nullptr; - CFlyingHandlingEntry* m_pFlyingHandlingEntry = nullptr; + std::unique_ptr m_FlyingHandlingEntry = nullptr; const CBoatHandlingEntry* m_pOriginalBoatHandlingEntry = nullptr; - CBoatHandlingEntry* m_pBoatHandlingEntry = nullptr; + std::unique_ptr m_BoatHandlingEntry = nullptr; const CBikeHandlingEntry* m_pOriginalBikeHandlingEntry = nullptr; - CBikeHandlingEntry* m_pBikeHandlingEntry = nullptr; + std::unique_ptr m_BikeHandlingEntry = nullptr; float m_fNitroLevel; char m_cNitroCount; float m_fWheelScale; diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index ebf2ba5140..787cd4c239 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -572,6 +572,10 @@ void CPacketHandler::Packet_ServerDisconnected(NetBitStreamInterface& bitStream) strReason = _("Disconnected: Serial verification failed"); strErrorCode = _E("CD44"); break; + case ePlayerDisconnectType::SERIAL_DUPLICATE: + strReason = _("Disconnected: Serial already in use"); + strErrorCode = _E("CD50"); + break; case ePlayerDisconnectType::CONNECTION_DESYNC: strReason = _("Disconnected: Connection desync %s"); strErrorCode = _E("CD45"); @@ -2393,6 +2397,7 @@ void CPacketHandler::Packet_MapInfo(NetBitStreamInterface& bitStream) g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::ROADSIGNSTEXT, wsProps.data3.roadsignstext); g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::EXTENDEDWATERCANNONS, wsProps.data4.extendedwatercannons); g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::TUNNELWEATHERBLEND, wsProps.data5.tunnelweatherblend); + g_pClientGame->SetWorldSpecialProperty(WorldSpecialProperty::IGNOREFIRESTATE, wsProps.data6.ignoreFireState); float fJetpackMaxHeight = 100; if (!bitStream.Read(fJetpackMaxHeight)) diff --git a/Client/mods/deathmatch/logic/CPacketHandler.h b/Client/mods/deathmatch/logic/CPacketHandler.h index ca0f6f3d69..9a50b24615 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.h +++ b/Client/mods/deathmatch/logic/CPacketHandler.h @@ -42,7 +42,8 @@ class CPacketHandler BAN, KICK, CUSTOM, - SHUTDOWN + SHUTDOWN, + SERIAL_DUPLICATE }; struct SEntityDependantStuff diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 5efe5b417e..fc1ae38e3b 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -8975,11 +8975,8 @@ bool CStaticFunctionDefinitions::ResetVehicleHandling(CClientVehicle* pVehicle) { assert(pVehicle); - eVehicleTypes eModel = (eVehicleTypes)pVehicle->GetModel(); CHandlingEntry* pEntry = pVehicle->GetHandlingData(); - const CHandlingEntry* pNewEntry; - - pNewEntry = pVehicle->GetOriginalHandlingData(); + const CHandlingEntry* pNewEntry = pVehicle->GetOriginalHandlingData(); pEntry->SetMass(pNewEntry->GetMass()); pEntry->SetTurnMass(pNewEntry->GetTurnMass()); @@ -9015,17 +9012,13 @@ bool CStaticFunctionDefinitions::ResetVehicleHandling(CClientVehicle* pVehicle) // pEntry->SetTailLight(pNewEntry->GetTailLight ()); pEntry->SetAnimGroup(pNewEntry->GetAnimGroup()); - // Lower and Upper limits cannot match or LSOD (unless boat) - // if ( eModel != VEHICLE_BOAT ) // Commented until fully tested + float fSuspensionLimitSize = pEntry->GetSuspensionUpperLimit() - pEntry->GetSuspensionLowerLimit(); + if (fSuspensionLimitSize > -0.1f && fSuspensionLimitSize < 0.1f) { - float fSuspensionLimitSize = pEntry->GetSuspensionUpperLimit() - pEntry->GetSuspensionLowerLimit(); - if (fSuspensionLimitSize > -0.1f && fSuspensionLimitSize < 0.1f) - { - if (fSuspensionLimitSize >= 0.f) - pEntry->SetSuspensionUpperLimit(pEntry->GetSuspensionLowerLimit() + 0.1f); - else - pEntry->SetSuspensionUpperLimit(pEntry->GetSuspensionLowerLimit() - 0.1f); - } + if (fSuspensionLimitSize >= 0.f) + pEntry->SetSuspensionUpperLimit(pEntry->GetSuspensionLowerLimit() + 0.1f); + else + pEntry->SetSuspensionUpperLimit(pEntry->GetSuspensionLowerLimit() - 0.1f); } pVehicle->ApplyHandling(); diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index 64708dea0c..e0f79e6ba4 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -910,6 +910,16 @@ ADD_ENUM(PreloadAreaOption::COLLISIONS, "collisions") ADD_ENUM(PreloadAreaOption::ALL, "all") IMPLEMENT_ENUM_CLASS_END("preload-area-option") +IMPLEMENT_ENUM_BEGIN(eEntityType) +ADD_ENUM(ENTITY_TYPE_NOTHING, "unknown") +ADD_ENUM(ENTITY_TYPE_BUILDING, "building") +ADD_ENUM(ENTITY_TYPE_VEHICLE, "vehicle") +ADD_ENUM(ENTITY_TYPE_PED, "ped") +ADD_ENUM(ENTITY_TYPE_OBJECT, "object") +ADD_ENUM(ENTITY_TYPE_DUMMY, "dummy") +ADD_ENUM(ENTITY_TYPE_NOTINPOOLS, "unknown") +IMPLEMENT_ENUM_END("entity-type") + // // CResource from userdata // diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index e134a73bea..fc692a8f16 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -88,6 +88,7 @@ DECLARE_ENUM(ePools); DECLARE_ENUM(eWorldProperty); DECLARE_ENUM_CLASS(eModelLoadState); DECLARE_ENUM_CLASS(PreloadAreaOption); +DECLARE_ENUM(eEntityType); class CRemoteCall; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp index fabdf76f16..0f9fcba457 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp @@ -2873,17 +2873,16 @@ int CLuaVehicleDefs::GetVehicleHandling(lua_State* luaVM) int CLuaVehicleDefs::GetOriginalHandling(lua_State* luaVM) { - int iType = 0; + std::uint32_t uiModel; + CScriptArgReader argStream(luaVM); - argStream.ReadNumber(iType); + argStream.ReadNumber(uiModel); if (!argStream.HasErrors()) { - eVehicleTypes eModel = static_cast(iType); - if (eModel) + if (uiModel) { - const CHandlingEntry* pEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(eModel); - if (pEntry) + if (const CHandlingEntry* pEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(uiModel)) { lua_newtable(luaVM); lua_pushnumber(luaVM, pEntry->GetMass()); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp index 9a9e038b19..185b0ae44b 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -142,7 +142,8 @@ void CLuaWorldDefs::LoadFunctions() {"isGarageOpen", IsGarageOpen}, {"isTimeFrozen", ArgumentParser}, {"isVolumetricShadowsEnabled", ArgumentParser}, - {"isDynamicPedShadowsEnabled", ArgumentParser}}; + {"isDynamicPedShadowsEnabled", ArgumentParser}, + {"testSphereAgainstWorld", ArgumentParser}}; // Add functions for (const auto& [name, func] : functions) @@ -2297,3 +2298,15 @@ bool CLuaWorldDefs::ResetDynamicPedShadows() noexcept { return g_pGame->GetSettings()->ResetDynamicPedShadows(); } + +CLuaMultiReturn CLuaWorldDefs::TestSphereAgainstWorld(CVector sphereCenter, float radius, std::optional ignoredEntity, std::optional checkBuildings, std::optional checkVehicles, std::optional checkPeds, std::optional checkObjects, std::optional checkDummies, std::optional cameraIgnore) +{ + STestSphereAgainstWorldResult result; + CClientEntity* collidedEntity = nullptr; + + CEntity* entity = g_pGame->GetWorld()->TestSphereAgainstWorld(sphereCenter, radius, ignoredEntity.has_value() ? ignoredEntity.value()->GetGameEntity() : nullptr, checkBuildings.value_or(true), checkVehicles.value_or(true), checkPeds.value_or(true), checkObjects.value_or(true), checkDummies.value_or(true), cameraIgnore.value_or(false), result); + if (entity) + collidedEntity = reinterpret_cast(entity->GetStoredPointer()); + + return {result.collisionDetected, collidedEntity, result.modelID, result.entityPosition.fX, result.entityPosition.fY, result.entityPosition.fZ, ConvertRadiansToDegrees(result.entityRotation.fX), ConvertRadiansToDegrees(result.entityRotation.fY), ConvertRadiansToDegrees(result.entityRotation.fZ), result.lodID, result.type}; +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h index f430bd63dd..3c19ed8857 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h @@ -144,5 +144,8 @@ class CLuaWorldDefs : public CLuaDefs static bool SetDynamicPedShadowsEnabled(bool enable); static bool IsDynamicPedShadowsEnabled() noexcept; static bool ResetDynamicPedShadows() noexcept; + + static CLuaMultiReturn TestSphereAgainstWorld(CVector sphereCenter, float radius, std::optional ignoredEntity, std::optional checkBuildings, std::optional checkVehicles, std::optional checkPeds, std::optional checkObjects, std::optional checkDummies, std::optional cameraIgnore); + }; diff --git a/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp index d92ba4788b..380767ccc7 100644 --- a/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp @@ -619,6 +619,12 @@ void CWorldRPCs::SetSyncIntervals(NetBitStreamInterface& bitStream) bitStream.Read(g_TickRateSettings.iObjectSync); bitStream.Read(g_TickRateSettings.iKeySyncRotation); bitStream.Read(g_TickRateSettings.iKeySyncAnalogMove); + + if (bitStream.Can(eBitStreamVersion::FixSyncerDistance)) + { + bitStream.Read(g_TickRateSettings.iPedSyncerDistance); + bitStream.Read(g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); + } } void CWorldRPCs::SetMoonSize(NetBitStreamInterface& bitStream) diff --git a/Client/multiplayer_sa/CMultiplayerSA.cpp b/Client/multiplayer_sa/CMultiplayerSA.cpp index 1b21f79a23..f0cd566133 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA.cpp @@ -1574,6 +1574,7 @@ void CMultiplayerSA::InitHooks() MemSet((void*)0x6C4453, 0x90, 0x68); InitHooks_CrashFixHacks(); + InitHooks_DeviceSelection(); // Init our 1.3 hooks. Init_13(); @@ -1861,6 +1862,7 @@ void CMultiplayerSA::DisableCloseRangeDamage(bool bDisabled) MemPut(0x73BA00, 0x86); } } + bool CMultiplayerSA::GetInteriorSoundsEnabled() { return bInteriorSoundsEnabled; @@ -4581,7 +4583,7 @@ void _cdecl CPhysical_ApplyGravity(DWORD dwThis) pVehicle->GetGravity(&vecGravity); pVehicle->GetMoveSpeed(&vecMoveSpeed); vecMoveSpeed += vecGravity * fTimeStep * fGravity; - pVehicle->SetMoveSpeed(&vecMoveSpeed); + pVehicle->SetMoveSpeed(vecMoveSpeed); } else { @@ -4678,7 +4680,7 @@ bool _cdecl VehicleCamStart(DWORD dwCam, DWORD pVehicleInterface) pVehicle->GetMoveSpeed(&gravcam_vecVehicleVelocity); CVector vecVelocityInverted = gravcam_matInvertGravity * gravcam_vecVehicleVelocity; - pVehicle->SetMoveSpeed(&vecVelocityInverted); + pVehicle->SetMoveSpeed(vecVelocityInverted); return true; } @@ -4874,7 +4876,7 @@ void _cdecl VehicleCamEnd(DWORD pVehicleInterface) return; pVehicle->SetMatrix(&gravcam_matVehicleTransform); - pVehicle->SetMoveSpeed(&gravcam_vecVehicleVelocity); + pVehicle->SetMoveSpeed(gravcam_vecVehicleVelocity); } void _declspec(naked) HOOK_VehicleCamEnd() @@ -5012,7 +5014,7 @@ void _cdecl ApplyVehicleBlowHop(DWORD pVehicleInterface) pVehicle->GetGravity(&vecGravity); pVehicle->GetMoveSpeed(&vecVelocity); vecVelocity -= vecGravity * 0.13f; - pVehicle->SetMoveSpeed(&vecVelocity); + pVehicle->SetMoveSpeed(vecVelocity); } void _declspec(naked) HOOK_ApplyCarBlowHop() @@ -6182,7 +6184,7 @@ void _declspec(naked) HOOK_ProcessVehicleCollision() } } -void CMultiplayerSA::UpdateVehicleSuspension() noexcept +void CMultiplayerSA::UpdateVehicleSuspension() const noexcept { HookInstallCall(CALL_CAutomobile_ProcessEntityCollision, reinterpret_cast(HOOK_ProcessVehicleCollision)); HookInstallCall(CALL_CMonsterTruck_ProcessEntityCollision, reinterpret_cast(HOOK_ProcessVehicleCollision)); diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 802b9b56ea..0dd642cb4b 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -80,6 +80,7 @@ class CMultiplayerSA : public CMultiplayer void InitHooks_ProjectileCollisionFix(); void InitHooks_ObjectStreamerOptimization(); void InitHooks_Postprocess(); + void InitHooks_DeviceSelection(); CRemoteDataStorage* CreateRemoteDataStorage(); void DestroyRemoteDataStorage(CRemoteDataStorage* pData); void AddRemoteDataStorage(CPlayerPed* pPed, CRemoteDataStorage* pData); @@ -311,7 +312,7 @@ class CMultiplayerSA : public CMultiplayer CLimits* GetLimits() { return &m_limits; } - void UpdateVehicleSuspension() noexcept; + void UpdateVehicleSuspension() const noexcept; virtual void FlushClothesCache(); virtual void SetFastClothesLoading(EFastClothesLoading fastClothesLoading); diff --git a/Client/multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp b/Client/multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp new file mode 100644 index 0000000000..586f387270 --- /dev/null +++ b/Client/multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp @@ -0,0 +1,155 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#define FUNC_rwDeviceSystemRequest 0x7F2AB0 +#define FUNC_DialogFunc 0x745E50 +#define FUNC_RwEngineGetSubSystemInfo 0x7F2C30 +#define CLASS_RwGlobals 0xC97B24 +#define CLASS_IDirect3D9 0xC97C20 +#define NUM_DialogFuncStackPushAddress 0x746239 + +// This is copied from SilentPatch: +// https://github.com/CookiePLMonster/SilentPatch/blob/dev/SilentPatch/FriendlyMonitorNames.cpp +std::unordered_map GetFriendlyMonitorNamesForDevicePaths() +{ + std::unordered_map monitorNames; + + HMODULE user32Lib = LoadLibrary(TEXT("user32")); + if (!user32Lib) + return monitorNames; + + auto* getDisplayConfigBufferSizes = (decltype(GetDisplayConfigBufferSizes)*)GetProcAddress(user32Lib, "GetDisplayConfigBufferSizes"); + auto* queryDisplayConfig = (decltype(QueryDisplayConfig)*)GetProcAddress(user32Lib, "QueryDisplayConfig"); + auto* displayConfigGetDeviceInfo = (decltype(DisplayConfigGetDeviceInfo)*)GetProcAddress(user32Lib, "DisplayConfigGetDeviceInfo"); + if (!getDisplayConfigBufferSizes || !queryDisplayConfig || !displayConfigGetDeviceInfo) + { + FreeLibrary(user32Lib); + return monitorNames; + } + + UINT32 pathCount, modeCount; + std::unique_ptr paths; + std::unique_ptr modes; + + LONG result = ERROR_SUCCESS; + do + { + result = getDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount); + if (result != ERROR_SUCCESS) + { + break; + } + paths = std::make_unique(pathCount); + modes = std::make_unique(modeCount); + result = queryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, paths.get(), &modeCount, modes.get(), nullptr); + } while (result == ERROR_INSUFFICIENT_BUFFER); + + if (result != ERROR_SUCCESS) + { + FreeLibrary(user32Lib); + return monitorNames; + } + + for (size_t i = 0; i < pathCount; i++) + { + DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {}; + targetName.header.adapterId = paths[i].targetInfo.adapterId; + targetName.header.id = paths[i].targetInfo.id; + targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + targetName.header.size = sizeof(targetName); + const LONG targetNameResult = DisplayConfigGetDeviceInfo(&targetName.header); + + DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName = {}; + sourceName.header.adapterId = paths[i].sourceInfo.adapterId; + sourceName.header.id = paths[i].sourceInfo.id; + sourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sourceName.header.size = sizeof(sourceName); + const LONG sourceNameResult = DisplayConfigGetDeviceInfo(&sourceName.header); + if (targetNameResult == ERROR_SUCCESS && sourceNameResult == ERROR_SUCCESS && targetName.monitorFriendlyDeviceName[0] != '\0') + { + char gdiDeviceName[std::size(sourceName.viewGdiDeviceName)]; + char monitorFriendlyDeviceName[std::size(targetName.monitorFriendlyDeviceName)]; + WideCharToMultiByte(CP_ACP, 0, sourceName.viewGdiDeviceName, -1, gdiDeviceName, static_cast(std::size(gdiDeviceName)), nullptr, nullptr); + WideCharToMultiByte(CP_ACP, 0, targetName.monitorFriendlyDeviceName, -1, monitorFriendlyDeviceName, + static_cast(std::size(monitorFriendlyDeviceName)), nullptr, nullptr); + + monitorNames.try_emplace(gdiDeviceName, monitorFriendlyDeviceName); + } + } + + FreeLibrary(user32Lib); + return monitorNames; +} + +struct RwSubSystemInfo +{ + char name[80]; +}; + +using rwDeviceSystemRequest = RwSubSystemInfo*(__cdecl*)(RwDevice* device, std::int32_t requestId, RwSubSystemInfo* pOut, void* pInOut, std::int32_t numIn); +static RwSubSystemInfo* RwEngineGetSubSystemInfo_Hooked(RwSubSystemInfo* subSystemInfo, std::int32_t subSystemIndex) +{ + auto* rwGlobals = *(RwGlobals**)CLASS_RwGlobals; + auto* rwDeviceSystemRequestFunc = (rwDeviceSystemRequest)(FUNC_rwDeviceSystemRequest); + if (!rwDeviceSystemRequestFunc(&rwGlobals->dOpenDevice, 14, subSystemInfo, nullptr, subSystemIndex)) + return nullptr; + + auto* pDxDevice = *(IDirect3D9**)CLASS_IDirect3D9; + if (!pDxDevice) + return subSystemInfo; + + D3DADAPTER_IDENTIFIER9 identifier; + if (FAILED(pDxDevice->GetAdapterIdentifier(subSystemIndex, 0, &identifier))) + return subSystemInfo; + + static const auto friendlyNames = GetFriendlyMonitorNamesForDevicePaths(); + + // If we can't find the friendly name, either because it doesn't exist or we're on an ancient Windows, fall back to the device name + auto it = friendlyNames.find(identifier.DeviceName); + if (it != friendlyNames.end()) + { + strncpy_s(subSystemInfo->name, it->second.c_str(), _TRUNCATE); + } + else + { + strncpy_s(subSystemInfo->name, identifier.Description, _TRUNCATE); + } + + return subSystemInfo; +} + +INT_PTR CALLBACK CustomDlgProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) +{ + auto* orgDialogFunc = (DLGPROC)FUNC_DialogFunc; + if (msg != WM_INITDIALOG) + return orgDialogFunc(window, msg, wParam, lParam); + + orgDialogFunc(window, msg, wParam, lParam); + + // Set Icon + HMODULE hGameModule = GetModuleHandle(nullptr); + SendMessage(window, WM_SETICON, ICON_SMALL, reinterpret_cast(LoadIcon(hGameModule, MAKEINTRESOURCE(100)))); + + // Make the dialog visible in the task bar + // https://stackoverflow.com/a/1462811 + SetWindowLongPtr(window, GWL_EXSTYLE, WS_EX_APPWINDOW); + ShowWindow(window, SW_HIDE); + ShowWindow(window, SW_SHOW); + return FALSE; +} + +void CMultiplayerSA::InitHooks_DeviceSelection() +{ + // 0x746239 -> Exact address where the original DialogFunc address is being pushed as an argument to DialogBoxParamA(), + // we're replacing it with out own proxy function + MemPut(NUM_DialogFuncStackPushAddress, (DLGPROC)&CustomDlgProc); + HookInstall(FUNC_RwEngineGetSubSystemInfo, (DWORD)RwEngineGetSubSystemInfo_Hooked, 6); +} diff --git a/Client/sdk/game/CGame.h b/Client/sdk/game/CGame.h index 2314fdad0e..51f94c9d77 100644 --- a/Client/sdk/game/CGame.h +++ b/Client/sdk/game/CGame.h @@ -108,7 +108,7 @@ class __declspec(novtable) CGame typedef std::unique_ptr AssocGroup_type; public: - virtual CPools* GetPools() = 0; + virtual CPools* GetPools() const noexcept = 0; virtual CPlayerInfo* GetPlayerInfo() = 0; virtual CProjectileInfo* GetProjectileInfo() = 0; virtual CRadar* GetRadar() = 0; @@ -137,7 +137,7 @@ class __declspec(novtable) CGame virtual CCarEnterExit* GetCarEnterExit() = 0; virtual CControllerConfigManager* GetControllerConfigManager() = 0; virtual CRenderWare* GetRenderWare() = 0; - virtual CHandlingManager* GetHandlingManager() = 0; + virtual CHandlingManager* GetHandlingManager() const noexcept = 0; virtual CAnimManager* GetAnimManager() = 0; virtual CStreaming* GetStreaming() = 0; virtual CVisibilityPlugins* GetVisibilityPlugins() = 0; @@ -230,6 +230,9 @@ class __declspec(novtable) CGame virtual bool IsTunnelWeatherBlendEnabled() const noexcept = 0; virtual void SetTunnelWeatherBlendEnabled(bool isEnabled) = 0; + virtual bool IsIgnoreFireStateEnabled() const noexcept = 0; + virtual void SetIgnoreFireStateEnabled(bool isEnabled) = 0; + virtual CWeapon* CreateWeapon() = 0; virtual CWeaponStat* CreateWeaponStat(eWeaponType weaponType, eWeaponSkill weaponSkill) = 0; diff --git a/Client/sdk/game/CHandlingEntry.h b/Client/sdk/game/CHandlingEntry.h index a2da6167c9..90038f6d07 100644 --- a/Client/sdk/game/CHandlingEntry.h +++ b/Client/sdk/game/CHandlingEntry.h @@ -91,78 +91,78 @@ class CHandlingEntry virtual ~CHandlingEntry(){}; // Use this to copy data from an another handling class to this - virtual void Assign(const CHandlingEntry* pEntry) = 0; + virtual void Assign(const CHandlingEntry* pEntry) noexcept = 0; // Get functions - virtual float GetMass() const = 0; - virtual float GetTurnMass() const = 0; - virtual float GetDragCoeff() const = 0; - virtual const CVector& GetCenterOfMass() const = 0; + virtual float GetMass() const noexcept = 0; + virtual float GetTurnMass() const noexcept = 0; + virtual float GetDragCoeff() const noexcept = 0; + virtual const CVector& GetCenterOfMass() const noexcept = 0; - virtual unsigned int GetPercentSubmerged() const = 0; - virtual float GetTractionMultiplier() const = 0; + virtual unsigned int GetPercentSubmerged() const noexcept = 0; + virtual float GetTractionMultiplier() const noexcept = 0; - virtual eDriveType GetCarDriveType() const = 0; - virtual eEngineType GetCarEngineType() const = 0; - virtual unsigned char GetNumberOfGears() const = 0; + virtual eDriveType GetCarDriveType() const noexcept = 0; + virtual eEngineType GetCarEngineType() const noexcept = 0; + virtual unsigned char GetNumberOfGears() const noexcept = 0; - virtual float GetEngineAcceleration() const = 0; - virtual float GetEngineInertia() const = 0; - virtual float GetMaxVelocity() const = 0; + virtual float GetEngineAcceleration() const noexcept = 0; + virtual float GetEngineInertia() const noexcept = 0; + virtual float GetMaxVelocity() const noexcept = 0; - virtual float GetBrakeDeceleration() const = 0; - virtual float GetBrakeBias() const = 0; - virtual bool GetABS() const = 0; + virtual float GetBrakeDeceleration() const noexcept = 0; + virtual float GetBrakeBias() const noexcept = 0; + virtual bool GetABS() const noexcept = 0; - virtual float GetSteeringLock() const = 0; - virtual float GetTractionLoss() const = 0; - virtual float GetTractionBias() const = 0; + virtual float GetSteeringLock() const noexcept = 0; + virtual float GetTractionLoss() const noexcept = 0; + virtual float GetTractionBias() const noexcept = 0; - virtual float GetSuspensionForceLevel() const = 0; - virtual float GetSuspensionDamping() const = 0; - virtual float GetSuspensionHighSpeedDamping() const = 0; - virtual float GetSuspensionUpperLimit() const = 0; - virtual float GetSuspensionLowerLimit() const = 0; - virtual float GetSuspensionFrontRearBias() const = 0; - virtual float GetSuspensionAntiDiveMultiplier() const = 0; + virtual float GetSuspensionForceLevel() const noexcept = 0; + virtual float GetSuspensionDamping() const noexcept = 0; + virtual float GetSuspensionHighSpeedDamping() const noexcept = 0; + virtual float GetSuspensionUpperLimit() const noexcept = 0; + virtual float GetSuspensionLowerLimit() const noexcept = 0; + virtual float GetSuspensionFrontRearBias() const noexcept = 0; + virtual float GetSuspensionAntiDiveMultiplier() const noexcept = 0; - virtual float GetCollisionDamageMultiplier() const = 0; + virtual float GetCollisionDamageMultiplier() const noexcept = 0; - virtual unsigned int GetHandlingFlags() const = 0; - virtual unsigned int GetModelFlags() const = 0; - virtual float GetSeatOffsetDistance() const = 0; - virtual unsigned int GetMonetary() const = 0; + virtual unsigned int GetHandlingFlags() const noexcept = 0; + virtual unsigned int GetModelFlags() const noexcept = 0; + virtual float GetSeatOffsetDistance() const noexcept = 0; + virtual unsigned int GetMonetary() const noexcept = 0; - virtual eLightType GetHeadLight() const = 0; - virtual eLightType GetTailLight() const = 0; - virtual unsigned char GetAnimGroup() const = 0; + virtual eLightType GetHeadLight() const noexcept = 0; + virtual eLightType GetTailLight() const noexcept = 0; + virtual unsigned char GetAnimGroup() const noexcept = 0; - virtual std::uint16_t GetVehicleID() const = 0; + virtual eHandlingTypes GetVehicleID() const noexcept = 0; // Set functions - virtual void SetMass(float fMass) = 0; - virtual void SetTurnMass(float fTurnMass) = 0; - virtual void SetDragCoeff(float fDrag) = 0; - virtual void SetCenterOfMass(const CVector& vecCenter) = 0; + virtual void SetMass(float fMass) noexcept = 0; + virtual void SetTurnMass(float fTurnMass) noexcept = 0; + virtual void SetDragCoeff(float fDrag) noexcept = 0; + virtual void SetCenterOfMass(const CVector& vecCenter) noexcept = 0; - virtual void SetPercentSubmerged(unsigned int uiPercent) = 0; - virtual void SetTractionMultiplier(float fTractionMultiplier) = 0; + virtual void SetPercentSubmerged(unsigned int uiPercent) noexcept = 0; + virtual void SetTractionMultiplier(float fTractionMultiplier) noexcept = 0; - virtual void SetCarDriveType(eDriveType Type) = 0; - virtual void SetCarEngineType(eEngineType Type) = 0; - virtual void SetNumberOfGears(unsigned char ucNumber) = 0; + virtual void SetCarDriveType(eDriveType Type) noexcept = 0; + virtual void SetCarEngineType(eEngineType Type) noexcept = 0; + virtual void SetNumberOfGears(unsigned char ucNumber) noexcept = 0; - virtual void SetEngineAcceleration(float fAcceleration) = 0; - virtual void SetEngineInertia(float fInertia) = 0; - virtual void SetMaxVelocity(float fVelocity) = 0; + virtual void SetEngineAcceleration(float fAcceleration) noexcept = 0; + virtual void SetEngineInertia(float fInertia) noexcept = 0; + virtual void SetMaxVelocity(float fVelocity) noexcept = 0; - virtual void SetBrakeDeceleration(float fDeceleration) = 0; - virtual void SetBrakeBias(float fBias) = 0; - virtual void SetABS(bool bABS) = 0; + virtual void SetBrakeDeceleration(float fDeceleration) noexcept = 0; + virtual void SetBrakeBias(float fBias) noexcept = 0; + virtual void SetABS(bool bABS) noexcept = 0; - virtual void SetSteeringLock(float fSteeringLock) = 0; - virtual void SetTractionLoss(float fTractionLoss) = 0; - virtual void SetTractionBias(float fTractionBias) = 0; + virtual void SetSteeringLock(float fSteeringLock) noexcept = 0; + virtual void SetTractionLoss(float fTractionLoss) noexcept = 0; + virtual void SetTractionBias(float fTractionBias) noexcept = 0; virtual void SetSuspensionForceLevel(float fForce) noexcept = 0; virtual void SetSuspensionDamping(float fDamping) noexcept = 0; @@ -172,18 +172,20 @@ class CHandlingEntry virtual void SetSuspensionFrontRearBias(float fBias) noexcept = 0; virtual void SetSuspensionAntiDiveMultiplier(float fAntiDive) noexcept = 0; - virtual void SetCollisionDamageMultiplier(float fMultiplier) = 0; + virtual void SetCollisionDamageMultiplier(float fMultiplier) noexcept = 0; - virtual void SetHandlingFlags(unsigned int uiFlags) = 0; - virtual void SetModelFlags(unsigned int uiFlags) = 0; - virtual void SetSeatOffsetDistance(float fDistance) = 0; - virtual void SetMonetary(unsigned int uiMonetary) = 0; + virtual void SetHandlingFlags(unsigned int uiFlags) noexcept = 0; + virtual void SetModelFlags(unsigned int uiFlags) noexcept = 0; + virtual void SetSeatOffsetDistance(float fDistance) noexcept = 0; + virtual void SetMonetary(unsigned int uiMonetary) noexcept = 0; - virtual void SetHeadLight(eLightType Style) = 0; - virtual void SetTailLight(eLightType Style) = 0; - virtual void SetAnimGroup(unsigned char ucGroup) = 0; + virtual void SetHeadLight(eLightType Style) noexcept = 0; + virtual void SetTailLight(eLightType Style) noexcept = 0; + virtual void SetAnimGroup(unsigned char ucGroup) noexcept = 0; + + virtual void CheckSuspensionChanges() const noexcept = 0; // Call this every time you're done changing something. This will recalculate // all transmission/handling values according to the new values. - virtual void Recalculate() = 0; + virtual void Recalculate() noexcept = 0; }; diff --git a/Client/sdk/game/CHandlingManager.h b/Client/sdk/game/CHandlingManager.h index 25d706220e..d10e55c8af 100644 --- a/Client/sdk/game/CHandlingManager.h +++ b/Client/sdk/game/CHandlingManager.h @@ -22,17 +22,17 @@ class CHandlingEntry; class CHandlingManager { public: - virtual CHandlingEntry* CreateHandlingData() = 0; - virtual CFlyingHandlingEntry* CreateFlyingHandlingData() = 0; - virtual CBoatHandlingEntry* CreateBoatHandlingData() = 0; - virtual CBikeHandlingEntry* CreateBikeHandlingData() = 0; + virtual std::unique_ptr CreateHandlingData() const noexcept = 0; + virtual std::unique_ptr CreateFlyingHandlingData() const noexcept = 0; + virtual std::unique_ptr CreateBoatHandlingData() const noexcept = 0; + virtual std::unique_ptr CreateBikeHandlingData() const noexcept = 0; - virtual const CHandlingEntry* GetOriginalHandlingData(enum eVehicleTypes eModel) const = 0; - virtual const CFlyingHandlingEntry* GetOriginalFlyingHandlingData(enum eVehicleTypes eModel) const = 0; - virtual const CBoatHandlingEntry* GetOriginalBoatHandlingData(enum eVehicleTypes eModel) const = 0; - virtual const CBikeHandlingEntry* GetOriginalBikeHandlingData(enum eVehicleTypes eModel) const = 0; + virtual const CHandlingEntry* GetOriginalHandlingData(std::uint32_t model) const noexcept = 0; + virtual const CFlyingHandlingEntry* GetOriginalFlyingHandlingData(std::uint32_t model) const noexcept = 0; + virtual const CBoatHandlingEntry* GetOriginalBoatHandlingData(std::uint32_t model) const noexcept = 0; + virtual const CBikeHandlingEntry* GetOriginalBikeHandlingData(std::uint32_t model) const noexcept = 0; - virtual eHandlingProperty GetPropertyEnumFromName(const std::string& strName) const = 0; + virtual eHandlingProperty GetPropertyEnumFromName(const std::string& name) const noexcept = 0; - virtual void CheckSuspensionChanges(CHandlingEntry* pEntry) noexcept = 0; + virtual void CheckSuspensionChanges(const CHandlingEntry* const pEntry) const noexcept = 0; }; diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index 08cb032e4c..c578be1990 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -15,6 +15,8 @@ #include "CAnimBlock.h" #include "Common.h" +constexpr std::uint16_t MODEL_PROPERTIES_GROUP_STATIC = 0xFFFF; + class CBaseModelInfoSAInterface; class CColModel; class CPedModelInfo; @@ -131,6 +133,7 @@ struct SVehicleSupportedUpgrades bool m_bMisc; bool m_bInitialised; }; + class CModelInfo { public: @@ -154,7 +157,7 @@ class CModelInfo virtual char* GetNameIfVehicle() = 0; - virtual BYTE GetVehicleType() = 0; + virtual BYTE GetVehicleType() const noexcept = 0; virtual void Request(EModelRequestType requestType, const char* szTag /* = NULL*/) = 0; virtual bool IsLoaded() = 0; virtual unsigned short GetFlags() = 0; @@ -165,7 +168,7 @@ class CModelInfo virtual void SetIdeFlag(eModelIdeFlag eFlag, bool bState) = 0; virtual CBoundingBox* GetBoundingBox() = 0; virtual bool IsValid() = 0; - virtual bool IsAllocatedInArchive() = 0; + virtual bool IsAllocatedInArchive() const noexcept = 0; virtual unsigned short GetTextureDictionaryID() = 0; virtual void SetTextureDictionaryID(unsigned short usTxdId) = 0; virtual void ResetTextureDictionaryID() = 0; diff --git a/Client/sdk/game/CPhysical.h b/Client/sdk/game/CPhysical.h index e46159456a..26e25465bb 100644 --- a/Client/sdk/game/CPhysical.h +++ b/Client/sdk/game/CPhysical.h @@ -20,7 +20,7 @@ class CPhysical : public virtual CEntity virtual CVector* GetMoveSpeed(CVector* vecMoveSpeed) = 0; virtual CVector* GetTurnSpeed(CVector* vecTurnSpeed) = 0; - virtual void SetMoveSpeed(CVector* vecMoveSpeed) = 0; + virtual void SetMoveSpeed(const CVector& vecMoveSpeed) noexcept = 0; virtual void SetTurnSpeed(CVector* vecTurnSpeed) = 0; virtual float GetMass() = 0; diff --git a/Client/sdk/game/CPools.h b/Client/sdk/game/CPools.h index 5b7dd0bd2b..46359a02a6 100644 --- a/Client/sdk/game/CPools.h +++ b/Client/sdk/game/CPools.h @@ -66,7 +66,7 @@ class CPools { public: // Vehicles pool - virtual CVehicle* AddVehicle(class CClientVehicle* pClientVehicle, eVehicleTypes eVehicleType, unsigned char ucVariation, unsigned char ucVariation2) = 0; + virtual CVehicle* AddVehicle(class CClientVehicle* pClientVehicle, std::uint16_t model, std::uint8_t variation, std::uint8_t variation2) noexcept = 0; virtual void RemoveVehicle(CVehicle* pVehicle, bool bDelete = true) = 0; virtual SClientEntity* GetVehicle(DWORD* pGameInterface) = 0; @@ -92,8 +92,8 @@ class CPools virtual unsigned long GetPedCount() = 0; // Others - virtual CVehicle* AddTrain(class CClientVehicle* pClientVehicle, CVector* vecPosition, DWORD dwModels[], int iSize, bool iDirection, - uchar ucTrackId = 0xFF) = 0; + virtual CVehicle* AddTrain(class CClientVehicle* pClientVehicle, const CVector& vecPosition, std::vector models, bool iDirection, + std::uint8_t ucTrackId = 255) noexcept = 0; virtual CEntity* GetEntity(DWORD* pGameInterface) = 0; virtual CClientEntity* GetClientEntity(DWORD* pGameInterface) = 0; diff --git a/Client/sdk/game/CProjectileInfo.h b/Client/sdk/game/CProjectileInfo.h index 586cbd029c..d32a538623 100644 --- a/Client/sdk/game/CProjectileInfo.h +++ b/Client/sdk/game/CProjectileInfo.h @@ -24,6 +24,7 @@ class CProjectileInfo virtual CProjectileInfo* GetProjectileInfo(void* projectileInfoInterface) = 0; // don't use virtual void RemoveProjectile(CProjectileInfo* pProjectileInfo, CProjectile* pProjectile, bool bBlow = true) = 0; virtual CProjectileInfo* GetProjectileInfo(DWORD Index) = 0; + virtual void RemoveEntityReferences(CEntity* entity) = 0; virtual CEntity* GetTarget() = 0; virtual void SetTarget(CEntity* pEntity) = 0; diff --git a/Client/sdk/game/CWorld.h b/Client/sdk/game/CWorld.h index 3684172f01..c22762f7a8 100644 --- a/Client/sdk/game/CWorld.h +++ b/Client/sdk/game/CWorld.h @@ -10,6 +10,7 @@ *****************************************************************************/ #pragma once +#include "CEntity.h" class CEntitySAInterface; class CVector; @@ -61,6 +62,16 @@ struct SProcessLineOfSightMaterialInfoResult { bool valid{}; //< Data found in this struct is only valid if this is `true`! }; +struct STestSphereAgainstWorldResult +{ + bool collisionDetected{false}; + std::uint32_t modelID{0}; + CVector entityPosition{}; + CVector entityRotation{}; + std::uint32_t lodID{0}; + eEntityType type{ENTITY_TYPE_NOTHING}; +}; + enum eDebugCaller { CEntity_SetMatrix, @@ -274,4 +285,6 @@ class CWorld virtual CSurfaceType* GetSurfaceInfo() = 0; virtual void ResetAllSurfaceInfo() = 0; virtual bool ResetSurfaceInfo(short sSurfaceID) = 0; + + virtual CEntity* TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) = 0; }; diff --git a/Client/sdk/game/RenderWare.h b/Client/sdk/game/RenderWare.h index 20249e01fd..d85011b291 100644 --- a/Client/sdk/game/RenderWare.h +++ b/Client/sdk/game/RenderWare.h @@ -526,3 +526,49 @@ struct RwError { int err1, err2; }; + +/*****************************************************************************/ +/** RenderWare Globals **/ +/*****************************************************************************/ + +typedef bool (*RwSystemFunc)(std::int32_t, void*, void*, std::int32_t); +struct RwDevice +{ + float gammaCorrection; + RwSystemFunc fpSystem; + float zBufferNear; + float zBufferFar; + // RwRenderStateSetFunction fpRenderStateSet; + // RwRenderStateGetFunction fpRenderStateGet; + // RwIm2DRenderLineFunction fpIm2DRenderLine; + // RwIm2DRenderTriangleFunction fpIm2DRenderTriangle; + // RwIm2DRenderPrimitiveFunction fpIm2DRenderPrimitive; + // RwIm2DRenderIndexedPrimitiveFunction fpIm2DRenderIndexedPrimitive; + // RwIm3DRenderLineFunction fpIm3DRenderLine; + // RwIm3DRenderTriangleFunction fpIm3DRenderTriangle; + // RwIm3DRenderPrimitiveFunction fpIm3DRenderPrimitive; + // RwIm3DRenderIndexedPrimitiveFunction fpIm3DRenderIndexedPrimitive; +}; +// static_assert(sizeof(RwDevice) == 0x38, "Incorrect class size: RwDevice"); + +typedef bool (*RwStandardFunc)(void*, void*, std::int32_t); +struct RwGlobals +{ + void* curCamera; + void* curWorld; + std::uint16_t renderFrame; + std::uint16_t lightFrame; + std::uint16_t pad[2]; + RwDevice dOpenDevice; + RwStandardFunc stdFunc[29]; + // RwLinkList dirtyFrameList; + // RwFileFunctions fileFuncs; + // RwStringFunctions stringFuncs; + // RwMemoryFunctions memoryFuncs; + // RwMemoryAllocFn memoryAlloc; + // RwMemoryFreeFn memoryFree; + // RwMetrics* metrics; + // RwEngineStatus engineStatus; + // RwUInt32 resArenaInitSize; +}; +//static_assert(sizeof(RwGlobals) == 0x158, "Incorrect class size: RwGlobals"); diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index 02c932cf57..33e349ea71 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -429,7 +429,7 @@ class CMultiplayer virtual CLimits* GetLimits() = 0; - virtual void UpdateVehicleSuspension() noexcept = 0; + virtual void UpdateVehicleSuspension() const noexcept = 0; virtual void FlushClothesCache() = 0; virtual void SetFastClothesLoading(EFastClothesLoading fastClothesLoading) = 0; diff --git a/Client/sdk/net/CNet.h b/Client/sdk/net/CNet.h index cb38718f47..24a61a7a22 100644 --- a/Client/sdk/net/CNet.h +++ b/Client/sdk/net/CNet.h @@ -115,7 +115,7 @@ class CNet virtual const char* GetNextBuffer() = 0; virtual const char* GetDiagnosticStatus() = 0; - virtual void UpdatePingStatus(const char* szStatus, ushort& usDataRef, bool& isVerified) = 0; + virtual void UpdatePingStatus(const char* status, size_t statusLength, ushort& usDataRef, bool& isVerified) = 0; virtual bool VerifySignature(const char* pData, unsigned long ulSize) = 0; diff --git a/Server/mods/deathmatch/StdInc.h b/Server/mods/deathmatch/StdInc.h index c2e6355739..fb397aad5b 100644 --- a/Server/mods/deathmatch/StdInc.h +++ b/Server/mods/deathmatch/StdInc.h @@ -49,6 +49,7 @@ #include #include #include +#include "version.h" extern class CNetServer* g_pRealNetServer; extern class CGame* g_pGame; diff --git a/Server/mods/deathmatch/editor.conf b/Server/mods/deathmatch/editor.conf index 3b2b75fa80..1355e673ee 100644 --- a/Server/mods/deathmatch/editor.conf +++ b/Server/mods/deathmatch/editor.conf @@ -268,6 +268,12 @@ Values: 0 - Off, 1 - Enabled. Default - 1 --> 1 + + 1 + diff --git a/Server/mods/deathmatch/local.conf b/Server/mods/deathmatch/local.conf index 039e155d81..d30a608781 100644 --- a/Server/mods/deathmatch/local.conf +++ b/Server/mods/deathmatch/local.conf @@ -274,6 +274,12 @@ Values: 0 - Off, 1 - Enabled. Default - 0 --> 0 + + 1 + diff --git a/Server/mods/deathmatch/logic/CConsoleCommands.cpp b/Server/mods/deathmatch/logic/CConsoleCommands.cpp index 5f19e566f3..a22c872eeb 100644 --- a/Server/mods/deathmatch/logic/CConsoleCommands.cpp +++ b/Server/mods/deathmatch/logic/CConsoleCommands.cpp @@ -24,6 +24,7 @@ #include "CDatabaseManager.h" #include "CGame.h" #include "CMainConfig.h" +#include "CMapManager.h" extern CGame* g_pGame; @@ -1111,6 +1112,9 @@ bool CConsoleCommands::Shutdown(CConsole* pConsole, const char* szArguments, CCl { // shutdown + CLuaArguments arguments; + arguments.PushNil(); + if (szArguments && strlen(szArguments) > 0) { // Copy to a buffer and strip it for bad characters @@ -1118,13 +1122,18 @@ bool CConsoleCommands::Shutdown(CConsole* pConsole, const char* szArguments, CCl // Output the action + reason to the console CLogger::LogPrintf("SHUTDOWN: Got shutdown command from %s (Reason: %s)\n", GetAdminNameForLog(pClient).c_str(), szBuffer); + arguments.PushString(szBuffer); } else { // Output the action to the console CLogger::LogPrintf("SHUTDOWN: Got shutdown command from %s (No reason specified)\n", GetAdminNameForLog(pClient).c_str()); + arguments.PushString("No reason specified"); } + // Call event + g_pGame->GetMapManager()->GetRootElement()->CallEvent("onShutdown", arguments); + // Shut the server down asap g_pGame->SetIsFinished(true); return true; diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 9543e1e447..ec09e810ae 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -58,6 +58,7 @@ #include "packets/CPlayerNetworkStatusPacket.h" #include "packets/CPlayerListPacket.h" #include "packets/CPlayerClothesPacket.h" +#include "packets/CPlayerWorldSpecialPropertyPacket.h" #include "packets/CServerInfoSyncPacket.h" #include "packets/CLuaPacket.h" #include "../utils/COpenPortsTester.h" @@ -166,7 +167,7 @@ CGame::CGame() : m_FloodProtect(4, 30000, 30000) // Max of 4 connecti m_pUnoccupiedVehicleSync = NULL; m_pConsole = NULL; m_pMapManager = NULL; - m_pHandlingManager = NULL; + m_HandlingManager = nullptr; m_pLuaManager = NULL; m_pPacketTranslator = NULL; m_pMarkerManager = NULL; @@ -258,6 +259,7 @@ CGame::CGame() : m_FloodProtect(4, 30000, 30000) // Max of 4 connecti m_WorldSpecialProps[WorldSpecialProperty::EXTENDEDWATERCANNONS] = true; m_WorldSpecialProps[WorldSpecialProperty::ROADSIGNSTEXT] = true; m_WorldSpecialProps[WorldSpecialProperty::TUNNELWEATHERBLEND] = true; + m_WorldSpecialProps[WorldSpecialProperty::IGNOREFIRESTATE] = false; m_JetpackWeapons[WEAPONTYPE_MICRO_UZI] = true; m_JetpackWeapons[WEAPONTYPE_TEC9] = true; @@ -343,9 +345,12 @@ CGame::~CGame() CSimControl::EnableSimSystem(false); // Disconnect all players - std::list::const_iterator iter = m_pPlayerManager->IterBegin(); - for (; iter != m_pPlayerManager->IterEnd(); iter++) - DisconnectPlayer(this, **iter, CPlayerDisconnectedPacket::SHUTDOWN); + if (m_pPlayerManager) + { + std::list::const_iterator iter = m_pPlayerManager->IterBegin(); + for (; iter != m_pPlayerManager->IterEnd(); iter++) + DisconnectPlayer(this, **iter, CPlayerDisconnectedPacket::SHUTDOWN); + } // Stop networking Stop(); @@ -372,7 +377,6 @@ CGame::~CGame() SAFE_DELETE(m_pRadarAreaManager); SAFE_DELETE(m_pPlayerManager); SAFE_DELETE(m_pVehicleManager); - SAFE_DELETE(m_pHandlingManager); SAFE_DELETE(m_pPickupManager); SAFE_DELETE(m_pObjectManager); SAFE_DELETE(m_pColManager); @@ -579,43 +583,57 @@ bool CGame::Start(int iArgumentCount, char* szArguments[]) CElement::StartupEntitiesFromRoot(); CSimControl::Startup(); - m_pGroups = new CGroups; - m_pClock = new CClock; - m_pBlipManager = new CBlipManager; - m_pColManager = new CColManager; - m_pObjectManager = new CObjectManager; - m_pPickupManager = new CPickupManager(m_pColManager); - m_pPlayerManager = new CPlayerManager; - m_pRadarAreaManager = new CRadarAreaManager; - m_pMarkerManager = new CMarkerManager(m_pColManager); - m_pHandlingManager = new CHandlingManager; - m_pVehicleManager = new CVehicleManager; - m_pPacketTranslator = new CPacketTranslator(m_pPlayerManager); - m_pBanManager = new CBanManager; - m_pTeamManager = new CTeamManager; - m_pPedManager = new CPedManager; - m_pWaterManager = new CWaterManager; - m_pScriptDebugging = new CScriptDebugging(); - m_pMapManager = - new CMapManager(m_pBlipManager, m_pObjectManager, m_pPickupManager, m_pPlayerManager, m_pRadarAreaManager, m_pMarkerManager, m_pVehicleManager, - m_pTeamManager, m_pPedManager, m_pColManager, m_pWaterManager, m_pClock, m_pGroups, &m_Events, m_pScriptDebugging, &m_ElementDeleter); - m_pACLManager = new CAccessControlListManager; - m_pHqComms = new CHqComms; - - m_pRegisteredCommands = new CRegisteredCommands(m_pACLManager); - m_pLuaManager = new CLuaManager(m_pObjectManager, m_pPlayerManager, m_pVehicleManager, m_pBlipManager, m_pRadarAreaManager, m_pRegisteredCommands, - m_pMapManager, &m_Events); - m_pConsole = new CConsole(m_pBlipManager, m_pMapManager, m_pPlayerManager, m_pRegisteredCommands, m_pVehicleManager, m_pBanManager, m_pACLManager); - m_pMainConfig = new CMainConfig(m_pConsole); - m_pRPCFunctions = new CRPCFunctions; - - m_pWeaponStatsManager = new CWeaponStatManager(); - - m_pBuildingRemovalManager = new CBuildingRemovalManager; - - m_pCustomWeaponManager = new CCustomWeaponManager(); - - m_pTrainTrackManager = std::make_shared(); + + try + { + m_pGroups = new CGroups; + m_pClock = new CClock; + m_pBlipManager = new CBlipManager; + m_pColManager = new CColManager; + m_pObjectManager = new CObjectManager; + m_pPickupManager = new CPickupManager(m_pColManager); + m_pPlayerManager = new CPlayerManager; + m_pRadarAreaManager = new CRadarAreaManager; + m_pMarkerManager = new CMarkerManager(m_pColManager); + m_HandlingManager = std::make_shared(); + m_pVehicleManager = new CVehicleManager; + m_pPacketTranslator = new CPacketTranslator(m_pPlayerManager); + m_pBanManager = new CBanManager; + m_pTeamManager = new CTeamManager; + m_pPedManager = new CPedManager; + m_pWaterManager = new CWaterManager; + m_pScriptDebugging = new CScriptDebugging(); + m_pMapManager = new CMapManager(m_pBlipManager, m_pObjectManager, m_pPickupManager, m_pPlayerManager, m_pRadarAreaManager, m_pMarkerManager, + m_pVehicleManager, m_pTeamManager, m_pPedManager, m_pColManager, m_pWaterManager, m_pClock, m_pGroups, &m_Events, + m_pScriptDebugging, &m_ElementDeleter); + m_pACLManager = new CAccessControlListManager; + m_pHqComms = new CHqComms; + + m_pRegisteredCommands = new CRegisteredCommands(m_pACLManager); + m_pLuaManager = new CLuaManager(m_pObjectManager, m_pPlayerManager, m_pVehicleManager, m_pBlipManager, m_pRadarAreaManager, m_pRegisteredCommands, + m_pMapManager, &m_Events); + m_pConsole = new CConsole(m_pBlipManager, m_pMapManager, m_pPlayerManager, m_pRegisteredCommands, m_pVehicleManager, m_pBanManager, m_pACLManager); + m_pMainConfig = new CMainConfig(m_pConsole); + m_pRPCFunctions = new CRPCFunctions; + + m_pWeaponStatsManager = new CWeaponStatManager(); + + m_pBuildingRemovalManager = new CBuildingRemovalManager; + + m_pCustomWeaponManager = new CCustomWeaponManager(); + + m_pTrainTrackManager = std::make_shared(); + } + catch (const std::bad_alloc& e) + { + std::cout << "ERROR: Memory allocations failed: " << e.what() << std::endl; + return false; + } + catch (const std::exception& e) + { + std::cout << "ERROR: Constructors failed: " << e.what() << std::endl; + return false; + } // Parse the commandline if (!m_CommandLineParser.Parse(iArgumentCount, szArguments)) @@ -1292,6 +1310,12 @@ bool CGame::ProcessPacket(CPacket& Packet) return true; } + case PACKET_ID_PLAYER_WORLD_SPECIAL_PROPERTY: + { + Packet_PlayerWorldSpecialProperty(static_cast(Packet)); + return true; + } + default: break; } @@ -1608,6 +1632,7 @@ void CGame::AddBuiltInEvents() m_Events.AddEvent("onPlayerTeamChange", "oldTeam, newTeam", nullptr, false); m_Events.AddEvent("onPlayerTriggerInvalidEvent", "eventName, isAdded, isRemote", nullptr, false); m_Events.AddEvent("onPlayerChangesProtectedData", "element, key, value", nullptr, false); + m_Events.AddEvent("onPlayerChangesWorldSpecialProperty", "property, enabled", nullptr, false); // Ped events m_Events.AddEvent("onPedVehicleEnter", "vehicle, seat, jacked", NULL, false); @@ -1665,6 +1690,7 @@ void CGame::AddBuiltInEvents() m_Events.AddEvent("onSettingChange", "setting, oldValue, newValue", NULL, false); m_Events.AddEvent("onChatMessage", "message, element", NULL, false); m_Events.AddEvent("onExplosion", "x, y, z, type, origin", nullptr, false); + m_Events.AddEvent("onShutdown", "resource, reason", nullptr, false); // Weapon events m_Events.AddEvent("onWeaponFire", "", NULL, false); @@ -1798,6 +1824,21 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) return; } + // Check if another player is using the same serial + if (m_pMainConfig->IsCheckDuplicateSerialsEnabled() && m_pPlayerManager->GetBySerial(strSerial)) + { + // Tell the console + CLogger::LogPrintf("CONNECT: %s failed to connect (Serial already in use) (%s)\n", szNick, strIPAndSerial.c_str()); + + // Tell the player the problem + if (pPlayer->CanBitStream(eBitStreamVersion::CheckDuplicateSerials)) + DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::SERIAL_DUPLICATE); + else + DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::KICK); + + return; + } + // Check the nick is valid if (!CheckNickProvided(szNick)) { @@ -4240,6 +4281,23 @@ void CGame::Packet_PlayerResourceStart(CPlayerResourceStartPacket& Packet) } } +void CGame::Packet_PlayerWorldSpecialProperty(CPlayerWorldSpecialPropertyPacket& packet) noexcept +{ + CPlayer* player = packet.GetSourcePlayer(); + + if (!player) + return; + + const std::string& property = packet.GetProperty(); + const bool enabled = packet.IsEnabled(); + + CLuaArguments arguments; + arguments.PushString(property); + arguments.PushBoolean(enabled); + + player->CallEvent("onPlayerChangesWorldSpecialProperty", arguments, nullptr); +} + void CGame::Packet_PlayerModInfo(CPlayerModInfoPacket& Packet) { CPlayer* pPlayer = Packet.GetSourcePlayer(); diff --git a/Server/mods/deathmatch/logic/CGame.h b/Server/mods/deathmatch/logic/CGame.h index d865e858ec..c68cc7dbff 100644 --- a/Server/mods/deathmatch/logic/CGame.h +++ b/Server/mods/deathmatch/logic/CGame.h @@ -215,55 +215,54 @@ class CGame void SetIsFinished(bool bFinished) { m_bIsFinished = bFinished; }; bool IsFinished() { return m_bIsFinished; }; - CMainConfig* GetConfig() { return m_pMainConfig; } - CHandlingManager* GetHandlingManager() { return m_pHandlingManager; } - CMapManager* GetMapManager() { return m_pMapManager; } - CPlayerManager* GetPlayerManager() { return m_pPlayerManager; } - CObjectManager* GetObjectManager() { return m_pObjectManager; } - CVehicleManager* GetVehicleManager() { return m_pVehicleManager; } - CTeamManager* GetTeamManager() { return m_pTeamManager; } - CUnoccupiedVehicleSync* GetUnoccupiedVehicleSync() { return m_pUnoccupiedVehicleSync; } - CPedSync* GetPedSync() { return m_pPedSync; } - CRegisteredCommands* GetRegisteredCommands() { return m_pRegisteredCommands; } + CMainConfig* GetConfig() { return m_pMainConfig; } + std::shared_ptr GetHandlingManager() { return m_HandlingManager; } + CMapManager* GetMapManager() { return m_pMapManager; } + CPlayerManager* GetPlayerManager() { return m_pPlayerManager; } + CObjectManager* GetObjectManager() { return m_pObjectManager; } + CVehicleManager* GetVehicleManager() { return m_pVehicleManager; } + CTeamManager* GetTeamManager() { return m_pTeamManager; } + CUnoccupiedVehicleSync* GetUnoccupiedVehicleSync() { return m_pUnoccupiedVehicleSync; } + CPedSync* GetPedSync() { return m_pPedSync; } + CRegisteredCommands* GetRegisteredCommands() { return m_pRegisteredCommands; } #ifdef WITH_OBJECT_SYNC - CObjectSync* GetObjectSync() { return m_pObjectSync; } + CObjectSync* GetObjectSync() { return m_pObjectSync; } #endif - CConsole* GetConsole() { return m_pConsole; } - CDatabaseManager* GetDatabaseManager() { return m_pDatabaseManager; } - CLuaCallbackManager* GetLuaCallbackManager() { return m_pLuaCallbackManager; } - CRegistryManager* GetRegistryManager() { return m_pRegistryManager; } - CRegistry* GetRegistry() { return m_pRegistry; } - CAccountManager* GetAccountManager() { return m_pAccountManager; } - CScriptDebugging* GetScriptDebugging() { return m_pScriptDebugging; } - CEvents* GetEvents() { return &m_Events; } - CColManager* GetColManager() { return m_pColManager; } - CLatentTransferManager* GetLatentTransferManager() { return m_pLatentTransferManager; } - CDebugHookManager* GetDebugHookManager() { return m_pDebugHookManager; } - CPedManager* GetPedManager() { return m_pPedManager; } - CResourceManager* GetResourceManager() { return m_pResourceManager; } - CMarkerManager* GetMarkerManager() { return m_pMarkerManager; } - CBlipManager* GetBlipManager() { return m_pBlipManager; } - CPickupManager* GetPickupManager() { return m_pPickupManager; } - CRadarAreaManager* GetRadarAreaManager() { return m_pRadarAreaManager; } - CGroups* GetGroups() { return m_pGroups; } - CElementDeleter* GetElementDeleter() { return &m_ElementDeleter; } - CConnectHistory* GetJoinFloodProtector() { return &m_FloodProtect; } - CHTTPD* GetHTTPD() { return m_pHTTPD; } - CSettings* GetSettings() { return m_pSettings; } - CAccessControlListManager* GetACLManager() { return m_pACLManager; } - CBanManager* GetBanManager() { return m_pBanManager; } - CRemoteCalls* GetRemoteCalls() { return m_pRemoteCalls; } - CZoneNames* GetZoneNames() { return m_pZoneNames; } - CClock* GetClock() { return m_pClock; } - CWaterManager* GetWaterManager() { return m_pWaterManager; } - CLightsyncManager* GetLightSyncManager() { return &m_lightsyncManager; } - CWeaponStatManager* GetWeaponStatManager() { return m_pWeaponStatsManager; } - CBuildingRemovalManager* GetBuildingRemovalManager() { return m_pBuildingRemovalManager; } - CCustomWeaponManager* GetCustomWeaponManager() { return m_pCustomWeaponManager; } - CFunctionUseLogger* GetFunctionUseLogger() { return m_pFunctionUseLogger; } - CMasterServerAnnouncer* GetMasterServerAnnouncer() { return m_pMasterServerAnnouncer; } - SharedUtil::CAsyncTaskScheduler* GetAsyncTaskScheduler() { return m_pAsyncTaskScheduler; } - + CConsole* GetConsole() { return m_pConsole; } + CDatabaseManager* GetDatabaseManager() { return m_pDatabaseManager; } + CLuaCallbackManager* GetLuaCallbackManager() { return m_pLuaCallbackManager; } + CRegistryManager* GetRegistryManager() { return m_pRegistryManager; } + CRegistry* GetRegistry() { return m_pRegistry; } + CAccountManager* GetAccountManager() { return m_pAccountManager; } + CScriptDebugging* GetScriptDebugging() { return m_pScriptDebugging; } + CEvents* GetEvents() { return &m_Events; } + CColManager* GetColManager() { return m_pColManager; } + CLatentTransferManager* GetLatentTransferManager() { return m_pLatentTransferManager; } + CDebugHookManager* GetDebugHookManager() { return m_pDebugHookManager; } + CPedManager* GetPedManager() { return m_pPedManager; } + CResourceManager* GetResourceManager() { return m_pResourceManager; } + CMarkerManager* GetMarkerManager() { return m_pMarkerManager; } + CBlipManager* GetBlipManager() { return m_pBlipManager; } + CPickupManager* GetPickupManager() { return m_pPickupManager; } + CRadarAreaManager* GetRadarAreaManager() { return m_pRadarAreaManager; } + CGroups* GetGroups() { return m_pGroups; } + CElementDeleter* GetElementDeleter() { return &m_ElementDeleter; } + CConnectHistory* GetJoinFloodProtector() { return &m_FloodProtect; } + CHTTPD* GetHTTPD() { return m_pHTTPD; } + CSettings* GetSettings() { return m_pSettings; } + CAccessControlListManager* GetACLManager() { return m_pACLManager; } + CBanManager* GetBanManager() { return m_pBanManager; } + CRemoteCalls* GetRemoteCalls() { return m_pRemoteCalls; } + CZoneNames* GetZoneNames() { return m_pZoneNames; } + CClock* GetClock() { return m_pClock; } + CWaterManager* GetWaterManager() { return m_pWaterManager; } + CLightsyncManager* GetLightSyncManager() { return &m_lightsyncManager; } + CWeaponStatManager* GetWeaponStatManager() { return m_pWeaponStatsManager; } + CBuildingRemovalManager* GetBuildingRemovalManager() { return m_pBuildingRemovalManager; } + CCustomWeaponManager* GetCustomWeaponManager() { return m_pCustomWeaponManager; } + CFunctionUseLogger* GetFunctionUseLogger() { return m_pFunctionUseLogger; } + CMasterServerAnnouncer* GetMasterServerAnnouncer() { return m_pMasterServerAnnouncer; } + SharedUtil::CAsyncTaskScheduler* GetAsyncTaskScheduler() { return m_pAsyncTaskScheduler; } std::shared_ptr GetTrainTrackManager() { return m_pTrainTrackManager; } void JoinPlayer(CPlayer& Player); @@ -519,6 +518,7 @@ class CGame void Packet_PlayerNoSocket(class CPlayerNoSocketPacket& Packet); void Packet_PlayerNetworkStatus(class CPlayerNetworkStatusPacket& Packet); void Packet_PlayerResourceStart(class CPlayerResourceStartPacket& Packet); + void Packet_PlayerWorldSpecialProperty(class CPlayerWorldSpecialPropertyPacket& packet) noexcept; static void PlayerCompleteConnect(CPlayer* pPlayer); @@ -528,53 +528,53 @@ class CGame // Technically, this could be put somewhere else. It's a callback function // which the voice server library will call to send out data. - CEvents m_Events; - CRemoteCalls* m_pRemoteCalls; - CHTTPD* m_pHTTPD; - CMainConfig* m_pMainConfig; - CBlipManager* m_pBlipManager; - CGroups* m_pGroups; - CColManager* m_pColManager; - CObjectManager* m_pObjectManager; - CPickupManager* m_pPickupManager; - CPlayerManager* m_pPlayerManager; - CRadarAreaManager* m_pRadarAreaManager; - CVehicleManager* m_pVehicleManager; - CPacketTranslator* m_pPacketTranslator; - CMapManager* m_pMapManager; - CElementDeleter m_ElementDeleter; - CConnectHistory m_FloodProtect; - CLuaManager* m_pLuaManager; - CScriptDebugging* m_pScriptDebugging; - CConsole* m_pConsole; - CUnoccupiedVehicleSync* m_pUnoccupiedVehicleSync; - CPedSync* m_pPedSync; + CEvents m_Events; + CRemoteCalls* m_pRemoteCalls; + CHTTPD* m_pHTTPD; + CMainConfig* m_pMainConfig; + CBlipManager* m_pBlipManager; + CGroups* m_pGroups; + CColManager* m_pColManager; + CObjectManager* m_pObjectManager; + CPickupManager* m_pPickupManager; + CPlayerManager* m_pPlayerManager; + CRadarAreaManager* m_pRadarAreaManager; + CVehicleManager* m_pVehicleManager; + CPacketTranslator* m_pPacketTranslator; + CMapManager* m_pMapManager; + CElementDeleter m_ElementDeleter; + CConnectHistory m_FloodProtect; + CLuaManager* m_pLuaManager; + CScriptDebugging* m_pScriptDebugging; + CConsole* m_pConsole; + CUnoccupiedVehicleSync* m_pUnoccupiedVehicleSync; + CPedSync* m_pPedSync; #ifdef WITH_OBJECT_SYNC - CObjectSync* m_pObjectSync; + CObjectSync* m_pObjectSync; #endif - CMarkerManager* m_pMarkerManager; - CClock* m_pClock; - CBanManager* m_pBanManager; - CTeamManager* m_pTeamManager; - CCommandLineParser m_CommandLineParser; - CRegisteredCommands* m_pRegisteredCommands; - CDatabaseManager* m_pDatabaseManager; - CLuaCallbackManager* m_pLuaCallbackManager; - CRegistryManager* m_pRegistryManager; - CRegistry* m_pRegistry; - CAccountManager* m_pAccountManager; - CLatentTransferManager* m_pLatentTransferManager; - CDebugHookManager* m_pDebugHookManager; - CPedManager* m_pPedManager; - CResourceManager* m_pResourceManager; - CAccessControlListManager* m_pACLManager; - CSettings* m_pSettings; - CZoneNames* m_pZoneNames; - ASE* m_pASE; - CHandlingManager* m_pHandlingManager; - CRPCFunctions* m_pRPCFunctions; - CLanBroadcast* m_pLanBroadcast; - CWaterManager* m_pWaterManager; + CMarkerManager* m_pMarkerManager; + CClock* m_pClock; + CBanManager* m_pBanManager; + CTeamManager* m_pTeamManager; + CCommandLineParser m_CommandLineParser; + CRegisteredCommands* m_pRegisteredCommands; + CDatabaseManager* m_pDatabaseManager; + CLuaCallbackManager* m_pLuaCallbackManager; + CRegistryManager* m_pRegistryManager; + CRegistry* m_pRegistry; + CAccountManager* m_pAccountManager; + CLatentTransferManager* m_pLatentTransferManager; + CDebugHookManager* m_pDebugHookManager; + CPedManager* m_pPedManager; + CResourceManager* m_pResourceManager; + CAccessControlListManager* m_pACLManager; + CSettings* m_pSettings; + CZoneNames* m_pZoneNames; + ASE* m_pASE; + std::shared_ptr m_HandlingManager; + CRPCFunctions* m_pRPCFunctions; + CLanBroadcast* m_pLanBroadcast; + CWaterManager* m_pWaterManager; CWeaponStatManager* m_pWeaponStatsManager; CBuildingRemovalManager* m_pBuildingRemovalManager; diff --git a/Server/mods/deathmatch/logic/CHandlingEntry.cpp b/Server/mods/deathmatch/logic/CHandlingEntry.cpp index 7079a9a223..eef8923604 100644 --- a/Server/mods/deathmatch/logic/CHandlingEntry.cpp +++ b/Server/mods/deathmatch/logic/CHandlingEntry.cpp @@ -2,10 +2,10 @@ * * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/CHandlingEntry.cpp + * FILE: Server/mods/deathmatch/logic/CHandlingEntry.cpp * PURPOSE: Vehicle handling data entry * - * Multi Theft Auto is available from http://www.multitheftauto.com/ + * Multi Theft Auto is available from https://multitheftauto.com/ * *****************************************************************************/ @@ -14,16 +14,19 @@ CHandlingEntry::CHandlingEntry(tHandlingData* pOriginal) { - if (pOriginal) - { - // Copy the data from our original - m_Handling = *pOriginal; - } + if (!pOriginal) + return; + + // Copy the data from our original + m_Handling = *pOriginal; } // Apply the handling data from another data -void CHandlingEntry::ApplyHandlingData(const CHandlingEntry* pData) +void CHandlingEntry::ApplyHandlingData(const CHandlingEntry* const pData) noexcept { + if (!pData) + return; + // Copy the data from our handling entry m_Handling = pData->m_Handling; } diff --git a/Server/mods/deathmatch/logic/CHandlingEntry.h b/Server/mods/deathmatch/logic/CHandlingEntry.h index 4dd866baac..7f2afeca2a 100644 --- a/Server/mods/deathmatch/logic/CHandlingEntry.h +++ b/Server/mods/deathmatch/logic/CHandlingEntry.h @@ -1,11 +1,11 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/CHandlingEntry.h + * FILE: Server/mods/deathmatch/logic/CHandlingEntry.h * PURPOSE: Header file for vehicle handling data entry class * - * Multi Theft Auto is available from http://www.multitheftauto.com/ + * Multi Theft Auto is available from https://multitheftauto.com/ * *****************************************************************************/ @@ -104,96 +104,96 @@ class CHandlingEntry ~CHandlingEntry(){}; // Use this to copy data from an another handling class to this - void ApplyHandlingData(const CHandlingEntry* pData); + void ApplyHandlingData(const CHandlingEntry* const pData) noexcept; // Get functions - tHandlingData GetHandlingData() { return m_Handling; }; - float GetMass() const { return m_Handling.fMass; }; - float GetTurnMass() const { return m_Handling.fTurnMass; }; - float GetDragCoeff() const { return m_Handling.fDragCoeff; }; - const CVector& GetCenterOfMass() const { return m_Handling.vecCenterOfMass; }; - - unsigned int GetPercentSubmerged() const { return m_Handling.uiPercentSubmerged; }; - float GetTractionMultiplier() const { return m_Handling.fTractionMultiplier; }; - - eDriveType GetCarDriveType() const { return static_cast(m_Handling.Transmission.ucDriveType); }; - eEngineType GetCarEngineType() const { return static_cast(m_Handling.Transmission.ucEngineType); }; - unsigned char GetNumberOfGears() const { return m_Handling.Transmission.ucNumberOfGears; }; - - float GetEngineAcceleration() const { return m_Handling.Transmission.fEngineAcceleration; }; - float GetEngineInertia() const { return m_Handling.Transmission.fEngineInertia; }; - float GetMaxVelocity() const { return m_Handling.Transmission.fMaxVelocity; }; - - float GetBrakeDeceleration() const { return m_Handling.fBrakeDeceleration; }; - float GetBrakeBias() const { return m_Handling.fBrakeBias; }; - bool GetABS() const { return m_Handling.bABS; }; - - float GetSteeringLock() const { return m_Handling.fSteeringLock; }; - float GetTractionLoss() const { return m_Handling.fTractionLoss; }; - float GetTractionBias() const { return m_Handling.fTractionBias; }; - - float GetSuspensionForceLevel() const { return m_Handling.fSuspensionForceLevel; }; - float GetSuspensionDamping() const { return m_Handling.fSuspensionDamping; }; - float GetSuspensionHighSpeedDamping() const { return m_Handling.fSuspensionHighSpdDamping; }; - float GetSuspensionUpperLimit() const { return m_Handling.fSuspensionUpperLimit; }; - float GetSuspensionLowerLimit() const { return m_Handling.fSuspensionLowerLimit; }; - float GetSuspensionFrontRearBias() const { return m_Handling.fSuspensionFrontRearBias; }; - float GetSuspensionAntiDiveMultiplier() const { return m_Handling.fSuspensionAntiDiveMultiplier; }; - - float GetCollisionDamageMultiplier() const { return m_Handling.fCollisionDamageMultiplier; }; - - unsigned int GetHandlingFlags() const { return m_Handling.uiHandlingFlags; }; - unsigned int GetModelFlags() const { return m_Handling.uiModelFlags; }; - float GetSeatOffsetDistance() const { return m_Handling.fSeatOffsetDistance; }; - unsigned int GetMonetary() const { return m_Handling.uiMonetary; }; - - eLightType GetHeadLight() const { return static_cast(m_Handling.ucHeadLight); }; - eLightType GetTailLight() const { return static_cast(m_Handling.ucTailLight); }; - unsigned char GetAnimGroup() const { return m_Handling.ucAnimGroup; }; + tHandlingData GetHandlingData() const noexcept { return m_Handling; } + float GetMass() const noexcept { return m_Handling.fMass; } + float GetTurnMass() const noexcept { return m_Handling.fTurnMass; } + float GetDragCoeff() const noexcept { return m_Handling.fDragCoeff; } + const CVector& GetCenterOfMass() const noexcept { return m_Handling.vecCenterOfMass; } + + unsigned int GetPercentSubmerged() const noexcept { return m_Handling.uiPercentSubmerged; } + float GetTractionMultiplier() const noexcept { return m_Handling.fTractionMultiplier; } + + eDriveType GetCarDriveType() const noexcept { return static_cast(m_Handling.Transmission.ucDriveType); } + eEngineType GetCarEngineType() const noexcept { return static_cast(m_Handling.Transmission.ucEngineType); } + unsigned char GetNumberOfGears() const noexcept { return m_Handling.Transmission.ucNumberOfGears; } + + float GetEngineAcceleration() const noexcept { return m_Handling.Transmission.fEngineAcceleration; } + float GetEngineInertia() const noexcept { return m_Handling.Transmission.fEngineInertia; } + float GetMaxVelocity() const noexcept { return m_Handling.Transmission.fMaxVelocity; } + + float GetBrakeDeceleration() const noexcept { return m_Handling.fBrakeDeceleration; } + float GetBrakeBias() const noexcept { return m_Handling.fBrakeBias; } + bool GetABS() const noexcept { return m_Handling.bABS; } + + float GetSteeringLock() const noexcept { return m_Handling.fSteeringLock; } + float GetTractionLoss() const noexcept { return m_Handling.fTractionLoss; } + float GetTractionBias() const noexcept { return m_Handling.fTractionBias; } + + float GetSuspensionForceLevel() const noexcept { return m_Handling.fSuspensionForceLevel; } + float GetSuspensionDamping() const noexcept { return m_Handling.fSuspensionDamping; } + float GetSuspensionHighSpeedDamping() const noexcept { return m_Handling.fSuspensionHighSpdDamping; } + float GetSuspensionUpperLimit() const noexcept { return m_Handling.fSuspensionUpperLimit; } + float GetSuspensionLowerLimit() const noexcept { return m_Handling.fSuspensionLowerLimit; } + float GetSuspensionFrontRearBias() const noexcept { return m_Handling.fSuspensionFrontRearBias; } + float GetSuspensionAntiDiveMultiplier() const noexcept { return m_Handling.fSuspensionAntiDiveMultiplier; } + + float GetCollisionDamageMultiplier() const noexcept { return m_Handling.fCollisionDamageMultiplier; } + + unsigned int GetHandlingFlags() const noexcept { return m_Handling.uiHandlingFlags; } + unsigned int GetModelFlags() const noexcept { return m_Handling.uiModelFlags; } + float GetSeatOffsetDistance() const noexcept { return m_Handling.fSeatOffsetDistance; } + unsigned int GetMonetary() const noexcept { return m_Handling.uiMonetary; } + + eLightType GetHeadLight() const noexcept { return static_cast(m_Handling.ucHeadLight); } + eLightType GetTailLight() const noexcept { return static_cast(m_Handling.ucTailLight); } + unsigned char GetAnimGroup() const noexcept { return m_Handling.ucAnimGroup; } // Set functions - void SetMass(float fMass) { m_Handling.fMass = fMass; }; - void SetTurnMass(float fTurnMass) { m_Handling.fTurnMass = fTurnMass; }; - void SetDragCoeff(float fDrag) { m_Handling.fDragCoeff = fDrag; }; - void SetCenterOfMass(const CVector& vecCenter) { m_Handling.vecCenterOfMass = vecCenter; }; - - void SetPercentSubmerged(unsigned int uiPercent) { m_Handling.uiPercentSubmerged = uiPercent; }; - void SetTractionMultiplier(float fTractionMultiplier) { m_Handling.fTractionMultiplier = fTractionMultiplier; }; - - void SetCarDriveType(eDriveType Type) { m_Handling.Transmission.ucDriveType = Type; }; - void SetCarEngineType(eEngineType Type) { m_Handling.Transmission.ucEngineType = Type; }; - void SetNumberOfGears(unsigned char ucNumber) { m_Handling.Transmission.ucNumberOfGears = ucNumber; }; - - void SetEngineAcceleration(float fAcceleration) { m_Handling.Transmission.fEngineAcceleration = fAcceleration; }; - void SetEngineInertia(float fInertia) { m_Handling.Transmission.fEngineInertia = fInertia; }; - void SetMaxVelocity(float fVelocity) { m_Handling.Transmission.fMaxVelocity = fVelocity; }; - - void SetBrakeDeceleration(float fDeceleration) { m_Handling.fBrakeDeceleration = fDeceleration; }; - void SetBrakeBias(float fBias) { m_Handling.fBrakeBias = fBias; }; - void SetABS(bool bABS) { m_Handling.bABS = bABS; }; - - void SetSteeringLock(float fSteeringLock) { m_Handling.fSteeringLock = fSteeringLock; }; - void SetTractionLoss(float fTractionLoss) { m_Handling.fTractionLoss = fTractionLoss; }; - void SetTractionBias(float fTractionBias) { m_Handling.fTractionBias = fTractionBias; }; - - void SetSuspensionForceLevel(float fForce) { m_Handling.fSuspensionForceLevel = fForce; }; - void SetSuspensionDamping(float fDamping) { m_Handling.fSuspensionDamping = fDamping; }; - void SetSuspensionHighSpeedDamping(float fDamping) { m_Handling.fSuspensionHighSpdDamping = fDamping; }; - void SetSuspensionUpperLimit(float fUpperLimit) { m_Handling.fSuspensionUpperLimit = fUpperLimit; }; - void SetSuspensionLowerLimit(float fLowerLimit) { m_Handling.fSuspensionLowerLimit = fLowerLimit; }; - void SetSuspensionFrontRearBias(float fBias) { m_Handling.fSuspensionFrontRearBias = fBias; }; - void SetSuspensionAntiDiveMultiplier(float fAntidive) { m_Handling.fSuspensionAntiDiveMultiplier = fAntidive; }; - - void SetCollisionDamageMultiplier(float fMultiplier) { m_Handling.fCollisionDamageMultiplier = fMultiplier; }; - - void SetHandlingFlags(unsigned int uiFlags) { m_Handling.uiHandlingFlags = uiFlags; }; - void SetModelFlags(unsigned int uiFlags) { m_Handling.uiModelFlags = uiFlags; }; - void SetSeatOffsetDistance(float fDistance) { m_Handling.fSeatOffsetDistance = fDistance; }; - void SetMonetary(unsigned int uiMonetary) { m_Handling.uiMonetary = uiMonetary; }; - - void SetHeadLight(eLightType Style) { m_Handling.ucHeadLight = Style; }; - void SetTailLight(eLightType Style) { m_Handling.ucTailLight = Style; }; - void SetAnimGroup(unsigned char ucGroup) { m_Handling.ucAnimGroup = ucGroup; }; + void SetMass(float fMass) noexcept { m_Handling.fMass = fMass; } + void SetTurnMass(float fTurnMass) noexcept { m_Handling.fTurnMass = fTurnMass; } + void SetDragCoeff(float fDrag) noexcept { m_Handling.fDragCoeff = fDrag; } + void SetCenterOfMass(const CVector& vecCenter) noexcept { m_Handling.vecCenterOfMass = vecCenter; } + + void SetPercentSubmerged(unsigned int uiPercent) noexcept { m_Handling.uiPercentSubmerged = uiPercent; } + void SetTractionMultiplier(float fTractionMultiplier) noexcept { m_Handling.fTractionMultiplier = fTractionMultiplier; } + + void SetCarDriveType(eDriveType Type) noexcept { m_Handling.Transmission.ucDriveType = Type; } + void SetCarEngineType(eEngineType Type) noexcept { m_Handling.Transmission.ucEngineType = Type; } + void SetNumberOfGears(unsigned char ucNumber) noexcept { m_Handling.Transmission.ucNumberOfGears = ucNumber; } + + void SetEngineAcceleration(float fAcceleration) noexcept { m_Handling.Transmission.fEngineAcceleration = fAcceleration; } + void SetEngineInertia(float fInertia) noexcept { m_Handling.Transmission.fEngineInertia = fInertia; } + void SetMaxVelocity(float fVelocity) noexcept { m_Handling.Transmission.fMaxVelocity = fVelocity; } + + void SetBrakeDeceleration(float fDeceleration) noexcept { m_Handling.fBrakeDeceleration = fDeceleration; } + void SetBrakeBias(float fBias) noexcept { m_Handling.fBrakeBias = fBias; } + void SetABS(bool bABS) noexcept { m_Handling.bABS = bABS; } + + void SetSteeringLock(float fSteeringLock) noexcept { m_Handling.fSteeringLock = fSteeringLock; } + void SetTractionLoss(float fTractionLoss) noexcept { m_Handling.fTractionLoss = fTractionLoss; } + void SetTractionBias(float fTractionBias) noexcept { m_Handling.fTractionBias = fTractionBias; } + + void SetSuspensionForceLevel(float fForce) noexcept { m_Handling.fSuspensionForceLevel = fForce; } + void SetSuspensionDamping(float fDamping) noexcept { m_Handling.fSuspensionDamping = fDamping; } + void SetSuspensionHighSpeedDamping(float fDamping) noexcept { m_Handling.fSuspensionHighSpdDamping = fDamping; } + void SetSuspensionUpperLimit(float fUpperLimit) noexcept { m_Handling.fSuspensionUpperLimit = fUpperLimit; } + void SetSuspensionLowerLimit(float fLowerLimit) noexcept { m_Handling.fSuspensionLowerLimit = fLowerLimit; } + void SetSuspensionFrontRearBias(float fBias) noexcept { m_Handling.fSuspensionFrontRearBias = fBias; } + void SetSuspensionAntiDiveMultiplier(float fAntidive) noexcept { m_Handling.fSuspensionAntiDiveMultiplier = fAntidive; } + + void SetCollisionDamageMultiplier(float fMultiplier) noexcept { m_Handling.fCollisionDamageMultiplier = fMultiplier; } + + void SetHandlingFlags(unsigned int uiFlags) noexcept { m_Handling.uiHandlingFlags = uiFlags; } + void SetModelFlags(unsigned int uiFlags) noexcept { m_Handling.uiModelFlags = uiFlags; } + void SetSeatOffsetDistance(float fDistance) noexcept { m_Handling.fSeatOffsetDistance = fDistance; } + void SetMonetary(unsigned int uiMonetary) noexcept { m_Handling.uiMonetary = uiMonetary; } + + void SetHeadLight(eLightType Style) noexcept { m_Handling.ucHeadLight = Style; } + void SetTailLight(eLightType Style) noexcept { m_Handling.ucTailLight = Style; } + void SetAnimGroup(unsigned char ucGroup) noexcept { m_Handling.ucAnimGroup = ucGroup; } private: tHandlingData m_Handling; diff --git a/Server/mods/deathmatch/logic/CHandlingManager.cpp b/Server/mods/deathmatch/logic/CHandlingManager.cpp index 8f7be518c9..bc491da14f 100644 --- a/Server/mods/deathmatch/logic/CHandlingManager.cpp +++ b/Server/mods/deathmatch/logic/CHandlingManager.cpp @@ -14,10 +14,15 @@ #include "CCommon.h" #include "CVehicleManager.h" -SFixedArray CHandlingManager::m_OriginalHandlingData; +// Original handling data +static tHandlingData m_OriginalHandlingData[HT_MAX]; +static std::unique_ptr m_OriginalEntries[HT_MAX]; -SFixedArray CHandlingManager::m_pOriginalEntries; -SFixedArray CHandlingManager::m_pModelEntries; +// Model handling data +static std::unordered_map> m_ModelEntries; +static std::unordered_map m_bModelHandlingChanged; + +static std::map m_HandlingNames; CHandlingManager::CHandlingManager() { @@ -25,14 +30,10 @@ CHandlingManager::CHandlingManager() InitializeDefaultHandlings(); // Create a handling entry - for (int i = 0; i < HT_MAX; i++) + for (std::size_t i = 0; i < HT_MAX; i++) { // For every original handling data - m_pOriginalEntries[i] = new CHandlingEntry(&m_OriginalHandlingData[i]); - - // For every model - m_pModelEntries[i] = new CHandlingEntry(&m_OriginalHandlingData[i]); - m_bModelHandlingChanged[i] = false; + m_OriginalEntries[i] = std::make_unique(&m_OriginalHandlingData[i]); } // http://www.gtamodding.com/index.php?title=Handling.cfg#GTA_San_Andreas @@ -76,93 +77,88 @@ CHandlingManager::CHandlingManager() CHandlingManager::~CHandlingManager() { - // Destroy - for (int i = 0; i < HT_MAX; i++) - { - // All original handling entries - delete m_pOriginalEntries[i]; - - // All model handling entries - delete m_pModelEntries[i]; - } } -CHandlingEntry* CHandlingManager::CreateHandlingData() +std::unique_ptr CHandlingManager::CreateHandlingData() const noexcept { - return new CHandlingEntry; + return std::make_unique(); } -bool CHandlingManager::ApplyHandlingData(eVehicleTypes eModel, CHandlingEntry* pEntry) +bool CHandlingManager::ApplyHandlingData(std::uint32_t model, CHandlingEntry* pEntry) const noexcept { - // Within range? - if (!CVehicleManager::IsValidModel(eModel)) + CHandlingEntry* pHandling = GetModelHandlingData(model); + if (!pHandling) return false; - // Get our Handling ID - eHandlingTypes eHandling = GetHandlingID(eModel); - // Apply the data and return success - m_pModelEntries[eHandling]->ApplyHandlingData(pEntry); + pHandling->ApplyHandlingData(pEntry); return true; } -const CHandlingEntry* CHandlingManager::GetOriginalHandlingData(eVehicleTypes eModel) +const CHandlingEntry* CHandlingManager::GetOriginalHandlingData(std::uint32_t model) const noexcept { // Within range? - if (!CVehicleManager::IsValidModel(eModel)) + if (!CVehicleManager::IsValidModel(model)) return nullptr; // Get our Handling ID - eHandlingTypes eHandling = GetHandlingID(eModel); + const eHandlingTypes eHandling = GetHandlingID(model); + // Return it - return m_pOriginalEntries[eHandling]; + return m_OriginalEntries[eHandling].get(); } -const CHandlingEntry* CHandlingManager::GetModelHandlingData(eVehicleTypes eModel) +CHandlingEntry* CHandlingManager::GetModelHandlingData(std::uint32_t model) const noexcept { // Within range? - if (!CVehicleManager::IsValidModel(eModel)) + if (!CVehicleManager::IsValidModel(model)) return nullptr; - // Get our Handling ID - eHandlingTypes eHandling = GetHandlingID(eModel); - // Return it - return m_pModelEntries[eHandling]; + auto entries = m_ModelEntries.find(model); + if (entries == m_ModelEntries.end()) + { + // Get our Handling ID + const eHandlingTypes eHandling = GetHandlingID(model); + + m_ModelEntries[model] = std::make_unique(&m_OriginalHandlingData[eHandling]); + if (!m_ModelEntries[model]) + return nullptr; + + entries = m_ModelEntries.find(model); + } + + return entries->second.get(); } -eHandlingProperty CHandlingManager::GetPropertyEnumFromName(const std::string& strName) +eHandlingProperty CHandlingManager::GetPropertyEnumFromName(const std::string& name) const noexcept { - const auto it = m_HandlingNames.find(strName); + const auto it = m_HandlingNames.find(name); return it != m_HandlingNames.end() ? it->second : HANDLING_MAX; } -bool CHandlingManager::HasModelHandlingChanged(eVehicleTypes eModel) +bool CHandlingManager::HasModelHandlingChanged(std::uint32_t model) const noexcept { // Within range? - if (!CVehicleManager::IsValidModel(eModel)) + if (!CVehicleManager::IsValidModel(model)) return false; - // Get our Handling ID - eHandlingTypes eHandling = GetHandlingID(eModel); // Return if we have changed - return m_bModelHandlingChanged[eHandling]; + return m_bModelHandlingChanged[model]; } -void CHandlingManager::SetModelHandlingHasChanged(eVehicleTypes eModel, bool bChanged) +void CHandlingManager::SetModelHandlingHasChanged(std::uint32_t model, bool bChanged) const noexcept { // Within range? - if (!CVehicleManager::IsValidModel(eModel)) + if (!CVehicleManager::IsValidModel(model)) return; - // Get our Handling ID - eHandlingTypes eHandling = GetHandlingID(eModel); // Return if we have changed. - m_bModelHandlingChanged[eHandling] = bChanged; + m_bModelHandlingChanged[model] = bChanged; } // Return the handling manager id -eHandlingTypes CHandlingManager::GetHandlingID(eVehicleTypes eModel) +eHandlingTypes CHandlingManager::GetHandlingID(std::uint32_t model) const noexcept { - switch (eModel) + switch (model) { case VT_LANDSTAL: return HT_LANDSTAL; @@ -594,7 +590,7 @@ eHandlingTypes CHandlingManager::GetHandlingID(eVehicleTypes eModel) return HT_LANDSTAL; } -void CHandlingManager::InitializeDefaultHandlings() +void CHandlingManager::InitializeDefaultHandlings() noexcept { // Reset memset(&m_OriginalHandlingData[0], 0, sizeof(m_OriginalHandlingData)); diff --git a/Server/mods/deathmatch/logic/CHandlingManager.h b/Server/mods/deathmatch/logic/CHandlingManager.h index 4d52c5cc18..bd0e2f0aa6 100644 --- a/Server/mods/deathmatch/logic/CHandlingManager.h +++ b/Server/mods/deathmatch/logic/CHandlingManager.h @@ -22,33 +22,20 @@ class CHandlingManager CHandlingManager(); ~CHandlingManager(); - CHandlingEntry* CreateHandlingData(); + std::unique_ptr CreateHandlingData() const noexcept; - bool ApplyHandlingData(eVehicleTypes eModel, CHandlingEntry* pEntry); + bool ApplyHandlingData(std::uint32_t model, CHandlingEntry* pEntry) const noexcept; - const CHandlingEntry* GetModelHandlingData(eVehicleTypes eModel); - const CHandlingEntry* GetOriginalHandlingData(eVehicleTypes eModel); + const CHandlingEntry* GetOriginalHandlingData(std::uint32_t model) const noexcept; + CHandlingEntry* GetModelHandlingData(std::uint32_t model) const noexcept; - eHandlingTypes GetHandlingID(eVehicleTypes eModel); + eHandlingTypes GetHandlingID(std::uint32_t model) const noexcept; // Helper functions - eHandlingProperty GetPropertyEnumFromName(const std::string& strName); - bool HasModelHandlingChanged(eVehicleTypes eModel); - void SetModelHandlingHasChanged(eVehicleTypes eModel, bool bChanged); - - std::map m_HandlingNames; + eHandlingProperty GetPropertyEnumFromName(const std::string& name) const noexcept; + bool HasModelHandlingChanged(std::uint32_t model) const noexcept; + void SetModelHandlingHasChanged(std::uint32_t model, bool bChanged) const noexcept; private: - void InitializeDefaultHandlings(); - - // Original handling data unaffected by handling.cfg changes - static SFixedArray m_OriginalHandlingData; - - // Array with the original handling entries - static SFixedArray m_pOriginalEntries; - - // Array with the model handling entries - static SFixedArray m_pModelEntries; - - SFixedArray m_bModelHandlingChanged; + void InitializeDefaultHandlings() noexcept; }; diff --git a/Server/mods/deathmatch/logic/CMainConfig.cpp b/Server/mods/deathmatch/logic/CMainConfig.cpp index bece65e885..49c73419ca 100644 --- a/Server/mods/deathmatch/logic/CMainConfig.cpp +++ b/Server/mods/deathmatch/logic/CMainConfig.cpp @@ -80,6 +80,7 @@ CMainConfig::CMainConfig(CConsole* pConsole) : CXMLConfig(NULL) m_iBackupAmount = 5; m_bSyncMapElementData = true; m_elementDataWhitelisted = false; + m_checkDuplicateSerials = true; } bool CMainConfig::Load() @@ -528,6 +529,7 @@ bool CMainConfig::Load() } GetBoolean(m_pRootNode, "elementdata_whitelisted", m_elementDataWhitelisted); + GetBoolean(m_pRootNode, "check_duplicate_serials", m_checkDuplicateSerials); ApplyNetOptions(); diff --git a/Server/mods/deathmatch/logic/CMainConfig.h b/Server/mods/deathmatch/logic/CMainConfig.h index 9758ae2dbf..05df0e2f32 100644 --- a/Server/mods/deathmatch/logic/CMainConfig.h +++ b/Server/mods/deathmatch/logic/CMainConfig.h @@ -127,6 +127,7 @@ class CMainConfig : public CXMLConfig bool IsDatabaseCredentialsProtectionEnabled() const { return m_bDatabaseCredentialsProtectionEnabled != 0; } bool IsFakeLagCommandEnabled() const { return m_bFakeLagCommandEnabled != 0; } bool IsElementDataWhitelisted() const { return m_elementDataWhitelisted; } + bool IsCheckDuplicateSerialsEnabled() const noexcept { return m_checkDuplicateSerials; } bool IsCheckResourceClientFilesEnabled() const noexcept { return m_checkResourceClientFiles != 0; } SString GetSetting(const SString& configSetting); @@ -230,5 +231,6 @@ class CMainConfig : public CXMLConfig int m_iPlayerTriggeredEventIntervalMs; int m_iMaxPlayerTriggeredEventsPerInterval; bool m_elementDataWhitelisted; + bool m_checkDuplicateSerials; int m_checkResourceClientFiles; }; diff --git a/Server/mods/deathmatch/logic/CPacketTranslator.cpp b/Server/mods/deathmatch/logic/CPacketTranslator.cpp index 3b6d92c3db..3cf0fa0965 100644 --- a/Server/mods/deathmatch/logic/CPacketTranslator.cpp +++ b/Server/mods/deathmatch/logic/CPacketTranslator.cpp @@ -48,6 +48,7 @@ #include "packets/CPlayerNoSocketPacket.h" #include "packets/CPlayerNetworkStatusPacket.h" #include "packets/CPlayerResourceStartPacket.h" +#include "packets/CPlayerWorldSpecialPropertyPacket.h" CPacketTranslator::CPacketTranslator(CPlayerManager* pPlayerManager) { @@ -212,6 +213,10 @@ CPacket* CPacketTranslator::Translate(const NetServerPlayerID& Socket, ePacketID pTemp = new CPlayerResourceStartPacket; break; + case PACKET_ID_PLAYER_WORLD_SPECIAL_PROPERTY: + pTemp = new CPlayerWorldSpecialPropertyPacket; + break; + default: break; } diff --git a/Server/mods/deathmatch/logic/CPlayerManager.cpp b/Server/mods/deathmatch/logic/CPlayerManager.cpp index abdf923df7..227d3677f2 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/CPlayerManager.cpp @@ -138,6 +138,17 @@ CPlayer* CPlayerManager::Get(const char* szNick, bool bCaseSensitive) return NULL; } +CPlayer* CPlayerManager::GetBySerial(const std::string_view serial) const noexcept +{ + for (const auto& player : m_Players) + { + if (player->GetSerial() == serial) + return player; + } + + return nullptr; +} + void CPlayerManager::DeleteAll() { // Delete all the items in the list diff --git a/Server/mods/deathmatch/logic/CPlayerManager.h b/Server/mods/deathmatch/logic/CPlayerManager.h index bd503380f4..0380c4bce4 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.h +++ b/Server/mods/deathmatch/logic/CPlayerManager.h @@ -40,6 +40,7 @@ class CPlayerManager CPlayer* Get(const NetServerPlayerID& PlayerSocket); CPlayer* Get(const char* szNick, bool bCaseSensitive = false); + CPlayer* GetBySerial(const std::string_view serial) const noexcept; std::list::const_iterator IterBegin() { return m_Players.begin(); }; std::list::const_iterator IterEnd() { return m_Players.end(); }; diff --git a/Server/mods/deathmatch/logic/CResource.cpp b/Server/mods/deathmatch/logic/CResource.cpp index 1c2ebe3ea8..279f1937a7 100644 --- a/Server/mods/deathmatch/logic/CResource.cpp +++ b/Server/mods/deathmatch/logic/CResource.cpp @@ -35,6 +35,7 @@ #include #include #include +#include "CStaticFunctionDefinitions.h" #ifdef WIN32 #include diff --git a/Server/mods/deathmatch/logic/CResourceChecker.Data.h b/Server/mods/deathmatch/logic/CResourceChecker.Data.h index e6bdee9212..630f70fd81 100644 --- a/Server/mods/deathmatch/logic/CResourceChecker.Data.h +++ b/Server/mods/deathmatch/logic/CResourceChecker.Data.h @@ -167,8 +167,8 @@ namespace //{false, "doesPedHaveJetPack", "isPedWearingJetpack"}, // Base Encoding & Decoding - {false, "base64Encode", "encodeString"}, - {false, "base64Decode", "decodeString"}, + {true, "base64Encode", "Please manually change this to encodeString (different syntax). Refer to the wiki for details"}, + {true, "base64Decode", "Please manually change this to decodeString (different syntax). Refer to the wiki for details"}, {false, "setHelicopterRotorSpeed", "setVehicleRotorSpeed"} }; @@ -271,7 +271,7 @@ namespace {true, "setPlayerDiscordJoinParams", "See GitHub PR #2499 for more details"}, // Base Encoding & Decoding - {false, "base64Encode", "encodeString"}, - {false, "base64Decode", "decodeString"} + {true, "base64Encode", "Please manually change this to encodeString (different syntax). Refer to the wiki for details"}, + {true, "base64Decode", "Please manually change this to decodeString (different syntax). Refer to the wiki for details"} }; } // namespace diff --git a/Server/mods/deathmatch/logic/CResourceChecker.cpp b/Server/mods/deathmatch/logic/CResourceChecker.cpp index 07f433f34f..9998b089ca 100644 --- a/Server/mods/deathmatch/logic/CResourceChecker.cpp +++ b/Server/mods/deathmatch/logic/CResourceChecker.cpp @@ -367,16 +367,25 @@ void CResourceChecker::CheckMetaSourceForIssues(CXMLNode* pRootNode, const strin attributes.Delete("client"); attributes.Delete("both"); - if (!m_strReqServerVersion.empty()) + // Use "both" if client and server versions are the same + if (!m_strReqServerVersion.empty() && !m_strReqClientVersion.empty() && m_strReqServerVersion == m_strReqClientVersion) { - CXMLAttribute* pAttr = attributes.Create("server"); + CXMLAttribute* pAttr = attributes.Create("both"); pAttr->SetValue(m_strReqServerVersion); } - - if (!m_strReqClientVersion.empty()) + else { - CXMLAttribute* pAttr = attributes.Create("client"); - pAttr->SetValue(m_strReqClientVersion); + if (!m_strReqServerVersion.empty()) + { + CXMLAttribute* pAttr = attributes.Create("server"); + pAttr->SetValue(m_strReqServerVersion); + } + + if (!m_strReqClientVersion.empty()) + { + CXMLAttribute* pAttr = attributes.Create("client"); + pAttr->SetValue(m_strReqClientVersion); + } } if (pbOutHasChanged) diff --git a/Server/mods/deathmatch/logic/CResourceChecker.h b/Server/mods/deathmatch/logic/CResourceChecker.h index 50c7ec00bb..ea9e7a1be9 100644 --- a/Server/mods/deathmatch/logic/CResourceChecker.h +++ b/Server/mods/deathmatch/logic/CResourceChecker.h @@ -2,7 +2,7 @@ * * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/CResourceChecker.cpp + * FILE: mods/deathmatch/logic/CResourceChecker.h * PURPOSE: Resource file content checker/validator/upgrader * * Multi Theft Auto is available from http://www.multitheftauto.com/ diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index b4d1de641f..40b370c58f 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -79,27 +79,28 @@ extern CGame* g_pGame; extern CTimeUsMarker<20> markerLatentEvent; -static CLuaManager* m_pLuaManager; -static CColManager* m_pColManager; -static CPickupManager* m_pPickupManager; -static CPlayerManager* m_pPlayerManager; -static CVehicleManager* m_pVehicleManager; -static CObjectManager* m_pObjectManager; -static CMarkerManager* m_pMarkerManager; -static CMapManager* m_pMapManager; -static CBlipManager* m_pBlipManager; -static CRadarAreaManager* m_pRadarAreaManager; -static CTeamManager* m_pTeamManager; -static CClock* m_pClock; -static CEvents* m_pEvents; -static CElementDeleter* m_pElementDeleter; -static CMainConfig* m_pMainConfig; -static CRegistry* m_pRegistry; -static CAccountManager* m_pAccountManager; -static CBanManager* m_pBanManager; -static CPedManager* m_pPedManager; -static CWaterManager* m_pWaterManager; -static CCustomWeaponManager* m_pCustomWeaponManager; +static CLuaManager* m_pLuaManager; +static CColManager* m_pColManager; +static CPickupManager* m_pPickupManager; +static CPlayerManager* m_pPlayerManager; +static CVehicleManager* m_pVehicleManager; +static CObjectManager* m_pObjectManager; +static CMarkerManager* m_pMarkerManager; +static CMapManager* m_pMapManager; +static CBlipManager* m_pBlipManager; +static CRadarAreaManager* m_pRadarAreaManager; +static CTeamManager* m_pTeamManager; +static CClock* m_pClock; +static CEvents* m_pEvents; +static CElementDeleter* m_pElementDeleter; +static CMainConfig* m_pMainConfig; +static CRegistry* m_pRegistry; +static CAccountManager* m_pAccountManager; +static CBanManager* m_pBanManager; +static CPedManager* m_pPedManager; +static CWaterManager* m_pWaterManager; +static CCustomWeaponManager* m_pCustomWeaponManager; +static std::shared_ptr m_HandlingManager; // Used to run a function on all the children of the elements too #define RUN_CHILDREN(func) \ @@ -134,6 +135,7 @@ CStaticFunctionDefinitions::CStaticFunctionDefinitions(CGame* pGame) m_pPedManager = pGame->GetPedManager(); m_pWaterManager = pGame->GetWaterManager(); m_pCustomWeaponManager = pGame->GetCustomWeaponManager(); + m_HandlingManager = pGame->GetHandlingManager(); } CStaticFunctionDefinitions::~CStaticFunctionDefinitions() @@ -5485,190 +5487,165 @@ bool CStaticFunctionDefinitions::GetVehicleHandling(CVehicle* pVehicle, eHandlin return false; } -bool CStaticFunctionDefinitions::GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, CVector& vecValue, bool bOriginal) +bool CStaticFunctionDefinitions::GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, CVector& vecValue, bool bOriginal) { - const CHandlingEntry* pEntry = NULL; + const CHandlingEntry* pEntry = nullptr; if (bOriginal) { - pEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(eModel); + pEntry = m_HandlingManager->GetOriginalHandlingData(model); } else { - pEntry = g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); + pEntry = m_HandlingManager->GetModelHandlingData(model); } - if (pEntry) + if (!pEntry) + return false; + + if (eProperty == HANDLING_CENTEROFMASS) { - if (eProperty == HANDLING_CENTEROFMASS) - { - vecValue = pEntry->GetCenterOfMass(); - return true; - } + vecValue = pEntry->GetCenterOfMass(); + return true; } + return false; } -bool CStaticFunctionDefinitions::GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, float& fValue, bool bOriginal) +bool CStaticFunctionDefinitions::GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, float& fValue, bool bOriginal) { - const CHandlingEntry* pEntry = NULL; + const CHandlingEntry* pEntry = nullptr; if (bOriginal) { - pEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(eModel); + pEntry = m_HandlingManager->GetOriginalHandlingData(model); } else { - pEntry = g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); + pEntry = m_HandlingManager->GetModelHandlingData(model); } - if (pEntry) - { - if (GetEntryHandling(pEntry, eProperty, fValue)) - { - return true; - } - } - return false; + if (!pEntry) + return false; + + return GetEntryHandling(pEntry, eProperty, fValue); } -bool CStaticFunctionDefinitions::GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, unsigned int& uiValue, bool bOriginal) +bool CStaticFunctionDefinitions::GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, unsigned int& uiValue, bool bOriginal) { - const CHandlingEntry* pEntry = NULL; + const CHandlingEntry* pEntry = nullptr; if (bOriginal) { - pEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(eModel); + pEntry = m_HandlingManager->GetOriginalHandlingData(model); } else { - pEntry = g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); + pEntry = m_HandlingManager->GetModelHandlingData(model); } - if (pEntry) - { - if (GetEntryHandling(pEntry, eProperty, uiValue)) - { - return true; - } - } - return false; + if (!pEntry) + return false; + + return GetEntryHandling(pEntry, eProperty, uiValue); } -bool CStaticFunctionDefinitions::GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, unsigned char& ucValue, bool bOriginal) +bool CStaticFunctionDefinitions::GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, unsigned char& ucValue, bool bOriginal) { - const CHandlingEntry* pEntry = NULL; + const CHandlingEntry* pEntry = nullptr; if (bOriginal) { - pEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(eModel); + pEntry = m_HandlingManager->GetOriginalHandlingData(model); } else { - pEntry = g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); + pEntry = m_HandlingManager->GetModelHandlingData(model); } - if (pEntry) - { - if (GetEntryHandling(pEntry, eProperty, ucValue)) - { - return true; - } - } - return false; + if (!pEntry) + return false; + + return GetEntryHandling(pEntry, eProperty, ucValue); } -bool CStaticFunctionDefinitions::GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, std::string& strValue, bool bOriginal) +bool CStaticFunctionDefinitions::GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, std::string& strValue, bool bOriginal) { - const CHandlingEntry* pEntry = NULL; + const CHandlingEntry* pEntry = nullptr; if (bOriginal) { - pEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(eModel); + pEntry = m_HandlingManager->GetOriginalHandlingData(model); } else { - pEntry = g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); + pEntry = m_HandlingManager->GetModelHandlingData(model); } - if (pEntry) - { - if (GetEntryHandling(pEntry, eProperty, strValue)) - { - return true; - } - } - return false; + if (!pEntry) + return false; + + return GetEntryHandling(pEntry, eProperty, strValue); } -bool CStaticFunctionDefinitions::SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, float fValue) +bool CStaticFunctionDefinitions::SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, float fValue) { - CHandlingEntry* pEntry = (CHandlingEntry*)g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); - if (pEntry) - { - if (SetEntryHandling(pEntry, eProperty, fValue)) - { - g_pGame->GetHandlingManager()->SetModelHandlingHasChanged(eModel, true); - return true; - } - } + CHandlingEntry* pEntry = m_HandlingManager->GetModelHandlingData(model); + if (!pEntry) + return false; - return false; + if (SetEntryHandling(pEntry, eProperty, fValue)) + return false; + + m_HandlingManager->SetModelHandlingHasChanged(model, true); + return true; } -bool CStaticFunctionDefinitions::SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, CVector vecValue) +bool CStaticFunctionDefinitions::SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, CVector vecValue) { - CHandlingEntry* pEntry = (CHandlingEntry*)g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); + CHandlingEntry* pEntry = m_HandlingManager->GetModelHandlingData(model); + if (!pEntry) + return false; - if (pEntry) - { - if (SetEntryHandling(pEntry, eProperty, vecValue)) - { - g_pGame->GetHandlingManager()->SetModelHandlingHasChanged(eModel, true); - return true; - } - } - return false; + if (!SetEntryHandling(pEntry, eProperty, vecValue)) + return false; + + m_HandlingManager->SetModelHandlingHasChanged(model, true); + return true; } -bool CStaticFunctionDefinitions::SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, std::string strValue) +bool CStaticFunctionDefinitions::SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, std::string strValue) { - CHandlingEntry* pEntry = (CHandlingEntry*)g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); - if (pEntry) - { - if (SetEntryHandling(pEntry, eProperty, strValue)) - { - g_pGame->GetHandlingManager()->SetModelHandlingHasChanged(eModel, true); - return true; - } - } + CHandlingEntry* pEntry = m_HandlingManager->GetModelHandlingData(model); + if (!pEntry) + return false; - return false; + if (!SetEntryHandling(pEntry, eProperty, strValue)) + return false; + + m_HandlingManager->SetModelHandlingHasChanged(model, true); + return true; } -bool CStaticFunctionDefinitions::SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, unsigned char ucValue) +bool CStaticFunctionDefinitions::SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, unsigned char ucValue) { - CHandlingEntry* pEntry = (CHandlingEntry*)g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); - if (pEntry) - { - if (SetEntryHandling(pEntry, eProperty, ucValue)) - { - g_pGame->GetHandlingManager()->SetModelHandlingHasChanged(eModel, true); - return true; - } - } + CHandlingEntry* pEntry = m_HandlingManager->GetModelHandlingData(model); + if (!pEntry) + return false; - return false; + if (!SetEntryHandling(pEntry, eProperty, ucValue)) + return false; + + m_HandlingManager->SetModelHandlingHasChanged(model, true); + return true; } -bool CStaticFunctionDefinitions::SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, unsigned int uiValue) +bool CStaticFunctionDefinitions::SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, unsigned int uiValue) { - CHandlingEntry* pEntry = (CHandlingEntry*)g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); - if (pEntry) - { - if (SetEntryHandling(pEntry, eProperty, uiValue)) - { - g_pGame->GetHandlingManager()->SetModelHandlingHasChanged(eModel, true); - return true; - } - } + CHandlingEntry* pEntry = m_HandlingManager->GetModelHandlingData(model); + if (!pEntry) + return false; - return false; + if (!SetEntryHandling(pEntry, eProperty, uiValue)) + return false; + + m_HandlingManager->SetModelHandlingHasChanged(model, true); + return true; } bool CStaticFunctionDefinitions::GetEntryHandling(const CHandlingEntry* pEntry, eHandlingProperty eProperty, float& fValue) @@ -7420,60 +7397,62 @@ bool CStaticFunctionDefinitions::SetVehicleHandling(CVehicle* pVehicle, eHandlin bool CStaticFunctionDefinitions::ResetVehicleHandling(CVehicle* pVehicle, bool bUseOriginal) { - assert(pVehicle); + try + { + const std::uint16_t model = pVehicle->GetModel(); + CHandlingEntry* pEntry = pVehicle->GetHandlingData(); + const CHandlingEntry* pNewEntry = nullptr; + CBitStream BitStream; - eVehicleTypes eModel = (eVehicleTypes)pVehicle->GetModel(); - CHandlingEntry* pEntry = pVehicle->GetHandlingData(); - const CHandlingEntry* pNewEntry; - CBitStream BitStream; + if (bUseOriginal) + { + pNewEntry = m_HandlingManager->GetOriginalHandlingData(model); + if (!pNewEntry) + return false; - if (bUseOriginal) - { - pNewEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(eModel); - m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pVehicle, RESET_VEHICLE_HANDLING, *BitStream.pBitStream)); - } - else - { - pNewEntry = g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); - - SVehicleHandlingSync handling; - handling.data.fMass = pNewEntry->GetMass(); - handling.data.fTurnMass = pNewEntry->GetTurnMass(); - handling.data.fDragCoeff = pNewEntry->GetDragCoeff(); - handling.data.vecCenterOfMass = pNewEntry->GetCenterOfMass(); - handling.data.ucPercentSubmerged = pNewEntry->GetPercentSubmerged(); - handling.data.fTractionMultiplier = pNewEntry->GetTractionMultiplier(); - handling.data.ucDriveType = pNewEntry->GetCarDriveType(); - handling.data.ucEngineType = pNewEntry->GetCarEngineType(); - handling.data.ucNumberOfGears = pNewEntry->GetNumberOfGears(); - handling.data.fEngineAcceleration = pNewEntry->GetEngineAcceleration(); - handling.data.fEngineInertia = pNewEntry->GetEngineInertia(); - handling.data.fMaxVelocity = pNewEntry->GetMaxVelocity(); - handling.data.fBrakeDeceleration = pNewEntry->GetBrakeDeceleration(); - handling.data.fBrakeBias = pNewEntry->GetBrakeBias(); - handling.data.bABS = pNewEntry->GetABS(); - handling.data.fSteeringLock = pNewEntry->GetSteeringLock(); - handling.data.fTractionLoss = pNewEntry->GetTractionLoss(); - handling.data.fTractionBias = pNewEntry->GetTractionBias(); - handling.data.fSuspensionForceLevel = pNewEntry->GetSuspensionForceLevel(); - handling.data.fSuspensionDamping = pNewEntry->GetSuspensionDamping(); - handling.data.fSuspensionHighSpdDamping = pNewEntry->GetSuspensionHighSpeedDamping(); - handling.data.fSuspensionUpperLimit = pNewEntry->GetSuspensionUpperLimit(); - handling.data.fSuspensionLowerLimit = pNewEntry->GetSuspensionLowerLimit(); - handling.data.fSuspensionFrontRearBias = pNewEntry->GetSuspensionFrontRearBias(); - handling.data.fSuspensionAntiDiveMultiplier = pNewEntry->GetSuspensionAntiDiveMultiplier(); - handling.data.fCollisionDamageMultiplier = pNewEntry->GetCollisionDamageMultiplier(); - handling.data.uiModelFlags = pNewEntry->GetModelFlags(); - handling.data.uiHandlingFlags = pNewEntry->GetHandlingFlags(); - handling.data.fSeatOffsetDistance = pNewEntry->GetSeatOffsetDistance(); - // handling.data.uiMonetary = pNewEntry->GetMonetary (); - // handling.data.ucHeadLight = pNewEntry->GetHeadLight (); - // handling.data.ucTailLight = pNewEntry->GetTailLight (); - handling.data.ucAnimGroup = pNewEntry->GetAnimGroup(); - - // Lower and Upper limits cannot match or LSOD (unless boat) - // if ( eModel != VEHICLE_BOAT ) // Commented until fully tested + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pVehicle, RESET_VEHICLE_HANDLING, *BitStream.pBitStream)); + } + else { + pNewEntry = m_HandlingManager->GetModelHandlingData(model); + if (!pNewEntry) + return false; + + SVehicleHandlingSync handling; + handling.data.fMass = pNewEntry->GetMass(); + handling.data.fTurnMass = pNewEntry->GetTurnMass(); + handling.data.fDragCoeff = pNewEntry->GetDragCoeff(); + handling.data.vecCenterOfMass = pNewEntry->GetCenterOfMass(); + handling.data.ucPercentSubmerged = pNewEntry->GetPercentSubmerged(); + handling.data.fTractionMultiplier = pNewEntry->GetTractionMultiplier(); + handling.data.ucDriveType = pNewEntry->GetCarDriveType(); + handling.data.ucEngineType = pNewEntry->GetCarEngineType(); + handling.data.ucNumberOfGears = pNewEntry->GetNumberOfGears(); + handling.data.fEngineAcceleration = pNewEntry->GetEngineAcceleration(); + handling.data.fEngineInertia = pNewEntry->GetEngineInertia(); + handling.data.fMaxVelocity = pNewEntry->GetMaxVelocity(); + handling.data.fBrakeDeceleration = pNewEntry->GetBrakeDeceleration(); + handling.data.fBrakeBias = pNewEntry->GetBrakeBias(); + handling.data.bABS = pNewEntry->GetABS(); + handling.data.fSteeringLock = pNewEntry->GetSteeringLock(); + handling.data.fTractionLoss = pNewEntry->GetTractionLoss(); + handling.data.fTractionBias = pNewEntry->GetTractionBias(); + handling.data.fSuspensionForceLevel = pNewEntry->GetSuspensionForceLevel(); + handling.data.fSuspensionDamping = pNewEntry->GetSuspensionDamping(); + handling.data.fSuspensionHighSpdDamping = pNewEntry->GetSuspensionHighSpeedDamping(); + handling.data.fSuspensionUpperLimit = pNewEntry->GetSuspensionUpperLimit(); + handling.data.fSuspensionLowerLimit = pNewEntry->GetSuspensionLowerLimit(); + handling.data.fSuspensionFrontRearBias = pNewEntry->GetSuspensionFrontRearBias(); + handling.data.fSuspensionAntiDiveMultiplier = pNewEntry->GetSuspensionAntiDiveMultiplier(); + handling.data.fCollisionDamageMultiplier = pNewEntry->GetCollisionDamageMultiplier(); + handling.data.uiModelFlags = pNewEntry->GetModelFlags(); + handling.data.uiHandlingFlags = pNewEntry->GetHandlingFlags(); + handling.data.fSeatOffsetDistance = pNewEntry->GetSeatOffsetDistance(); + // handling.data.uiMonetary = pNewEntry->GetMonetary (); + // handling.data.ucHeadLight = pNewEntry->GetHeadLight (); + // handling.data.ucTailLight = pNewEntry->GetTailLight (); + handling.data.ucAnimGroup = pNewEntry->GetAnimGroup(); + float fSuspensionLimitSize = handling.data.fSuspensionUpperLimit - handling.data.fSuspensionLowerLimit; if (fSuspensionLimitSize > -0.1f && fSuspensionLimitSize < 0.1f) { @@ -7482,32 +7461,38 @@ bool CStaticFunctionDefinitions::ResetVehicleHandling(CVehicle* pVehicle, bool b else handling.data.fSuspensionUpperLimit = handling.data.fSuspensionLowerLimit - 0.1f; } + + BitStream.pBitStream->Write(&handling); + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pVehicle, SET_VEHICLE_HANDLING, *BitStream.pBitStream)); } - BitStream.pBitStream->Write(&handling); - m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pVehicle, SET_VEHICLE_HANDLING, *BitStream.pBitStream)); + pEntry->ApplyHandlingData(pNewEntry); + return true; + } + catch (...) + { + return false; } - - pEntry->ApplyHandlingData(pNewEntry); - return true; } bool CStaticFunctionDefinitions::ResetVehicleHandlingProperty(CVehicle* pVehicle, eHandlingProperty eProperty, bool bUseOriginal) { - assert(pVehicle); - - eVehicleTypes eModel = (eVehicleTypes)pVehicle->GetModel(); - CHandlingEntry* pEntry = pVehicle->GetHandlingData(); - if (pEntry) + try { + CHandlingEntry* pEntry = pVehicle->GetHandlingData(); + if (!pEntry) + return false; + CBitStream BitStream; - float fValue = 0.0f; - CVector vecValue = CVector(0.0f, 0.0f, 0.0f); - SString strValue = ""; - unsigned int uiValue = 0; - unsigned int ucValue = 0; - if (GetModelHandling(eModel, eProperty, fValue, bUseOriginal)) + const std::uint32_t model = pVehicle->GetModel(); + + float fValue; + CVector vecValue; + std::string strValue; + std::uint32_t uiValue; + std::uint32_t ucValue; + if (GetModelHandling(model, eProperty, fValue, bUseOriginal)) { BitStream.pBitStream->Write(static_cast(eProperty)); @@ -7515,7 +7500,7 @@ bool CStaticFunctionDefinitions::ResetVehicleHandlingProperty(CVehicle* pVehicle BitStream.pBitStream->Write(fValue); } - else if (GetModelHandling(eModel, eProperty, uiValue, bUseOriginal)) + else if (GetModelHandling(model, eProperty, uiValue, bUseOriginal)) { BitStream.pBitStream->Write(static_cast(eProperty)); @@ -7523,7 +7508,7 @@ bool CStaticFunctionDefinitions::ResetVehicleHandlingProperty(CVehicle* pVehicle BitStream.pBitStream->Write(uiValue); } - else if (GetModelHandling(eModel, eProperty, ucValue, bUseOriginal)) + else if (GetModelHandling(model, eProperty, ucValue, bUseOriginal)) { BitStream.pBitStream->Write(static_cast(eProperty)); @@ -7531,7 +7516,7 @@ bool CStaticFunctionDefinitions::ResetVehicleHandlingProperty(CVehicle* pVehicle BitStream.pBitStream->Write(ucValue); } - else if (GetModelHandling(eModel, eProperty, strValue, bUseOriginal)) + else if (GetModelHandling(model, eProperty, strValue, bUseOriginal)) { unsigned char ucValue = 0; BitStream.pBitStream->Write(static_cast(eProperty)); @@ -7541,7 +7526,7 @@ bool CStaticFunctionDefinitions::ResetVehicleHandlingProperty(CVehicle* pVehicle BitStream.pBitStream->Write(ucValue); } - else if (GetModelHandling(eModel, eProperty, vecValue, bUseOriginal)) + else if (GetModelHandling(model, eProperty, vecValue, bUseOriginal)) { BitStream.pBitStream->Write(static_cast(eProperty)); @@ -7559,53 +7544,53 @@ bool CStaticFunctionDefinitions::ResetVehicleHandlingProperty(CVehicle* pVehicle m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pVehicle, SET_VEHICLE_HANDLING_PROPERTY, *BitStream.pBitStream)); return true; } - - return false; + catch (...) + { + return false; + } } -bool CStaticFunctionDefinitions::ResetModelHandling(eVehicleTypes eModel) +bool CStaticFunctionDefinitions::ResetModelHandling(std::uint32_t model) { - CHandlingEntry* pEntry = (CHandlingEntry*)g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); - if (pEntry) - { - const CHandlingEntry* pHandlingEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(eModel); - if (pHandlingEntry) - { - pEntry->ApplyHandlingData(pHandlingEntry); - return true; - } - } + CHandlingEntry* pEntry = m_HandlingManager->GetModelHandlingData(model); + if (!pEntry) + return false; - return false; + const CHandlingEntry* pHandlingEntry = m_HandlingManager->GetOriginalHandlingData(model); + if (!pHandlingEntry) + return false; + + pEntry->ApplyHandlingData(pHandlingEntry); + return true; } -bool CStaticFunctionDefinitions::ResetModelHandlingProperty(eVehicleTypes eModel, eHandlingProperty eProperty) +bool CStaticFunctionDefinitions::ResetModelHandlingProperty(std::uint32_t model, eHandlingProperty eProperty) { - CHandlingEntry* pEntry = (CHandlingEntry*)g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); + CHandlingEntry* pEntry = m_HandlingManager->GetModelHandlingData(model); - float fValue = 0.0f; - CVector vecValue = CVector(0.0f, 0.0f, 0.0f); - SString strValue = ""; - uint uiValue = 0; - uchar ucValue = 0; + float fValue; + CVector vecValue; + std::string strValue; + std::uint32_t uiValue; + std::uint8_t ucValue; - if (GetModelHandling(eModel, eProperty, fValue, true)) + if (GetModelHandling(model, eProperty, fValue, true)) { SetEntryHandling(pEntry, eProperty, fValue); } - else if (GetModelHandling(eModel, eProperty, strValue, true)) + else if (GetModelHandling(model, eProperty, strValue, true)) { SetEntryHandling(pEntry, eProperty, strValue); } - else if (GetModelHandling(eModel, eProperty, vecValue, true)) + else if (GetModelHandling(model, eProperty, vecValue, true)) { SetEntryHandling(pEntry, eProperty, vecValue); } - else if (GetModelHandling(eModel, eProperty, uiValue, true)) + else if (GetModelHandling(model, eProperty, uiValue, true)) { SetEntryHandling(pEntry, eProperty, uiValue); } - else if (GetModelHandling(eModel, eProperty, ucValue, true)) + else if (GetModelHandling(model, eProperty, ucValue, true)) { SetEntryHandling(pEntry, eProperty, ucValue); } @@ -10852,19 +10837,35 @@ bool CStaticFunctionDefinitions::ResetMoonSize() bool CStaticFunctionDefinitions::SendSyncIntervals(CPlayer* pPlayer) { - CBitStream BitStream; - BitStream.pBitStream->Write(g_TickRateSettings.iPureSync); - BitStream.pBitStream->Write(g_TickRateSettings.iLightSync); - BitStream.pBitStream->Write(g_TickRateSettings.iCamSync); - BitStream.pBitStream->Write(g_TickRateSettings.iPedSync); - BitStream.pBitStream->Write(g_TickRateSettings.iUnoccupiedVehicle); - BitStream.pBitStream->Write(g_TickRateSettings.iObjectSync); - BitStream.pBitStream->Write(g_TickRateSettings.iKeySyncRotation); - BitStream.pBitStream->Write(g_TickRateSettings.iKeySyncAnalogMove); - if (pPlayer) + auto sendSyncIntervalPatket = [](CPlayer* pPlayer) + { + CBitStream BitStream; + BitStream.pBitStream->Write(g_TickRateSettings.iPureSync); + BitStream.pBitStream->Write(g_TickRateSettings.iLightSync); + BitStream.pBitStream->Write(g_TickRateSettings.iCamSync); + BitStream.pBitStream->Write(g_TickRateSettings.iPedSync); + BitStream.pBitStream->Write(g_TickRateSettings.iUnoccupiedVehicle); + BitStream.pBitStream->Write(g_TickRateSettings.iObjectSync); + BitStream.pBitStream->Write(g_TickRateSettings.iKeySyncRotation); + BitStream.pBitStream->Write(g_TickRateSettings.iKeySyncAnalogMove); + + if (pPlayer->CanBitStream(eBitStreamVersion::FixSyncerDistance)) + { + BitStream.pBitStream->Write(g_TickRateSettings.iPedSyncerDistance); + BitStream.pBitStream->Write(g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); + } + pPlayer->Send(CLuaPacket(SET_SYNC_INTERVALS, *BitStream.pBitStream)); + }; + + + if (pPlayer) + sendSyncIntervalPatket(pPlayer); else - m_pPlayerManager->BroadcastOnlyJoined(CLuaPacket(SET_SYNC_INTERVALS, *BitStream.pBitStream)); + { + for (auto iter = m_pPlayerManager->IterBegin(); iter != m_pPlayerManager->IterEnd(); ++iter) + sendSyncIntervalPatket(*iter); + } return true; } diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 8c947d6f34..ffb21fa804 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -286,11 +286,11 @@ class CStaticFunctionDefinitions static bool GetVehicleHandling(CVehicle* pVehicle, eHandlingProperty eProperty, std::string& strValue); static bool GetVehicleHandling(CVehicle* pVehicle, eHandlingProperty eProperty, unsigned int& uiValue); static bool GetVehicleHandling(CVehicle* pVehicle, eHandlingProperty eProperty, unsigned char& ucValue); - static bool GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, float& fValue, bool origin = false); - static bool GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, CVector& vecValue, bool origin = false); - static bool GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, std::string& strValue, bool origin = false); - static bool GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, unsigned int& uiValue, bool origin = false); - static bool GetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, unsigned char& ucValue, bool origin = false); + static bool GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, float& fValue, bool origin = false); + static bool GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, CVector& vecValue, bool origin = false); + static bool GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, std::string& strValue, bool origin = false); + static bool GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, unsigned int& uiValue, bool origin = false); + static bool GetModelHandling(std::uint32_t model, eHandlingProperty eProperty, unsigned char& ucValue, bool origin = false); static bool GetEntryHandling(const CHandlingEntry* pEntry, eHandlingProperty eProperty, float& fValue); static bool GetEntryHandling(const CHandlingEntry* pEntry, eHandlingProperty eProperty, std::string& strValue); static bool GetEntryHandling(const CHandlingEntry* pEntry, eHandlingProperty eProperty, unsigned int& uiValue); @@ -352,13 +352,13 @@ class CStaticFunctionDefinitions static bool SetVehicleHandling(CVehicle* pVehicle, eHandlingProperty eProperty, std::string strValue); static bool SetVehicleHandling(CVehicle* pVehicle, eHandlingProperty eProperty, unsigned int uiValue); static bool SetVehicleHandling(CVehicle* pVehicle, eHandlingProperty eProperty, unsigned char ucValue); - static bool ResetModelHandling(eVehicleTypes eModel); - static bool ResetModelHandlingProperty(eVehicleTypes eModel, eHandlingProperty eProperty); - static bool SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, float fValue); - static bool SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, CVector vecValue); - static bool SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, std::string strValue); - static bool SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, unsigned int uiValue); - static bool SetModelHandling(eVehicleTypes eModel, eHandlingProperty eProperty, unsigned char ucValue); + static bool ResetModelHandling(std::uint32_t model); + static bool ResetModelHandlingProperty(std::uint32_t model, eHandlingProperty eProperty); + static bool SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, float fValue); + static bool SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, CVector vecValue); + static bool SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, std::string strValue); + static bool SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, unsigned int uiValue); + static bool SetModelHandling(std::uint32_t model, eHandlingProperty eProperty, unsigned char ucValue); static bool SetEntryHandling(CHandlingEntry* pEntry, eHandlingProperty eProperty, float fValue); static bool SetEntryHandling(CHandlingEntry* pEntry, eHandlingProperty eProperty, CVector vecValue); static bool SetEntryHandling(CHandlingEntry* pEntry, eHandlingProperty eProperty, std::string strValue); diff --git a/Server/mods/deathmatch/logic/CVehicle.cpp b/Server/mods/deathmatch/logic/CVehicle.cpp index ee5f7eb0e6..503bed059c 100644 --- a/Server/mods/deathmatch/logic/CVehicle.cpp +++ b/Server/mods/deathmatch/logic/CVehicle.cpp @@ -54,7 +54,7 @@ CVehicle::CVehicle(CVehicleManager* pVehicleManager, CElement* pParent, unsigned m_pTowedByVehicle = NULL; m_ucPaintjob = 3; m_ucMaxPassengersOverride = VEHICLE_PASSENGERS_UNDEFINED; - m_pHandlingEntry = NULL; + m_HandlingEntry = nullptr; m_fRespawnHealth = DEFAULT_VEHICLE_HEALTH; m_bRespawnEnabled = false; @@ -167,7 +167,6 @@ CVehicle::~CVehicle() } } delete m_pUpgrades; - delete m_pHandlingEntry; CElementRefManager::RemoveElementRefs(ELEMENT_REF_DEBUG(this, "CVehicle"), &m_pTowedVehicle, &m_pTowedByVehicle, &m_pSyncer, &m_pJackingPed, NULL); @@ -849,13 +848,16 @@ void CVehicle::GetInitialDoorStates(SFixedArray& ucOut } } -void CVehicle::GenerateHandlingData() +void CVehicle::GenerateHandlingData() noexcept { + const auto handlingManager = g_pGame->GetHandlingManager(); + // Make a new CHandlingEntry - if (m_pHandlingEntry == NULL) - m_pHandlingEntry = g_pGame->GetHandlingManager()->CreateHandlingData(); + if (!m_HandlingEntry) + m_HandlingEntry = handlingManager->CreateHandlingData(); + // Apply the model handling info - m_pHandlingEntry->ApplyHandlingData(g_pGame->GetHandlingManager()->GetModelHandlingData(static_cast(m_usModel))); + m_HandlingEntry->ApplyHandlingData(handlingManager->GetModelHandlingData(m_usModel)); m_bHandlingChanged = false; } diff --git a/Server/mods/deathmatch/logic/CVehicle.h b/Server/mods/deathmatch/logic/CVehicle.h index d5dbb43243..0e2ecbd278 100644 --- a/Server/mods/deathmatch/logic/CVehicle.h +++ b/Server/mods/deathmatch/logic/CVehicle.h @@ -374,8 +374,8 @@ class CVehicle final : public CElement void SpawnAt(const CVector& vecPosition, const CVector& vecRotation); void Respawn(); - void GenerateHandlingData(); - CHandlingEntry* GetHandlingData() { return m_pHandlingEntry; }; + void GenerateHandlingData() noexcept; + CHandlingEntry* GetHandlingData() noexcept { return m_HandlingEntry.get(); }; uint GetTimeSinceLastPush() { return (uint)(CTickCount::Now(true) - m_LastPushedTime).ToLongLong(); } void ResetLastPushTime() { m_LastPushedTime = CTickCount::Now(true); } @@ -485,8 +485,8 @@ class CVehicle final : public CElement unsigned short m_usAdjustableProperty; bool m_bCollisionsEnabled; - CHandlingEntry* m_pHandlingEntry; - bool m_bHandlingChanged; + std::unique_ptr m_HandlingEntry; + bool m_bHandlingChanged; unsigned char m_ucVariant; unsigned char m_ucVariant2; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaDefs.cpp index 8d8e3a3646..a5c2a95a7b 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaDefs.cpp @@ -38,32 +38,32 @@ namespace bool ms_bRegisterdPostCallHook = false; } // namespace -CElementDeleter* CLuaDefs::m_pElementDeleter = NULL; -CBlipManager* CLuaDefs::m_pBlipManager = NULL; -CHandlingManager* CLuaDefs::m_pHandlingManager = NULL; -CLuaManager* CLuaDefs::m_pLuaManager = NULL; -CMarkerManager* CLuaDefs::m_pMarkerManager = NULL; -CObjectManager* CLuaDefs::m_pObjectManager = NULL; -CPickupManager* CLuaDefs::m_pPickupManager = NULL; -CPlayerManager* CLuaDefs::m_pPlayerManager = NULL; -CRadarAreaManager* CLuaDefs::m_pRadarAreaManager = NULL; -CRegisteredCommands* CLuaDefs::m_pRegisteredCommands; -CElement* CLuaDefs::m_pRootElement = NULL; -CScriptDebugging* CLuaDefs::m_pScriptDebugging = NULL; -CVehicleManager* CLuaDefs::m_pVehicleManager = NULL; -CTeamManager* CLuaDefs::m_pTeamManager = NULL; -CAccountManager* CLuaDefs::m_pAccountManager = NULL; -CColManager* CLuaDefs::m_pColManager = NULL; -CResourceManager* CLuaDefs::m_pResourceManager = NULL; -CAccessControlListManager* CLuaDefs::m_pACLManager = NULL; -CMainConfig* CLuaDefs::m_pMainConfig = NULL; +CElementDeleter* CLuaDefs::m_pElementDeleter = NULL; +CBlipManager* CLuaDefs::m_pBlipManager = NULL; +std::shared_ptr CLuaDefs::m_HandlingManager = nullptr; +CLuaManager* CLuaDefs::m_pLuaManager = NULL; +CMarkerManager* CLuaDefs::m_pMarkerManager = NULL; +CObjectManager* CLuaDefs::m_pObjectManager = NULL; +CPickupManager* CLuaDefs::m_pPickupManager = NULL; +CPlayerManager* CLuaDefs::m_pPlayerManager = NULL; +CRadarAreaManager* CLuaDefs::m_pRadarAreaManager = NULL; +CRegisteredCommands* CLuaDefs::m_pRegisteredCommands; +CElement* CLuaDefs::m_pRootElement = NULL; +CScriptDebugging* CLuaDefs::m_pScriptDebugging = NULL; +CVehicleManager* CLuaDefs::m_pVehicleManager = NULL; +CTeamManager* CLuaDefs::m_pTeamManager = NULL; +CAccountManager* CLuaDefs::m_pAccountManager = NULL; +CColManager* CLuaDefs::m_pColManager = NULL; +CResourceManager* CLuaDefs::m_pResourceManager = NULL; +CAccessControlListManager* CLuaDefs::m_pACLManager = NULL; +CMainConfig* CLuaDefs::m_pMainConfig = NULL; void CLuaDefs::Initialize(CGame* pGame) { m_pRootElement = pGame->GetMapManager()->GetRootElement(); m_pElementDeleter = pGame->GetElementDeleter(); m_pBlipManager = pGame->GetBlipManager(); - m_pHandlingManager = pGame->GetHandlingManager(); + m_HandlingManager = pGame->GetHandlingManager(); m_pLuaManager = pGame->GetLuaManager(); m_pMarkerManager = pGame->GetMarkerManager(); m_pObjectManager = pGame->GetObjectManager(); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaDefs.h index ae81ecdf4e..45653f84ed 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaDefs.h @@ -66,26 +66,26 @@ class CLuaDefs // This is just for the Lua funcs. Please don't public this and use it other // places in the server. protected: - static CElementDeleter* m_pElementDeleter; - static CBlipManager* m_pBlipManager; - static CHandlingManager* m_pHandlingManager; - static CLuaManager* m_pLuaManager; - static CMarkerManager* m_pMarkerManager; - static CObjectManager* m_pObjectManager; - static CPickupManager* m_pPickupManager; - static CPlayerManager* m_pPlayerManager; - static CRadarAreaManager* m_pRadarAreaManager; - static CRegisteredCommands* m_pRegisteredCommands; - static CElement* m_pRootElement; - static CScriptDebugging* m_pScriptDebugging; - static CVehicleManager* m_pVehicleManager; - static CTeamManager* m_pTeamManager; - static CAccountManager* m_pAccountManager; - static CColManager* m_pColManager; - static CResourceManager* m_pResourceManager; - static CAccessControlListManager* m_pACLManager; - static CMainConfig* m_pMainConfig; - static inline CLuaModuleManager* m_pLuaModuleManager = nullptr; + static CElementDeleter* m_pElementDeleter; + static CBlipManager* m_pBlipManager; + static std::shared_ptr m_HandlingManager; + static CLuaManager* m_pLuaManager; + static CMarkerManager* m_pMarkerManager; + static CObjectManager* m_pObjectManager; + static CPickupManager* m_pPickupManager; + static CPlayerManager* m_pPlayerManager; + static CRadarAreaManager* m_pRadarAreaManager; + static CRegisteredCommands* m_pRegisteredCommands; + static CElement* m_pRootElement; + static CScriptDebugging* m_pScriptDebugging; + static CVehicleManager* m_pVehicleManager; + static CTeamManager* m_pTeamManager; + static CAccountManager* m_pAccountManager; + static CColManager* m_pColManager; + static CResourceManager* m_pResourceManager; + static CAccessControlListManager* m_pACLManager; + static CMainConfig* m_pMainConfig; + static inline CLuaModuleManager* m_pLuaModuleManager = nullptr; protected: // Old style: Only warn on failure. This should diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp index 554bf2efc9..4aa82ac5f9 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp @@ -16,6 +16,7 @@ #include "ASE.h" #include "CStaticFunctionDefinitions.h" #include "CPerfStatManager.h" +#include "CMapManager.h" #define MIN_SERVER_REQ_CALLREMOTE_QUEUE_NAME "1.5.3-9.11270" #define MIN_SERVER_REQ_CALLREMOTE_CONNECTION_ATTEMPTS "1.3.0-9.04563" @@ -349,6 +350,12 @@ bool CLuaFunctionDefs::Shutdown(lua_State* luaVM, std::optionalGetModManager()->SetExitCode(maybeExitCode.value()); + // Call event + CLuaArguments arguments; + arguments.PushResource(&resource); + arguments.PushString(reason.data()); + g_pGame->GetMapManager()->GetRootElement()->CallEvent("onShutdown", arguments); + g_pGame->SetIsFinished(true); return true; } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.cpp index 4a80b4acfd..9b449a640e 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaHandlingDefs.cpp @@ -47,7 +47,7 @@ int CLuaHandlingDefs::SetVehicleHandling(lua_State* luaVM) SString strProperty; argStream.ReadString(strProperty); - eHandlingProperty eProperty = m_pHandlingManager->GetPropertyEnumFromName(strProperty); + eHandlingProperty eProperty = m_HandlingManager->GetPropertyEnumFromName(strProperty); if (eProperty) { if (argStream.NextIsNil()) @@ -213,15 +213,14 @@ int CLuaHandlingDefs::SetVehicleHandling(lua_State* luaVM) int CLuaHandlingDefs::SetModelHandling(lua_State* luaVM) { // bool setModelHandling ( int modelId, [ string property, var value ] ) - unsigned short usModel; + std::uint16_t model; CScriptArgReader argStream(luaVM); - argStream.ReadNumber(usModel); + argStream.ReadNumber(model); if (!argStream.HasErrors()) { - eVehicleTypes eModel = static_cast(usModel); - if (eModel) + if (model) { if (argStream.NextIsString()) { @@ -230,12 +229,12 @@ int CLuaHandlingDefs::SetModelHandling(lua_State* luaVM) if (!argStream.HasErrors()) { - eHandlingProperty eProperty = m_pHandlingManager->GetPropertyEnumFromName(strProperty); + eHandlingProperty eProperty = m_HandlingManager->GetPropertyEnumFromName(strProperty); if (eProperty) { if (argStream.NextIsNil()) { - if (CStaticFunctionDefinitions::ResetModelHandlingProperty(eModel, eProperty)) + if (CStaticFunctionDefinitions::ResetModelHandlingProperty(model, eProperty)) { lua_pushboolean(luaVM, true); return 1; @@ -269,7 +268,7 @@ int CLuaHandlingDefs::SetModelHandling(lua_State* luaVM) { float fValue; argStream.ReadNumber(fValue); - if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(eModel, eProperty, fValue)) + if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(model, eProperty, fValue)) { lua_pushboolean(luaVM, true); return 1; @@ -289,7 +288,7 @@ int CLuaHandlingDefs::SetModelHandling(lua_State* luaVM) { argStream.SetCustomError("Invalid value"); } - if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(eModel, eProperty, uiValue)) + if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(model, eProperty, uiValue)) { lua_pushboolean(luaVM, true); return 1; @@ -302,7 +301,7 @@ int CLuaHandlingDefs::SetModelHandling(lua_State* luaVM) { unsigned char ucValue; argStream.ReadNumber(ucValue); - if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(eModel, eProperty, ucValue)) + if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(model, eProperty, ucValue)) { lua_pushboolean(luaVM, true); return 1; @@ -330,7 +329,7 @@ int CLuaHandlingDefs::SetModelHandling(lua_State* luaVM) CVector vecCenterOfMass(fX, fY, fZ); - if (CStaticFunctionDefinitions::SetModelHandling(eModel, eProperty, vecCenterOfMass)) + if (CStaticFunctionDefinitions::SetModelHandling(model, eProperty, vecCenterOfMass)) { lua_pushboolean(luaVM, true); return 1; @@ -348,7 +347,7 @@ int CLuaHandlingDefs::SetModelHandling(lua_State* luaVM) { SString strValue; argStream.ReadString(strValue); - if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(eModel, eProperty, strValue)) + if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(model, eProperty, strValue)) { lua_pushboolean(luaVM, true); return 1; @@ -358,7 +357,7 @@ int CLuaHandlingDefs::SetModelHandling(lua_State* luaVM) { bool bValue; argStream.ReadBool(bValue); - if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(eModel, eProperty, bValue ? 1.0f : 0.0f)) + if (!argStream.HasErrors() && CStaticFunctionDefinitions::SetModelHandling(model, eProperty, bValue ? 1.0f : 0.0f)) { lua_pushboolean(luaVM, true); return 1; @@ -403,7 +402,7 @@ int CLuaHandlingDefs::GetVehicleHandling(lua_State* luaVM) SString strProperty; argStream.ReadString(strProperty); - eHandlingProperty eProperty = m_pHandlingManager->GetPropertyEnumFromName(strProperty); + eHandlingProperty eProperty = m_HandlingManager->GetPropertyEnumFromName(strProperty); if (eProperty == HANDLING_MAX) { argStream.SetCustomError("Invalid property"); @@ -611,17 +610,16 @@ int CLuaHandlingDefs::GetVehicleHandling(lua_State* luaVM) int CLuaHandlingDefs::GetModelHandling(lua_State* luaVM) { // table getModelHandling ( int modelId ) - unsigned short usModel; + std::uint16_t model; CScriptArgReader argStream(luaVM); - argStream.ReadNumber(usModel); + argStream.ReadNumber(model); if (!argStream.HasErrors()) { - eVehicleTypes eModel = static_cast(usModel); - if (eModel) + if (model) { - const CHandlingEntry* pEntry = g_pGame->GetHandlingManager()->GetModelHandlingData(eModel); + const CHandlingEntry* pEntry = m_HandlingManager->GetModelHandlingData(model); if (pEntry) { lua_newtable(luaVM); @@ -784,17 +782,16 @@ int CLuaHandlingDefs::GetModelHandling(lua_State* luaVM) int CLuaHandlingDefs::GetOriginalHandling(lua_State* luaVM) { // table getOriginalHandling ( int modelID ) - unsigned short usModel; + std::uint16_t model; CScriptArgReader argStream(luaVM); - argStream.ReadNumber(usModel); + argStream.ReadNumber(model); if (!argStream.HasErrors()) { - eVehicleTypes eModel = static_cast(usModel); - if (eModel) + if (model) { - const CHandlingEntry* pEntry = g_pGame->GetHandlingManager()->GetOriginalHandlingData(eModel); + const CHandlingEntry* pEntry = m_HandlingManager->GetOriginalHandlingData(model); if (pEntry) { lua_newtable(luaVM); diff --git a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp index a001ba518f..8973abc6b1 100644 --- a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp @@ -612,8 +612,7 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const BitStream.WriteBit(false); // Write handling - if (g_pGame->GetHandlingManager()->HasModelHandlingChanged(static_cast(pVehicle->GetModel())) || - pVehicle->HasHandlingChanged()) + if (g_pGame->GetHandlingManager()->HasModelHandlingChanged(pVehicle->GetModel()) || pVehicle->HasHandlingChanged()) { BitStream.WriteBit(true); SVehicleHandlingSync handling; diff --git a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp index e62547b3fb..e2adf9a5bc 100644 --- a/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CMapInfoPacket.cpp @@ -192,6 +192,7 @@ bool CMapInfoPacket::Write(NetBitStreamInterface& BitStream) const wsProps.data3.roadsignstext = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::ROADSIGNSTEXT); wsProps.data4.extendedwatercannons = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::EXTENDEDWATERCANNONS); wsProps.data5.tunnelweatherblend = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::TUNNELWEATHERBLEND); + wsProps.data6.ignoreFireState = g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::IGNOREFIRESTATE); BitStream.Write(&wsProps); } diff --git a/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h index 82fdfbd1b0..541f9b191c 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h @@ -39,7 +39,8 @@ class CPlayerDisconnectedPacket final : public CPacket BAN, KICK, CUSTOM, - SHUTDOWN + SHUTDOWN, + SERIAL_DUPLICATE }; CPlayerDisconnectedPacket(const char* szReason); diff --git a/Server/mods/deathmatch/logic/packets/CPlayerWorldSpecialPropertyPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerWorldSpecialPropertyPacket.cpp new file mode 100644 index 0000000000..59c3ec4c7b --- /dev/null +++ b/Server/mods/deathmatch/logic/packets/CPlayerWorldSpecialPropertyPacket.cpp @@ -0,0 +1,20 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/packets/CPlayerWorldSpecialPropertyPacket.cpp + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CPlayerWorldSpecialPropertyPacket.h" + +bool CPlayerWorldSpecialPropertyPacket::Read(NetBitStreamInterface& stream) noexcept +{ + stream.ReadString(m_property); + stream.ReadBit(m_enabled); + + return true; +} diff --git a/Server/mods/deathmatch/logic/packets/CPlayerWorldSpecialPropertyPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerWorldSpecialPropertyPacket.h new file mode 100644 index 0000000000..cb6dd9e2f1 --- /dev/null +++ b/Server/mods/deathmatch/logic/packets/CPlayerWorldSpecialPropertyPacket.h @@ -0,0 +1,34 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/packets/CPlayerWorldSpecialPropertyPacket.h + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include +#include "CPacket.h" + +class CPlayerWorldSpecialPropertyPacket final : public CPacket +{ +public: + CPlayerWorldSpecialPropertyPacket() noexcept {} + + ePacketID GetPacketID() const noexcept { return PACKET_ID_PLAYER_WORLD_SPECIAL_PROPERTY; } + unsigned long GetFlags() const noexcept { return PACKET_HIGH_PRIORITY | PACKET_RELIABLE | PACKET_SEQUENCED; } + virtual ePacketOrdering GetPacketOrdering() const noexcept { return PACKET_ORDERING_DEFAULT; } + + bool Read(NetBitStreamInterface& stream) noexcept; + + std::string GetProperty() const noexcept { return m_property; } + bool IsEnabled() const noexcept { return m_enabled; } + +private: + std::string m_property; + bool m_enabled; +}; diff --git a/Server/mods/deathmatch/mtaserver.conf b/Server/mods/deathmatch/mtaserver.conf index 11ef497fa7..726199d548 100644 --- a/Server/mods/deathmatch/mtaserver.conf +++ b/Server/mods/deathmatch/mtaserver.conf @@ -274,6 +274,12 @@ Values: 0 - Off, 1 - Enabled. Default - 0 --> 0 + + 1 + 0 + + 1 +