diff --git a/Client/game_sa/CBuildingsPoolSA.cpp b/Client/game_sa/CBuildingsPoolSA.cpp index b8363f6507f..caa392c132e 100644 --- a/Client/game_sa/CBuildingsPoolSA.cpp +++ b/Client/game_sa/CBuildingsPoolSA.cpp @@ -101,7 +101,14 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding) // Remove plant pGame->GetPlantManager()->RemovePlant(pInterface); - RemoveBuildingFromWorld(pInterface); + // Remove shadow + pInterface->RemoveShadows(); + + // Remove building from world + pGame->GetWorld()->Remove(pInterface, CBuildingPool_Destructor); + + // Call virtual destructor + ((void*(__thiscall*)(void*, char))pInterface->vtbl->SCALAR_DELETING_DESTRUCTOR)(pInterface, 0); // Remove col reference auto modelInfo = pGame->GetModelInfo(pBuilding->GetModelIndex()); diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 482a283ac07..837c84415d7 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -145,6 +145,8 @@ CGameSA::CGameSA() m_pPlantManager = new CPlantManagerSA(); m_pBuildingRemoval = new CBuildingRemovalSA(); + m_pRenderer = std::make_unique(); + // Normal weapon types (WEAPONSKILL_STD) for (int i = 0; i < NUM_WeaponInfosStdSkill; i++) { diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index f958cb0e793..8124f99843b 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -17,6 +17,7 @@ #include "CStreamingSA.h" #include "CCoverManagerSA.h" #include "CPlantManagerSA.h" +#include "CRendererSA.h" class CAnimBlendClumpDataSAInterface; class CObjectGroupPhysicalPropertiesSA; @@ -172,7 +173,8 @@ class CGameSA : public CGame CCoverManagerSA* GetCoverManager() const noexcept { return m_pCoverManager; }; CPlantManagerSA* GetPlantManager() const noexcept { return m_pPlantManager; }; CBuildingRemoval* GetBuildingRemoval() { return m_pBuildingRemoval; } - + CRenderer* GetRenderer() const noexcept override { return m_pRenderer.get(); } + CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD); CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false); CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup); @@ -348,6 +350,8 @@ class CGameSA : public CGame CPlantManagerSA* m_pPlantManager; CBuildingRemoval* m_pBuildingRemoval; + std::unique_ptr m_pRenderer; + CPad* m_pPad; CAERadioTrackManager* m_pCAERadioTrackManager; CAudioEngine* m_pAudioEngine; diff --git a/Client/game_sa/CHeliSA.h b/Client/game_sa/CHeliSA.h index 49fc0d866dd..497fe46a707 100644 --- a/Client/game_sa/CHeliSA.h +++ b/Client/game_sa/CHeliSA.h @@ -15,10 +15,47 @@ class CHeliSAInterface : public CAutomobileSAInterface { +public: + std::uint8_t m_heliFlags; + + std::uint8_t _pad1[3]; + std::uint32_t m_leftRightSkid; + std::uint32_t m_steeringUpDown; + std::uint32_t m_steeringLeftRight; + std::uint32_t m_accelerationBreakStatus; + std::uint32_t field_99C; + std::uint32_t m_rotorZ; + std::uint32_t m_secondRotorZ; + std::uint32_t m_maxAltitude; + std::uint32_t field_9AC; + std::uint32_t m_minAltitude; + std::uint32_t field_9B4; + std::uint8_t field_9B8; + std::uint8_t m_numSwatOccupants; + std::uint8_t m_swatIDs[4]; + + std::uint8_t _pad2[2]; + std::uint32_t field_9C0[4]; + std::uint32_t field_9D0; + + std::uint32_t m_particlesList; + std::uint8_t field_9D8[24]; + std::uint32_t field_9F0; + CVector m_searchLightTarget; + std::uint32_t m_searchLightIntensity; + std::uint32_t field_A04; + std::uint32_t field_A08; + std::uint32_t m_gunflashFx; + std::uint8_t m_firingMultiplier; + std::uint8_t m_searchLightEnabled; + std::uint8_t _pad3[2]; + std::uint32_t field_A14; }; +static_assert(sizeof(CHeliSAInterface) == 0xA18, "Invalid size for CHeliSAInterface"); class CHeliSA final : public virtual CHeli, public virtual CAutomobileSA { public: CHeliSA(CHeliSAInterface* pInterface); + CHeliSAInterface* GetHeliInterface() noexcept { return reinterpret_cast(GetInterface()); } }; diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 72b2c92b746..c8f37cf9a8a 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -2025,7 +2025,10 @@ void CModelInfoSA::RestoreAllObjectsPropertiesGroups() eModelInfoType CModelInfoSA::GetModelType() { - return ((eModelInfoType(*)())m_pInterface->VFTBL->GetModelType)(); + if (auto pInterface = GetInterface()) + return ((eModelInfoType(*)())pInterface->VFTBL->GetModelType)(); + + return eModelInfoType::UNKNOWN; } bool CModelInfoSA::IsTowableBy(CModelInfo* towingModel) diff --git a/Client/game_sa/CRendererSA.cpp b/Client/game_sa/CRendererSA.cpp new file mode 100644 index 00000000000..bad607d5ba2 --- /dev/null +++ b/Client/game_sa/CRendererSA.cpp @@ -0,0 +1,55 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CRendererSA.cpp + * PURPOSE: Game renderer class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CRendererSA.h" +#include "CModelInfoSA.h" +#include "CMatrix.h" +#include "gamesa_renderware.h" + +CRendererSA::CRendererSA() +{ +} + +CRendererSA::~CRendererSA() +{ +} + +void CRendererSA::RenderModel(CModelInfo* pModelInfo, const CMatrix& matrix) +{ + CBaseModelInfoSAInterface* pModelInfoSAInterface = pModelInfo->GetInterface(); + if (!pModelInfoSAInterface) + return; + + RwObject* pRwObject = pModelInfoSAInterface->pRwObject; + if (!pRwObject) + return; + + RwFrame* pFrame = RpGetFrame(pRwObject); + + static RwMatrix rwMatrix; + rwMatrix.right = (RwV3d&)matrix.vRight; + rwMatrix.up = (RwV3d&)matrix.vFront; + rwMatrix.at = (RwV3d&)matrix.vUp; + rwMatrix.pos = (RwV3d&)matrix.vPos; + RwFrameTransform(pFrame, &rwMatrix, rwCOMBINEREPLACE); + + if (pRwObject->type == RP_TYPE_ATOMIC) + { + RpAtomic* pRpAtomic = reinterpret_cast(pRwObject); + pRpAtomic->renderCallback(reinterpret_cast(pRwObject)); + } + else + { + RpClump* pClump = reinterpret_cast(pRwObject); + RpClumpRender(pClump); + } +} diff --git a/Client/game_sa/CRendererSA.h b/Client/game_sa/CRendererSA.h new file mode 100644 index 00000000000..e71a83665ed --- /dev/null +++ b/Client/game_sa/CRendererSA.h @@ -0,0 +1,23 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CRendererSA.h + * PURPOSE: Game renderer class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include + +class CRendererSA : public CRenderer +{ +public: + CRendererSA(); + ~CRendererSA(); + + void RenderModel(CModelInfo* pModelInfo, const CMatrix& matrix) override; +}; diff --git a/Client/game_sa/CVisibilityPluginsSA.cpp b/Client/game_sa/CVisibilityPluginsSA.cpp index d7cf9849bc1..b5fe2d92c6f 100644 --- a/Client/game_sa/CVisibilityPluginsSA.cpp +++ b/Client/game_sa/CVisibilityPluginsSA.cpp @@ -12,6 +12,8 @@ #include "StdInc.h" #include "CVisibilityPluginsSA.h" +#define FUNC_CVisibilityPlugins_InsertEntityIntoEntityList 0x733DD0 + void CVisibilityPluginsSA::SetClumpAlpha(RpClump* pClump, int iAlpha) { DWORD dwFunc = FUNC_CVisiblityPlugins_SetClumpAlpha; @@ -51,3 +53,8 @@ int CVisibilityPluginsSA::GetAtomicId(RwObject* pAtomic) } return iResult; } + +bool CVisibilityPluginsSA::InsertEntityIntoEntityList(void* entity, float distance, void* callback) +{ + return ((bool(_cdecl*)(void*, float, void*))FUNC_CVisibilityPlugins_InsertEntityIntoEntityList)(entity, distance, callback); +} diff --git a/Client/game_sa/CVisibilityPluginsSA.h b/Client/game_sa/CVisibilityPluginsSA.h index 57cab620c07..f4a583bcf29 100644 --- a/Client/game_sa/CVisibilityPluginsSA.h +++ b/Client/game_sa/CVisibilityPluginsSA.h @@ -21,4 +21,6 @@ class CVisibilityPluginsSA : public CVisibilityPlugins public: void SetClumpAlpha(RpClump* pClump, int iAlpha); int GetAtomicId(RwObject* pAtomic); + + bool InsertEntityIntoEntityList(void* entity, float distance, void* callback); }; diff --git a/Client/game_sa/gamesa_renderware.h b/Client/game_sa/gamesa_renderware.h index e2f2d9a472d..594c203b59e 100644 --- a/Client/game_sa/gamesa_renderware.h +++ b/Client/game_sa/gamesa_renderware.h @@ -38,6 +38,7 @@ typedef RwFrame*(__cdecl* RwFrameAddChild_t)(RwFrame* parent, RwFrame* child); typedef RwFrame*(__cdecl* RwFrameRemoveChild_t)(RwFrame* child); typedef RwFrame*(__cdecl* RwFrameForAllObjects_t)(RwFrame* frame, void* callback, void* data); typedef RwFrame*(__cdecl* RwFrameTranslate_t)(RwFrame* frame, const RwV3d* v, RwTransformOrder order); +typedef RwFrame*(__cdecl* RwFrameTransform_t)(RwFrame* frame, const RwMatrix* m, RwOpCombineType combine); typedef RwFrame*(__cdecl* RwFrameScale_t)(RwFrame* frame, const RwV3d* v, RwTransformOrder order); typedef RwFrame*(__cdecl* RwFrameUpdateObjects_t)(RwFrame*); typedef RwFrame*(__cdecl* RwFrameCreate_t)(); @@ -69,6 +70,7 @@ typedef RwTexture*(__cdecl* RwTexDictionaryAddTexture_t)(RwTexDictionary* dict, typedef RwTexDictionary*(__cdecl* RwTexDictionaryGetCurrent_t)(); typedef RwTexture*(__cdecl* RwTexDictionaryFindNamedTexture_t)(RwTexDictionary* dict, const char* name); typedef void(__cdecl* RpPrtStdGlobalDataSetStreamEmbedded_t)(void* value); +typedef RpClump*(__cdecl* RpClumpRender_t)(RpClump* clump); typedef RpWorld*(__cdecl* RpWorldAddAtomic_t)(RpWorld* world, RpAtomic* atomic); typedef RpWorld*(__cdecl* RpWorldAddClump_t)(RpWorld* world, RpClump* clump); typedef RpWorld*(__cdecl* RpWorldAddLight_t)(RpWorld* world, RpLight* light); @@ -125,6 +127,7 @@ RWFUNC(RwStreamSkip_t RwStreamSkip, (RwStreamSkip_t)0xDEAD) RWFUNC(RpClumpDestroy_t RpClumpDestroy, (RpClumpDestroy_t)0xDEAD) RWFUNC(RpClumpGetNumAtomics_t RpClumpGetNumAtomics, (RpClumpGetNumAtomics_t)0xDEAD) RWFUNC(RwFrameTranslate_t RwFrameTranslate, (RwFrameTranslate_t)0xDEAD) +RWFUNC(RwFrameTransform_t RwFrameTransform, (RwFrameTransform_t)0xDEAD) RWFUNC(RpClumpForAllAtomics_t RpClumpForAllAtomics, (RpClumpForAllAtomics_t)0xDEAD) RWFUNC(RwFrameAddChild_t RwFrameAddChild, (RwFrameAddChild_t)0xDEAD) RWFUNC(RpClumpAddAtomic_t RpClumpAddAtomic, (RpClumpAddAtomic_t)0xDEAD) @@ -138,6 +141,7 @@ RWFUNC(RwTexDictionaryAddTexture_t RwTexDictionaryAddTexture, (RwTexDictionaryAd RWFUNC(RwTexDictionaryStreamWrite_t RwTexDictionaryStreamWrite, (RwTexDictionaryStreamWrite_t)0xDEAD) RWFUNC(rwD3D9NativeTextureRead_t rwD3D9NativeTextureRead, (rwD3D9NativeTextureRead_t)0xDEAD) RWFUNC(RpPrtStdGlobalDataSetStreamEmbedded_t RpPrtStdGlobalDataSetStreamEmbedded, (RpPrtStdGlobalDataSetStreamEmbedded_t)0xDEAD) +RWFUNC(RpClumpRender_t RpClumpRender, (RpClumpRender_t)0xDEAD) RWFUNC(RpClumpRemoveAtomic_t RpClumpRemoveAtomic, (RpClumpRemoveAtomic_t)0xDEAD) RWFUNC(RpAtomicClone_t RpAtomicClone, (RpAtomicClone_t)0xDEAD) RWFUNC(RwTexDictionaryFindNamedTexture_t RwTexDictionaryFindNamedTexture, (RwTexDictionaryFindNamedTexture_t)0xDEAD) diff --git a/Client/game_sa/gamesa_renderware.hpp b/Client/game_sa/gamesa_renderware.hpp index 804040c802e..a638cfede04 100644 --- a/Client/game_sa/gamesa_renderware.hpp +++ b/Client/game_sa/gamesa_renderware.hpp @@ -20,6 +20,7 @@ void InitRwFunctions() RwStreamSkip = (RwStreamSkip_t)0x007ECD00; RpClumpDestroy = (RpClumpDestroy_t)0x0074A310; RpClumpGetNumAtomics = (RpClumpGetNumAtomics_t)0x007498E0; + RwFrameTransform = (RwFrameTransform_t)0x007F0F70; RwFrameTranslate = (RwFrameTranslate_t)0x007F0E30; RpClumpForAllAtomics = (RpClumpForAllAtomics_t)0x00749B70; RwFrameAddChild = (RwFrameAddChild_t)0x007F0B00; @@ -34,6 +35,7 @@ void InitRwFunctions() RwTexDictionaryStreamWrite = (RwTexDictionaryStreamWrite_t)0x008049F0; rwD3D9NativeTextureRead = (rwD3D9NativeTextureRead_t)0x004CD820; RpPrtStdGlobalDataSetStreamEmbedded = (RpPrtStdGlobalDataSetStreamEmbedded_t)0x0041B350; + RpClumpRender = (RpClumpRender_t)0x00749B20; RpClumpRemoveAtomic = (RpClumpRemoveAtomic_t)0x0074A4C0; RpAtomicClone = (RpAtomicClone_t)0x00749E60; RwTexDictionaryFindNamedTexture = (RwTexDictionaryFindNamedTexture_t)0x007F39F0; diff --git a/Client/loader/MainFunctions.cpp b/Client/loader/MainFunctions.cpp index 9940fde94af..ed802555abe 100644 --- a/Client/loader/MainFunctions.cpp +++ b/Client/loader/MainFunctions.cpp @@ -863,15 +863,15 @@ void CheckDataFiles() { const char* expected; const char* fileName; - } integrityCheckList[] = {{"36CB1B284BC7CBB4F25CD00BBB044550", "bass.dll"}, {"1B909B47946167D153FB94020393E781", "bass_aac.dll"}, - {"E7E69A3B369F0ABA1A4A18C831BC4364", "bass_ac3.dll"}, {"E20A57EA7D845FADC9A48A0AA919121A", "bass_fx.dll"}, + } integrityCheckList[] = {{"36CB1B284BC7CBB4F25CD00BBB044550", "bass.dll"}, {"80CDC5A50B27C47E53B99DE4D4523698", "bass_aac.dll"}, + {"2757D3E0F63C8C62DB32F90D776AB815", "bass_ac3.dll"}, {"539BE2B8762FF618C3BA04B638FD4A8B", "bass_fx.dll"}, {"F47DCE69DAFAA06A55A4BC1F07F80C8A", "bassflac.dll"}, {"F246D72BA73E9624FE8BE66E785FB5C5", "bassmidi.dll"}, {"5DEEC10A943E352EF7E0223327E8B48C", "bassmix.dll"}, {"2F87C5E0A1B7B28C8FC0D7E74116DDFC", "bassopus.dll"}, {"0F1B2FC6C0C703A43A24DC05352E7ADA", "basswebm.dll"}, {"893113C6C49DC1E1EF288310E68DB306", "basswma.dll"}, {"C6A44FC3CF2F5801561804272217B14D", "D3DX9_42.dll"}, {"D439E8EDD8C93D7ADE9C04BCFE9197C6", "sa.dat"}, - {"B33B21DB610116262D906305CE65C354", "D3DCompiler_42.dll"}, {"02ECD2919B3DAA59D6014EEFD29FC294", "tags.dll"}, + {"B33B21DB610116262D906305CE65C354", "D3DCompiler_42.dll"}, {"7A1665DD46726DA4592E77DC05D114F8", "tags.dll"}, {"0B3DD892007FB366D1F52F2247C046F5", "d3dcompiler_43.dll"}, {"D5D8C8561C6DDA7EF0D7D6ABB0D772F4", "xinput1_3_mta.dll"}, - {"7096EB0458485D89BB749474550C7651", "d3dcompiler_47.dll"}, {"E2BAC93166B0C2AD4D83E97FC1E88F8F", "XInput9_1_0_mta.dll"}}; + {"7096EB0458485D89BB749474550C7651", "d3dcompiler_47.dll"}, {"87F689D5636B6F31DBB4B9CBF56E17E3", "XInput9_1_0_mta.dll"}}; for (const auto& item : integrityCheckList) { diff --git a/Client/mods/deathmatch/StdInc.h b/Client/mods/deathmatch/StdInc.h index 68b18a6ab58..465478454f5 100644 --- a/Client/mods/deathmatch/StdInc.h +++ b/Client/mods/deathmatch/StdInc.h @@ -105,6 +105,7 @@ #include #include #include +#include #include #include #include diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 0f8cf2414b5..92683d213a3 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -251,6 +251,9 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) // Singular file download manager m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); + // 3D model renderer + m_pModelRenderer = std::make_unique(); + // Register the message and the net packet handler g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); @@ -267,6 +270,7 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); + g_pMultiplayer->SetRenderEverythingBarRoadsHandler(CClientGame::StaticRenderEverythingBarRoadsHandler); g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); @@ -470,6 +474,7 @@ CClientGame::~CClientGame() g_pMultiplayer->SetRender3DStuffHandler(NULL); g_pMultiplayer->SetPreRenderSkyHandler(NULL); g_pMultiplayer->SetRenderHeliLightHandler(nullptr); + g_pMultiplayer->SetRenderEverythingBarRoadsHandler(nullptr); g_pMultiplayer->SetChokingHandler(NULL); g_pMultiplayer->SetPreWorldProcessHandler(NULL); g_pMultiplayer->SetPostWorldProcessHandler(NULL); @@ -3546,6 +3551,11 @@ void CClientGame::StaticRenderHeliLightHandler() g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); } +void CClientGame::StaticRenderEverythingBarRoadsHandler() +{ + g_pClientGame->GetModelRenderer()->Render(); +} + bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) { return g_pClientGame->ChokingHandler(ucWeaponType); @@ -3853,6 +3863,8 @@ void CClientGame::PostWorldProcessPedsAfterPreRenderHandler() { CLuaArguments Arguments; m_pRootEntity->CallEvent("onClientPedsProcessed", Arguments, false); + + g_pClientGame->GetModelRenderer()->Update(); } void CClientGame::IdleHandler() diff --git a/Client/mods/deathmatch/logic/CClientGame.h b/Client/mods/deathmatch/logic/CClientGame.h index f2c290d94ca..97f7e08dab2 100644 --- a/Client/mods/deathmatch/logic/CClientGame.h +++ b/Client/mods/deathmatch/logic/CClientGame.h @@ -308,6 +308,8 @@ class CClientGame CRemoteCalls* GetRemoteCalls() { return m_pRemoteCalls; } CResourceFileDownloadManager* GetResourceFileDownloadManager() { return m_pResourceFileDownloadManager; } + CModelRenderer* GetModelRenderer() const noexcept { return m_pModelRenderer.get(); } + SharedUtil::CAsyncTaskScheduler* GetAsyncTaskScheduler() { return m_pAsyncTaskScheduler; } // Status toggles @@ -504,6 +506,7 @@ class CClientGame static void StaticRender3DStuffHandler(); static void StaticPreRenderSkyHandler(); static void StaticRenderHeliLightHandler(); + static void StaticRenderEverythingBarRoadsHandler(); static bool StaticChokingHandler(unsigned char ucWeaponType); static void StaticPreWorldProcessHandler(); static void StaticPostWorldProcessHandler(); @@ -698,6 +701,8 @@ class CClientGame CRemoteCalls* m_pRemoteCalls; CResourceFileDownloadManager* m_pResourceFileDownloadManager; + std::unique_ptr m_pModelRenderer; + // Revised facilities CServer m_Server; diff --git a/Client/mods/deathmatch/logic/CModelRenderer.cpp b/Client/mods/deathmatch/logic/CModelRenderer.cpp new file mode 100644 index 00000000000..2f06c836ec8 --- /dev/null +++ b/Client/mods/deathmatch/logic/CModelRenderer.cpp @@ -0,0 +1,72 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CModelRenderer.cpp + * PURPOSE: 3D models renderer + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "game\CRenderer.h" +#include "game\CVisibilityPlugins.h" + +bool CModelRenderer::EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix) +{ + if (g_pCore->IsWindowMinimized()) + return false; + + if (pModelInfo && pModelInfo->IsLoaded()) + { + m_Queue.emplace_back(pModelInfo, matrix); + return true; + } + + return false; +} + +void CModelRenderer::Update() +{ + CVisibilityPlugins* pVisibilityPlugins = g_pGame->GetVisibilityPlugins(); + assert(pVisibilityPlugins); + + for (auto& modelDesc : m_Queue) + { + // Insert transparent entities into a sorted list + if (modelDesc.pModelInfo->GetIdeFlag(eModelIdeFlag::DRAW_LAST)) + { + const CVector& vecCameraPosition = *(CVector*)0xB76870; // CRenderer::ms_vecCameraPosition + const float fDistance = (modelDesc.matrix.GetPosition() - vecCameraPosition).Length(); + + pVisibilityPlugins->InsertEntityIntoEntityList(&modelDesc, fDistance, RenderEntity); + } + } +} + +void CModelRenderer::Render() +{ + CRenderer* pRenderer = g_pGame->GetRenderer(); + assert(pRenderer); + + // Draw opaque entities + for (auto& modelDesc : m_Queue) + { + if (modelDesc.pModelInfo->IsLoaded() && !modelDesc.pModelInfo->GetIdeFlag(eModelIdeFlag::DRAW_LAST)) + pRenderer->RenderModel(modelDesc.pModelInfo, modelDesc.matrix); + } + + m_Queue.clear(); +} + +void CModelRenderer::RenderEntity(SModelToRender* modelDesc, float distance) +{ + if (!modelDesc->pModelInfo->IsLoaded()) + return; + + CRenderer* pRenderer = g_pGame->GetRenderer(); + assert(pRenderer); + + pRenderer->RenderModel(modelDesc->pModelInfo, modelDesc->matrix); +} diff --git a/Client/mods/deathmatch/logic/CModelRenderer.h b/Client/mods/deathmatch/logic/CModelRenderer.h new file mode 100644 index 00000000000..d923db6c7f8 --- /dev/null +++ b/Client/mods/deathmatch/logic/CModelRenderer.h @@ -0,0 +1,40 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CModelRenderer.h + * PURPOSE: 3D models renderer + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +class CModelRenderer final +{ +public: + struct SModelToRender final + { + CModelInfo* pModelInfo; + CMatrix matrix; + + SModelToRender(CModelInfo* pModelInfo, const CMatrix& matrix) : + pModelInfo(pModelInfo), + matrix(matrix) + { + } + }; + + bool EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix); + + void Update(); + + void Render(); + + static void RenderEntity(SModelToRender* entity, float distance); + +private: + + std::vector m_Queue; +}; diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index ed8ba623c1e..ebf2ba5140f 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -2724,6 +2724,7 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) // bool (1) - static // SObjectHealthSync (?) - health // bool (1) - is break + // bool (1) - respawnable // Pickups: // CVector (12) - position @@ -3089,7 +3090,10 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream) if (bitStream.ReadBit()) pObject->Break(); } - + + if (bitStream.Can(eBitStreamVersion::RespawnObject_Serverside)) + pObject->SetRespawnEnabled(bitStream.ReadBit()); + pObject->SetCollisionEnabled(bCollisonsEnabled); if (ucEntityTypeID == CClientGame::WEAPON) { diff --git a/Client/mods/deathmatch/logic/lua/CLuaMain.cpp b/Client/mods/deathmatch/logic/lua/CLuaMain.cpp index 446fdc866e3..6b794be0165 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaMain.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaMain.cpp @@ -127,6 +127,7 @@ void CLuaMain::InitClasses(lua_State* luaVM) CLuaVehicleDefs::AddClass(luaVM); CLuaWaterDefs::AddClass(luaVM); CLuaWeaponDefs::AddClass(luaVM); + CLuaBuildingDefs::AddClass(luaVM); CLuaShared::AddClasses(luaVM); } diff --git a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp index 317de7f16d8..4c70d03f047 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.cpp @@ -21,7 +21,10 @@ void CLuaTimerManager::DoPulse(CLuaMain* pLuaMain) // Use a separate queue to avoid trouble for (CFastList::const_iterator iter = m_TimerList.begin(); iter != m_TimerList.end(); iter++) - m_ProcessQueue.push_back(*iter); + { + if (!(*iter)->IsPaused()) + m_ProcessQueue.push_back(*iter); + } while (!m_ProcessQueue.empty()) { @@ -108,6 +111,16 @@ void CLuaTimerManager::RemoveAllTimers() m_pProcessingTimer = NULL; } +void CLuaTimerManager::SetTimerPaused(CLuaTimer* timer, bool paused) +{ + assert(timer); + + timer->SetPaused(paused); + if (paused) + ListRemove(m_ProcessQueue, timer); +} + + void CLuaTimerManager::ResetTimer(CLuaTimer* pLuaTimer) { assert(pLuaTimer); diff --git a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.h b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.h index 055b644fcbf..c4f97d2626b 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaTimerManager.h +++ b/Client/mods/deathmatch/logic/lua/CLuaTimerManager.h @@ -36,6 +36,7 @@ class CLuaTimerManager void RemoveAllTimers(); unsigned long GetTimerCount() const { return m_TimerList.size(); } + void SetTimerPaused(CLuaTimer* timer, bool paused); void ResetTimer(CLuaTimer* pLuaTimer); CFastList::const_iterator IterBegin() { return m_TimerList.begin(); } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp index f45efbf09c3..bcb765e7128 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp @@ -30,10 +30,10 @@ void CLuaBuildingDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "create", "createBuilding"); - lua_registerclass(luaVM, "Building"); + lua_registerclass(luaVM, "Building", "Element"); } -CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, uint16_t modelId, CVector pos, CVector rot, std::optional interior) +CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, std::uint16_t modelId, CVector pos, std::optional rot, std::optional interior) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); @@ -48,11 +48,14 @@ CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, uint16 if (!CClientBuildingManager::IsValidPosition(pos)) throw std::invalid_argument("Position is outside of game world"); - ConvertDegreesToRadians(rot); + if (rot.has_value()) + ConvertDegreesToRadians(rot.value()); + else + rot.emplace(CVector(0, 0, 0)); m_pBuildingManager->ResizePoolIfNeeds(); - CClientBuilding* pBuilding = new CClientBuilding(m_pManager, INVALID_ELEMENT_ID, modelId, pos, rot, interior.value_or(0)); + CClientBuilding* pBuilding = new CClientBuilding(m_pManager, INVALID_ELEMENT_ID, modelId, pos, rot.value() , interior.value_or(0)); CClientEntity* pRoot = pResource->GetResourceDynamicEntity(); pBuilding->SetParent(pRoot); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h index 628d320844d..a244c74bbb1 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h @@ -19,7 +19,7 @@ class CLuaBuildingDefs : public CLuaDefs static void AddClass(lua_State* luaVM); // Buiding create funcs - static CClientBuilding* CreateBuilding(lua_State* const luaVM, uint16_t modelId, CVector pos, CVector rot, std::optional interior); + static CClientBuilding* CreateBuilding(lua_State* const luaVM, std::uint16_t modelId, CVector pos, std::optional rot, std::optional interior); static void RemoveAllGameBuildings(); static void RestoreGameBuildings(); }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index e30b7f3ba24..f54378944de 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -36,6 +36,7 @@ void CLuaDrawingDefs::LoadFunctions() {"dxDrawMaterialPrimitive", DxDrawMaterialPrimitive}, {"dxDrawMaterialPrimitive3D", DxDrawMaterialPrimitive3D}, {"dxDrawWiredSphere", ArgumentParser}, + {"dxDrawModel3D", ArgumentParser}, {"dxGetTextWidth", DxGetTextWidth}, {"dxGetTextSize", ArgumentParser}, {"dxGetFontHeight", DxGetFontHeight}, @@ -2121,3 +2122,21 @@ bool CLuaDrawingDefs::DxDrawWiredSphere(lua_State* const luaVM, const CVector po g_pCore->GetGraphics()->DrawWiredSphere(position, radius, color.value(), lineWidth.value_or(1), iterations.value_or(1)); return true; } + +bool CLuaDrawingDefs::DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale) +{ + CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelID); + if (!pModelInfo) + throw std::invalid_argument("Invalid model ID"); + + if (auto modelType = pModelInfo->GetModelType(); + modelType == eModelInfoType::UNKNOWN || modelType == eModelInfoType::VEHICLE || modelType == eModelInfoType::PED) + { + throw std::invalid_argument("Invalid model type"); + } + + ConvertDegreesToRadians(rotation); + + return g_pClientGame->GetModelRenderer()->EnqueueModel(pModelInfo, + CMatrix{position, rotation, scale.value_or(CVector{1.0f, 1.0f, 1.0f})}); +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h index 0bda34f5e92..55dc3adda17 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h @@ -82,6 +82,8 @@ class CLuaDrawingDefs : public CLuaDefs static bool DxDrawWiredSphere(lua_State* const luaVM, const CVector position, const float radius, const std::optional color, const std::optional lineWidth, const std::optional iterations); + static bool DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale); + private: static void AddDxMaterialClass(lua_State* luaVM); static void AddDxTextureClass(lua_State* luaVM); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp index c47934bc075..81d1b4d7042 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp @@ -25,6 +25,7 @@ void CLuaObjectDefs::LoadFunctions() {"getObjectMass", GetObjectMass}, {"getObjectProperty", GetObjectProperty}, {"isObjectMoving", ArgumentParser}, + {"isObjectRespawnable", ArgumentParser}, // Object set funcs {"moveObject", MoveObject}, @@ -61,6 +62,7 @@ void CLuaObjectDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "getProperties", GetObjectProperties); lua_classfunction(luaVM, "getProperty", "getObjectProperty"); lua_classfunction(luaVM, "isMoving", "isObjectMoving"); + lua_classfunction(luaVM, "isRespawnable", "isObjectRespawnable"); lua_classfunction(luaVM, "setScale", "setObjectScale"); lua_classfunction(luaVM, "setBreakable", "setObjectBreakable"); @@ -707,3 +709,15 @@ int CLuaObjectDefs::SetObjectProperty(lua_State* luaVM) lua_pushboolean(luaVM, false); return 1; } + +bool CLuaObjectDefs::IsObjectRespawnable(CClientEntity* const pEntity) noexcept +{ + if (!IS_OBJECT(pEntity)) + return false; + + auto* pObject = static_cast(pEntity); + if (!pObject) + return false; + + return pObject->IsRespawnEnabled(); +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h index e614ef9f29b..1ce12ad20e7 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h @@ -29,6 +29,7 @@ class CLuaObjectDefs : public CLuaDefs LUA_DECLARE(GetObjectMass); LUA_DECLARE(GetObjectProperty); LUA_DECLARE(GetObjectProperties); + static bool IsObjectRespawnable(CClientEntity* const pEntity) noexcept; // Object set funcs LUA_DECLARE(SetObjectRotation); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp index 401abcfd96d..e0c8a96ba03 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp @@ -10,12 +10,14 @@ *****************************************************************************/ #include "StdInc.h" +#include void CLuaTimerDefs::LoadFunctions() { constexpr static const std::pair functions[]{ - {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, - {"getTimers", GetTimers}, {"isTimer", IsTimer}, {"getTimerDetails", GetTimerDetails}, + {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, + {"setTimerPaused", ArgumentParser},{"isTimerPaused", ArgumentParser}, + {"getTimers", GetTimers}, {"isTimer", IsTimer}, {"getTimerDetails", GetTimerDetails}, }; // Add functions @@ -31,10 +33,10 @@ void CLuaTimerDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "destroy", "killTimer"); lua_classfunction(luaVM, "reset", "resetTimer"); lua_classfunction(luaVM, "isValid", "isTimer"); - lua_classfunction(luaVM, "getDetails", "getTimerDetails"); lua_classvariable(luaVM, "valid", NULL, "isTimer"); + lua_classvariable(luaVM, "paused", "setTimerPaused", "isTimerPaused"); lua_registerclass(luaVM, "Timer"); } @@ -111,6 +113,22 @@ int CLuaTimerDefs::KillTimer(lua_State* luaVM) return 1; } +bool CLuaTimerDefs::IsTimerPaused(CLuaTimer* timer) noexcept +{ + return timer->IsPaused(); +} + +bool CLuaTimerDefs::SetTimerPaused(lua_State* luaVM, CLuaTimer* timer, bool paused) +{ + // bool setTimerPaused ( timer theTimer, bool paused ) + CLuaMain* luaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (!luaMain) + return false; + + luaMain->GetTimerManager()->SetTimerPaused(timer, paused); + return true; +} + int CLuaTimerDefs::ResetTimer(lua_State* luaVM) { // bool resetTimer ( timer theTimer ) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h index 671a329b289..db6cac48a9a 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h @@ -24,4 +24,6 @@ class CLuaTimerDefs : public CLuaDefs LUA_DECLARE(GetTimers); LUA_DECLARE(IsTimer); LUA_DECLARE(GetTimerDetails); + static bool IsTimerPaused(CLuaTimer* timer) noexcept; + static bool SetTimerPaused(lua_State* luaVM, CLuaTimer* timer, bool paused); }; diff --git a/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp index 5ef2bb66b1b..40984f5892b 100644 --- a/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp @@ -22,6 +22,8 @@ void CObjectRPCs::LoadFunctions() AddHandler(SET_OBJECT_VISIBLE_IN_ALL_DIMENSIONS, SetObjectVisibleInAllDimensions, "SetObjectVisibleInAllDimensions"); AddHandler(SET_OBJECT_BREAKABLE, SetObjectBreakable, "SetObjectBreakable"); AddHandler(BREAK_OBJECT, BreakObject, "BreakObject"); + AddHandler(RESPAWN_OBJECT, RespawnObject, "RespawnObject"); + AddHandler(TOGGLE_OBJECT_RESPAWN, ToggleObjectRespawn, "ToggleObjectRespawn"); } void CObjectRPCs::DestroyAllObjects(NetBitStreamInterface& bitStream) @@ -130,8 +132,24 @@ void CObjectRPCs::SetObjectBreakable(CClientEntity* pSource, NetBitStreamInterfa void CObjectRPCs::BreakObject(CClientEntity* pSource, NetBitStreamInterface& bitStream) { - auto pObject = static_cast(m_pObjectManager->Get(pSource->GetID())); + auto* pObject = static_cast(m_pObjectManager->Get(pSource->GetID())); - if (pObject != nullptr) + if (pObject) pObject->Break(); } + +void CObjectRPCs::RespawnObject(CClientEntity* pSource, NetBitStreamInterface& bitStream) +{ + auto* pObject = static_cast(m_pObjectManager->Get(pSource->GetID())); + + if (pObject) + g_pClientGame->GetObjectRespawner()->Respawn(pObject); +} + +void CObjectRPCs::ToggleObjectRespawn(CClientEntity* pSource, NetBitStreamInterface& bitStream) +{ + auto* pObject = static_cast(m_pObjectManager->Get(pSource->GetID())); + + if (pObject) + pObject->SetRespawnEnabled(bitStream.ReadBit()); +} diff --git a/Client/mods/deathmatch/logic/rpc/CObjectRPCs.h b/Client/mods/deathmatch/logic/rpc/CObjectRPCs.h index 8aa427c14f7..5a342b743b6 100644 --- a/Client/mods/deathmatch/logic/rpc/CObjectRPCs.h +++ b/Client/mods/deathmatch/logic/rpc/CObjectRPCs.h @@ -27,4 +27,6 @@ class CObjectRPCs : public CRPCFunctions DECLARE_ELEMENT_RPC(SetObjectVisibleInAllDimensions); DECLARE_ELEMENT_RPC(SetObjectBreakable); DECLARE_ELEMENT_RPC(BreakObject); + DECLARE_ELEMENT_RPC(RespawnObject); + DECLARE_ELEMENT_RPC(ToggleObjectRespawn); }; diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index f725f37b639..802b9b56eac 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -268,6 +268,7 @@ class CMultiplayerSA : public CMultiplayer void SetRender3DStuffHandler(Render3DStuffHandler* pHandler); void SetPreRenderSkyHandler(PreRenderSkyHandler* pHandler); void SetRenderHeliLightHandler(RenderHeliLightHandler* pHandler); + void SetRenderEverythingBarRoadsHandler(RenderEverythingBarRoadsHandler* pHandler) override; void Reset(); diff --git a/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp b/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp index 03a27688d2b..b346f258740 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp @@ -13,6 +13,7 @@ extern CCoreInterface* g_pCore; GameEntityRenderHandler* pGameEntityRenderHandler = nullptr; PreRenderSkyHandler* pPreRenderSkyHandlerHandler = nullptr; RenderHeliLightHandler* pRenderHeliLightHandler = nullptr; +RenderEverythingBarRoadsHandler* pRenderEverythingBarRoadsHandler = nullptr; #define VAR_CCullZones_NumMirrorAttributeZones 0x0C87AC4 // int #define VAR_CMirrors_d3dRestored 0x0C7C729 // uchar @@ -581,6 +582,17 @@ void CMultiplayerSA::SetRenderHeliLightHandler(RenderHeliLightHandler* pHandler) pRenderHeliLightHandler = pHandler; } +////////////////////////////////////////////////////////////////////////////////////////// +// +// CMultiplayerSA::SetRenderEverythingBarRoadsHandler +// +// +////////////////////////////////////////////////////////////////////////////////////////// +void CMultiplayerSA::SetRenderEverythingBarRoadsHandler(RenderEverythingBarRoadsHandler* pHandler) +{ + pRenderEverythingBarRoadsHandler = pHandler; +} + ////////////////////////////////////////////////////////////////////////////////////////// // // CMultiplayerSA::SetIsMinimizedAndNotConnected @@ -703,6 +715,30 @@ void _declspec(naked) HOOK_CVisibilityPlugins_RenderPedCB() } } +// Hook info +#define HOOKPOS_CRenderer_EverythingBarRoads 0x553C78 +#define HOOKSIZE_CRenderer_EverythingBarRoads 5 +DWORD RETURN_CRenderer_EverythingBarRoads = 0x553C7D; +DWORD DO_CRenderer_EverythingBarRoads = 0x7EE180; +void _declspec(naked) HOOK_CRenderer_EverythingBarRoads() +{ + _asm + { + pushad + } + + if (pRenderEverythingBarRoadsHandler) + pRenderEverythingBarRoadsHandler(); + + _asm + { + popad + call DO_CRenderer_EverythingBarRoads + jmp RETURN_CRenderer_EverythingBarRoads + + } +} + ////////////////////////////////////////////////////////////////////////////////////////// // // CMultiplayerSA::InitHooks_Rendering @@ -726,4 +762,5 @@ void CMultiplayerSA::InitHooks_Rendering() EZHookInstallChecked(CClouds_RenderSkyPolys); EZHookInstallChecked(RwCameraSetNearClipPlane); EZHookInstall(RenderEffects_HeliLight); + EZHookInstall(CRenderer_EverythingBarRoads); } diff --git a/Client/sdk/game/CGame.h b/Client/sdk/game/CGame.h index d487b524fb0..b3da8af6e3e 100644 --- a/Client/sdk/game/CGame.h +++ b/Client/sdk/game/CGame.h @@ -68,6 +68,7 @@ class CWeather; class CWorld; class CIplStore; class CBuildingRemoval; +class CRenderer; enum eEntityType; enum ePedPieceTypes; @@ -149,6 +150,7 @@ class __declspec(novtable) CGame virtual CPointLights* GetPointLights() = 0; virtual CColStore* GetCollisionStore() = 0; virtual CBuildingRemoval* GetBuildingRemoval() = 0; + virtual CRenderer* GetRenderer() const noexcept = 0; virtual CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD) = 0; virtual CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false) = 0; diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index a1a9e14d4fa..1938fe4f7e1 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -60,6 +60,7 @@ enum class eModelInfoType : unsigned char VEHICLE = 6, PED = 7, LOD_ATOMIC = 8, + UNKNOWN = 9 }; enum eVehicleUpgradePosn diff --git a/Client/sdk/game/CRenderer.h b/Client/sdk/game/CRenderer.h new file mode 100644 index 00000000000..65d6a8bdcaf --- /dev/null +++ b/Client/sdk/game/CRenderer.h @@ -0,0 +1,23 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/game/CRenderer.h + * PURPOSE: Renderer interface + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +class CModelInfo; +class CMatrix; + +class CRenderer +{ +public: + virtual ~CRenderer() {} + + virtual void RenderModel(CModelInfo* pModelInfo, const CMatrix& matrix) = 0; +}; diff --git a/Client/sdk/game/CVisibilityPlugins.h b/Client/sdk/game/CVisibilityPlugins.h index 1d8d1b47cc4..f2e948f65a3 100644 --- a/Client/sdk/game/CVisibilityPlugins.h +++ b/Client/sdk/game/CVisibilityPlugins.h @@ -22,4 +22,6 @@ class CVisibilityPlugins public: virtual void SetClumpAlpha(RpClump* pClump, int iAlpha) = 0; virtual int GetAtomicId(RwObject* pAtomic) = 0; + + virtual bool InsertEntityIntoEntityList(void* entity, float distance, void* callback) = 0; }; diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index c8b043a37fa..02c932cf574 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -104,6 +104,7 @@ typedef void(IdleHandler)(); typedef void(PreFxRenderHandler)(); typedef void(PostColorFilterRenderHandler)(); typedef void(PreHudRenderHandler)(); +typedef void(RenderEverythingBarRoadsHandler)(); typedef CAnimBlendAssociationSAInterface*(AddAnimationHandler)(RpClump* pClump, AssocGroupId animGroup, AnimationId animID); typedef CAnimBlendAssociationSAInterface*(AddAnimationAndSyncHandler)(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, AssocGroupId animGroup, AnimationId animID); @@ -385,6 +386,7 @@ class CMultiplayer virtual void SetRender3DStuffHandler(Render3DStuffHandler* pHandler) = 0; virtual void SetPreRenderSkyHandler(PreRenderSkyHandler* pHandler) = 0; virtual void SetRenderHeliLightHandler(RenderHeliLightHandler* pHandler) = 0; + virtual void SetRenderEverythingBarRoadsHandler(RenderEverythingBarRoadsHandler* pHandler) = 0; virtual void Reset() = 0; diff --git a/Server/dbconmy/premake5.lua b/Server/dbconmy/premake5.lua index 3bd8cf5eff1..125047f9060 100644 --- a/Server/dbconmy/premake5.lua +++ b/Server/dbconmy/premake5.lua @@ -41,6 +41,7 @@ project "Dbconmy" includedirs { os.findheader("mysql.h", { "/usr/local/opt/mysql/include/mysql", + "/opt/homebrew/include/mysql", "/opt/osxcross/macports/pkgs/opt/local/include/mysql8/mysql", }) } diff --git a/Server/mods/deathmatch/logic/CObject.cpp b/Server/mods/deathmatch/logic/CObject.cpp index c88dbf3e603..31aa8b2113d 100644 --- a/Server/mods/deathmatch/logic/CObject.cpp +++ b/Server/mods/deathmatch/logic/CObject.cpp @@ -33,6 +33,7 @@ CObject::CObject(CElement* pParent, CObjectManager* pObjectManager, bool bIsLowL m_bIsFrozen = false; m_bDoubleSided = false; m_bBreakable = false; + m_bRespawnable = false; m_bCollisionsEnabled = true; @@ -58,6 +59,7 @@ CObject::CObject(const CObject& Copy) : CElement(Copy.m_pParent), m_bIsLowLod(Co m_bBreakable = Copy.m_bBreakable; m_vecPosition = Copy.m_vecPosition; m_vecRotation = Copy.m_vecRotation; + m_bRespawnable = Copy.m_bRespawnable; m_pMoveAnimation = NULL; if (Copy.m_pMoveAnimation != NULL) diff --git a/Server/mods/deathmatch/logic/CObject.h b/Server/mods/deathmatch/logic/CObject.h index 9e2c23c360b..e5032b91ce7 100644 --- a/Server/mods/deathmatch/logic/CObject.h +++ b/Server/mods/deathmatch/logic/CObject.h @@ -81,6 +81,9 @@ class CObject : public CElement bool IsBreakable() { return m_bBreakable; } void SetBreakable(bool bBreakable) { m_bBreakable = bBreakable; } + bool IsRespawnEnabled() const noexcept { return m_bRespawnable; } + void SetRespawnEnabled(bool bRespawn) noexcept { m_bRespawnable = bRespawn; } + protected: bool ReadSpecialData(const int iLine) override; @@ -96,6 +99,7 @@ class CObject : public CElement bool m_bSyncable; CPlayer* m_pSyncer; bool m_bVisibleInAllDimensions = false; + bool m_bRespawnable; protected: bool m_bCollisionsEnabled; diff --git a/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp b/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp index 2f9cfa8ce91..7468fc5e6d7 100644 --- a/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp +++ b/Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp @@ -226,6 +226,8 @@ ADD_ENUM1(SET_COLPOLYGON_HEIGHT) ADD_ENUM1(SET_OBJECT_BREAKABLE) ADD_ENUM1(BREAK_OBJECT) ADD_ENUM1(SET_PLAYER_SCRIPT_DEBUG_LEVEL) +ADD_ENUM1(RESPAWN_OBJECT) +ADD_ENUM1(TOGGLE_OBJECT_RESPAWN) IMPLEMENT_ENUM_END("eElementRPCFunctions") DECLARE_ENUM(CRPCFunctions::eRPCFunctions); diff --git a/Server/mods/deathmatch/logic/CResourceChecker.Data.h b/Server/mods/deathmatch/logic/CResourceChecker.Data.h index a0234eb386d..e6bdee92125 100644 --- a/Server/mods/deathmatch/logic/CResourceChecker.Data.h +++ b/Server/mods/deathmatch/logic/CResourceChecker.Data.h @@ -168,7 +168,9 @@ namespace // Base Encoding & Decoding {false, "base64Encode", "encodeString"}, - {false, "base64Decode", "decodeString"} + {false, "base64Decode", "decodeString"}, + + {false, "setHelicopterRotorSpeed", "setVehicleRotorSpeed"} }; SDeprecatedItem serverDeprecatedList[] = { diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index ab24fe0d66c..ad06e54a704 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -8358,6 +8358,43 @@ bool CStaticFunctionDefinitions::SetObjectBreakable(CElement* pElement, const bo return false; } +bool CStaticFunctionDefinitions::RespawnObject(CElement* const pElement) noexcept +{ + RUN_CHILDREN(RespawnObject(*iter)); + + if (!IS_OBJECT(pElement)) + return false; + + CObject* pObject = static_cast(pElement); + if (!pObject) + return false; + + CBitStream BitStream; + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pObject, RESPAWN_OBJECT, *BitStream.pBitStream)); + + return true; +} + +bool CStaticFunctionDefinitions::ToggleObjectRespawn(CElement* const pElement, const bool bRespawn) noexcept +{ + RUN_CHILDREN(ToggleObjectRespawn(*iter, bRespawn)); + + if (!IS_OBJECT(pElement)) + return false; + + CObject* pObject = static_cast(pElement); + if (!pObject) + return false; + + pObject->SetRespawnEnabled(bRespawn); + + CBitStream BitStream; + BitStream->WriteBit(bRespawn); + m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pObject, TOGGLE_OBJECT_RESPAWN, *BitStream.pBitStream)); + + return true; +} + CRadarArea* CStaticFunctionDefinitions::CreateRadarArea(CResource* pResource, const CVector2D& vecPosition2D, const CVector2D& vecSize, const SColor color, CElement* pVisibleTo) { diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 2f260e3ea59..bb0e99c0ee5 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -424,6 +424,8 @@ class CStaticFunctionDefinitions static bool BreakObject(CElement* pElement); static bool SetObjectVisibleInAllDimensions(CElement* pElement, bool bVisible, unsigned short usNewDimension = 0); static bool SetObjectBreakable(CElement* pElement, const bool bBreakable); + static bool RespawnObject(CElement* const pElement) noexcept; + static bool ToggleObjectRespawn(CElement* const pElement, const bool bRespawn) noexcept; // Radar area create/destroy funcs static CRadarArea* CreateRadarArea(CResource* pResource, const CVector2D& vecPosition, const CVector2D& vecSize, const SColor color, CElement* pVisibleTo); diff --git a/Server/mods/deathmatch/logic/lua/CLuaTimerManager.cpp b/Server/mods/deathmatch/logic/lua/CLuaTimerManager.cpp index fbd86eccaf1..0af771b2891 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaTimerManager.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaTimerManager.cpp @@ -26,7 +26,10 @@ void CLuaTimerManager::DoPulse(CLuaMain* pLuaMain) // Use a separate queue to avoid trouble // What kind of problems are we trying to avoid? Doing a copy each frame isn't quite efficient for (CFastList::const_iterator iter = m_TimerList.begin(); iter != m_TimerList.end(); ++iter) - m_ProcessQueue.push_back(*iter); + { + if (!(*iter)->IsPaused()) + m_ProcessQueue.push_back(*iter); + } while (!m_ProcessQueue.empty()) { @@ -113,6 +116,15 @@ void CLuaTimerManager::RemoveAllTimers() m_pProcessingTimer = NULL; } +void CLuaTimerManager::SetTimerPaused(CLuaTimer* timer, bool paused) +{ + assert(timer); + + timer->SetPaused(paused); + if (paused) + ListRemove(m_ProcessQueue, timer); +} + void CLuaTimerManager::ResetTimer(CLuaTimer* pLuaTimer) { assert(pLuaTimer); diff --git a/Server/mods/deathmatch/logic/lua/CLuaTimerManager.h b/Server/mods/deathmatch/logic/lua/CLuaTimerManager.h index d9d2fc41f2b..d63e659147a 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaTimerManager.h +++ b/Server/mods/deathmatch/logic/lua/CLuaTimerManager.h @@ -36,6 +36,7 @@ class CLuaTimerManager void RemoveAllTimers(); unsigned long GetTimerCount() const { return m_TimerList.size(); } + void SetTimerPaused(CLuaTimer* timer, bool paused); void ResetTimer(CLuaTimer* pLuaTimer); CFastList::const_iterator IterBegin() { return m_TimerList.begin(); } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp index 22d7e6b3162..898825673c4 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp @@ -19,12 +19,14 @@ void CLuaObjectDefs::LoadFunctions() constexpr static const std::pair functions[]{ // Object create/destroy funcs {"createObject", CreateObject}, + {"respawnObject", ArgumentParser}, // Object get funcs {"getObjectRotation", GetObjectRotation}, {"getObjectScale", GetObjectScale}, {"isObjectBreakable", ArgumentParser}, {"isObjectMoving", ArgumentParser}, + {"isObjectRespawnable", ArgumentParser}, // Object set funcs {"setObjectRotation", SetObjectRotation}, @@ -33,6 +35,7 @@ void CLuaObjectDefs::LoadFunctions() {"moveObject", MoveObject}, {"stopObject", StopObject}, {"breakObject", ArgumentParser}, + {"toggleObjectRespawn", ArgumentParser}, }; // Add functions @@ -48,16 +51,19 @@ void CLuaObjectDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "move", "moveObject"); lua_classfunction(luaVM, "stop", "stopObject"); lua_classfunction(luaVM, "break", "breakObject"); + lua_classfunction(luaVM, "respawn", "respawnObject"); lua_classfunction(luaVM, "getScale", "getObjectScale"); lua_classfunction(luaVM, "setScale", "setObjectScale"); lua_classfunction(luaVM, "isBreakable", "isObjectBreakable"); lua_classfunction(luaVM, "setBreakable", "setObjectBreakable"); lua_classfunction(luaVM, "isMoving", "isObjectMoving"); + lua_classfunction(luaVM, "toggleRespawn", "toggleObjectRespawn"); lua_classvariable(luaVM, "scale", "setObjectScale", "getObjectScale"); lua_classvariable(luaVM, "breakable", "setObjectBreakable", "isObjectBreakable"); lua_classvariable(luaVM, "moving", nullptr, "isObjectMoving"); + lua_classvariable(luaVM, "isRespawnable", nullptr, "isObjectRespawnable"); lua_registerclass(luaVM, "Object", "Element"); } @@ -312,3 +318,18 @@ bool CLuaObjectDefs::BreakObject(CObject* const pObject) { return CStaticFunctionDefinitions::BreakObject(pObject); } + +bool CLuaObjectDefs::RespawnObject(CObject* const pObject) noexcept +{ + return CStaticFunctionDefinitions::RespawnObject(pObject); +} + +bool CLuaObjectDefs::ToggleObjectRespawn(CObject* const pObject, const bool bRespawn) noexcept +{ + return CStaticFunctionDefinitions::ToggleObjectRespawn(pObject, bRespawn); +} + +bool CLuaObjectDefs::IsObjectRespawnable(CObject* const pObject) noexcept +{ + return pObject->IsRespawnEnabled(); +} diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h index 159ba47d283..76a96a982b9 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h @@ -20,6 +20,7 @@ class CLuaObjectDefs : public CLuaDefs // Object create/destroy functions LUA_DECLARE(CreateObject); + static bool RespawnObject(CObject* const pObject) noexcept; // Object get functions LUA_DECLARE(GetObjectName); @@ -27,6 +28,7 @@ class CLuaObjectDefs : public CLuaDefs LUA_DECLARE(GetObjectScale); static bool IsObjectBreakable(CObject* const pObject); static bool IsObjectMoving(CObject* const pObject); + static bool IsObjectRespawnable(CObject* const pObject) noexcept; // Object set functions LUA_DECLARE(SetObjectName); @@ -36,4 +38,5 @@ class CLuaObjectDefs : public CLuaDefs LUA_DECLARE(MoveObject); LUA_DECLARE(StopObject); static bool BreakObject(CObject* const pObject); + static bool ToggleObjectRespawn(CObject* const pObject, const bool bRespawn) noexcept; }; diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp index 49c83bd576c..c3e0478c8b3 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.cpp @@ -16,8 +16,9 @@ void CLuaTimerDefs::LoadFunctions() { constexpr static const std::pair functions[]{ - {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, - {"getTimers", GetTimers}, {"isTimer", IsTimer}, {"getTimerDetails", GetTimerDetails}, + {"setTimer", SetTimer}, {"killTimer", KillTimer}, {"resetTimer", ResetTimer}, + {"setTimerPaused", ArgumentParser},{"isTimerPaused", ArgumentParser}, + {"getTimers", GetTimers}, {"isTimer", IsTimer},{"getTimerDetails", GetTimerDetails}, }; // Add functions @@ -33,10 +34,10 @@ void CLuaTimerDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "destroy", "killTimer"); lua_classfunction(luaVM, "reset", "resetTimer"); lua_classfunction(luaVM, "isValid", "isTimer"); - lua_classfunction(luaVM, "getDetails", "getTimerDetails"); lua_classvariable(luaVM, "valid", NULL, "isTimer"); + lua_classvariable(luaVM, "paused", "setTimerPaused", "isTimerPaused"); lua_registerclass(luaVM, "Timer"); } @@ -114,6 +115,22 @@ int CLuaTimerDefs::KillTimer(lua_State* luaVM) return 1; } +bool CLuaTimerDefs::IsTimerPaused(CLuaTimer* timer) noexcept +{ + return timer->IsPaused(); +} + +bool CLuaTimerDefs::SetTimerPaused(lua_State* luaVM, CLuaTimer* timer, bool paused) +{ + // bool setTimerPaused ( timer theTimer, bool paused ) + CLuaMain* luaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (!luaMain) + return false; + + luaMain->GetTimerManager()->SetTimerPaused(timer, paused); + return true; +} + int CLuaTimerDefs::ResetTimer(lua_State* luaVM) { // bool resetTimer ( timer theTimer ) diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h index fd37e2aaa48..abf1b725d6c 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaTimerDefs.h @@ -24,4 +24,6 @@ class CLuaTimerDefs : public CLuaDefs LUA_DECLARE(GetTimers); LUA_DECLARE(IsTimer); LUA_DECLARE(GetTimerDetails); -}; \ No newline at end of file + static bool IsTimerPaused(CLuaTimer* timer) noexcept; + static bool SetTimerPaused(lua_State* luaVM, CLuaTimer* timer, bool paused); +}; diff --git a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp index 2502b4cc309..a001ba518fd 100644 --- a/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CEntityAddPacket.cpp @@ -301,6 +301,10 @@ bool CEntityAddPacket::Write(NetBitStreamInterface& BitStream) const if (BitStream.Can(eBitStreamVersion::BreakObject_Serverside)) BitStream.WriteBit(pObject->GetHealth() <= 0); + // Respawnable + if (BitStream.Can(eBitStreamVersion::RespawnObject_Serverside)) + BitStream.WriteBit(pObject->IsRespawnEnabled()); + if (ucEntityTypeID == CElement::WEAPON) { CCustomWeapon* pWeapon = static_cast(pElement); diff --git a/Shared/data/MTA San Andreas/MTA/XInput9_1_0_mta.dll b/Shared/data/MTA San Andreas/MTA/XInput9_1_0_mta.dll index 3483103b055..74387b00136 100644 Binary files a/Shared/data/MTA San Andreas/MTA/XInput9_1_0_mta.dll and b/Shared/data/MTA San Andreas/MTA/XInput9_1_0_mta.dll differ diff --git a/Shared/data/MTA San Andreas/MTA/bass_aac.dll b/Shared/data/MTA San Andreas/MTA/bass_aac.dll index 84e82ec090c..91f61becc30 100644 Binary files a/Shared/data/MTA San Andreas/MTA/bass_aac.dll and b/Shared/data/MTA San Andreas/MTA/bass_aac.dll differ diff --git a/Shared/data/MTA San Andreas/MTA/bass_ac3.dll b/Shared/data/MTA San Andreas/MTA/bass_ac3.dll index ba58ffb6dc2..abbb2d6bd86 100644 Binary files a/Shared/data/MTA San Andreas/MTA/bass_ac3.dll and b/Shared/data/MTA San Andreas/MTA/bass_ac3.dll differ diff --git a/Shared/data/MTA San Andreas/MTA/bass_fx.dll b/Shared/data/MTA San Andreas/MTA/bass_fx.dll index 065a5961059..3d8184b34a1 100644 Binary files a/Shared/data/MTA San Andreas/MTA/bass_fx.dll and b/Shared/data/MTA San Andreas/MTA/bass_fx.dll differ diff --git a/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot b/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot index 986344b426f..ea684a182f8 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: MTA San Andreas 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-08-14 19:10+0000\n" +"POT-Creation-Date: 2024-09-03 15:15+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -398,116 +398,116 @@ msgstr[1] "" msgid "Disconnected" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:370 +#: Client/mods/deathmatch/logic/CClientGame.cpp:374 msgid "Flying a UFO around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:370 +#: Client/mods/deathmatch/logic/CClientGame.cpp:374 msgid "Cruising around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:370 +#: Client/mods/deathmatch/logic/CClientGame.cpp:374 msgid "Riding the waves of" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:371 +#: Client/mods/deathmatch/logic/CClientGame.cpp:375 msgid "Riding the train in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:371 +#: Client/mods/deathmatch/logic/CClientGame.cpp:375 msgid "Flying around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:372 +#: Client/mods/deathmatch/logic/CClientGame.cpp:376 msgid "Riding around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:372 +#: Client/mods/deathmatch/logic/CClientGame.cpp:376 msgid "Monster truckin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:372 +#: Client/mods/deathmatch/logic/CClientGame.cpp:376 msgid "Quaddin' around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:373 +#: Client/mods/deathmatch/logic/CClientGame.cpp:377 msgid "Bunny hopping around" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:373 +#: Client/mods/deathmatch/logic/CClientGame.cpp:377 msgid "Doing weird stuff in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:381 msgid "Climbing around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:378 -#: Client/mods/deathmatch/logic/CClientGame.cpp:379 +#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:383 msgid "Doing a drive-by in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:384 msgid "Blub blub..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:381 +#: Client/mods/deathmatch/logic/CClientGame.cpp:385 msgid "Breathing water" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:382 +#: Client/mods/deathmatch/logic/CClientGame.cpp:386 msgid "Drowning in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:383 +#: Client/mods/deathmatch/logic/CClientGame.cpp:387 msgid "Ducking for cover in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:388 msgid "Fighting in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:385 +#: Client/mods/deathmatch/logic/CClientGame.cpp:389 msgid "Throwing fists in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:386 +#: Client/mods/deathmatch/logic/CClientGame.cpp:390 msgid "Blastin' fools in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:391 msgid "Shooting up" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:392 msgid "Jetpacking in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:389 +#: Client/mods/deathmatch/logic/CClientGame.cpp:393 msgid "Literally on fire in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:390 +#: Client/mods/deathmatch/logic/CClientGame.cpp:394 msgid "Burning up in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:395 msgid "Swimming in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:396 msgid "Floating around in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:393 +#: Client/mods/deathmatch/logic/CClientGame.cpp:397 msgid "Being chased by a shark" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:394 +#: Client/mods/deathmatch/logic/CClientGame.cpp:398 msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:528 +#: Client/mods/deathmatch/logic/CClientGame.cpp:533 #: Client/core/CSettings.cpp:3479 Client/core/CMainMenu.cpp:304 #: Client/core/CCore.cpp:674 msgid "Main menu" @@ -517,17 +517,17 @@ msgstr "" #. Display an error, reset the error status and exit #. Show a message that the connection timed out and abort #. Show failed message and abort the attempt -#: Client/mods/deathmatch/logic/CClientGame.cpp:636 -#: Client/mods/deathmatch/logic/CClientGame.cpp:710 -#: Client/mods/deathmatch/logic/CClientGame.cpp:734 -#: Client/mods/deathmatch/logic/CClientGame.cpp:756 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1169 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1249 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1259 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1328 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1365 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1414 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +#: Client/mods/deathmatch/logic/CClientGame.cpp:641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:715 +#: Client/mods/deathmatch/logic/CClientGame.cpp:739 +#: Client/mods/deathmatch/logic/CClientGame.cpp:761 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1174 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1254 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1333 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1370 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1419 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1431 #: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 #: Client/core/CConnectManager.cpp:80 Client/core/CConnectManager.cpp:111 #: Client/core/CConnectManager.cpp:127 Client/core/CConnectManager.cpp:263 @@ -549,146 +549,146 @@ msgstr "" msgid "Error" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:636 -#: Client/mods/deathmatch/logic/CClientGame.cpp:734 +#: Client/mods/deathmatch/logic/CClientGame.cpp:641 +#: Client/mods/deathmatch/logic/CClientGame.cpp:739 #: Client/core/ServerBrowser/CServerBrowser.cpp:1300 #: Client/core/ServerBrowser/CServerBrowser.cpp:1357 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "" #. Display the status box -#: Client/mods/deathmatch/logic/CClientGame.cpp:652 +#: Client/mods/deathmatch/logic/CClientGame.cpp:657 #: Client/core/CConnectManager.cpp:148 msgid "CONNECTING" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:652 +#: Client/mods/deathmatch/logic/CClientGame.cpp:657 msgid "Entering the game ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:710 +#: Client/mods/deathmatch/logic/CClientGame.cpp:715 msgid "" "Not connected; please use Quick Connect or the 'connect' command to connect " "to a server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:756 +#: Client/mods/deathmatch/logic/CClientGame.cpp:761 msgid "Could not start the local server. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:766 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1238 +#: Client/mods/deathmatch/logic/CClientGame.cpp:771 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1243 msgid "Local Server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:766 +#: Client/mods/deathmatch/logic/CClientGame.cpp:771 msgid "Starting local server ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1014 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1019 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1023 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1028 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1084 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1089 #: Client/mods/deathmatch/logic/CResource.cpp:375 #: Client/core/CSettings.cpp:3483 Client/core/CCore.cpp:674 msgid "In-game" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1169 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1174 #, c-format msgid "You were kicked from the game ( %s )" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1238 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1243 msgid "Connecting to local server..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1249 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1254 msgid "Error connecting to server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1259 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1264 msgid "Connecting to local server timed out. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1328 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1333 #: Client/core/CConnectManager.cpp:263 msgid "Connection timed out" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1365 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1370 msgid "Connection with the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1376 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1381 #: Client/core/CConnectManager.cpp:277 Client/core/CConnectManager.cpp:281 msgid "Disconnected: unknown protocol error" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1380 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1385 #: Client/core/CConnectManager.cpp:285 msgid "Disconnected: disconnected remotely" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1384 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1389 #: Client/core/CConnectManager.cpp:289 msgid "Disconnected: connection lost remotely" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1388 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1393 #: Client/core/CConnectManager.cpp:293 msgid "Disconnected: you are banned from this server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1392 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1397 msgid "Disconnected: the server is currently full" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1396 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1401 #: Client/core/CConnectManager.cpp:300 msgid "Disconnected: disconnected from the server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1400 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1405 #: Client/core/CConnectManager.cpp:304 msgid "Disconnected: connection to the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1404 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1409 msgid "Disconnected: invalid password specified" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1408 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1413 #: Client/core/CConnectManager.cpp:311 msgid "Disconnected: connection was refused" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1431 msgid "MTA Client verification failed!" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5713 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5725 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5713 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5725 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5713 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5725 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5714 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5726 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5714 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5726 msgid "Wasted" msgstr "" diff --git a/Shared/data/MTA San Andreas/MTA/tags.dll b/Shared/data/MTA San Andreas/MTA/tags.dll index f73a96cae27..874ef2c6727 100644 Binary files a/Shared/data/MTA San Andreas/MTA/tags.dll and b/Shared/data/MTA San Andreas/MTA/tags.dll differ diff --git a/Shared/data/MTA San Andreas/server/arm64/libcrypto-3-arm64.dll b/Shared/data/MTA San Andreas/server/arm64/libcrypto-3-arm64.dll index a1aacfd7888..666c0f287b6 100644 Binary files a/Shared/data/MTA San Andreas/server/arm64/libcrypto-3-arm64.dll and b/Shared/data/MTA San Andreas/server/arm64/libcrypto-3-arm64.dll differ diff --git a/Shared/data/MTA San Andreas/server/arm64/libmysql.dll b/Shared/data/MTA San Andreas/server/arm64/libmysql.dll index a570d69c37d..3f3e2895e85 100644 Binary files a/Shared/data/MTA San Andreas/server/arm64/libmysql.dll and b/Shared/data/MTA San Andreas/server/arm64/libmysql.dll differ diff --git a/Shared/data/MTA San Andreas/server/arm64/libssl-3-arm64.dll b/Shared/data/MTA San Andreas/server/arm64/libssl-3-arm64.dll index dd2936ac564..51a8eb0eb2e 100644 Binary files a/Shared/data/MTA San Andreas/server/arm64/libssl-3-arm64.dll and b/Shared/data/MTA San Andreas/server/arm64/libssl-3-arm64.dll differ diff --git a/Shared/data/MTA San Andreas/server/mods/deathmatch/libcrypto-3.dll b/Shared/data/MTA San Andreas/server/mods/deathmatch/libcrypto-3.dll index a54d2e20d5b..f7ce3d098ea 100644 Binary files a/Shared/data/MTA San Andreas/server/mods/deathmatch/libcrypto-3.dll and b/Shared/data/MTA San Andreas/server/mods/deathmatch/libcrypto-3.dll differ diff --git a/Shared/data/MTA San Andreas/server/mods/deathmatch/libmysql.dll b/Shared/data/MTA San Andreas/server/mods/deathmatch/libmysql.dll index f543bf51036..8efa94f3a65 100644 Binary files a/Shared/data/MTA San Andreas/server/mods/deathmatch/libmysql.dll and b/Shared/data/MTA San Andreas/server/mods/deathmatch/libmysql.dll differ diff --git a/Shared/data/MTA San Andreas/server/mods/deathmatch/libssl-3.dll b/Shared/data/MTA San Andreas/server/mods/deathmatch/libssl-3.dll index 4d45e0095b7..e09cfd88c7f 100644 Binary files a/Shared/data/MTA San Andreas/server/mods/deathmatch/libssl-3.dll and b/Shared/data/MTA San Andreas/server/mods/deathmatch/libssl-3.dll differ diff --git a/Shared/data/MTA San Andreas/server/x64/libcrypto-3-x64.dll b/Shared/data/MTA San Andreas/server/x64/libcrypto-3-x64.dll index ef3d63129cd..01a84081b06 100644 Binary files a/Shared/data/MTA San Andreas/server/x64/libcrypto-3-x64.dll and b/Shared/data/MTA San Andreas/server/x64/libcrypto-3-x64.dll differ diff --git a/Shared/data/MTA San Andreas/server/x64/libmysql.dll b/Shared/data/MTA San Andreas/server/x64/libmysql.dll index 96e63b50d03..7e1949a4853 100644 Binary files a/Shared/data/MTA San Andreas/server/x64/libmysql.dll and b/Shared/data/MTA San Andreas/server/x64/libmysql.dll differ diff --git a/Shared/data/MTA San Andreas/server/x64/libssl-3-x64.dll b/Shared/data/MTA San Andreas/server/x64/libssl-3-x64.dll index 8e7f859cd63..849cd5f0ba3 100644 Binary files a/Shared/data/MTA San Andreas/server/x64/libssl-3-x64.dll and b/Shared/data/MTA San Andreas/server/x64/libssl-3-x64.dll differ diff --git a/Shared/data/launchers/CEFLauncher.exe b/Shared/data/launchers/CEFLauncher.exe index 62684b73d05..8ddad15d39e 100644 Binary files a/Shared/data/launchers/CEFLauncher.exe and b/Shared/data/launchers/CEFLauncher.exe differ diff --git a/Shared/data/launchers/MTA Server ARM64.exe b/Shared/data/launchers/MTA Server ARM64.exe index 1dba234e53b..f64006f3d81 100644 Binary files a/Shared/data/launchers/MTA Server ARM64.exe and b/Shared/data/launchers/MTA Server ARM64.exe differ diff --git a/Shared/data/launchers/MTA Server.exe b/Shared/data/launchers/MTA Server.exe index f89f45b7ef4..bc664aec899 100644 Binary files a/Shared/data/launchers/MTA Server.exe and b/Shared/data/launchers/MTA Server.exe differ diff --git a/Shared/data/launchers/MTA Server64.exe b/Shared/data/launchers/MTA Server64.exe index 0914af8aa5c..021e55401f8 100644 Binary files a/Shared/data/launchers/MTA Server64.exe and b/Shared/data/launchers/MTA Server64.exe differ diff --git a/Shared/data/launchers/Multi Theft Auto.exe b/Shared/data/launchers/Multi Theft Auto.exe index 3093964d55d..99fcb3c6bf6 100644 Binary files a/Shared/data/launchers/Multi Theft Auto.exe and b/Shared/data/launchers/Multi Theft Auto.exe differ diff --git a/Shared/data/launchers/wow64_helper.exe b/Shared/data/launchers/wow64_helper.exe index 38927395bb8..24a78f7abbf 100644 Binary files a/Shared/data/launchers/wow64_helper.exe and b/Shared/data/launchers/wow64_helper.exe differ diff --git a/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp b/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp index f632a1a237f..bd0383222be 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp +++ b/Shared/mods/deathmatch/logic/lua/CLuaTimer.cpp @@ -23,6 +23,7 @@ CLuaTimer::CLuaTimer(const CLuaFunctionRef& iLuaFunction, const CLuaArguments& A m_uiRepeats = 1; m_iLuaFunction = iLuaFunction; m_Arguments = Arguments; + m_paused = false; } CLuaTimer::~CLuaTimer() @@ -64,8 +65,30 @@ void CLuaTimer::ExecuteTimer(CLuaMain* pLuaMain) } } +void CLuaTimer::SetPaused(bool paused) +{ + if (paused == IsPaused()) + return; + + CTickCount llTimeRemaining = GetTimeLeft(); + if (paused) + { + m_pausedRemainingTime = llTimeRemaining.ToLongLong() == 0LL ? m_llDelay : llTimeRemaining; + } + else + { + CTickCount llCurrentTime = CTickCount::Now(); + CTickCount llNewStartTime = llCurrentTime - (m_llDelay - llTimeRemaining); + SetStartTime(llNewStartTime); + } + m_paused = paused; +} + CTickCount CLuaTimer::GetTimeLeft() { + if (IsPaused()) + return m_pausedRemainingTime; + CTickCount llCurrentTime = CTickCount::Now(); CTickCount llTimeLeft = m_llStartTime + m_llDelay - llCurrentTime; return llTimeLeft.ToLongLong() < 0LL ? CTickCount(0LL) : llTimeLeft; diff --git a/Shared/mods/deathmatch/logic/lua/CLuaTimer.h b/Shared/mods/deathmatch/logic/lua/CLuaTimer.h index 62bb3c97a53..9534c2c47f8 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaTimer.h +++ b/Shared/mods/deathmatch/logic/lua/CLuaTimer.h @@ -17,7 +17,7 @@ class CLuaTimer; #include "lua/LuaCommon.h" #include "lua/CLuaArguments.h" -#define LUA_TIMER_MIN_INTERVAL 0 +#define LUA_TIMER_MIN_INTERVAL 0 class CLuaTimer { @@ -35,6 +35,8 @@ class CLuaTimer unsigned int GetRepeats() const { return m_uiRepeats; }; void SetRepeats(unsigned int uiRepeats) { m_uiRepeats = uiRepeats; } + bool IsPaused() const noexcept { return m_paused; }; + void SetPaused(bool paused); void ExecuteTimer(class CLuaMain* pLuaMain); @@ -45,10 +47,12 @@ class CLuaTimer void SetLuaDebugInfo(const SLuaDebugInfo& luaDebugInfo) { m_LuaDebugInfo = luaDebugInfo; } private: + bool m_paused; CLuaFunctionRef m_iLuaFunction; CLuaArguments m_Arguments; CTickCount m_llStartTime; CTickCount m_llDelay; + CTickCount m_pausedRemainingTime; unsigned int m_uiRepeats; uint m_uiScriptID; SLuaDebugInfo m_LuaDebugInfo; diff --git a/Shared/sdk/SharedUtil.File.hpp b/Shared/sdk/SharedUtil.File.hpp index 351afa63c33..0a1cf56c7c1 100644 --- a/Shared/sdk/SharedUtil.File.hpp +++ b/Shared/sdk/SharedUtil.File.hpp @@ -156,11 +156,18 @@ bool SharedUtil::FileLoad(std::nothrow_t, const SString& filePath, SString& outB CloseHandle(handle); return true; +#else +#ifdef __APPLE__ + struct stat info; + + if (stat(filePath, &info) != 0) + return false; #else struct stat64 info; if (stat64(filePath, &info) != 0) return false; +#endif size_t fileSize = static_cast(info.st_size); diff --git a/Shared/sdk/SharedUtil.Misc.hpp b/Shared/sdk/SharedUtil.Misc.hpp index ed789460d1e..5697da49f49 100644 --- a/Shared/sdk/SharedUtil.Misc.hpp +++ b/Shared/sdk/SharedUtil.Misc.hpp @@ -36,8 +36,8 @@ #endif #endif -#ifdef __APPLE__ - #include "cpuid.h" +#if defined(__APPLE__) && !defined(__aarch64__) + #include #endif CCriticalSection CRefCountable::ms_CS; @@ -1834,6 +1834,8 @@ namespace SharedUtil return FnGetCurrentProcessorNumber(); return _GetCurrentProcessorNumberXP(); +#elif defined(__APPLE__) && defined(__aarch64__) + return -1; #elif defined(__APPLE__) // Hacked from https://stackoverflow.com/a/40398183/1517394 unsigned long cpu; diff --git a/Shared/sdk/net/bitstream.h b/Shared/sdk/net/bitstream.h index e4dc40adf2d..c6337f7af71 100644 --- a/Shared/sdk/net/bitstream.h +++ b/Shared/sdk/net/bitstream.h @@ -552,6 +552,10 @@ enum class eBitStreamVersion : unsigned short // 2024-05-31 BreakObject_Serverside, + // Add respawnObject and toggleObjectRespawn to serverside + // 2024-06-09 + RespawnObject_Serverside, + // Ped syncronization revision // 2024-06-16 PedSync_Revision, diff --git a/Shared/sdk/net/rpc_enums.h b/Shared/sdk/net/rpc_enums.h index e4ce53df298..a5fcdca509a 100644 --- a/Shared/sdk/net/rpc_enums.h +++ b/Shared/sdk/net/rpc_enums.h @@ -278,6 +278,8 @@ enum eElementRPCFunctions SET_WORLD_SPECIAL_PROPERTY, BREAK_OBJECT, + RESPAWN_OBJECT, + TOGGLE_OBJECT_RESPAWN, SET_PLAYER_SCRIPT_DEBUG_LEVEL, diff --git a/premake5.lua b/premake5.lua index 34dc2e37f45..c3375ad1e04 100644 --- a/premake5.lua +++ b/premake5.lua @@ -26,7 +26,7 @@ workspace "MTASA" configurations {"Debug", "Release", "Nightly"} if os.host() == "macosx" then - platforms { "x64" } + platforms { "x64", "arm64" } elseif os.host() == "windows" then platforms { "x86", "x64", "arm64" } else @@ -103,6 +103,10 @@ workspace "MTASA" defaultplatform "x86" end + filter { "system:macosx", "platforms:arm64" } + includedirs { "/opt/homebrew/include" } + libdirs { "/opt/homebrew/lib" } + filter {"system:windows", "configurations:Nightly", "kind:not StaticLib"} symbolspath "$(SolutionDir)Symbols\\$(Configuration)_$(Platform)\\$(ProjectName).pdb" diff --git a/utils/buildactions/install_cef.lua b/utils/buildactions/install_cef.lua index f01f92af475..194fcde4e6f 100644 --- a/utils/buildactions/install_cef.lua +++ b/utils/buildactions/install_cef.lua @@ -9,8 +9,8 @@ local CEF_URL_PREFIX = "https://cef-builds.spotifycdn.com/cef_binary_" local CEF_URL_SUFFIX = "_windows32_minimal.tar.bz2" -- Change here to update CEF version -local CEF_VERSION = "127.3.5+g114ea2a+chromium-127.0.6533.120" -local CEF_HASH = "ad91d535873bdd2b6f36135d42a383f92ab2f2959be33db0a6f0f4178cf49436" +local CEF_VERSION = "128.4.8+g88b5034+chromium-128.0.6613.114" +local CEF_HASH = "eb5a84db83b51f6d6be43e9bb7f8a557e86dd056a9a565251c28c301feb1c9ef" function make_cef_download_url() return CEF_URL_PREFIX..http.escapeUrlParam(CEF_VERSION)..CEF_URL_SUFFIX