From acd3fdd94a7a5493a8b186d327c764db9b33acb5 Mon Sep 17 00:00:00 2001 From: "sebajura1234@gmail.com" Date: Sat, 13 May 2023 19:32:18 +0200 Subject: [PATCH 1/3] dxDrawModel (cherry picked from commit 279c8ac549fd58168e7968b056338111edd9ff79) --- Client/game_sa/CModelInfoSA.cpp | 22 ++++++++++++++++++ Client/game_sa/CModelInfoSA.h | 3 +++ Client/game_sa/CWorldSA.cpp | 13 +++++++++++ Client/game_sa/gamesa_renderware.h | 2 ++ Client/game_sa/gamesa_renderware.hpp | 2 ++ Client/mods/deathmatch/logic/CClientGame.cpp | 5 ++++ .../logic/luadefs/CLuaDrawingDefs.cpp | 11 +++++++++ Client/multiplayer_sa/CMultiplayerSA.cpp | 23 ++++++++++++++++++- Client/sdk/game/CModelInfo.h | 2 ++ 9 files changed, 82 insertions(+), 1 deletion(-) diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 422a306501..ef19ea2012 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -2039,3 +2039,25 @@ bool CModelInfoSA::ForceUnload() return true; } + +bool CModelInfoSA::Render(CVector position) +{ + CBaseModelInfoSAInterface* pModelInfoSAInterface = GetInterface(); + RwObject* pRwObject = pModelInfoSAInterface->pRwObject; + // RwEngineInstance->dOpenDevice.fpRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, 100u); + RwFrame* pFrame = RpGetFrame(pRwObject); + RwFrameSetIdentity(pFrame); + RwFrameTranslate(pFrame, (RwV3d*)&position, TRANSFORM_INITIAL); + + if (pRwObject->type == RwObjectType::Atomic) + { + RpAtomic* pRpAtomic = reinterpret_cast(pRwObject); + pRpAtomic->renderCallback(pRpAtomic); + } + else + { + RpClump* pRpClump = reinterpret_cast(pRwObject); + RpClumpRender(pRpClump); + } + return true; +} diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index cf497e0747..7c79f1625c 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -451,6 +451,9 @@ class CModelInfoSA : public CModelInfo // Vehicle towing functions bool IsTowableBy(CModelInfo* towingModel) override; + // It can crash when called in wrong moment, be careful. Good moment is when all objects are rendered. + bool Render(CVector position); + private: void CopyStreamingInfoFromModel(ushort usCopyFromModelID); void RwSetSupportedUpgrades(RwFrame* parent, DWORD dwModel); diff --git a/Client/game_sa/CWorldSA.cpp b/Client/game_sa/CWorldSA.cpp index 291b90da66..5f299f7b7c 100644 --- a/Client/game_sa/CWorldSA.cpp +++ b/Client/game_sa/CWorldSA.cpp @@ -81,10 +81,23 @@ bool CWorldSA::ResetSurfaceInfo(short sSurfaceID) void HOOK_FallenPeds(); void HOOK_FallenCars(); +DWORD CONTINUE_HookDefaultRender = 0x7491C5; + +void _declspec(naked) HookDefaultRender() +{ + _asm + { + push esi + mov esi, [esp+4+4] + jmp CONTINUE_HookDefaultRender + } +} + void CWorldSA::InstallHooks() { HookInstall(0x565CB0, (DWORD)HOOK_FallenPeds, 5); HookInstall(0x565E80, (DWORD)HOOK_FallenCars, 5); + HookInstall(0x7491C0, (DWORD)HookDefaultRender, 5); } DWORD CONTINUE_CWorld_FallenPeds = 0x00565CBA; diff --git a/Client/game_sa/gamesa_renderware.h b/Client/game_sa/gamesa_renderware.h index e2f2d9a472..96bb48b3bc 100644 --- a/Client/game_sa/gamesa_renderware.h +++ b/Client/game_sa/gamesa_renderware.h @@ -69,6 +69,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); @@ -138,6 +139,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 2e5386095c..36bdfea851 100644 --- a/Client/game_sa/gamesa_renderware.hpp +++ b/Client/game_sa/gamesa_renderware.hpp @@ -40,6 +40,7 @@ void InitRwFunctions(eGameVersion version) RwTexDictionaryStreamWrite = (RwTexDictionaryStreamWrite_t)0x00804A30; rwD3D9NativeTextureRead = (rwD3D9NativeTextureRead_t)0x004CD820; RpPrtStdGlobalDataSetStreamEmbedded = (RpPrtStdGlobalDataSetStreamEmbedded_t)0x0041B350; + RpClumpRender = (RpClumpRender_t)0x00749B20; RpClumpRemoveAtomic = (RpClumpRemoveAtomic_t)0x0074A510; RpAtomicClone = (RpAtomicClone_t)0x00749EB0; RwTexDictionaryFindNamedTexture = (RwTexDictionaryFindNamedTexture_t)0x007F3A30; @@ -137,6 +138,7 @@ void InitRwFunctions(eGameVersion version) 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/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 29655566f7..b9ba7cad51 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -3687,6 +3687,11 @@ void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) void CClientGame::Render3DStuffHandler() { + auto modelInfo = g_pGame->GetModelInfo(1632); + if (!modelInfo->IsLoaded()) + return; + + modelInfo->Render(CVector(0,30,6.0f)); } void CClientGame::PreRenderSkyHandler() diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index 21abf7f403..6a6afaac23 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -19,6 +19,16 @@ #define MIN_CLIENT_REQ_DXSETRENDERTARGET_CALL_RESTRICTIONS "1.3.0-9.04431" extern bool g_bAllowAspectRatioAdjustment; +bool DxDrawModel3d(uint16_t usModel, CVector position) +{ + auto modelInfo = g_pGame->GetModelInfo(usModel); + if (!modelInfo->IsLoaded()) + return false; + + modelInfo->Render(position); + return true; +} + void CLuaDrawingDefs::LoadFunctions() { constexpr static const std::pair functions[]{ @@ -64,6 +74,7 @@ void CLuaDrawingDefs::LoadFunctions() {"dxSetAspectRatioAdjustmentEnabled", DxSetAspectRatioAdjustmentEnabled}, {"dxIsAspectRatioAdjustmentEnabled", DxIsAspectRatioAdjustmentEnabled}, {"dxSetTextureEdge", DxSetTextureEdge}, + {"dxDrawModel3d", ArgumentParser}, }; // Add functions diff --git a/Client/multiplayer_sa/CMultiplayerSA.cpp b/Client/multiplayer_sa/CMultiplayerSA.cpp index e4c40fc364..e79fb59015 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA.cpp @@ -301,6 +301,7 @@ const DWORD RETURN_Idle_CWorld_ProcessPedsAfterPreRender = 0x53EA08; #define HOOKPOS_CWeapon__TakePhotograph 0x73C26E #define HOOKPOS_CCollision__CheckCameraCollisionObjects 0x41AB8E +#define HOOKPOS_CRenderer__RenderFadingInEntities_MID 0x55320E CPed* pContextSwitchedPed = 0; CVector vecCenterOfWorld; @@ -548,6 +549,7 @@ void HOOK_CAutomobile__dmgDrawCarCollidingParticles(); void HOOK_CWeapon__TakePhotograph(); void HOOK_CCollision__CheckCameraCollisionObjects(); +void HOOK_CRenderer__RenderFadingInEntities_MID(); CMultiplayerSA::CMultiplayerSA() { @@ -785,6 +787,7 @@ void CMultiplayerSA::InitHooks() HookInstall(HOOKPOS_CWeapon__TakePhotograph, (DWORD)HOOK_CWeapon__TakePhotograph, 3 + 2); HookInstall(HOOKPOS_CCollision__CheckCameraCollisionObjects, (DWORD)HOOK_CCollision__CheckCameraCollisionObjects, 6 + 4); + HookInstall(HOOKPOS_CRenderer__RenderFadingInEntities_MID, (DWORD)HOOK_CRenderer__RenderFadingInEntities_MID, 5); // Disable GTA setting g_bGotFocus to false when we minimize MemSet((void*)ADDR_GotFocus, 0x90, pGameInterface->GetGameVersion() == VERSION_EU_10 ? 6 : 10); @@ -3086,7 +3089,7 @@ void _declspec(naked) HOOK_Render3DStuff() { pushad } - if (m_pRender3DStuffHandler) m_pRender3DStuffHandler(); + //if (m_pRender3DStuffHandler) m_pRender3DStuffHandler(); _asm { @@ -7112,6 +7115,24 @@ bool CanEntityCollideWithCamera(CEntitySAInterface* pEntity) return true; } +constexpr DWORD _Z17SetAmbientColoursv = 0x735D30; + +constexpr DWORD CONTINUE_CRenderer__RenderFadingInEntities_MID = 0x553213; +void _declspec(naked) HOOK_CRenderer__RenderFadingInEntities_MID() +{ + _asm { + call _Z17SetAmbientColoursv + pushad + } + + if (m_pRender3DStuffHandler) m_pRender3DStuffHandler(); + + _asm { + popad + jmp CONTINUE_CRenderer__RenderFadingInEntities_MID + } +} + void _declspec(naked) HOOK_CCollision__CheckCameraCollisionObjects() { _asm diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index c26042b9fd..3c1de97940 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -243,4 +243,6 @@ class CModelInfo virtual bool IsTowableBy(CModelInfo* towingModel) = 0; virtual unsigned int GetParentID() = 0; + + virtual bool Render(CVector position) = 0; }; From 3eb3d4f8d95245fe452b983973c440f49e9f4347 Mon Sep 17 00:00:00 2001 From: Sebastian Jura Date: Sun, 3 Sep 2023 17:06:33 +0200 Subject: [PATCH 2/3] make it work --- Client/game_sa/CModelInfoSA.cpp | 15 +++++--- Client/game_sa/CModelInfoSA.h | 2 +- Client/game_sa/gamesa_renderware.h | 2 ++ Client/game_sa/gamesa_renderware.hpp | 2 ++ Client/mods/deathmatch/logic/CClientGame.cpp | 36 ++++++++++++++++--- Client/mods/deathmatch/logic/CClientGame.h | 10 ++++++ .../logic/luadefs/CLuaDrawingDefs.cpp | 13 +++---- Client/sdk/game/CModelInfo.h | 3 +- 8 files changed, 67 insertions(+), 16 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index b6d9cb0de5..733f4a362b 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -2093,16 +2093,23 @@ bool CModelInfoSA::ForceUnload() return true; } -bool CModelInfoSA::Render(CVector position) +bool CModelInfoSA::Render(CMatrix& matrix) { CBaseModelInfoSAInterface* pModelInfoSAInterface = GetInterface(); RwObject* pRwObject = pModelInfoSAInterface->pRwObject; // RwEngineInstance->dOpenDevice.fpRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, 100u); RwFrame* pFrame = RpGetFrame(pRwObject); RwFrameSetIdentity(pFrame); - RwFrameTranslate(pFrame, (RwV3d*)&position, TRANSFORM_INITIAL); - - if (pRwObject->type == RwObjectType::Atomic) + 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); + RwFrameUpdateObjects(pFrame); + //RwFrameRotate(pFrame, &yaxis, rotation.fX, RwOpCombineType::rwCOMBINEREPLACE); + + if (pRwObject->type == RP_TYPE_ATOMIC) { RpAtomic* pRpAtomic = reinterpret_cast(pRwObject); pRpAtomic->renderCallback(pRpAtomic); diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index 3fe2541738..ed48c7a455 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -466,7 +466,7 @@ class CModelInfoSA : public CModelInfo bool IsTowableBy(CModelInfo* towingModel) override; // It can crash when called in wrong moment, be careful. Good moment is when all objects are rendered. - bool Render(CVector position); + bool Render(CMatrix& matrix); private: void CopyStreamingInfoFromModel(ushort usCopyFromModelID); diff --git a/Client/game_sa/gamesa_renderware.h b/Client/game_sa/gamesa_renderware.h index 96bb48b3bc..594c203b59 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)(); @@ -126,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) diff --git a/Client/game_sa/gamesa_renderware.hpp b/Client/game_sa/gamesa_renderware.hpp index 36bdfea851..a70ba53766 100644 --- a/Client/game_sa/gamesa_renderware.hpp +++ b/Client/game_sa/gamesa_renderware.hpp @@ -26,6 +26,7 @@ void InitRwFunctions(eGameVersion version) RwStreamSkip = (RwStreamSkip_t)0x007ECD40; // check RpClumpDestroy = (RpClumpDestroy_t)0x0074A360; RpClumpGetNumAtomics = (RpClumpGetNumAtomics_t)0x00749930; + RwFrameTransform = (RwFrameTransform_t)0x007F0F70; RwFrameTranslate = (RwFrameTranslate_t)0x007F0E70; RpClumpForAllAtomics = (RpClumpForAllAtomics_t)0x00749BC0; RwFrameAddChild = (RwFrameAddChild_t)0x007F0B40; @@ -124,6 +125,7 @@ void InitRwFunctions(eGameVersion version) 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; diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index bcd1d5f9a8..0d0653931f 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -3548,8 +3548,36 @@ void CClientGame::StaticGameRunNamedAnimDestructorHandler(class CTaskSimpleRunNa g_pClientGame->GameRunNamedAnimDestructorHandler(pTask); } +void CClientGame::EnqueueModelToRender(SModelToRender modelToRender) +{ + m_vecModelsToRender.push_back(modelToRender); +} + +void CClientGame::GameEntityRenderHandler(CEntitySAInterface* pGameEntity) +{ + if (m_vecModelsToRender.empty()) + return; + + for (auto& extraEntity : m_vecModelsToRender) + { + auto modelInfo = g_pGame->GetModelInfo(extraEntity.usModel); + if (modelInfo == nullptr) + continue; + if (!modelInfo->IsLoaded()) + modelInfo->Request(EModelRequestType::BLOCKING, "Lua::DxDrawModel3d"); + if (!modelInfo->IsLoaded()) + continue; + + modelInfo->Render(extraEntity.matrix); + } + + m_vecModelsToRender.clear(); +} + void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) { + g_pClientGame->GameEntityRenderHandler(pGameEntity); + if (pGameEntity) { CPools* pPools = g_pGame->GetPools(); @@ -3687,11 +3715,11 @@ void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) void CClientGame::Render3DStuffHandler() { - auto modelInfo = g_pGame->GetModelInfo(1632); - if (!modelInfo->IsLoaded()) - return; + //auto modelInfo = g_pGame->GetModelInfo(1632); + //if (!modelInfo->IsLoaded()) + // return; - modelInfo->Render(CVector(0,30,6.0f)); + //modelInfo->Render(CVector(0,30,6.0f)); } void CClientGame::PreRenderSkyHandler() diff --git a/Client/mods/deathmatch/logic/CClientGame.h b/Client/mods/deathmatch/logic/CClientGame.h index 7f06f6b3bb..2e4f73254c 100644 --- a/Client/mods/deathmatch/logic/CClientGame.h +++ b/Client/mods/deathmatch/logic/CClientGame.h @@ -71,6 +71,12 @@ struct SMiscGameSettings bool bAllowShotgunDamageFix; }; +struct SModelToRender +{ + uint16_t usModel; + CMatrix matrix; +}; + class CClientGame { friend class CPacketHandler; @@ -581,6 +587,7 @@ class CClientGame void TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId); AnimationId DrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId); void AudioZoneRadioSwitchHandler(DWORD dwStationID); + void GameEntityRenderHandler(CEntitySAInterface* pGameEntity); static bool StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); bool ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -633,6 +640,7 @@ class CClientGame void PedStepHandler(CPedSAInterface* pPed, bool bFoot); void VehicleWeaponHitHandler(SVehicleWeaponHitEvent& event); + void EnqueueModelToRender(SModelToRender modelToRender); private: eStatus m_Status; @@ -808,6 +816,8 @@ class CClientGame bool m_bShowCollision; bool m_bShowSound; + std::vector m_vecModelsToRender; + // Debug class. Empty in release. public: CFoo m_Foo; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index b2b5563106..e19db2907f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -19,13 +19,14 @@ #define MIN_CLIENT_REQ_DXSETRENDERTARGET_CALL_RESTRICTIONS "1.3.0-9.04431" extern bool g_bAllowAspectRatioAdjustment; -bool DxDrawModel3d(uint16_t usModel, CVector position) +bool DxDrawModel3d(uint16_t usModel, CVector position, CVector rotation, std::optional scale) { - auto modelInfo = g_pGame->GetModelInfo(usModel); - if (!modelInfo->IsLoaded()) - return false; - - modelInfo->Render(position); + SModelToRender modelToRender; + modelToRender.usModel = usModel; + ConvertDegreesToRadians(rotation); + CMatrix matrix(position, rotation, scale.value_or(CVector(1.0f, 1.0f, 1.0f))); + modelToRender.matrix = matrix; + g_pClientGame->EnqueueModelToRender(modelToRender); return true; } diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index c57f7a0582..5ce83d9768 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -18,6 +18,7 @@ class CBaseModelInfoSAInterface; class CColModel; class CPedModelInfo; +class CMatrix; struct RpClump; struct RwObject; @@ -247,5 +248,5 @@ class CModelInfo virtual unsigned int GetParentID() = 0; - virtual bool Render(CVector position) = 0; + virtual bool Render(CMatrix& transform) = 0; }; From f647159be65afc3b8213862c9574470721ad2939 Mon Sep 17 00:00:00 2001 From: Sebastian Jura Date: Sat, 14 Oct 2023 07:45:18 +0200 Subject: [PATCH 3/3] update --- Client/mods/deathmatch/logic/CClientGame.cpp | 2 +- Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index b5d6936b9f..6aad8d6aff 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -3575,7 +3575,7 @@ void CClientGame::GameEntityRenderHandler(CEntitySAInterface* pGameEntity) if (modelInfo == nullptr) continue; if (!modelInfo->IsLoaded()) - modelInfo->Request(EModelRequestType::BLOCKING, "Lua::DxDrawModel3d"); + modelInfo->Request(EModelRequestType::BLOCKING, "Lua::DxDrawModel3D"); if (!modelInfo->IsLoaded()) continue; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index e19db2907f..8ac3e1b381 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -19,8 +19,13 @@ #define MIN_CLIENT_REQ_DXSETRENDERTARGET_CALL_RESTRICTIONS "1.3.0-9.04431" extern bool g_bAllowAspectRatioAdjustment; -bool DxDrawModel3d(uint16_t usModel, CVector position, CVector rotation, std::optional scale) +bool DxDrawModel3D(uint16_t usModel, CVector position, CVector rotation, std::optional scale) { + CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModel); + if (pModelInfo->GetModelType() == eModelInfoType::VEHICLE || pModelInfo->GetModelType() == eModelInfoType::PED) + { + throw std::invalid_argument("Vehicle and Ped models are not allowed"); + } SModelToRender modelToRender; modelToRender.usModel = usModel; ConvertDegreesToRadians(rotation); @@ -75,7 +80,7 @@ void CLuaDrawingDefs::LoadFunctions() {"dxSetAspectRatioAdjustmentEnabled", DxSetAspectRatioAdjustmentEnabled}, {"dxIsAspectRatioAdjustmentEnabled", DxIsAspectRatioAdjustmentEnabled}, {"dxSetTextureEdge", DxSetTextureEdge}, - {"dxDrawModel3d", ArgumentParser}, + {"dxDrawModel3D", ArgumentParser}, }; // Add functions