diff --git a/MTA10/core/CGraphics.cpp b/MTA10/core/CGraphics.cpp index 9655f91d3d..bfb6516ccc 100644 --- a/MTA10/core/CGraphics.cpp +++ b/MTA10/core/CGraphics.cpp @@ -586,6 +586,9 @@ void CGraphics::DrawRectQueued ( float fX, float fY, bool CGraphics::DrawTextureQueued ( float fX, float fY, float fWidth, float fHeight, + float fU, float fV, + float fSizeU, float fSizeV, + bool bRelativeUV, const string& strFilename, float fRotation, float fRotCenOffX, @@ -600,13 +603,18 @@ bool CGraphics::DrawTextureQueued ( float fX, float fY, Item.Texture.fY = fY; Item.Texture.fWidth = fWidth; Item.Texture.fHeight = fHeight; - Item.Texture.texture = CacheTexture( strFilename ); + Item.Texture.fU = fU; + Item.Texture.fV = fV; + Item.Texture.fSizeU = fSizeU; + Item.Texture.fSizeV = fSizeV; + Item.Texture.bRelativeUV = bRelativeUV; + Item.Texture.info = CacheTexture( strFilename ); Item.Texture.fRotation = fRotation; Item.Texture.fRotCenOffX = fRotCenOffX; Item.Texture.fRotCenOffY = fRotCenOffY; Item.Texture.ulColor = ulColor; - if ( !Item.Texture.texture ) + if ( !Item.Texture.info.d3dTexture ) return false; // Add it to the queue @@ -892,7 +900,11 @@ void CGraphics::DrawQueue ( std::vector < sDrawQueueItem >& Queue ) { bSpriteMode = IsDrawQueueItemSprite ( *iter ); if ( bSpriteMode ) + { m_pDXSprite->Begin ( D3DXSPRITE_ALPHABLEND ); + m_pDevice->SetSamplerState ( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); + m_pDevice->SetSamplerState ( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); + } else m_pDXSprite->End (); } @@ -990,18 +1002,25 @@ void CGraphics::DrawQueueItem ( const sDrawQueueItem& Item ) } case QUEUE_TEXTURE: { - D3DSURFACE_DESC texureDesc; - Item.Texture.texture->GetLevelDesc( 0, &texureDesc ); - float texureWidth = texureDesc.Width; - float texureHeight = texureDesc.Height; - float fRotationRad = Item.Texture.fRotation * (6.2832f/360.f); + RECT cutImagePos; + const float fSurfaceWidth = Item.Texture.info.uiSurfaceWidth; + const float fSurfaceHeight = Item.Texture.info.uiSurfaceHeight; + const float fFileWidth = Item.Texture.info.uiFileWidth; + const float fFileHeight = Item.Texture.info.uiFileHeight; + cutImagePos.left = ( Item.Texture.fU ) * ( Item.Texture.bRelativeUV ? fSurfaceWidth : fSurfaceWidth / fFileWidth ); + cutImagePos.top = ( Item.Texture.fV ) * ( Item.Texture.bRelativeUV ? fSurfaceHeight : fSurfaceHeight / fFileHeight ); + cutImagePos.right = ( Item.Texture.fU + Item.Texture.fSizeU ) * ( Item.Texture.bRelativeUV ? fSurfaceWidth : fSurfaceWidth / fFileWidth ); + cutImagePos.bottom = ( Item.Texture.fV + Item.Texture.fSizeV ) * ( Item.Texture.bRelativeUV ? fSurfaceHeight : fSurfaceHeight / fFileHeight ); + const float fCutWidth = cutImagePos.right - cutImagePos.left; + const float fCutHeight = cutImagePos.bottom - cutImagePos.top; + const D3DXVECTOR2 scaling ( Item.Texture.fWidth / fCutWidth, Item.Texture.fHeight / fCutHeight ); + const D3DXVECTOR2 rotationCenter ( Item.Texture.fWidth * 0.5f + Item.Texture.fRotCenOffX, Item.Texture.fHeight * 0.5f + Item.Texture.fRotCenOffY ); + const D3DXVECTOR2 position ( Item.Texture.fX, Item.Texture.fY ); + const float fRotationRad = Item.Texture.fRotation * (6.2832f/360.f); D3DXMATRIX matrix; - D3DXVECTOR2 scaling ( Item.Texture.fWidth / texureWidth, Item.Texture.fHeight / texureHeight ); - D3DXVECTOR2 rotationCenter ( Item.Texture.fWidth * 0.5f + Item.Texture.fRotCenOffX, Item.Texture.fHeight * 0.5f + Item.Texture.fRotCenOffY ); - D3DXVECTOR2 position ( Item.Texture.fX, Item.Texture.fY ); D3DXMatrixTransformation2D ( &matrix, NULL, 0.0f, &scaling, &rotationCenter, fRotationRad, &position ); m_pDXSprite->SetTransform ( &matrix ); - m_pDXSprite->Draw ( Item.Texture.texture, NULL, NULL, NULL, Item.Texture.ulColor ); + m_pDXSprite->Draw ( Item.Texture.info.d3dTexture, &cutImagePos, NULL, NULL, Item.Texture.ulColor ); break; } // Circle type? @@ -1014,7 +1033,7 @@ void CGraphics::DrawQueueItem ( const sDrawQueueItem& Item ) // Cache a texture for current and future use. -IDirect3DTexture9* CGraphics::CacheTexture ( const string& strFilename ) +SCachedTextureInfo& CGraphics::CacheTexture ( const string& strFilename ) { // Find exisiting map < string, SCachedTextureInfo >::iterator iter = m_CachedTextureInfoMap.find ( strFilename ); @@ -1026,13 +1045,33 @@ IDirect3DTexture9* CGraphics::CacheTexture ( const string& strFilename ) iter = m_CachedTextureInfoMap.find ( strFilename ); SCachedTextureInfo& info = iter->second; - info.texture = LoadTexture( strFilename.c_str () ); + info.d3dTexture = LoadTexture( strFilename.c_str () ); + info.uiFileWidth = 1; + info.uiFileHeight = 1; + info.uiSurfaceWidth = 1; + info.uiSurfaceHeight = 1; + + if ( info.d3dTexture ) + { + D3DXIMAGE_INFO imageInfo; + if ( SUCCEEDED ( D3DXGetImageInfoFromFile( strFilename.c_str (), &imageInfo ) ) ) + { + info.uiFileWidth = imageInfo.Width; + info.uiFileHeight = imageInfo.Height; + } + D3DSURFACE_DESC surfaceDesc; + if ( SUCCEEDED ( info.d3dTexture->GetLevelDesc( 0, &surfaceDesc ) ) ) + { + info.uiSurfaceWidth = surfaceDesc.Width; + info.uiSurfaceHeight = surfaceDesc.Height; + } + } } SCachedTextureInfo& info = iter->second; info.ulTimeLastUsed = GetTickCount(); - return info.texture; + return info; } @@ -1053,7 +1092,7 @@ void CGraphics::ExpireCachedTextures ( bool bExpireAll ) unsigned long ulAge = GetTickCount() - info.ulTimeLastUsed; if ( ulAge > ulMaxAgeSeconds * 1000 || bExpireAll ) { - SAFE_RELEASE ( info.texture ); + SAFE_RELEASE ( info.d3dTexture ); iter = m_CachedTextureInfoMap.erase ( iter ); } else diff --git a/MTA10/core/CGraphics.h b/MTA10/core/CGraphics.h index faac379c5e..381cb60d45 100644 --- a/MTA10/core/CGraphics.h +++ b/MTA10/core/CGraphics.h @@ -26,6 +26,16 @@ class CGraphics; struct IDirect3DDevice9; struct IDirect3DSurface9; +struct SCachedTextureInfo +{ + IDirect3DTexture9* d3dTexture; + unsigned long ulTimeLastUsed; + unsigned int uiSurfaceWidth; + unsigned int uiSurfaceHeight; + unsigned int uiFileWidth; + unsigned int uiFileHeight; +}; + class CGraphics : public CGraphicsInterface, public CSingleton < CGraphics > { friend class CDirect3DEvents9; @@ -110,6 +120,9 @@ class CGraphics : public CGraphicsInterface, public CSingleton < CGraphics > bool DrawTextureQueued ( float fX, float fY, float fWidth, float fHeight, + float fU, float fV, + float fSizeU, float fSizeV, + bool bRelativeUV, const std::string& strFilename, float fRotation, float fRotCenOffX, @@ -135,7 +148,7 @@ class CGraphics : public CGraphicsInterface, public CSingleton < CGraphics > void OnDeviceCreate ( IDirect3DDevice9 * pDevice ); void OnDeviceInvalidate ( IDirect3DDevice9 * pDevice ); void OnDeviceRestore ( IDirect3DDevice9 * pDevice ); - IDirect3DTexture9* CacheTexture ( const std::string& strFilename ); + SCachedTextureInfo& CacheTexture ( const std::string& strFilename ); void ExpireCachedTextures ( bool bExpireAll = false ); ID3DXFont* GetBigFont ( ID3DXFont* pDXFont ); @@ -239,15 +252,20 @@ class CGraphics : public CGraphicsInterface, public CSingleton < CGraphics > struct sDrawQueueTexture { - IDirect3DTexture9* texture; + SCachedTextureInfo info; float fX; float fY; float fWidth; float fHeight; + float fU; + float fV; + float fSizeU; + float fSizeV; float fRotation; float fRotCenOffX; float fRotCenOffY; unsigned long ulColor; + bool bRelativeUV; }; struct sDrawQueueItem @@ -287,16 +305,7 @@ class CGraphics : public CGraphicsInterface, public CSingleton < CGraphics > // Drawing types struct ID3DXLine* m_pLineInterface; - - // Texures cached with DrawTextureQueued - struct SCachedTextureInfo - { - IDirect3DTexture9* texture; - unsigned long ulTimeLastUsed; - }; - std::map < std::string, SCachedTextureInfo > m_CachedTextureInfoMap; - }; #endif diff --git a/MTA10/game_sa/CGameSA.cpp b/MTA10/game_sa/CGameSA.cpp index afb6cf4a3a..b621e18d2d 100644 --- a/MTA10/game_sa/CGameSA.cpp +++ b/MTA10/game_sa/CGameSA.cpp @@ -10,6 +10,7 @@ * Cecill Etheredge * Stanislav Bobrov * Alberto Alonso +* Sebas Lamers * * Multi Theft Auto is available from http://www.multitheftauto.com/ * @@ -405,6 +406,9 @@ void CGameSA::Initialize ( void ) { // Initialize garages m_pGarages->Initialize(); + + // *Sebas* Hide the GTA:SA Main menu. + *(BYTE *)(CLASS_CMenu+0x5C) = 0; } eGameVersion CGameSA::GetGameVersion ( void ) diff --git a/MTA10/game_sa/CGameSA.h b/MTA10/game_sa/CGameSA.h index 6fe0846904..135bf9f1a4 100644 --- a/MTA10/game_sa/CGameSA.h +++ b/MTA10/game_sa/CGameSA.h @@ -10,6 +10,7 @@ * Cecill Etheredge * Stanislav Bobrov * Alberto Alonso +* Sebas Lamers * * Multi Theft Auto is available from http://www.multitheftauto.com/ * @@ -27,6 +28,7 @@ #define CLASS_CPad 0xB73458 // ##SA## #define CLASS_CGarages 0x96C048 // ##SA## #define CLASS_CFx 0xa9ae00 // ##SA## +#define CLASS_CMenu 0xBA6748 #define CLASS_RwCamera 0xB6F97C diff --git a/MTA10/gui/CGUIElement_Impl.cpp b/MTA10/gui/CGUIElement_Impl.cpp index 35509ed2a6..68cb84faa3 100644 --- a/MTA10/gui/CGUIElement_Impl.cpp +++ b/MTA10/gui/CGUIElement_Impl.cpp @@ -32,6 +32,9 @@ void CGUIElement_Impl::DestroyElement ( void ) { m_pManager->RemoveFromRedrawQueue ( reinterpret_cast < CGUIElement* > ( ( m_pWindow )->getUserData () ) ); + // Clear pointer back to this + m_pWindow->setUserData ( NULL ); + // Destroy the control m_pManager->GetWindowManager ()->destroyWindow ( m_pWindow ); diff --git a/MTA10/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/MTA10/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 7d0538ceb0..8c888a20e8 100644 --- a/MTA10/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/MTA10/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -301,9 +301,10 @@ bool CStaticFunctionDefinitions::GetElementRotation ( CClientEntity& Entity, CVe Ped.GetRotationDegrees ( vecRotation ); // Correct the rotation - vecRotation.fZ = 0.0f - vecRotation.fZ; + vecRotation.fZ = fmod( -vecRotation.fZ, 360); if ( vecRotation.fZ < 0 ) - vecRotation.fZ = vecRotation.fZ + 360; + vecRotation.fZ = 360 + vecRotation.fZ; + break; } case CCLIENTVEHICLE: diff --git a/MTA10/mods/shared_logic/CClientPed.cpp b/MTA10/mods/shared_logic/CClientPed.cpp index ee598e2d05..872b911928 100644 --- a/MTA10/mods/shared_logic/CClientPed.cpp +++ b/MTA10/mods/shared_logic/CClientPed.cpp @@ -543,12 +543,18 @@ void CClientPed::GetRotationRadians ( CVector& vecRotation ) const void CClientPed::SetRotationDegrees ( const CVector& vecRotation ) { // Convert from degrees to radians - float fTempRotation = vecRotation.fZ * 3.1415926535897932384626433832795f / 180.0f; + CVector vecTemp; + vecTemp.fX = vecRotation.fX * 3.1415926535897932384626433832795f / 180.0f; + vecTemp.fY = vecRotation.fY * 3.1415926535897932384626433832795f / 180.0f; + vecTemp.fZ = vecRotation.fZ * 3.1415926535897932384626433832795f / 180.0f; - // Set the rotation - SetCurrentRotation ( fTempRotation ); + // Set the rotation as radians + SetRotationRadians ( vecTemp ); + + // HACK: set again the z rotation to work on ground + SetCurrentRotation ( vecTemp.fZ ); if ( !IS_PLAYER ( this ) ) - SetCameraRotation ( fTempRotation ); + SetCameraRotation ( vecTemp.fZ ); } diff --git a/MTA10/mods/shared_logic/CClientSound.cpp b/MTA10/mods/shared_logic/CClientSound.cpp index 82aded483e..beb79ec16b 100644 --- a/MTA10/mods/shared_logic/CClientSound.cpp +++ b/MTA10/mods/shared_logic/CClientSound.cpp @@ -30,6 +30,7 @@ CClientSound::CClientSound ( CClientManager* pManager, ElementID ID ) : CClientE m_fVolume = 1.0f; m_fSpeed = 1.0f; m_fMinDistance = 2.0f; + m_fMaxDistance = 10.0f; m_usDimension = 0; m_b3D = false; } @@ -211,6 +212,7 @@ float CClientSound::GetMinDistance ( void ) void CClientSound::SetMaxDistance ( float fDistance ) { + m_fMaxDistance = fDistance; if ( m_pSound ) { m_pSound->setMaxDistance ( fDistance ); @@ -255,20 +257,19 @@ void CClientSound::Process3D ( CVector vecPosition, CVector vecLookAt ) // Volume float fDistance = DistanceBetweenPoints3D ( vecPosition, m_vecPosition ); - float fSilenceDistance = m_fMinDistance * 20.0f; float fVolume = 1.0; if ( fDistance <= m_fMinDistance ) { fVolume = 1.0f; } - else if ( fDistance >= fSilenceDistance ) + else if ( fDistance >= m_fMaxDistance ) { fVolume = 0.0f; } else { - float fLinear = (fSilenceDistance - fDistance) / fSilenceDistance; + float fLinear = (m_fMaxDistance - fDistance) / m_fMaxDistance; fVolume = sqrt ( fLinear ) * fLinear; } diff --git a/MTA10/mods/shared_logic/CClientSound.h b/MTA10/mods/shared_logic/CClientSound.h index a0183c53a0..a533d2f973 100644 --- a/MTA10/mods/shared_logic/CClientSound.h +++ b/MTA10/mods/shared_logic/CClientSound.h @@ -79,6 +79,7 @@ class CClientSound : public CClientEntity float m_fVolume; float m_fSpeed; float m_fMinDistance; + float m_fMaxDistance; CVector m_vecPosition; diff --git a/MTA10/mods/shared_logic/lua/CLuaArgument.cpp b/MTA10/mods/shared_logic/lua/CLuaArgument.cpp index 3dc25c5bd8..9325ae76ae 100644 --- a/MTA10/mods/shared_logic/lua/CLuaArgument.cpp +++ b/MTA10/mods/shared_logic/lua/CLuaArgument.cpp @@ -519,6 +519,7 @@ bool CLuaArgument::ReadFromBitStream ( NetBitStreamInterface& bitStream, std::ve m_pTableData = new CLuaArguments ( bitStream, pKnownTables ); m_bWeakTableRef = false; m_iType = LUA_TTABLE; + m_pTableData->ValidateTableKeys (); break; } diff --git a/MTA10/mods/shared_logic/lua/CLuaArguments.cpp b/MTA10/mods/shared_logic/lua/CLuaArguments.cpp index da9550cf66..c59a8eda3e 100644 --- a/MTA10/mods/shared_logic/lua/CLuaArguments.cpp +++ b/MTA10/mods/shared_logic/lua/CLuaArguments.cpp @@ -363,6 +363,42 @@ void CLuaArguments::DeleteArguments ( void ) } +void CLuaArguments::ValidateTableKeys ( void ) +{ + // Iterate over m_Arguments as pairs + // If first is LUA_TNIL, then remove pair + vector < CLuaArgument* > ::iterator iter = m_Arguments.begin (); + for ( ; iter != m_Arguments.end () ; ) + { + // Check first in pair + if ( (*iter)->GetType () == LUA_TNIL ) + { + // Remove pair + delete *iter; + iter = m_Arguments.erase ( iter ); + if ( iter != m_Arguments.end () ) + { + delete *iter; + iter = m_Arguments.erase ( iter ); + } + // Check if end + if ( iter == m_Arguments.end () ) + break; + } + else + { + // Skip second in pair + iter++; + // Check if end + if ( iter == m_Arguments.end () ) + break; + + iter++; + } + } +} + + bool CLuaArguments::ReadFromBitStream ( NetBitStreamInterface& bitStream, std::vector < CLuaArguments* > * pKnownTables ) { bool bKnownTablesCreated = false; diff --git a/MTA10/mods/shared_logic/lua/CLuaArguments.h b/MTA10/mods/shared_logic/lua/CLuaArguments.h index 98cd5797f6..f8d5d52ce0 100644 --- a/MTA10/mods/shared_logic/lua/CLuaArguments.h +++ b/MTA10/mods/shared_logic/lua/CLuaArguments.h @@ -73,6 +73,7 @@ class CLuaArguments bool ReadFromBitStream ( NetBitStreamInterface& bitStream, std::vector < CLuaArguments* > * pKnownTables = NULL ); bool WriteToBitStream ( NetBitStreamInterface& bitStream, std::map < CLuaArguments*, unsigned long > * pKnownTables = NULL ) const; + void ValidateTableKeys ( void ); unsigned int Count ( void ) const { return static_cast < unsigned int > ( m_Arguments.size () ); }; std::vector < CLuaArgument* > ::const_iterator IterBegin ( void ) { return m_Arguments.begin (); }; diff --git a/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Drawing.cpp b/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Drawing.cpp index 11eed0d5d9..d9ee6fb4d2 100644 --- a/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Drawing.cpp +++ b/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Drawing.cpp @@ -361,7 +361,7 @@ int CLuaFunctionDefs::dxDrawImage ( lua_State* luaVM ) // Get the correct directory SString strPath; if ( CResourceManager::ParseResourcePathInput( szFile, pResource, strPath ) && - g_pCore->GetGraphics ()->DrawTextureQueued ( fX, fY, fWidth, fHeight, strPath, fRotation, fRotCenOffX, fRotCenOffY, ulColor, bPostGUI ) ) + g_pCore->GetGraphics ()->DrawTextureQueued ( fX, fY, fWidth, fHeight, 0, 0, 1, 1, true, strPath, fRotation, fRotCenOffX, fRotCenOffY, ulColor, bPostGUI ) ) { // Success lua_pushboolean ( luaVM, true ); @@ -380,6 +380,105 @@ int CLuaFunctionDefs::dxDrawImage ( lua_State* luaVM ) } +int CLuaFunctionDefs::dxDrawImageSection ( lua_State* luaVM ) +{ + // dxDrawImageSection ( float x,float y,float width,float height,float u, float v, float usize, float vsize, filename,[float rotation=0, + // float rotCenOffX=0, float rotCenOffY=0, int color=0xffffffff, bool postgui=false] ) + + + // Grab all argument types + int iArgument1 = lua_type ( luaVM, 1 ); + int iArgument2 = lua_type ( luaVM, 2 ); + int iArgument3 = lua_type ( luaVM, 3 ); + int iArgument4 = lua_type ( luaVM, 4 ); + int iArgument5 = lua_type ( luaVM, 5 ); + int iArgument6 = lua_type ( luaVM, 6 ); + int iArgument7 = lua_type ( luaVM, 7 ); + int iArgument8 = lua_type ( luaVM, 8 ); + int iArgument9 = lua_type ( luaVM, 9 ); + if ( ( iArgument1 == LUA_TNUMBER || iArgument1 == LUA_TSTRING ) && + ( iArgument2 == LUA_TNUMBER || iArgument2 == LUA_TSTRING ) && + ( iArgument3 == LUA_TNUMBER || iArgument3 == LUA_TSTRING ) && + ( iArgument4 == LUA_TNUMBER || iArgument4 == LUA_TSTRING ) && + ( iArgument5 == LUA_TNUMBER || iArgument5 == LUA_TSTRING ) && + ( iArgument6 == LUA_TNUMBER || iArgument6 == LUA_TSTRING ) && + ( iArgument7 == LUA_TNUMBER || iArgument7 == LUA_TSTRING ) && + ( iArgument8 == LUA_TNUMBER || iArgument8 == LUA_TSTRING ) && + ( iArgument9 == LUA_TSTRING ) ) + { + float fX = static_cast < float > ( lua_tonumber ( luaVM, 1 ) ); + float fY = static_cast < float > ( lua_tonumber ( luaVM, 2 ) ); + float fWidth = static_cast < float > ( lua_tonumber ( luaVM, 3 ) ); + float fHeight = static_cast < float > ( lua_tonumber ( luaVM, 4 ) ); + float fU = static_cast < float > ( lua_tonumber ( luaVM, 5 ) ); + float fV = static_cast < float > ( lua_tonumber ( luaVM, 6 ) ); + float fSizeU = static_cast < float > ( lua_tonumber ( luaVM, 7 ) ); + float fSizeV = static_cast < float > ( lua_tonumber ( luaVM, 8 ) ); + const char * szFile = lua_tostring ( luaVM, 9 ); + float fRotation = 0; + float fRotCenOffX = 0; + float fRotCenOffY = 0; + unsigned long ulColor = 0xFFFFFFFF; + + int iArgument10 = lua_type ( luaVM, 10 ); + if ( ( iArgument10 == LUA_TNUMBER || iArgument10 == LUA_TSTRING ) ) + { + fRotation = static_cast < float > ( lua_tonumber ( luaVM, 10 ) ); + } + + int iArgument11 = lua_type ( luaVM, 11 ); + if ( ( iArgument11 == LUA_TNUMBER || iArgument11 == LUA_TSTRING ) ) + { + fRotCenOffX = static_cast < float > ( lua_tonumber ( luaVM, 11 ) ); + } + + int iArgument12 = lua_type ( luaVM, 12 ); + if ( ( iArgument12 == LUA_TNUMBER || iArgument12 == LUA_TSTRING ) ) + { + fRotCenOffY = static_cast < float > ( lua_tonumber ( luaVM, 12 ) ); + } + + int iArgument13 = lua_type ( luaVM, 13 ); + if ( ( iArgument13 == LUA_TNUMBER || iArgument13 == LUA_TSTRING ) ) + { + ulColor = static_cast < unsigned long > ( lua_tonumber ( luaVM, 13 ) ); + } + + // Got a post gui specifier? + bool bPostGUI = false; + int iArgument14 = lua_type ( luaVM, 14 ); + if ( iArgument14 == LUA_TBOOLEAN ) + { + bPostGUI = ( lua_toboolean ( luaVM, 14 ) ) ? true:false; + } + + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); + CResource* pResource = pLuaMain ? pLuaMain->GetResource() : NULL; + + // Check for a valid (and sane) file path + if ( pResource && szFile ) + { + // Get the correct directory + SString strPath; + if ( CResourceManager::ParseResourcePathInput( szFile, pResource, strPath ) && + g_pCore->GetGraphics ()->DrawTextureQueued ( fX, fY, fWidth, fHeight, fU, fV, fSizeU, fSizeV, false, strPath, fRotation, fRotCenOffX, fRotCenOffY, ulColor, bPostGUI ) ) + { + // Success + lua_pushboolean ( luaVM, true ); + return 1; + } + + m_pScriptDebugging->LogError ( luaVM, "dxDrawImageSection can't load %s", szFile ); + } + } + else + m_pScriptDebugging->LogBadType ( luaVM, "dxDrawImageSection" ); + + // Failed + lua_pushboolean ( luaVM, false ); + return 1; +} + int CLuaFunctionDefs::dxGetTextWidth ( lua_State* luaVM ) { diff --git a/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Projectile.cpp b/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Projectile.cpp index 3a787dbd2a..b0d6009f55 100644 --- a/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Projectile.cpp +++ b/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Projectile.cpp @@ -153,7 +153,7 @@ int CLuaFunctionDefs::GetProjectileType ( lua_State* luaVM ) return 1; } else - m_pScriptDebugging->LogBadPointer ( luaVM, "getProjectileType", "pickup", 1 ); + m_pScriptDebugging->LogBadPointer ( luaVM, "getProjectileType", "projectile", 1 ); } else m_pScriptDebugging->LogBadType ( luaVM, "getProjectileType" ); @@ -162,6 +162,69 @@ int CLuaFunctionDefs::GetProjectileType ( lua_State* luaVM ) return 1; } +int CLuaFunctionDefs::GetProjectileTarget ( lua_State* luaVM ) +{ + // Verify the argument + if ( lua_type ( luaVM, 1 ) == LUA_TLIGHTUSERDATA ) + { + CClientProjectile* pProjectile = lua_toprojectile ( luaVM, 1 ); + if ( pProjectile ) + { + unsigned char ucWeapon = pProjectile->GetWeaponType(); + if (ucWeapon == WEAPONTYPE_ROCKET_HS) + { + lua_pushelement ( luaVM, pProjectile->GetTargetEntity() ); + return 1; + } + } + else + m_pScriptDebugging->LogBadPointer ( luaVM, "getProjectileTarget", "projectile", 1 ); + } + else + m_pScriptDebugging->LogBadType ( luaVM, "getProjectileTarget" ); + lua_pushboolean ( luaVM, false ); + return 1; +} +int CLuaFunctionDefs::GetProjectileCreator ( lua_State* luaVM ) +{ + // Verify the argument + if ( lua_type ( luaVM, 1 ) == LUA_TLIGHTUSERDATA ) + { + CClientProjectile* pProjectile = lua_toprojectile ( luaVM, 1 ); + if ( pProjectile ) + { + lua_pushelement ( luaVM, pProjectile->GetCreator() ); + return 1; + } + else + m_pScriptDebugging->LogBadPointer ( luaVM, "getProjectileCreator", "projectile", 1 ); + } + else + m_pScriptDebugging->LogBadType ( luaVM, "getProjectileCreator" ); + + lua_pushboolean ( luaVM, false ); + return 1; +} +int CLuaFunctionDefs::GetProjectileForce ( lua_State* luaVM ) +{ + // Verify the argument + if ( lua_type ( luaVM, 1 ) == LUA_TLIGHTUSERDATA ) + { + CClientProjectile* pProjectile = lua_toprojectile ( luaVM, 1 ); + if ( pProjectile ) + { + lua_pushnumber ( luaVM, static_cast < lua_Number > ( pProjectile->GetForce() ) ); + return 1; + } + else + m_pScriptDebugging->LogBadPointer ( luaVM, "getProjectileForce", "projectile", 1 ); + } + else + m_pScriptDebugging->LogBadType ( luaVM, "getProjectileForce" ); + + lua_pushboolean ( luaVM, false ); + return 1; +} diff --git a/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Util.cpp b/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Util.cpp index 29d9842230..d15c2deb09 100644 --- a/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Util.cpp +++ b/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Util.cpp @@ -233,6 +233,27 @@ int CLuaFunctionDefs::IsTimer ( lua_State* luaVM ) return 1; } +int CLuaFunctionDefs::GetTimerDetails ( lua_State* luaVM ) +{ + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); + if ( pLuaMain ) + { + CLuaTimer* pLuaTimer = lua_totimer ( luaVM, 1 ); + if ( pLuaTimer ) + { + lua_pushnumber( luaVM, pLuaTimer->GetTimeLeft () ); + lua_pushnumber( luaVM, pLuaTimer->GetRepeats () ); + lua_pushnumber( luaVM, pLuaTimer->GetDelay () ); + return 3; + } + else + m_pScriptDebugging->LogBadType ( luaVM, "getTimerDetails" ); + } + + lua_pushboolean ( luaVM, false ); + return 1; +} + int CLuaFunctionDefs::GetTickCount_ ( lua_State* luaVM ) { diff --git a/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.h b/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.h index fa1ac48fd0..4e90078b5c 100644 --- a/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.h +++ b/MTA10/mods/shared_logic/lua/CLuaFunctionDefs.h @@ -451,6 +451,7 @@ class CLuaFunctionDefs LUA_DECLARE ( dxDrawText ); LUA_DECLARE ( dxDrawRectangle ); LUA_DECLARE ( dxDrawImage ); + LUA_DECLARE ( dxDrawImageSection ); LUA_DECLARE ( dxGetTextWidth ); LUA_DECLARE ( dxGetFontHeight ); @@ -463,6 +464,7 @@ class CLuaFunctionDefs LUA_DECLARE ( ResetTimer ); LUA_DECLARE ( GetTimers ); LUA_DECLARE ( IsTimer ); + LUA_DECLARE ( GetTimerDetails ); LUA_DECLARE ( GetTickCount_ ); LUA_DECLARE ( GetCTime ); LUA_DECLARE ( tocolor ); @@ -654,6 +656,9 @@ class CLuaFunctionDefs // Projectile funcs LUA_DECLARE ( CreateProjectile ); LUA_DECLARE ( GetProjectileType ); + LUA_DECLARE ( GetProjectileTarget ); + LUA_DECLARE ( GetProjectileCreator ); + LUA_DECLARE ( GetProjectileForce ); // Shape create funcs LUA_DECLARE ( CreateColCircle ); diff --git a/MTA10/mods/shared_logic/lua/CLuaManager.cpp b/MTA10/mods/shared_logic/lua/CLuaManager.cpp index 804e371369..86bfc43518 100644 --- a/MTA10/mods/shared_logic/lua/CLuaManager.cpp +++ b/MTA10/mods/shared_logic/lua/CLuaManager.cpp @@ -554,6 +554,7 @@ void CLuaManager::LoadCFunctions ( void ) CLuaCFunctions::AddFunction ( "dxDrawText", CLuaFunctionDefs::dxDrawText ); CLuaCFunctions::AddFunction ( "dxDrawRectangle", CLuaFunctionDefs::dxDrawRectangle ); CLuaCFunctions::AddFunction ( "dxDrawImage", CLuaFunctionDefs::dxDrawImage ); + CLuaCFunctions::AddFunction ( "dxDrawImageSection", CLuaFunctionDefs::dxDrawImageSection ); CLuaCFunctions::AddFunction ( "dxGetTextWidth", CLuaFunctionDefs::dxGetTextWidth ); CLuaCFunctions::AddFunction ( "dxGetFontHeight", CLuaFunctionDefs::dxGetFontHeight ); @@ -761,6 +762,7 @@ void CLuaManager::LoadCFunctions ( void ) CLuaCFunctions::AddFunction ( "killTimer", CLuaFunctionDefs::KillTimer ); CLuaCFunctions::AddFunction ( "getTimers", CLuaFunctionDefs::GetTimers ); CLuaCFunctions::AddFunction ( "isTimer", CLuaFunctionDefs::IsTimer ); + CLuaCFunctions::AddFunction ( "getTimerDetails", CLuaFunctionDefs::GetTimerDetails ); CLuaCFunctions::AddFunction ( "getTickCount", CLuaFunctionDefs::GetTickCount_ ); CLuaCFunctions::AddFunction ( "getRealTime", CLuaFunctionDefs::GetCTime ); CLuaCFunctions::AddFunction ( "tocolor", CLuaFunctionDefs::tocolor ); @@ -850,6 +852,9 @@ void CLuaManager::LoadCFunctions ( void ) // Projectile funcs CLuaCFunctions::AddFunction ( "createProjectile", CLuaFunctionDefs::CreateProjectile ); CLuaCFunctions::AddFunction ( "getProjectileType", CLuaFunctionDefs::GetProjectileType ); + CLuaCFunctions::AddFunction ( "getProjectileTarget", CLuaFunctionDefs::GetProjectileTarget ); + CLuaCFunctions::AddFunction ( "getProjectileCreator", CLuaFunctionDefs::GetProjectileCreator ); + CLuaCFunctions::AddFunction ( "getProjectileForce", CLuaFunctionDefs::GetProjectileForce ); // Shape create funcs CLuaCFunctions::AddFunction ( "createColCircle", CLuaFunctionDefs::CreateColCircle ); diff --git a/MTA10/mods/shared_logic/lua/CLuaTimer.cpp b/MTA10/mods/shared_logic/lua/CLuaTimer.cpp index fdbe661e4c..74e13c0bf7 100644 --- a/MTA10/mods/shared_logic/lua/CLuaTimer.cpp +++ b/MTA10/mods/shared_logic/lua/CLuaTimer.cpp @@ -48,3 +48,11 @@ void CLuaTimer::ExecuteTimer ( CLuaMain* pLuaMain ) if ( m_iLuaFunction != LUA_REFNIL && m_pArguments ) m_pArguments->Call ( pLuaMain, m_iLuaFunction ); } + + +unsigned long CLuaTimer::GetTimeLeft ( void ) +{ + unsigned long ulCurrentTime = timeGetTime (); + unsigned long ulTimeLeft = m_ulStartTime + m_ulDelay - ulCurrentTime; + return ulTimeLeft; +} diff --git a/MTA10/mods/shared_logic/lua/CLuaTimer.h b/MTA10/mods/shared_logic/lua/CLuaTimer.h index 629866cd2a..709e49a7b7 100644 --- a/MTA10/mods/shared_logic/lua/CLuaTimer.h +++ b/MTA10/mods/shared_logic/lua/CLuaTimer.h @@ -46,6 +46,8 @@ class CLuaTimer void ExecuteTimer ( class CLuaMain* pLuaMain ); + unsigned long GetTimeLeft ( void ); + inline bool IsBeingDeleted ( void ) { return m_bBeingDeleted; } inline void SetBeingDeleted ( bool bBeingDeleted ) { m_bBeingDeleted = bBeingDeleted; } private: diff --git a/MTA10/multiplayer_sa/CMultiplayerSA.cpp b/MTA10/multiplayer_sa/CMultiplayerSA.cpp index 8654f5612e..2cd6d3ae3f 100644 --- a/MTA10/multiplayer_sa/CMultiplayerSA.cpp +++ b/MTA10/multiplayer_sa/CMultiplayerSA.cpp @@ -11,6 +11,7 @@ * Stanislav Bobrov * Alberto Alonso * Peter <> +* Sebas Lamers * * Multi Theft Auto is available from http://www.multitheftauto.com/ * @@ -1017,6 +1018,12 @@ void CMultiplayerSA::InitHooks() // Allow all screen aspect ratios in multi-monitor dialog *(WORD *)0x7459E1 = 0x9090; + + // Show the GTA:SA Main menu, this fixes some issues (#4374 and MAYBE #4000). + // We are hiding the menu in "void CGameSA::Initialize ( void )". + // + // - Sebas + *(BYTE *)((0xBA6748)+0x5C) = 1; } @@ -1100,7 +1107,7 @@ CShotSyncData * CMultiplayerSA::GetLocalShotSyncData ( ) return GetLocalPedShotSyncData(); } -void CMultiplayerSA::DisablePadHandler( bool bDisabled ) +void CMultiplayerSA::DisablePadHandler ( bool bDisabled ) { // DISABLE GAMEPADS (testing) if ( bDisabled ) diff --git a/MTA10/sdk/core/CGraphicsInterface.h b/MTA10/sdk/core/CGraphicsInterface.h index 3d2650210b..b273458700 100644 --- a/MTA10/sdk/core/CGraphicsInterface.h +++ b/MTA10/sdk/core/CGraphicsInterface.h @@ -97,6 +97,9 @@ class CGraphicsInterface virtual bool DrawTextureQueued ( float fX, float fY, float fWidth, float fHeight, + float fU, float fV, + float fSizeU, float fSizeV, + bool bRelativeUV, const std::string& strFilename, float fRotation, float fRotCenOffX, diff --git a/MTA10_Server/mods/deathmatch/logic/ASE.cpp b/MTA10_Server/mods/deathmatch/logic/ASE.cpp index 0b9ed01731..018cd322d9 100644 --- a/MTA10_Server/mods/deathmatch/logic/ASE.cpp +++ b/MTA10_Server/mods/deathmatch/logic/ASE.cpp @@ -250,7 +250,7 @@ std::string ASE::QueryFull ( void ) // skin (skip) reply << ( unsigned char ) 1; // score - const std::string& strScore = pPlayer->GetAnnounceValue ( "Score" ); + const std::string& strScore = pPlayer->GetAnnounceValue ( "score" ); reply << ( unsigned char ) ( strScore.length () + 1 ); reply << strScore.c_str (); // ping diff --git a/MTA10_Server/mods/deathmatch/logic/CGame.cpp b/MTA10_Server/mods/deathmatch/logic/CGame.cpp index 406d8805da..dd3929d0bc 100644 --- a/MTA10_Server/mods/deathmatch/logic/CGame.cpp +++ b/MTA10_Server/mods/deathmatch/logic/CGame.cpp @@ -449,10 +449,10 @@ bool CGame::Start ( int iArgumentCount, char* szArguments [] ) "= Multi Theft Auto: San Andreas v%s\n" \ "===========================================================\n" \ "= Server name : %s\n" \ - "= Server IP address : %s\n" \ + "= Server IP address: %s\n" \ "= Server port : %u\n" \ "= \n" \ - "= Log file : %s\n" \ + "= Log file : %s\n" \ "= Maximum players : %u\n" \ "= MTU packet size : %u\n" \ "= HTTP port : %u\n" \ diff --git a/MTA10_Server/mods/deathmatch/logic/CPedSync.cpp b/MTA10_Server/mods/deathmatch/logic/CPedSync.cpp index 0b4ee9a5c6..1640566008 100644 --- a/MTA10_Server/mods/deathmatch/logic/CPedSync.cpp +++ b/MTA10_Server/mods/deathmatch/logic/CPedSync.cpp @@ -26,7 +26,7 @@ CPedSync::CPedSync ( CPlayerManager* pPlayerManager, CPedManager* pPedManager ) void CPedSync::DoPulse ( void ) { - // Time to check for players that should no longer be syncing a vehicle or vehicles that should be synced? + // Time to check for players that should no longer be syncing a ped or peds that should be synced? unsigned long ulCurrentTime = GetTime (); if ( ulCurrentTime >= m_ulLastSweepTime + 500 ) { @@ -71,7 +71,7 @@ void CPedSync::Update ( unsigned long ulCurrentTime ) for ( ; iter != m_pPedManager->IterEnd (); iter++ ) { // It is a ped, yet not a player - if ( IS_PED ( *iter ) && !IS_PLAYER ( *iter ) && ( *iter )->IsSyncable() ) + if ( IS_PED ( *iter ) && !IS_PLAYER ( *iter ) ) UpdatePed ( *iter ); } } @@ -81,10 +81,22 @@ void CPedSync::UpdatePed ( CPed* pPed ) { CPlayer* pSyncer = pPed->GetSyncer (); - // This vehicle got a syncer? + // Handle no syncing + if ( !pPed->IsSyncable () ) + { + // This ped got a syncer? + if ( pSyncer ) + { + // Tell the syncer to stop syncing + StopSync ( pPed ); + } + return; + } + + // This ped got a syncer? if ( pSyncer ) { - // He isn't close enough to the vehicle and in the right dimension? + // He isn't close enough to the ped and in the right dimension? if ( ( !IsPointNearPoint3D ( pSyncer->GetPosition (), pPed->GetPosition (), MAX_PLAYER_SYNC_DISTANCE ) ) || ( pPed->GetDimension () != pSyncer->GetDimension () ) ) { @@ -105,6 +117,8 @@ void CPedSync::UpdatePed ( CPed* pPed ) void CPedSync::FindSyncer ( CPed* pPed ) { + assert ( pPed->IsSyncable () ); + // Find a player close enough to him CPlayer* pPlayer = FindPlayerCloseToPed ( pPed, MAX_PLAYER_SYNC_DISTANCE - 20.0f ); if ( pPlayer ) @@ -117,6 +131,9 @@ void CPedSync::FindSyncer ( CPed* pPed ) void CPedSync::StartSync ( CPlayer* pPlayer, CPed* pPed ) { + if ( !pPed->IsSyncable () ) + return; + // Tell the player pPlayer->Send ( CPedStartSyncPacket ( pPed ) ); diff --git a/MTA10_Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/MTA10_Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index c5ea0aef2c..c44ae6ddff 100644 --- a/MTA10_Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/MTA10_Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -779,13 +779,13 @@ CElement* CStaticFunctionDefinitions::GetElementSyncer ( CElement* pElement ) case CElement::PED: { CPed* pPed = static_cast < CPed* > ( pElement ); - return static_cast < CElement* > ( pPed->GetSyncer() ); + return pPed->IsSyncable () ? static_cast < CElement* > ( pPed->GetSyncer() ) : NULL; break; } case CElement::VEHICLE: { CVehicle* pVehicle = static_cast < CVehicle* > ( pElement ); - return static_cast < CElement* > ( pVehicle->GetSyncer() ); + return pVehicle->IsUnoccupiedSyncable () ? static_cast < CElement* > ( pVehicle->GetSyncer() ) : NULL; break; } } @@ -1491,6 +1491,33 @@ bool CStaticFunctionDefinitions::ClearElementVisibleTo ( CElement* pElement ) return true; } +bool CStaticFunctionDefinitions::SetElementSyncer ( CElement* pElement, CPlayer* pPlayer, bool bEnable ) +{ + assert ( pElement ); + + switch ( pElement->GetType () ) + { + case CElement::PED: + { + CPed* pPed = static_cast < CPed* > ( pElement ); + pPed->SetSyncable ( bEnable ); + g_pGame->GetPedSync()->OverrideSyncer ( pPed, pPlayer ); + return true; + break; + } + case CElement::VEHICLE: + { + CVehicle* pVehicle = static_cast < CVehicle* > ( pElement ); + pVehicle->SetUnoccupiedSyncable ( bEnable ); + g_pGame->GetUnoccupiedVehicleSync()->OverrideSyncer ( pVehicle, pPlayer ); + return true; + break; + } + default: return false; + } + return false; +} + bool CStaticFunctionDefinitions::GetPlayerName ( CElement* pElement, char* szNick ) { diff --git a/MTA10_Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/MTA10_Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h index dd69c55405..058e9acdf9 100644 --- a/MTA10_Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/MTA10_Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -92,6 +92,7 @@ class CStaticFunctionDefinitions static bool SetElementHealth ( CElement* pElement, float fHealth ); static bool SetElementModel ( CElement* pElement, unsigned short usModel ); static bool SetElementAttachedOffsets ( CElement* pElement, CVector & vecPosition, CVector & vecRotation ); + static bool SetElementSyncer ( CElement* pElement, CPlayer* pPlayer, bool bEnable = true ); // Scoreboard static bool AddScoreboardColumn ( const char* szID, const char* szName, float fWidth ); diff --git a/MTA10_Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp b/MTA10_Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp index 23402cc7a5..c029cecafb 100644 --- a/MTA10_Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp +++ b/MTA10_Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp @@ -85,6 +85,18 @@ void CUnoccupiedVehicleSync::UpdateVehicle ( CVehicle* pVehicle ) CPlayer* pSyncer = pVehicle->GetSyncer (); CPed* pController = pVehicle->GetController (); + // Handle no syncing when not occupied + if ( !pVehicle->IsUnoccupiedSyncable () ) + { + // This vehicle got a syncer? + if ( pSyncer ) + { + // Tell the syncer to stop syncing + StopSync ( pVehicle ); + } + return; + } + // If someones driving it, or its being towed by someone driving (and not just entering/exiting) if ( pController && IS_PLAYER ( pController ) && pController->GetVehicleAction () == CPlayer::VEHICLEACTION_NONE ) { @@ -122,6 +134,8 @@ void CUnoccupiedVehicleSync::UpdateVehicle ( CVehicle* pVehicle ) void CUnoccupiedVehicleSync::FindSyncer ( CVehicle* pVehicle ) { + assert ( pVehicle->IsUnoccupiedSyncable () ); + // This vehicle got any passengers? CPed* pPassenger = pVehicle->GetFirstOccupant (); if ( pPassenger && IS_PLAYER ( pPassenger ) && !pPassenger->IsBeingDeleted() ) @@ -144,6 +158,9 @@ void CUnoccupiedVehicleSync::FindSyncer ( CVehicle* pVehicle ) void CUnoccupiedVehicleSync::StartSync ( CPlayer* pPlayer, CVehicle* pVehicle ) { + if ( !pVehicle->IsUnoccupiedSyncable () ) + return; + // Tell the player pPlayer->Send ( CUnoccupiedVehicleStartSyncPacket ( pVehicle ) ); diff --git a/MTA10_Server/mods/deathmatch/logic/CVehicle.cpp b/MTA10_Server/mods/deathmatch/logic/CVehicle.cpp index 996367d2da..cbb1d1b335 100644 --- a/MTA10_Server/mods/deathmatch/logic/CVehicle.cpp +++ b/MTA10_Server/mods/deathmatch/logic/CVehicle.cpp @@ -35,6 +35,7 @@ CVehicle::CVehicle ( CVehicleManager* pVehicleManager, CElement* pParent, CXMLNo m_bLandingGearDown = true; m_usAdjustableProperty = 0; m_bIsFrozen = false; + m_bUnoccupiedSyncable = true; m_pSyncer = NULL; GetInitialDoorStates ( m_ucDoorStates ); memset ( m_ucWheelStates, 0, sizeof ( m_ucWheelStates ) ); diff --git a/MTA10_Server/mods/deathmatch/logic/CVehicle.h b/MTA10_Server/mods/deathmatch/logic/CVehicle.h index 1ebfc6f0ad..b0f2981113 100644 --- a/MTA10_Server/mods/deathmatch/logic/CVehicle.h +++ b/MTA10_Server/mods/deathmatch/logic/CVehicle.h @@ -196,6 +196,9 @@ class CVehicle : public CElement inline class CPlayer* GetSyncer ( void ) { return m_pSyncer; }; void SetSyncer ( class CPlayer* pPlayer ); + bool IsUnoccupiedSyncable ( void ) { return m_bUnoccupiedSyncable; }; + void SetUnoccupiedSyncable ( bool bUnoccupiedSynced ) { m_bUnoccupiedSyncable = bUnoccupiedSynced; }; + unsigned char GetMaxPassengers ( void ); unsigned char GetFreePassengerSeat ( void ); @@ -301,6 +304,7 @@ class CVehicle : public CElement CVehicleColor m_Color; bool m_bIsFrozen; + bool m_bUnoccupiedSyncable; CVehicleUpgrades* m_pUpgrades; diff --git a/MTA10_Server/mods/deathmatch/logic/lua/CLuaArgument.cpp b/MTA10_Server/mods/deathmatch/logic/lua/CLuaArgument.cpp index 838861f55f..2f778f7386 100644 --- a/MTA10_Server/mods/deathmatch/logic/lua/CLuaArgument.cpp +++ b/MTA10_Server/mods/deathmatch/logic/lua/CLuaArgument.cpp @@ -538,6 +538,7 @@ bool CLuaArgument::ReadFromBitStream ( NetBitStreamInterface& bitStream, std::ve m_pTableData = new CLuaArguments ( bitStream, pKnownTables ); m_bWeakTableRef = false; m_iType = LUA_TTABLE; + m_pTableData->ValidateTableKeys (); break; } diff --git a/MTA10_Server/mods/deathmatch/logic/lua/CLuaArguments.cpp b/MTA10_Server/mods/deathmatch/logic/lua/CLuaArguments.cpp index aa7b699370..a7645a1b84 100644 --- a/MTA10_Server/mods/deathmatch/logic/lua/CLuaArguments.cpp +++ b/MTA10_Server/mods/deathmatch/logic/lua/CLuaArguments.cpp @@ -490,6 +490,42 @@ void CLuaArguments::DeleteArguments ( void ) } +void CLuaArguments::ValidateTableKeys ( void ) +{ + // Iterate over m_Arguments as pairs + // If first is LUA_TNIL, then remove pair + vector < CLuaArgument* > ::iterator iter = m_Arguments.begin (); + for ( ; iter != m_Arguments.end () ; ) + { + // Check first in pair + if ( (*iter)->GetType () == LUA_TNIL ) + { + // Remove pair + delete *iter; + iter = m_Arguments.erase ( iter ); + if ( iter != m_Arguments.end () ) + { + delete *iter; + iter = m_Arguments.erase ( iter ); + } + // Check if end + if ( iter == m_Arguments.end () ) + break; + } + else + { + // Skip second in pair + iter++; + // Check if end + if ( iter == m_Arguments.end () ) + break; + + iter++; + } + } +} + + bool CLuaArguments::ReadFromBitStream ( NetBitStreamInterface& bitStream, std::vector < CLuaArguments* > * pKnownTables ) { bool bKnownTablesCreated = false; diff --git a/MTA10_Server/mods/deathmatch/logic/lua/CLuaArguments.h b/MTA10_Server/mods/deathmatch/logic/lua/CLuaArguments.h index f99721604f..77dbe1cd6f 100644 --- a/MTA10_Server/mods/deathmatch/logic/lua/CLuaArguments.h +++ b/MTA10_Server/mods/deathmatch/logic/lua/CLuaArguments.h @@ -86,6 +86,7 @@ class CLuaArguments CLuaArgument* PushTable ( CLuaArguments * table ); void DeleteArguments ( void ); + void ValidateTableKeys ( void ); bool ReadFromBitStream ( NetBitStreamInterface& bitStream, std::vector < CLuaArguments* > * pKnownTables = NULL ); bool ReadFromJSONString ( const char* szJSON ); diff --git a/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.cpp b/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.cpp index cf25aca5c1..13f6f398e5 100644 --- a/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.cpp +++ b/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.cpp @@ -9429,6 +9429,28 @@ int CLuaFunctionDefinitions::GetTimers ( lua_State* luaVM ) } +int CLuaFunctionDefinitions::GetTimerDetails ( lua_State* luaVM ) +{ + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); + if ( pLuaMain ) + { + CLuaTimer* pLuaTimer = lua_totimer ( luaVM, 1 ); + if ( pLuaTimer ) + { + lua_pushnumber( luaVM, pLuaTimer->GetTimeLeft () ); + lua_pushnumber( luaVM, pLuaTimer->GetRepeats () ); + lua_pushnumber( luaVM, pLuaTimer->GetDelay () ); + return 3; + } + else + m_pScriptDebugging->LogBadType ( luaVM, "getTimerDetails" ); + } + + lua_pushboolean ( luaVM, false ); + return 1; +} + + int CLuaFunctionDefinitions::GetColorFromString ( lua_State* luaVM ) { unsigned char ucColorRed, ucColorGreen, ucColorBlue, ucColorAlpha; diff --git a/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.h b/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.h index 38510df99d..b031d3fd42 100644 --- a/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.h +++ b/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.h @@ -418,6 +418,7 @@ class CLuaFunctionDefinitions static int ResetTimer ( lua_State* luaVM ); static int GetTimers ( lua_State* luaVM ); static int IsTimer ( lua_State* luaVM ); + static int GetTimerDetails ( lua_State* luaVM ); static int GetColorFromString ( lua_State* luaVM ); static int Reference ( lua_State* luaVM ); static int Dereference ( lua_State* luaVM ); diff --git a/MTA10_Server/mods/deathmatch/logic/lua/CLuaManager.cpp b/MTA10_Server/mods/deathmatch/logic/lua/CLuaManager.cpp index 841c83a3dc..df5d2ed8f6 100644 --- a/MTA10_Server/mods/deathmatch/logic/lua/CLuaManager.cpp +++ b/MTA10_Server/mods/deathmatch/logic/lua/CLuaManager.cpp @@ -586,6 +586,7 @@ void CLuaManager::LoadCFunctions ( void ) CLuaCFunctions::AddFunction ( "resetTimer", CLuaFunctionDefinitions::ResetTimer ); CLuaCFunctions::AddFunction ( "getTimers", CLuaFunctionDefinitions::GetTimers ); CLuaCFunctions::AddFunction ( "isTimer", CLuaFunctionDefinitions::IsTimer ); + CLuaCFunctions::AddFunction ( "getTimerDetails", CLuaFunctionDefinitions::GetTimerDetails ); CLuaCFunctions::AddFunction ( "getColorFromString", CLuaFunctionDefinitions::GetColorFromString ); CLuaCFunctions::AddFunction ( "ref", CLuaFunctionDefinitions::Reference ); CLuaCFunctions::AddFunction ( "deref", CLuaFunctionDefinitions::Dereference ); diff --git a/MTA10_Server/mods/deathmatch/logic/lua/CLuaTimer.cpp b/MTA10_Server/mods/deathmatch/logic/lua/CLuaTimer.cpp index a344750467..97eec8a7e4 100644 --- a/MTA10_Server/mods/deathmatch/logic/lua/CLuaTimer.cpp +++ b/MTA10_Server/mods/deathmatch/logic/lua/CLuaTimer.cpp @@ -44,3 +44,11 @@ void CLuaTimer::ExecuteTimer ( CLuaMain* pLuaMain ) m_Arguments.Call ( pLuaMain, m_iLuaFunction ); } } + + +unsigned long CLuaTimer::GetTimeLeft ( void ) +{ + unsigned long ulCurrentTime = GetTime (); + unsigned long ulTimeLeft = m_ulStartTime + m_ulDelay - ulCurrentTime; + return ulTimeLeft; +} diff --git a/MTA10_Server/mods/deathmatch/logic/lua/CLuaTimer.h b/MTA10_Server/mods/deathmatch/logic/lua/CLuaTimer.h index dcb7479964..b37f8ce0b2 100644 --- a/MTA10_Server/mods/deathmatch/logic/lua/CLuaTimer.h +++ b/MTA10_Server/mods/deathmatch/logic/lua/CLuaTimer.h @@ -46,6 +46,8 @@ class CLuaTimer void ExecuteTimer ( class CLuaMain* pLuaMain ); + unsigned long GetTimeLeft ( void ); + inline bool IsBeingDeleted ( void ) { return m_bBeingDeleted; } inline void SetBeingDeleted ( bool bBeingDeleted ) { m_bBeingDeleted = bBeingDeleted; } private: diff --git a/MTA10_Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp b/MTA10_Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp index f35c927b1c..fa775c1eb7 100644 --- a/MTA10_Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp +++ b/MTA10_Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp @@ -84,6 +84,7 @@ void CLuaElementDefs::LoadFunctions ( void ) CLuaCFunctions::AddFunction ( "setElementAlpha", CLuaElementDefs::setElementAlpha ); CLuaCFunctions::AddFunction ( "setElementHealth", CLuaElementDefs::setElementHealth ); CLuaCFunctions::AddFunction ( "setElementModel", CLuaElementDefs::setElementModel ); + CLuaCFunctions::AddFunction ( "setElementSyncer", CLuaElementDefs::setElementSyncer ); } @@ -1744,3 +1745,37 @@ int CLuaElementDefs::setElementModel ( lua_State* luaVM ) lua_pushboolean ( luaVM, false ); return 1; } + +int CLuaElementDefs::setElementSyncer ( lua_State* luaVM ) +{ + int iArgument2 = lua_type ( luaVM, 2 ); + if ( lua_type ( luaVM, 1 ) == LUA_TLIGHTUSERDATA && ( iArgument2 == LUA_TLIGHTUSERDATA || iArgument2 == LUA_TBOOLEAN ) ) + { + CElement* pElement = lua_toelement ( luaVM, 1 ); + CPlayer* pPlayer = NULL; + bool bEnable = true; + + if ( iArgument2 == LUA_TLIGHTUSERDATA ) + pPlayer = lua_toplayer ( luaVM, 2 ); + if ( iArgument2 == LUA_TBOOLEAN ) + bEnable = lua_toboolean ( luaVM, 2 ) ? true : false; + + if ( pElement ) + { + if ( pPlayer || iArgument2 == LUA_TBOOLEAN ) + { + lua_pushboolean ( luaVM, CStaticFunctionDefinitions::SetElementSyncer ( pElement, pPlayer, bEnable ) ); + return 1; + } + else + m_pScriptDebugging->LogBadPointer ( luaVM, "setElementSyncer", "player", 2 ); + } + else + m_pScriptDebugging->LogBadPointer ( luaVM, "setElementSyncer", "element", 1 ); + } + else + m_pScriptDebugging->LogBadType ( luaVM, "setElementSyncer" ); + + lua_pushboolean ( luaVM, false ); + return 1; +} diff --git a/MTA10_Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h b/MTA10_Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h index c04c67dac9..ac4ba45eca 100644 --- a/MTA10_Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h +++ b/MTA10_Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h @@ -85,6 +85,7 @@ class CLuaElementDefs: public CLuaDefs static int setElementAlpha ( lua_State* luaVM ); static int setElementHealth ( lua_State* luaVM ); static int setElementModel ( lua_State* luaVM ); + static int setElementSyncer ( lua_State* luaVM ); }; #endif diff --git a/Shared/sdk/SharedUtil.h b/Shared/sdk/SharedUtil.h index 737eb11fcc..5bd1cd4b5b 100644 --- a/Shared/sdk/SharedUtil.h +++ b/Shared/sdk/SharedUtil.h @@ -215,7 +215,17 @@ namespace SharedUtil V* MapFind ( std::map < T, V, TR >& collection, const T2& key ) { typename std::map < T, V, TR > ::iterator it = collection.find ( key ); - if ( it != collection.end () ) + if ( it == collection.end () ) + return NULL; + return &it->second; + } + + // Find value in const collection + template < class T, class V, class TR, class T2 > + const V* MapFind ( const std::map < T, V, TR >& collection, const T2& key ) + { + typename std::map < T, V, TR > ::const_iterator it = collection.find ( key ); + if ( it == collection.end () ) return NULL; return &it->second; }