From f0053fb9e36b2db82231ae6d8a5a51345a531612 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Sun, 19 Nov 2017 17:19:16 +0100 Subject: [PATCH 01/27] onTransferBoxStateChange event example script: https://pastebin.com/Ny153ayg This event allow to overwrite currently transfer box into your custom. Arguments are current progress and total size in Bytes --- Client/mods/deathmatch/logic/CClientGame.cpp | 11 +++++++---- .../deathmatch/logic/CResourceFileDownloadManager.cpp | 10 +++++++++- .../deathmatch/logic/CResourceFileDownloadManager.h | 2 +- Client/mods/deathmatch/logic/CTransferBox.cpp | 8 +++++--- Client/mods/deathmatch/logic/CTransferBox.h | 3 ++- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 1f27276ffc7..06eb94d16a5 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -391,8 +391,8 @@ CClientGame::~CClientGame ( void ) #endif // Hide the transfer box incase it is showing - m_pTransferBox->Hide(); - m_pBigPacketTransferBox->Hide(); + m_pTransferBox->Hide( true ); + m_pBigPacketTransferBox->Hide( true ); // Stop async task scheduler SAFE_DELETE(m_pAsyncTaskScheduler); @@ -2876,6 +2876,9 @@ void CClientGame::AddBuiltInEvents ( void ) m_Events.AddEvent ( "onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false ); m_Events.AddEvent ( "onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false ); + // Trasnfer box event + m_Events.AddEvent( "onTransferBoxStateChange", "currentStatus, totalSize", NULL, false ); + // Marker events m_Events.AddEvent ( "onClientMarkerHit", "entity, matchingDimension", NULL, false ); m_Events.AddEvent ( "onClientMarkerLeave", "entity, matchingDimension", NULL, false ); @@ -6011,7 +6014,7 @@ void CClientGame::NotifyBigPacketProgress ( unsigned long ulBytesReceived, unsig { // Switch off progress box m_bReceivingBigPacket = false; - m_pBigPacketTransferBox->Hide (); + m_pBigPacketTransferBox->Hide ( true ); } return; } @@ -6021,7 +6024,7 @@ void CClientGame::NotifyBigPacketProgress ( unsigned long ulBytesReceived, unsig { m_bReceivingBigPacket = true; m_ulBigPacketSize = ulTotalSize; - m_pBigPacketTransferBox->Hide (); + m_pBigPacketTransferBox->Hide ( true ); m_pBigPacketTransferBox->AddToTotalSize ( ulTotalSize ); m_pBigPacketTransferBox->Show (); } diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp index b4d98c2d5bd..d44e2dd2696 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp @@ -144,6 +144,14 @@ void CResourceFileDownloadManager::DoPulse( void ) GetTransferBox()->SetInfo( uiDownloadSizeTotal ); GetTransferBox()->DoPulse(); + CLuaArguments Arguments; + Arguments.PushNumber( uiDownloadSizeTotal ); + Arguments.PushNumber( GetTransferBox()->GetTotalSize() ); + if ( !g_pClientGame->GetLocalPlayer()->CallEvent( "onTransferBoxStateChange", Arguments, false ) ) + { + GetTransferBox()->Hide( false ); + }; + // Check if completed downloading current group if ( m_ActiveFileDownloadList.empty() ) { @@ -151,7 +159,7 @@ void CResourceFileDownloadManager::DoPulse( void ) if ( m_PendingFileDownloadList.empty() ) { m_bIsTransferingFiles = false; - GetTransferBox()->Hide (); + GetTransferBox()->Hide ( true ); } // Load our newly ready resources diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.h b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.h index cd19c95220a..afa2542be2a 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.h +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.h @@ -38,7 +38,7 @@ class CResourceFileDownloadManager void DownloadFinished ( const SHttpDownloadResult& result ); SString* MakeDownloadContextString ( CDownloadableResource* pDownloadableResource ); CDownloadableResource* ResolveDownloadContextString ( SString* pString ); - + double GetTotalSize (void) { return g_pClientGame->GetTransferBox()->GetTotalSize(); }; std::vector < CDownloadableResource* > m_PendingFileDownloadList; std::vector < CDownloadableResource* > m_ActiveFileDownloadList; std::vector < SHttpServerInfo > m_HttpServerList; diff --git a/Client/mods/deathmatch/logic/CTransferBox.cpp b/Client/mods/deathmatch/logic/CTransferBox.cpp index 33c6d503d1f..fd8f03b6e31 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.cpp +++ b/Client/mods/deathmatch/logic/CTransferBox.cpp @@ -104,12 +104,14 @@ void CTransferBox::Show ( void ) g_pCore->GetGUI ()->SetTransferBoxVisible ( true ); } -void CTransferBox::Hide ( void ) +void CTransferBox::Hide ( bool resetTotalSize) { m_pWindow->SetVisible ( false ); g_pCore->GetGUI ()->SetTransferBoxVisible ( false ); - - m_dTotalSize = 0; + if ( resetTotalSize ) + { + m_dTotalSize = 0; + } } void CTransferBox::SetInfo ( double dDownloadSizeNow, CTransferBox::Type eTransferType ) diff --git a/Client/mods/deathmatch/logic/CTransferBox.h b/Client/mods/deathmatch/logic/CTransferBox.h index a6138bd9d85..9ec31893f55 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.h +++ b/Client/mods/deathmatch/logic/CTransferBox.h @@ -38,7 +38,7 @@ class CTransferBox virtual ~CTransferBox ( void ); void Show ( void ); - void Hide ( void ); + void Hide ( bool resetTotalSize ); void SetInfo ( double dDownloadSizeNow, CTransferBox::Type eTransferType = CTransferBox::NORMAL ); @@ -49,6 +49,7 @@ class CTransferBox inline bool IsVisible ( void ) { return m_pWindow->IsVisible (); }; inline void AddToTotalSize ( double dSize ) { m_dTotalSize += dSize; }; + double GetTotalSize ( void ) { return m_dTotalSize; }; private: CGUIWindow* m_pWindow; From 9955117df6265ab9cb9fe0b540ee65ac2449b3de Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Sun, 19 Nov 2017 20:09:00 +0100 Subject: [PATCH 02/27] 3 patches found by Citizen01 Fixed typo, Removed unneded argument in method `Hide` Added another argument at the beginning which say status `show` `progress` and `hide` New example script: ```lua addEventHandler ( "onTransferBoxProgressChange", localPlayer,function(typ,current,total) cancelEvent() -- disable current transfer box outputChatBox(inspect({typ,current,total})) end) ``` output ``` { "show" } { "progress", 446094, 8921880 } { "progress", 669141, 8921880 } { "progress", 1115235, 8921880 } { "progress", 1784376, 8921880 } { "progress", 8921880, 8921880 } { "progress", 8921880, 8921880 } { "hide" } ``` --- Client/mods/deathmatch/logic/CClientGame.cpp | 12 ++++++------ .../logic/CResourceFileDownloadManager.cpp | 8 +++----- Client/mods/deathmatch/logic/CTransferBox.cpp | 19 ++++++++++++------- Client/mods/deathmatch/logic/CTransferBox.h | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 06eb94d16a5..c20fc503838 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -391,8 +391,8 @@ CClientGame::~CClientGame ( void ) #endif // Hide the transfer box incase it is showing - m_pTransferBox->Hide( true ); - m_pBigPacketTransferBox->Hide( true ); + m_pTransferBox->Hide( ); + m_pBigPacketTransferBox->Hide( ); // Stop async task scheduler SAFE_DELETE(m_pAsyncTaskScheduler); @@ -2876,8 +2876,8 @@ void CClientGame::AddBuiltInEvents ( void ) m_Events.AddEvent ( "onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false ); m_Events.AddEvent ( "onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false ); - // Trasnfer box event - m_Events.AddEvent( "onTransferBoxStateChange", "currentStatus, totalSize", NULL, false ); + // Transfer box event + m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); // Marker events m_Events.AddEvent ( "onClientMarkerHit", "entity, matchingDimension", NULL, false ); @@ -6014,7 +6014,7 @@ void CClientGame::NotifyBigPacketProgress ( unsigned long ulBytesReceived, unsig { // Switch off progress box m_bReceivingBigPacket = false; - m_pBigPacketTransferBox->Hide ( true ); + m_pBigPacketTransferBox->Hide ( ); } return; } @@ -6024,7 +6024,7 @@ void CClientGame::NotifyBigPacketProgress ( unsigned long ulBytesReceived, unsig { m_bReceivingBigPacket = true; m_ulBigPacketSize = ulTotalSize; - m_pBigPacketTransferBox->Hide ( true ); + m_pBigPacketTransferBox->Hide ( ); m_pBigPacketTransferBox->AddToTotalSize ( ulTotalSize ); m_pBigPacketTransferBox->Show (); } diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp index d44e2dd2696..0ff367654d6 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp @@ -145,12 +145,10 @@ void CResourceFileDownloadManager::DoPulse( void ) GetTransferBox()->DoPulse(); CLuaArguments Arguments; + Arguments.PushString( "progress" ); Arguments.PushNumber( uiDownloadSizeTotal ); Arguments.PushNumber( GetTransferBox()->GetTotalSize() ); - if ( !g_pClientGame->GetLocalPlayer()->CallEvent( "onTransferBoxStateChange", Arguments, false ) ) - { - GetTransferBox()->Hide( false ); - }; + g_pClientGame->GetLocalPlayer()->CallEvent( "onTransferBoxProgressChange", Arguments, false ); // Check if completed downloading current group if ( m_ActiveFileDownloadList.empty() ) @@ -159,7 +157,7 @@ void CResourceFileDownloadManager::DoPulse( void ) if ( m_PendingFileDownloadList.empty() ) { m_bIsTransferingFiles = false; - GetTransferBox()->Hide ( true ); + GetTransferBox()->Hide ( ); } // Load our newly ready resources diff --git a/Client/mods/deathmatch/logic/CTransferBox.cpp b/Client/mods/deathmatch/logic/CTransferBox.cpp index fd8f03b6e31..08bc23e90b9 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.cpp +++ b/Client/mods/deathmatch/logic/CTransferBox.cpp @@ -100,18 +100,23 @@ CTransferBox::~CTransferBox ( void ) void CTransferBox::Show ( void ) { - m_pWindow->SetVisible ( true ); - g_pCore->GetGUI ()->SetTransferBoxVisible ( true ); + m_dTotalSize = 0; + CLuaArguments Arguments; + Arguments.PushString("show"); + if (g_pClientGame->GetLocalPlayer()->CallEvent("onTransferBoxProgressChange", Arguments, false) ) + { + m_pWindow->SetVisible(true); + g_pCore->GetGUI()->SetTransferBoxVisible(true); + }; } -void CTransferBox::Hide ( bool resetTotalSize) +void CTransferBox::Hide ( void ) { m_pWindow->SetVisible ( false ); g_pCore->GetGUI ()->SetTransferBoxVisible ( false ); - if ( resetTotalSize ) - { - m_dTotalSize = 0; - } + CLuaArguments Arguments; + Arguments.PushString("hide"); + g_pClientGame->GetLocalPlayer()->CallEvent("onTransferBoxProgressChange", Arguments, false); } void CTransferBox::SetInfo ( double dDownloadSizeNow, CTransferBox::Type eTransferType ) diff --git a/Client/mods/deathmatch/logic/CTransferBox.h b/Client/mods/deathmatch/logic/CTransferBox.h index 9ec31893f55..8541d78a4f4 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.h +++ b/Client/mods/deathmatch/logic/CTransferBox.h @@ -38,7 +38,7 @@ class CTransferBox virtual ~CTransferBox ( void ); void Show ( void ); - void Hide ( bool resetTotalSize ); + void Hide ( void ); void SetInfo ( double dDownloadSizeNow, CTransferBox::Type eTransferType = CTransferBox::NORMAL ); From 89537a48561ca28356b8a2cb9b2b24405c89c009 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Sun, 19 Nov 2017 20:45:51 +0100 Subject: [PATCH 03/27] event name back to onTransferBoxStateChange --- Client/mods/deathmatch/logic/CClientGame.cpp | 2 +- Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index c20fc503838..43b6e45a71c 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -2877,7 +2877,7 @@ void CClientGame::AddBuiltInEvents ( void ) m_Events.AddEvent ( "onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false ); // Transfer box event - m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); + m_Events.AddEvent( "onTransferBoxStateChange", "type, currentStatus, totalSize", NULL, false ); // Marker events m_Events.AddEvent ( "onClientMarkerHit", "entity, matchingDimension", NULL, false ); diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp index 0ff367654d6..fa7659007ef 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp @@ -148,7 +148,7 @@ void CResourceFileDownloadManager::DoPulse( void ) Arguments.PushString( "progress" ); Arguments.PushNumber( uiDownloadSizeTotal ); Arguments.PushNumber( GetTransferBox()->GetTotalSize() ); - g_pClientGame->GetLocalPlayer()->CallEvent( "onTransferBoxProgressChange", Arguments, false ); + g_pClientGame->GetLocalPlayer()->CallEvent( "onTransferBoxStateChange", Arguments, false ); // Check if completed downloading current group if ( m_ActiveFileDownloadList.empty() ) @@ -157,7 +157,7 @@ void CResourceFileDownloadManager::DoPulse( void ) if ( m_PendingFileDownloadList.empty() ) { m_bIsTransferingFiles = false; - GetTransferBox()->Hide ( ); + GetTransferBox()->Hide (); } // Load our newly ready resources From fd6e0d58fda22f60a4f6964554f8f1f8d85425ac Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Sun, 19 Nov 2017 20:47:31 +0100 Subject: [PATCH 04/27] removed 2 spaces --- Client/mods/deathmatch/logic/CClientGame.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 43b6e45a71c..a024fd1bdda 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -6014,7 +6014,7 @@ void CClientGame::NotifyBigPacketProgress ( unsigned long ulBytesReceived, unsig { // Switch off progress box m_bReceivingBigPacket = false; - m_pBigPacketTransferBox->Hide ( ); + m_pBigPacketTransferBox->Hide (); } return; } @@ -6024,7 +6024,7 @@ void CClientGame::NotifyBigPacketProgress ( unsigned long ulBytesReceived, unsig { m_bReceivingBigPacket = true; m_ulBigPacketSize = ulTotalSize; - m_pBigPacketTransferBox->Hide ( ); + m_pBigPacketTransferBox->Hide (); m_pBigPacketTransferBox->AddToTotalSize ( ulTotalSize ); m_pBigPacketTransferBox->Show (); } From 4ea4e76d6f62488aabd638ff1d7f1265fdbf2fa1 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Sun, 19 Nov 2017 20:48:01 +0100 Subject: [PATCH 05/27] another 2 space removed --- Client/mods/deathmatch/logic/CClientGame.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index a024fd1bdda..b4a555e6cdf 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -391,8 +391,8 @@ CClientGame::~CClientGame ( void ) #endif // Hide the transfer box incase it is showing - m_pTransferBox->Hide( ); - m_pBigPacketTransferBox->Hide( ); + m_pTransferBox->Hide(); + m_pBigPacketTransferBox->Hide(); // Stop async task scheduler SAFE_DELETE(m_pAsyncTaskScheduler); From 096bfc183000246a97c7a1341b7abaf9f1a77566 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 11 Dec 2017 14:25:10 +0100 Subject: [PATCH 06/27] bettern name for event --- Client/mods/deathmatch/logic/CClientGame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index b4a555e6cdf..baed9fe62da 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -2877,7 +2877,7 @@ void CClientGame::AddBuiltInEvents ( void ) m_Events.AddEvent ( "onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false ); // Transfer box event - m_Events.AddEvent( "onTransferBoxStateChange", "type, currentStatus, totalSize", NULL, false ); + m_Events.AddEvent( "onTransferBoxProgressChange", "type, currentStatus, totalSize", NULL, false ); // Marker events m_Events.AddEvent ( "onClientMarkerHit", "entity, matchingDimension", NULL, false ); From daf09b081f9c2df56d3de41766c4ef1ce0884e65 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 11 Dec 2017 14:37:49 +0100 Subject: [PATCH 07/27] Update CResourceFileDownloadManager.cpp --- Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp index fa7659007ef..00c499b54f3 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp @@ -148,7 +148,7 @@ void CResourceFileDownloadManager::DoPulse( void ) Arguments.PushString( "progress" ); Arguments.PushNumber( uiDownloadSizeTotal ); Arguments.PushNumber( GetTransferBox()->GetTotalSize() ); - g_pClientGame->GetLocalPlayer()->CallEvent( "onTransferBoxStateChange", Arguments, false ); + g_pClientGame->GetLocalPlayer()->CallEvent( "onTransferBoxProgressChange", Arguments, false ); // Check if completed downloading current group if ( m_ActiveFileDownloadList.empty() ) From f29f36abe432196a0f688be6c9897313df6d36af Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 2 Jul 2018 21:14:10 +0200 Subject: [PATCH 08/27] rebuilded --- Client/gui/CGUI_Impl.h | 3 +++ Client/mods/deathmatch/logic/CClientGame.cpp | 2 +- .../logic/CResourceFileDownloadManager.cpp | 2 +- Client/mods/deathmatch/logic/CTransferBox.cpp | 7 +---- Client/mods/deathmatch/logic/CTransferBox.h | 4 +++ .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 27 +++++++++++++++++++ .../deathmatch/logic/luadefs/CLuaGUIDefs.h | 2 ++ Client/sdk/gui/CGUI.h | 1 + 8 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Client/gui/CGUI_Impl.h b/Client/gui/CGUI_Impl.h index 65506b565f6..b0e41b02bed 100644 --- a/Client/gui/CGUI_Impl.h +++ b/Client/gui/CGUI_Impl.h @@ -258,6 +258,8 @@ class CGUI_Impl : public CGUI, public CGUITabList bool IsTransferBoxVisible(void) { return m_bTransferBoxVisible; }; void SetTransferBoxVisible(bool bVisible) { m_bTransferBoxVisible = bVisible; }; + void SetTransferBoxEnabled(bool bEnabled) { m_bTransferBoxEnabled = bEnabled; }; + bool IsTransferBoxEnabled(void) { return m_bTransferBoxEnabled; }; bool Event_CharacterKey(const CEGUI::EventArgs& e); bool Event_KeyDown(const CEGUI::EventArgs& e); @@ -351,6 +353,7 @@ class CGUI_Impl : public CGUI, public CGUITabList std::list m_GuiWorkingDirectoryStack; bool m_bTransferBoxVisible; + bool m_bTransferBoxEnabled = true; bool m_HasSchemeLoaded; SString m_CurrentSchemeName; diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 20df56937fb..c9922b6c13b 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -2837,7 +2837,7 @@ void CClientGame::AddBuiltInEvents(void) m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); // Transfer box event - m_Events.AddEvent( "onTransferBoxProgressChange", "type, currentStatus, totalSize", NULL, false ); + m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); // Marker events m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp index 9dc695e8bbc..a501a5c99ce 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp @@ -141,7 +141,6 @@ void CResourceFileDownloadManager::DoPulse(void) GetTransferBox()->DoPulse(); CLuaArguments Arguments; - Arguments.PushString( "progress" ); Arguments.PushNumber( uiDownloadSizeTotal ); Arguments.PushNumber( GetTransferBox()->GetTotalSize() ); g_pClientGame->GetLocalPlayer()->CallEvent( "onTransferBoxProgressChange", Arguments, false ); @@ -229,6 +228,7 @@ bool CResourceFileDownloadManager::BeginResourceFileDownload(CDownloadableResour SString* pstrContext = MakeDownloadContextString(pResourceFile); SString strFilename = pResourceFile->GetName(); + bool bUniqueDownload = pHTTP->QueueFile(strHTTPDownloadURLFull, strFilename, NULL, 0, false, pstrContext, StaticDownloadFinished, g_pClientGame->IsLocalGame(), serverInfo.uiConnectionAttempts, serverInfo.uiConnectTimeoutMs, true); if (!bUniqueDownload) diff --git a/Client/mods/deathmatch/logic/CTransferBox.cpp b/Client/mods/deathmatch/logic/CTransferBox.cpp index b91ba97754f..626e2507fc5 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.cpp +++ b/Client/mods/deathmatch/logic/CTransferBox.cpp @@ -98,9 +98,7 @@ CTransferBox::~CTransferBox(void) void CTransferBox::Show(void) { m_dTotalSize = 0; - CLuaArguments Arguments; - Arguments.PushString("show"); - if (g_pClientGame->GetLocalPlayer()->CallEvent("onTransferBoxProgressChange", Arguments, false) ) + if (IsEnabled()) { m_pWindow->SetVisible(true); g_pCore->GetGUI()->SetTransferBoxVisible(true); @@ -111,9 +109,6 @@ void CTransferBox::Hide(void) { m_pWindow->SetVisible(false); g_pCore->GetGUI()->SetTransferBoxVisible(false); - CLuaArguments Arguments; - Arguments.PushString("hide"); - g_pClientGame->GetLocalPlayer()->CallEvent("onTransferBoxProgressChange", Arguments, false); m_dTotalSize = 0; } diff --git a/Client/mods/deathmatch/logic/CTransferBox.h b/Client/mods/deathmatch/logic/CTransferBox.h index bd7e1ad455e..aba0bb6364c 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.h +++ b/Client/mods/deathmatch/logic/CTransferBox.h @@ -41,9 +41,12 @@ class CTransferBox bool OnCancelClick(CGUIElement* pElement); bool IsVisible(void) { return m_pWindow->IsVisible(); }; + bool IsEnabled(void) { return m_bEnabled; }; + void SetEnabled(bool bEnabled) { m_bEnabled = bEnabled; }; void AddToTotalSize(double dSize) { m_dTotalSize += dSize; }; + double GetTotalSize(void) { return m_dTotalSize; }; private: CGUIWindow* m_pWindow; SFixedArray m_pIcon; @@ -51,6 +54,7 @@ class CTransferBox CGUIProgressBar* m_pProgress; bool m_bMultipleDownloads; + bool m_bEnabled; unsigned int m_uiVisible; CElapsedTime m_AnimTimer; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index 4b98679cbc4..2435109f0b5 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -24,7 +24,10 @@ void CLuaGUIDefs::LoadFunctions(void) CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); + CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); + CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); + CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); @@ -638,6 +641,30 @@ int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) +{ + bool bEnabled; + CScriptArgReader argStream(luaVM); + argStream.ReadBool(bEnabled); + + if (!argStream.HasErrors()) + { + g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + return 1; +} + +int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); + return 1; +} + int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) { // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.h index 5af0702a76a..aa7bae3a250 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.h @@ -29,6 +29,8 @@ class CLuaGUIDefs : public CLuaDefs LUA_DECLARE(GUIIsMainMenuActive); LUA_DECLARE(GUIIsMTAWindowActive); LUA_DECLARE(GUIIsTransferBoxActive); + LUA_DECLARE(GUIIsTransferBoxEnabled); + LUA_DECLARE(GUISetTransferBoxEnabled); LUA_DECLARE(GUICreateWindow); LUA_DECLARE(GUICreateLabel); LUA_DECLARE(GUICreateButton); diff --git a/Client/sdk/gui/CGUI.h b/Client/sdk/gui/CGUI.h index c472762c0d3..f2c78bff903 100644 --- a/Client/sdk/gui/CGUI.h +++ b/Client/sdk/gui/CGUI.h @@ -166,6 +166,7 @@ class CGUI virtual bool IsTransferBoxVisible(void) = 0; virtual void SetTransferBoxVisible(bool bVisible) = 0; + virtual bool IsTransferBoxEnabled(void) = 0; virtual void CleanDeadPool(void) = 0; From cd8ac81fd3ba8210a702adf1c45d2f082a06f447 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 17:36:38 +0200 Subject: [PATCH 09/27] added option to allow server control transfer box --- Client/core/CClientVariables.cpp | 1 + Client/core/CSettings.cpp | 21 +- Client/core/CSettings.h | 4 + Client/mods/deathmatch/logic/CClientGame.cpp | 13748 ++++++++-------- .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 7764 ++++----- 5 files changed, 10786 insertions(+), 10752 deletions(-) diff --git a/Client/core/CClientVariables.cpp b/Client/core/CClientVariables.cpp index 4516a4813b6..e8b9a2245ee 100644 --- a/Client/core/CClientVariables.cpp +++ b/Client/core/CClientVariables.cpp @@ -330,6 +330,7 @@ void CClientVariables::LoadDefaults(void) DEFAULT("high_detail_vehicles", 0); // Disable rendering high detail vehicles all the time DEFAULT("fast_clothes_loading", 1); // 0-off 1-auto 2-on DEFAULT("allow_screen_upload", 1); // 0-off 1-on + DEFAULT("allow_server_control_transfebox", 1); // 0-off 1-on DEFAULT("max_clientscript_log_kb", 5000); // Max size in KB (0-No limit) DEFAULT("display_fullscreen_style", 0); // 0-standard 1-borderless 2-borderless keep res 3-borderless stretch DEFAULT("display_windowed", 0); // 0-off 1-on diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 13ce2ee374b..5dab8377fa5 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -376,6 +376,11 @@ void CSettings::CreateGUI(void) m_pCheckBoxAllowScreenUpload->GetPosition(vecTemp, false); m_pCheckBoxAllowScreenUpload->AutoSize(NULL, 20.0f); + m_pCheckBoxAllowControlTransferBox = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Allow server to control transfer box"), true)); + m_pCheckBoxAllowControlTransferBox->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); + m_pCheckBoxAllowControlTransferBox->GetPosition(vecTemp, false); + m_pCheckBoxAllowControlTransferBox->AutoSize(NULL, 20.0f); + m_pCheckBoxCustomizedSAFiles = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Use customized GTA:SA files"), true)); m_pCheckBoxCustomizedSAFiles->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); m_pCheckBoxCustomizedSAFiles->GetPosition(vecTemp, false); @@ -1488,6 +1493,11 @@ void CSettings::UpdateVideoTab(void) CVARS_GET("allow_screen_upload", bAllowScreenUploadEnabled); m_pCheckBoxAllowScreenUpload->SetSelected(bAllowScreenUploadEnabled); + // Allow screen upload + bool bAllowServerTransferBoxControl; + CVARS_GET("allow_server_control_transfebox", bAllowServerTransferBoxControl); + m_pCheckBoxAllowControlTransferBox->SetSelected(bAllowServerTransferBoxControl); + // Customized sa files m_pCheckBoxCustomizedSAFiles->SetSelected(GetApplicationSettingInt("customized-sa-files-request") != 0); m_pCheckBoxCustomizedSAFiles->SetVisible(GetApplicationSettingInt("customized-sa-files-show") != 0); @@ -3294,9 +3304,13 @@ void CSettings::SaveData(void) CVARS_SET("show_unsafe_resolutions", bShowUnsafeResolutions); // Allow screen upload - bool bAllowScreenUploadEnabled = m_pCheckBoxAllowScreenUpload->GetSelected(); + bAllowScreenUploadEnabled = m_pCheckBoxAllowScreenUpload->GetSelected(); CVARS_SET("allow_screen_upload", bAllowScreenUploadEnabled); + // Allow screen upload + bool m_pCheckBoxAllowScreenUpload = m_pCheckBoxAllowControlTransferBox->GetSelected(); + CVARS_SET("allow_server_control_transfebox", m_pCheckBoxAllowScreenUpload); + // Grass bool bGrassEnabled = m_pCheckBoxGrass->GetSelected(); CVARS_SET("grass", bGrassEnabled); @@ -4534,3 +4548,8 @@ bool CSettings::IsActive(void) { return m_pWindow->IsActive(); } + +bool CSettings::IsTransferBoxControlEnabled(void) +{ + return bAllowScreenUploadEnabled; +} diff --git a/Client/core/CSettings.h b/Client/core/CSettings.h index 0fb9c252a20..b46dec45061 100644 --- a/Client/core/CSettings.h +++ b/Client/core/CSettings.h @@ -117,6 +117,7 @@ class CSettings void TabSkip(bool bBackwards); bool IsActive(void); + bool IsTransferBoxControlEnabled(void); void SetSelectedIndex(unsigned int uiIndex); @@ -151,6 +152,7 @@ class CSettings CGUICheckBox* m_pCheckBoxDeviceSelectionDialog; CGUICheckBox* m_pCheckBoxShowUnsafeResolutions; CGUICheckBox* m_pCheckBoxAllowScreenUpload; + CGUICheckBox* m_pCheckBoxAllowControlTransferBox; CGUICheckBox* m_pCheckBoxCustomizedSAFiles; CGUICheckBox* m_pCheckBoxGrass; CGUICheckBox* m_pCheckBoxHeatHaze; @@ -443,4 +445,6 @@ class CSettings int m_iMaxAnisotropic; std::list m_pKeyBindSections; + + bool bAllowScreenUploadEnabled; }; diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index cef5af3a459..80cb359d464 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -1,6874 +1,6874 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto v1.0 - * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/CClientGame.cpp - * PURPOSE: Client game manager - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#include "StdInc.h" -#include -#include "game/CAnimBlendAssocGroup.h" -#include "game/CAnimBlendAssociation.h" -#include "game/CAnimBlendHierarchy.h" - -SString StringZeroPadout(const SString& strInput, uint uiPadoutSize) -{ - SString strResult = strInput; - while (strResult.length() < uiPadoutSize) - strResult += '\0'; - return strResult; -} - -using SharedUtil::CalcMTASAPath; -using std::list; -using std::vector; - -// Hide the "conversion from 'unsigned long' to 'DWORD*' of greater size" warning -#pragma warning(disable:4312) - -// Used within this file by the packet handler to grab the this pointer of CClientGame -extern CClientGame* g_pClientGame; -extern int g_iDamageEventLimit; -float g_fApplyDamageLastAmount; -uchar g_ucApplyDamageLastHitZone; -CClientPed* g_pApplyDamageLastDamagedPed; -bool g_bBulletFireVectorsValid; -CVector g_vecBulletFireStartPosition; -CVector g_vecBulletFireEndPosition; - -#define DEFAULT_GRAVITY 0.008f -#define DEFAULT_GAME_SPEED 1.0f -#define DEFAULT_BLUR_LEVEL 36 -#define DEFAULT_JETPACK_MAXHEIGHT 100 -#define DEFAULT_AIRCRAFT_MAXHEIGHT 800 -#define DEFAULT_AIRCRAFT_MAXVELOCITY 1.5f -#define DEFAULT_MINUTE_DURATION 1000 -#define DOUBLECLICK_TIMEOUT 330 -#define DOUBLECLICK_MOVE_THRESHOLD 10.0f - -CClientGame::CClientGame(bool bLocalPlay) -{ - // Init the global var with ourself - g_pClientGame = this; - - // Packet handler - m_pPacketHandler = new CPacketHandler(); - - // Init - m_bLocalPlay = bLocalPlay; - m_bErrorStartingLocal = false; - m_iLocalConnectAttempts = 0; - m_Status = CClientGame::STATUS_CONNECTING; - m_ulVerifyTimeStart = 0; - m_ulLastClickTick = 0; - m_pLocalPlayer = NULL; - m_LocalID = INVALID_ELEMENT_ID; - m_bShowNametags = true; - m_bWaitingForLocalConnect = false; - m_bShowRadar = false; - m_bGameLoaded = false; - m_bTriggeredIngameAndConnected = false; - m_bGracefulDisconnect = false; - m_ulLastVehicleInOutTime = 0; - m_bIsGettingOutOfVehicle = false; - m_bIsGettingIntoVehicle = false; - m_bIsGettingJacked = false; - m_bIsJackingVehicle = false; - m_VehicleInOutID = INVALID_ELEMENT_ID; - m_pGettingJackedBy = NULL; - m_ucVehicleInOutSeat = 0xFF; - m_pTargetedEntity = NULL; - m_TargetedPlayerID = INVALID_ELEMENT_ID; - m_pDamageEntity = NULL; - m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageBodyPiece = 0xFF; - m_ucDamageWeapon = 0xFF; - m_ulDamageTime = 0; - m_bDamageSent = true; - m_bShowNetstat = false; - m_bShowFPS = false; - m_bHudAreaNameDisabled = false; - m_fGameSpeed = 1.0f; - m_lMoney = 0; - m_dwWanted = 0; - m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) - ResetAmmoInClip(); - - m_bNoNewVehicleTask = false; - m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; - - m_bCursorEventsEnabled = false; - m_bInitiallyFadedOut = true; - - m_bIsPlayingBack = false; - m_bFirstPlaybackFrame = false; - - // Setup game glitch defaults ( false = disabled ). Remember to update these serverside if you alter them! - m_Glitches[GLITCH_QUICKRELOAD] = false; - g_pMultiplayer->DisableQuickReload(true); - m_Glitches[GLITCH_FASTFIRE] = false; - m_Glitches[GLITCH_FASTMOVE] = false; - m_Glitches[GLITCH_CROUCHBUG] = false; - m_Glitches[GLITCH_CLOSEDAMAGE] = false; - g_pMultiplayer->DisableCloseRangeDamage(true); - m_Glitches[GLITCH_HITANIM] = false; - m_Glitches[GLITCH_FASTSPRINT] = false; - m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; - m_Glitches[GLITCH_QUICKSTAND] = false; - g_pMultiplayer->DisableBadDrivebyHitboxes(true); - - // Remove Night & Thermal vision view (if enabled). - g_pMultiplayer->SetNightVisionEnabled(false); - g_pMultiplayer->SetThermalVisionEnabled(false); - - m_bCloudsEnabled = true; - - m_bBirdsEnabled = true; - - m_bWasMinimized = false; - - // Grab the mod path - m_strModRoot = g_pCore->GetModInstallRoot("deathmatch"); - - // Figure out which directory to use for the client resource file cache - SetFileCacheRoot(); - - // Override CGUI's global events - g_pCore->GetGUI()->SetKeyDownHandler(INPUT_MOD, GUI_CALLBACK_KEY(&CClientGame::OnKeyDown, this)); - g_pCore->GetGUI()->SetMouseClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseClick, this)); - g_pCore->GetGUI()->SetMouseDoubleClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseDoubleClick, this)); - g_pCore->GetGUI()->SetMouseButtonDownHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonDown, this)); - g_pCore->GetGUI()->SetMouseButtonUpHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonUp, this)); - g_pCore->GetGUI()->SetMouseMoveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseMove, this)); - g_pCore->GetGUI()->SetMouseEnterHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseEnter, this)); - g_pCore->GetGUI()->SetMouseLeaveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseLeave, this)); - g_pCore->GetGUI()->SetMouseWheelHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseWheel, this)); - g_pCore->GetGUI()->SetMovedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnMove, this)); - g_pCore->GetGUI()->SetSizedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnSize, this)); - g_pCore->GetGUI()->SetFocusGainedHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusGain, this)); - g_pCore->GetGUI()->SetFocusLostHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusLoss, this)); - g_pCore->GetGUI()->SelectInputHandlers(INPUT_MOD); - - // Startup "entities from root" optimization for getElementsByType - CClientEntity::StartupEntitiesFromRoot(); - - // Startup game entity tracking manager - m_pGameEntityXRefManager = NewGameEntityXRefManager(); - m_pModelCacheManager = NewClientModelCacheManager(); - - // Initialize our root entity with an invalid id, we dont know the true id until map-start - m_pRootEntity = new CClientDummy(NULL, INVALID_ELEMENT_ID, "root"); - m_pRootEntity->MakeSystemEntity(); - - m_pDebugHookManager = new CDebugHookManager(); - - // Movings objects manager - m_pMovingObjectsManager = new CMovingObjectsManager(); - - // Create the manager and grab the most important pointers - m_pManager = new CClientManager; - m_pCamera = m_pManager->GetCamera(); - m_pMarkerManager = m_pManager->GetMarkerManager(); - m_pObjectManager = m_pManager->GetObjectManager(); - m_pPickupManager = m_pManager->GetPickupManager(); - m_pPlayerManager = m_pManager->GetPlayerManager(); - m_pRadarAreaManager = m_pManager->GetRadarAreaManager(); - m_pDisplayManager = m_pManager->GetDisplayManager(); - m_pVehicleManager = m_pManager->GetVehicleManager(); - m_pRadarMarkerManager = m_pManager->GetRadarMarkerManager(); - m_pPathManager = m_pManager->GetPathManager(); - m_pTeamManager = m_pManager->GetTeamManager(); - m_pPedManager = m_pManager->GetPedManager(); - m_pGUIManager = m_pManager->GetGUIManager(); - m_pResourceManager = m_pManager->GetResourceManager(); - m_pProjectileManager = m_pManager->GetProjectileManager(); - m_pLocalServer = NULL; - - m_pLatentTransferManager = new CLatentTransferManager(); - m_pZoneNames = new CZoneNames; - m_pScriptKeyBinds = new CScriptKeyBinds; - m_pRemoteCalls = new CRemoteCalls(); - m_pResourceFileDownloadManager = new CResourceFileDownloadManager(); - - // Create our net API - m_pNetAPI = new CNetAPI(m_pManager); - m_pNetworkStats = new CNetworkStats(m_pDisplayManager); - m_pSyncDebug = new CSyncDebug(m_pManager); - - // Create our blended weather class - m_pBlendedWeather = new CBlendedWeather; - - // Create our RPC class - m_pRPCFunctions = new CRPCFunctions(this); - - // Our management classes - m_pUnoccupiedVehicleSync = new CUnoccupiedVehicleSync(m_pVehicleManager); - m_pPedSync = new CPedSync(m_pPedManager); -#ifdef WITH_OBJECT_SYNC - m_pObjectSync = new CObjectSync(m_pObjectManager); -#endif - m_pNametags = new CNametags(m_pManager); - m_pRadarMap = new CRadarMap(m_pManager); - - // Set the screenshot path - /* This is now done in CCore, to maintain a global screenshot path - SString strScreenShotPath = SString::Printf ( "%s\\screenshots", m_szModRoot ); - g_pCore->SetScreenShotPath ( strScreenShotPath ); - */ - - // Create the transfer boxes (GUI) - m_pTransferBox = new CTransferBox(); - m_pBigPacketTransferBox = new CTransferBox(); - - // Store the time we started on - if (bLocalPlay) - m_ulTimeStart = 0; - else - m_ulTimeStart = CClientTime::GetTime(); - - // MTA Voice - m_pVoiceRecorder = new CVoiceRecorder(); - - // Singular file download manager - m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); - - // Register the message and the net packet handler - g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); - g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); - g_pMultiplayer->SetBulletImpactHandler(CClientGame::BulletImpact); - g_pMultiplayer->SetBulletFireHandler(CClientGame::BulletFire); - g_pMultiplayer->SetExplosionHandler(CClientExplosionManager::Hook_StaticExplosionCreation); - g_pMultiplayer->SetBreakTowLinkHandler(CClientGame::StaticBreakTowLinkHandler); - g_pMultiplayer->SetDrawRadarAreasHandler(CClientGame::StaticDrawRadarAreasHandler); - g_pMultiplayer->SetDamageHandler(CClientGame::StaticDamageHandler); - g_pMultiplayer->SetDeathHandler(CClientGame::StaticDeathHandler); - g_pMultiplayer->SetFireHandler(CClientGame::StaticFireHandler); - g_pMultiplayer->SetProjectileStopHandler(CClientProjectileManager::Hook_StaticProjectileAllow); - g_pMultiplayer->SetProjectileHandler(CClientProjectileManager::Hook_StaticProjectileCreation); - g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); - g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); - g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); - g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); - g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); - g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); - g_pMultiplayer->SetPreFxRenderHandler(CClientGame::StaticPreFxRenderHandler); - g_pMultiplayer->SetPreHudRenderHandler(CClientGame::StaticPreHudRenderHandler); - g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(CClientGame::StaticCAnimBlendAssocDestructorHandler); - g_pMultiplayer->SetAddAnimationHandler(CClientGame::StaticAddAnimationHandler); - g_pMultiplayer->SetAddAnimationAndSyncHandler(CClientGame::StaticAddAnimationAndSyncHandler); - g_pMultiplayer->SetAssocGroupCopyAnimationHandler(CClientGame::StaticAssocGroupCopyAnimationHandler); - g_pMultiplayer->SetBlendAnimationHierarchyHandler(CClientGame::StaticBlendAnimationHierarchyHandler); - g_pMultiplayer->SetProcessCollisionHandler(CClientGame::StaticProcessCollisionHandler); - g_pMultiplayer->SetVehicleCollisionHandler(CClientGame::StaticVehicleCollisionHandler); - g_pMultiplayer->SetVehicleDamageHandler(CClientGame::StaticVehicleDamageHandler); - g_pMultiplayer->SetHeliKillHandler(CClientGame::StaticHeliKillHandler); - g_pMultiplayer->SetObjectDamageHandler(CClientGame::StaticObjectDamageHandler); - g_pMultiplayer->SetObjectBreakHandler(CClientGame::StaticObjectBreakHandler); - g_pMultiplayer->SetWaterCannonHitHandler(CClientGame::StaticWaterCannonHandler); - g_pMultiplayer->SetVehicleFellThroughMapHandler(CClientGame::StaticVehicleFellThroughMapHandler); - g_pMultiplayer->SetGameObjectDestructHandler(CClientGame::StaticGameObjectDestructHandler); - g_pMultiplayer->SetGameVehicleDestructHandler(CClientGame::StaticGameVehicleDestructHandler); - g_pMultiplayer->SetGamePlayerDestructHandler(CClientGame::StaticGamePlayerDestructHandler); - g_pMultiplayer->SetGameProjectileDestructHandler(CClientGame::StaticGameProjectileDestructHandler); - g_pMultiplayer->SetGameModelRemoveHandler(CClientGame::StaticGameModelRemoveHandler); - g_pMultiplayer->SetGameEntityRenderHandler(CClientGame::StaticGameEntityRenderHandler); - g_pMultiplayer->SetFxSystemDestructionHandler(CClientGame::StaticFxSystemDestructionHandler); - g_pMultiplayer->SetDrivebyAnimationHandler(CClientGame::StaticDrivebyAnimationHandler); - g_pGame->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); - g_pGame->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); - g_pGame->SetTaskSimpleBeHitHandler(CClientGame::StaticTaskSimpleBeHitHandler); - g_pCore->SetMessageProcessor(CClientGame::StaticProcessMessage); - g_pCore->GetKeyBinds()->SetKeyStrokeHandler(CClientGame::StaticKeyStrokeHandler); - g_pCore->GetKeyBinds()->SetCharacterKeyHandler(CClientGame::StaticCharacterKeyHandler); - g_pNet->RegisterPacketHandler(CClientGame::StaticProcessPacket); - - m_pLuaManager = new CLuaManager(this); - m_pScriptDebugging = new CScriptDebugging(m_pLuaManager); - m_pScriptDebugging->SetLogfile(CalcMTASAPath("mta\\logs\\clientscript.log"), 3); - - CStaticFunctionDefinitions(m_pLuaManager, &m_Events, g_pCore, g_pGame, this, m_pManager); - CLuaFunctionDefs::Initialize(m_pLuaManager, m_pScriptDebugging, this); - CLuaDefs::Initialize(this, m_pLuaManager, m_pScriptDebugging); - - // Start async task scheduler - m_pAsyncTaskScheduler = new SharedUtil::CAsyncTaskScheduler(2); - - // Disable the enter/exit vehicle key button (we want to handle this button ourselves) - g_pMultiplayer->DisableEnterExitVehicleKey(true); - - // Disable GTA's pickup processing as we want to confirm the hits with the server - m_pPickupManager->SetPickupProcessingDisabled(true); - - // Key-bind for fire-key (for handling satchels and stealth-kills) - g_pCore->GetKeyBinds()->AddControlFunction("fire", CClientGame::StaticUpdateFireKey, true); - - // Init big packet progress vars - m_bReceivingBigPacket = false; - m_ulBigPacketSize = 0; - m_ulBigPacketBytesReceivedBase = 0; - - m_bBeingDeleted = false; - - #if defined (MTA_DEBUG) || defined (MTA_BETA) - m_bShowSyncingInfo = false; - #endif - - #ifdef MTA_DEBUG - m_pShowPlayer = m_pShowPlayerTasks = NULL; - m_bMimicLag = false; - m_ulLastMimicLag = 0; - m_bDoPaintballs = false; - m_bShowInterpolation = false; - #endif - - // Add our lua events - AddBuiltInEvents(); - - // Init debugger class - m_Foo.Init(this); - - // Load some stuff from the core config - float fScale; - g_pCore->GetCVars()->Get("text_scale", fScale); - CClientTextDisplay::SetGlobalScale(fScale); - - // Reset async loading script settings to default - g_pGame->SetAsyncLoadingFromScript(true, false); - - // Reset test mode script settings to default - g_pCore->GetGraphics()->GetRenderItemManager()->SetTestMode(DX_TEST_MODE_NONE); -} - -CClientGame::~CClientGame(void) -{ - m_bBeingDeleted = true; - // Stop all explosions. Unfortunately this doesn't fix the crash - // if a vehicle is destroyed while it explodes. - g_pGame->GetExplosionManager()->RemoveAllExplosions(); - - // Reset camera shaking - g_pGame->GetCamera()->SetShakeForce(0.0f); - - // Stop playing the continious sounds - // if the game was loaded. This is done by - // playing these special IDS. - if (m_bGameLoaded) - { - g_pGame->GetAudio()->PlayFrontEndSound(35); - g_pGame->GetAudio()->PlayFrontEndSound(48); - } - - // Reset the GUI input mode - g_pCore->GetGUI()->SetGUIInputMode(INPUTMODE_NO_BINDS_ON_EDIT); - - // Reset CGUI's global events - g_pCore->GetGUI()->ClearInputHandlers(INPUT_MOD); - - // Destroy mimics - #ifdef MTA_DEBUG - list::const_iterator iterMimics = m_Mimics.begin(); - for (; iterMimics != m_Mimics.end(); iterMimics++) - { - CClientPlayer* pPlayer = *iterMimics; - CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); - if (pVehicle) - delete pVehicle; - - delete pPlayer; - } - #endif - - // Hide the transfer box incase it is showing - m_pTransferBox->Hide(); - m_pBigPacketTransferBox->Hide(); - - // Stop async task scheduler - SAFE_DELETE(m_pAsyncTaskScheduler); - - SAFE_DELETE(m_pVoiceRecorder); - - // Singular file download manager - SAFE_DELETE(m_pSingularFileDownloadManager); - - // NULL the message/net stuff - g_pMultiplayer->SetPreContextSwitchHandler(NULL); - g_pMultiplayer->SetPostContextSwitchHandler(NULL); - g_pMultiplayer->SetPreWeaponFireHandler(NULL); - g_pMultiplayer->SetPostWeaponFireHandler(NULL); - g_pMultiplayer->SetBulletImpactHandler(NULL); - g_pMultiplayer->SetBulletFireHandler(NULL); - g_pMultiplayer->SetExplosionHandler(NULL); - g_pMultiplayer->SetBreakTowLinkHandler(NULL); - g_pMultiplayer->SetDrawRadarAreasHandler(NULL); - g_pMultiplayer->SetDamageHandler(NULL); - g_pMultiplayer->SetFireHandler(NULL); - g_pMultiplayer->SetProjectileStopHandler(NULL); - g_pMultiplayer->SetProjectileHandler(NULL); - g_pMultiplayer->SetProcessCamHandler(nullptr); - g_pMultiplayer->SetRender3DStuffHandler(NULL); - g_pMultiplayer->SetPreRenderSkyHandler(NULL); - g_pMultiplayer->SetRenderHeliLightHandler(nullptr); - g_pMultiplayer->SetChokingHandler(NULL); - g_pMultiplayer->SetPreWorldProcessHandler(NULL); - g_pMultiplayer->SetPostWorldProcessHandler(NULL); - g_pMultiplayer->SetPreFxRenderHandler(NULL); - g_pMultiplayer->SetPreHudRenderHandler(NULL); - g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(NULL); - g_pMultiplayer->SetAddAnimationHandler(NULL); - g_pMultiplayer->SetAddAnimationAndSyncHandler(NULL); - g_pMultiplayer->SetAssocGroupCopyAnimationHandler(NULL); - g_pMultiplayer->SetBlendAnimationHierarchyHandler(NULL); - g_pMultiplayer->SetProcessCollisionHandler(NULL); - g_pMultiplayer->SetVehicleCollisionHandler(NULL); - g_pMultiplayer->SetVehicleDamageHandler(NULL); - g_pMultiplayer->SetHeliKillHandler(NULL); - g_pMultiplayer->SetObjectDamageHandler(NULL); - g_pMultiplayer->SetObjectBreakHandler(NULL); - g_pMultiplayer->SetWaterCannonHitHandler(NULL); - g_pMultiplayer->SetGameObjectDestructHandler(NULL); - g_pMultiplayer->SetGameVehicleDestructHandler(NULL); - g_pMultiplayer->SetGamePlayerDestructHandler(NULL); - g_pMultiplayer->SetGameProjectileDestructHandler(NULL); - g_pMultiplayer->SetGameModelRemoveHandler(NULL); - g_pMultiplayer->SetGameEntityRenderHandler(NULL); - g_pMultiplayer->SetDrivebyAnimationHandler(nullptr); - g_pGame->SetPreWeaponFireHandler(NULL); - g_pGame->SetPostWeaponFireHandler(NULL); - g_pGame->SetTaskSimpleBeHitHandler(NULL); - g_pGame->GetAudio()->SetWorldSoundHandler(NULL); - g_pCore->SetMessageProcessor(NULL); - g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); - g_pCore->GetKeyBinds()->SetCharacterKeyHandler(NULL); - g_pNet->StopNetwork(); - g_pNet->RegisterPacketHandler(NULL); - CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); - pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessClientKeyBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessClientControlBind); - pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessServerKeyBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessServerControlBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticUpdateFireKey); - pKeyBinds->SetAllControlsEnabled(true, true, true); - g_pCore->ForceCursorVisible(false); - SetCursorEventsEnabled(false); - - // Destroy our stuff - SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop - SAFE_DELETE(m_pNametags); - SAFE_DELETE(m_pSyncDebug); - SAFE_DELETE(m_pNetworkStats); - SAFE_DELETE(m_pNetAPI); - SAFE_DELETE(m_pRPCFunctions); - SAFE_DELETE(m_pUnoccupiedVehicleSync); - SAFE_DELETE(m_pPedSync); -#ifdef WITH_OBJECT_SYNC - SAFE_DELETE(m_pObjectSync); -#endif - SAFE_DELETE(m_pBlendedWeather); - SAFE_DELETE(m_pMovingObjectsManager); - SAFE_DELETE(m_pRadarMap); - SAFE_DELETE(m_pRemoteCalls); - SAFE_DELETE(m_pLuaManager); - SAFE_DELETE(m_pLatentTransferManager); - SAFE_DELETE(m_pResourceFileDownloadManager); - - SAFE_DELETE(m_pRootEntity); - - SAFE_DELETE(m_pModelCacheManager); - SAFE_DELETE(m_pGameEntityXRefManager); - SAFE_DELETE(m_pZoneNames); - SAFE_DELETE(m_pScriptKeyBinds); - - // Delete the scriptdebugger - SAFE_DELETE(m_pScriptDebugging); - - // Delete the transfer boxes - SAFE_DELETE(m_pTransferBox); - SAFE_DELETE(m_pBigPacketTransferBox); - - SAFE_DELETE(m_pLocalServer); - SAFE_DELETE(m_pDebugHookManager); - - // Packet handler - SAFE_DELETE(m_pPacketHandler); - - // Delete PerfStatManager - delete CClientPerfStatManager::GetSingleton(); - - // NULL the global CClientGame var - g_pClientGame = NULL; - m_bBeingDeleted = false; -} - -/* -bool CClientGame::StartGame ( void ) // for an offline game (e.g. editor) -{ - m_Status = STATUS_OFFLINE; - g_pCore->SetOfflineMod ( true ); // hide chatbox etc - g_pCore->SetConnected ( true ); // not sure, but its required :) - g_pCore->HideMainMenu (); // duh - - // If the game isn't started, start it - if ( g_pGame->GetSystemState () == 7 ) - { - g_pGame->StartGame (); - } - return true; -} -*/ - -#include -//#define _CRTDBG_CHECK_EVERY_16_DF 0x00100000 /* check heap every 16 heap ops */ -//#define _CRTDBG_CHECK_EVERY_128_DF 0x00800000 /* check heap every 128 heap ops */ -//#define _CRTDBG_CHECK_EVERY_1024_DF 0x04000000 /* check heap every 1024 heap ops */ - -void CClientGame::EnablePacketRecorder(const char* szFilename) -{ - m_pManager->GetPacketRecorder()->StartRecord(szFilename, true); -} - -void CClientGame::StartPlayback(void) -{ - // strcpy ( m_szNick, "Playback" ); - - m_bIsPlayingBack = true; - m_bFirstPlaybackFrame = true; - m_pManager->GetPacketRecorder()->SetPacketHandler(CClientGame::StaticProcessPacket); - - if (!m_pManager->IsGameLoaded()) - { - g_pGame->StartGame(); - } -} - -bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerType Type) -{ - m_ServerType = Type; - // int dbg = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ); - // dbg |= _CRTDBG_ALLOC_MEM_DF; - // dbg |= _CRTDBG_CHECK_ALWAYS_DF; - // dbg |= _CRTDBG_DELAY_FREE_MEM_DF; - // dbg |= _CRTDBG_LEAK_CHECK_DF; - //_CrtSetDbgFlag(dbg); - - // Verify that the nickname is valid - if (!IsNickValid(szNick)) - { - g_pCore->ShowMessageBox(_("Error") + _E("CD01"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - // Store our nickname - m_strLocalNick.AssignLeft(szNick, MAX_PLAYER_NICK_LENGTH); - - // Are we connected? - if (g_pNet->IsConnected() || m_bIsPlayingBack) - { - // Hide the console when connecting.. - if (g_pCore->GetConsole()->IsVisible()) - g_pCore->GetConsole()->SetVisible(false); - - // Display the status box - g_pCore->ShowMessageBox(_("CONNECTING"), _("Entering the game ..."), MB_ICON_INFO); - - // Send the initial data to the server - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Hash the password if neccessary - MD5 Password; - memset(Password.data, 0, sizeof(MD5)); - if (szPassword) - { - // Is it long enough? - size_t sizePassword = strlen(szPassword); - if (sizePassword > 0) - { - // Hash the password and put it in the struct - CMD5Hasher Hasher; - Hasher.Calculate(szPassword, sizePassword, Password); - } - } - - // Append version information - pBitStream->Write(static_cast(MTA_DM_NETCODE_VERSION)); - pBitStream->Write(static_cast(MTA_DM_VERSION)); - pBitStream->Write(static_cast(MTA_DM_BITSTREAM_VERSION)); - - SString strPlayerVersion("%d.%d.%d-%d.%05d.%d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, - MTASA_VERSION_BUILD, g_pNet->GetNetRev()); - pBitStream->WriteString(strPlayerVersion); - - pBitStream->WriteBit(g_pCore->IsOptionalUpdateInfoRequired(g_pNet->GetConnectedServer(true))); - - pBitStream->Write(static_cast(g_pGame->GetGameVersion())); - - // Append user details - SString strTemp = StringZeroPadout(m_strLocalNick, MAX_PLAYER_NICK_LENGTH); - pBitStream->Write(strTemp.c_str(), MAX_PLAYER_NICK_LENGTH); - pBitStream->Write(reinterpret_cast(Password.data), sizeof(MD5)); - - // Append community information (Removed) - std::string strUser; - pBitStream->Write(strUser.c_str(), MAX_SERIAL_LENGTH); - - // Send the packet as joindata - g_pNet->SendPacket(PACKET_ID_PLAYER_JOINDATA, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - return true; - } - } - else - { - g_pCore->ShowMessageBox(_("Error") + _E("CD02"), _("Not connected; please use Quick Connect or the 'connect' command to connect to a server."), - MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - } - - return false; -} - -void CClientGame::SetupLocalGame(eServerType Type) -{ - SString strConfig = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; - m_bWaitingForLocalConnect = true; - if (!m_pLocalServer) - m_pLocalServer = new CLocalServer(strConfig); -} - -bool CClientGame::StartLocalGame(eServerType Type, const char* szPassword) -{ - // Verify that the nickname is valid - std::string strNick; - g_pCore->GetCVars()->Get("nick", strNick); - - if (!IsNickValid(strNick.c_str())) - { - g_pCore->ShowMessageBox(_("Error") + _E("CD03"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - m_bWaitingForLocalConnect = false; - m_ServerType = Type; - SString strTemp = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; - - SAFE_DELETE(m_pLocalServer); - - // Store our nickname - m_strLocalNick.AssignLeft(strNick.c_str(), MAX_PLAYER_NICK_LENGTH); - - // Got a server? - if (m_bLocalPlay) - { - // Start the server locally - if (!m_Server.Start(strTemp)) - { - m_bWaitingForLocalConnect = true; - m_bErrorStartingLocal = true; - g_pCore->ShowMessageBox(_("Error") + _E("CD04"), _("The server is not installed"), MB_ICON_ERROR | MB_BUTTON_OK); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - if (szPassword) - m_Server.SetPassword(szPassword); - - // Display the status box<<<<< - m_OnCancelLocalGameClick = GUI_CALLBACK(&CClientGame::OnCancelLocalGameClick, this); - g_pCore->ShowMessageBox(_("Local Server"), _("Starting local server ..."), MB_BUTTON_CANCEL | MB_ICON_INFO, &m_OnCancelLocalGameClick); - } - else - { - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - // We're waiting for connection - m_bWaitingForLocalConnect = true; - return true; -} - -bool CClientGame::OnCancelLocalGameClick(CGUIElement* pElement) -{ - if (m_bLocalPlay && m_bWaitingForLocalConnect) - { - g_pCore->RemoveMessageBox(); - g_pCore->GetModManager()->RequestUnload(); - return true; - } - return false; -} - -void CClientGame::DoPulsePreFrame(void) -{ - if (m_Status == CClientGame::STATUS_JOINED) - { - if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) - { - m_pVoiceRecorder->DoPulse(); - } - } -} - -void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRenderTargets) -{ - // Allow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); - - // If appropriate, call onClientRestore - if (bDidUnminimize) - { - CLuaArguments Arguments; - Arguments.PushBoolean(bDidRecreateRenderTargets); - m_pRootEntity->CallEvent("onClientRestore", Arguments, false); - m_bWasMinimized = false; - - // Reverse any mute on minimize effects - g_pGame->GetAudio()->SetEffectsMasterVolume(g_pGame->GetSettings()->GetSFXVolume()); - g_pGame->GetAudio()->SetMusicMasterVolume(g_pGame->GetSettings()->GetRadioVolume()); - m_pManager->GetSoundManager()->SetMinimizeMuted(false); - } - - // Call onClientHUDRender LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientHUDRender", Arguments, false); - - // Disallow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); - - // Restore in case script forgets - g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); - - DebugElementRender(); -} - -void CClientGame::DoPulsePostFrame(void) -{ - TIMING_CHECKPOINT("+CClientGame::DoPulsePostFrame"); - #ifdef DEBUG_KEYSTATES - // Get the controller state - CControllerState cs; - g_pGame->GetPad()->GetCurrentControllerState(&cs); - - SString strBuffer; - strBuffer = SString::Printf( - "LeftShoulder1: %u\n" - "LeftShoulder2: %u\n" - "RightShoulder1: %u\n" - "RightShoulder2: %u\n" - "DPadUp: %u\n" - "DPadDown: %u\n" - "DPadLeft: %u\n" - "DPadRight: %u\n" - "Start: %u\n" - "Select: %u\n" - "ButtonSquare: %u\n" - "ButtonTriangle: %u\n" - "ButtonCross: %u\n" - "ButtonCircle: %u\n" - "ShockButtonL: %u\n" - "ShockButtonR: %u\n" - "PedWalk: %u\n", - cs.LeftShoulder1, cs.LeftShoulder2, cs.RightShoulder1, cs.RightShoulder2, cs.DPadUp, cs.DPadDown, cs.DPadLeft, cs.DPadRight, cs.Start, cs.Select, - cs.ButtonSquare, cs.ButtonTriangle, cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.ShockButtonR, cs.m_bPedWalk); - - g_pCore->GetGraphics()->DrawTextTTF(300, 10, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); - - strBuffer = SString::Printf( - "VehicleMouseLook: %u\n" - "LeftStickX: %u\n" - "LeftStickY: %u\n" - "RightStickX: %u\n" - "RightStickY: %u", - cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, cs.RightStickX, cs.RightStickY); - - g_pCore->GetGraphics()->DrawTextTTF(300, 320, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); - #endif - - UpdateModuleTickCount64(); - - if (m_pManager->IsGameLoaded()) - { - // Pulse the nametags before anything that changes player positions, we'll be 1 frame behind, but so is the camera - // If nametags are enabled, pulse the nametag manager - if (m_bShowNametags) - { - m_pNametags->DoPulse(); - } - - // Sync debug - m_pSyncDebug->OnPulse(); - - // Also eventually draw FPS - if (m_bShowFPS) - { - DrawFPS(); - } - - CGraphicsInterface* pGraphics = g_pCore->GetGraphics(); - unsigned int uiHeight = pGraphics->GetViewportHeight(); - unsigned int uiWidth = pGraphics->GetViewportWidth(); - - // Draw a little star in the corner if async is on - if (g_pGame->IsASyncLoadingEnabled(true)) - { - unsigned int uiPosY = g_pGame->IsASyncLoadingEnabled() ? uiHeight - 7 : uiHeight - 12; - pGraphics->DrawString(uiWidth - 5, uiPosY, 0x80ffffff, 1, "*"); - } - - // Draw notice text if dx test mode is enabled - if (g_pCore->GetGraphics()->GetRenderItemManager()->GetTestMode()) - { - unsigned int uiPosY = uiHeight - 30; - pGraphics->DrawString(uiWidth - 155, uiPosY, 0x40ffffff, 1, "dx test mode enabled"); - } - - // Draw notice text if diagnostic mode enabled - EDiagnosticDebugType diagnosticDebug = g_pCore->GetDiagnosticDebug(); - if (diagnosticDebug == EDiagnosticDebug::LOG_TIMING_0000) - { - unsigned int uiPosY = uiHeight - 30; - pGraphics->DrawString(uiWidth - 185, uiPosY, 0xffffff00, 1, "Debug setting: #0000 Log timing"); - } - - // Draw network trouble message if required - if (m_pNetAPI->IsNetworkTrouble()) - { - int iPosX = uiWidth / 2; // Half way across - int iPosY = uiHeight * 45 / 100; // 45/100 down - g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, - DT_NOCLIP | DT_CENTER); - } - - // Adjust the streaming memory limit. - unsigned int uiStreamingMemoryPrev; - g_pCore->GetCVars()->Get("streaming_memory", uiStreamingMemoryPrev); - uint uiStreamingMemory = SharedUtil::Clamp(g_pCore->GetMinStreamingMemory(), uiStreamingMemoryPrev, g_pCore->GetMaxStreamingMemory()); - if (uiStreamingMemory != uiStreamingMemoryPrev) - g_pCore->GetCVars()->Set("streaming_memory", uiStreamingMemory); - - int iStreamingMemoryBytes = static_cast(uiStreamingMemory) * 1024 * 1024; - if (g_pMultiplayer->GetLimits()->GetStreamingMemory() != iStreamingMemoryBytes) - g_pMultiplayer->GetLimits()->SetStreamingMemory(iStreamingMemoryBytes); - - // If we're in debug mode and are supposed to show task data, do it - #ifdef MTA_DEBUG - if (m_pShowPlayerTasks) - { - DrawTasks(m_pShowPlayerTasks); - } - - if (m_pShowPlayer) - { - DrawPlayerDetails(m_pShowPlayer); - } - - std::vector::const_iterator iter = m_pPlayerManager->IterBegin(); - for (; iter != m_pPlayerManager->IterEnd(); ++iter) - { - CClientPlayer* pPlayer = *iter; - if (pPlayer->IsStreamedIn() && pPlayer->IsShowingWepdata()) - DrawWeaponsyncData(pPlayer); - } - #endif - - #if defined (MTA_DEBUG) || defined (MTA_BETA) - if (m_bShowSyncingInfo) - { - // Draw the header boxz - CVector vecPosition = CVector(0.05f, 0.32f, 0); - m_pDisplayManager->DrawText2D("Syncing vehicles:", vecPosition, 1.0f, 0xFFFFFFFF); - - // Print each vehicle we're syncing - CDeathmatchVehicle* pVehicle; - list::const_iterator iter = m_pUnoccupiedVehicleSync->IterBegin(); - for (; iter != m_pUnoccupiedVehicleSync->IterEnd(); iter++) - { - vecPosition.fY += 0.03f; - pVehicle = *iter; - - SString strBuffer("ID: %u (%s)", pVehicle->GetID(), pVehicle->GetNamePointer()); - - m_pDisplayManager->DrawText2D(strBuffer, vecPosition, 1.0f, 0xFFFFFFFF); - } - } - #endif - // Heli Clear time - if (m_LastClearTime.Get() > HeliKill_List_Clear_Rate) - { - // Clear our list now - m_HeliCollisionsMap.clear(); - m_LastClearTime.Reset(); - } - - CClientPerfStatManager::GetSingleton()->DoPulse(); - } - - m_pRadarMap->DoRender(); - m_pManager->DoRender(); - DoPulses(); - - // If we're supposed to show netstat, draw them infront of everything else - if (m_bShowNetstat) - { - m_pNetworkStats->Draw(); - } -} - -void CClientGame::DoPulses(void) -{ - TIMING_CHECKPOINT("-CClientGame::DoPulsePostFrame"); - - g_pCore->ApplyFrameRateLimit(); - - TIMING_CHECKPOINT("+CClientGame::DoPulses"); - - m_BuiltCollisionMapThisFrame = false; - - if (m_bIsPlayingBack && m_bFirstPlaybackFrame && m_pManager->IsGameLoaded()) - { - g_pCore->GetConsole()->Printf("First playback frame, starting"); - m_pManager->GetPacketRecorder()->StartPlayback("log.rec", false); - m_bFirstPlaybackFrame = false; - } - - // Call debug code if debug mode - m_Foo.DoPulse(); - - // Output stuff from our internal server eventually - m_Server.DoPulse(); - - if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED && GetTickCount64_() - m_llLastTransgressionTime > 60000) - { - uint uiLevel = 0; - uint uiInform = 0; - SString strMessage; - - // Is the player a cheater? - if (!m_pManager->GetAntiCheat().PerformChecks()) - { - uiLevel = 1; - uiInform = 2; - } - else - { - strMessage = g_pNet->GetNextBuffer(); - if (strMessage.length()) - { - uiLevel = atoi(strMessage.SplitLeft(":", &strMessage)); - uiInform = atoi(strMessage.SplitLeft(":", &strMessage)); - } - } - - // Send message to the server - if (uiLevel) - { - SString strPrefix = (uiInform == 2) ? "AC" : (uiInform == 1) ? "VF" : "SD"; - SString strMessageCombo = SString("%s #%d %s", *strPrefix, uiLevel, strMessage.c_str()).TrimEnd(" "); - m_llLastTransgressionTime = GetTickCount64_(); - AddReportLog(3100, strMessageCombo + SString(" (%d)", uiInform)); - - if (uiInform > 0) - { - // The server will use the whole message as supplied here - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write(uiLevel); - pBitStream->WriteString(strMessageCombo); - g_pNet->SendPacket(PACKET_ID_PLAYER_TRANSGRESSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - else - { - // Otherwise, disconnect here - AddReportLog(7105, SString("Core - Kicked (%s)", *strMessageCombo)); - g_pCore->ShowMessageBox(_("Error") + _E("CD05"), SString(_("You were kicked from the game ( %s )"), *strMessageCombo), - MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - } - - // Send diagnostic info - if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED) - { - // Retrieve data - SString strMessage = g_pNet->GetDiagnosticStatus(); - - // Send to the server if changed - if (strMessage != m_strLastDiagnosticStatus) - { - m_strLastDiagnosticStatus = strMessage; - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->WriteString(strMessage); - g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } - - // Pulse the network interface - - // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) - DoPulses2(false); - - m_pUnoccupiedVehicleSync->DoPulse(); - m_pPedSync->DoPulse(); -#ifdef WITH_OBJECT_SYNC - m_pObjectSync->DoPulse(); -#endif - m_pLatentTransferManager->DoPulse(); - m_pLuaManager->DoPulse(); - m_pScriptDebugging->UpdateLogOutput(); - - GetModelCacheManager()->DoPulse(); - - #ifdef MTA_DEBUG - UpdateMimics(); - #endif - - // Grab the current time - unsigned long ulCurrentTime = CClientTime::GetTime(); - - // Waiting for a connect? - if (m_bWaitingForLocalConnect) - { - // Connected? - if (g_pNet->IsConnected()) - { - // No longer waiting for connect - m_bWaitingForLocalConnect = false; - - // Assume local server has the same bitstream version - g_pNet->SetServerBitStreamVersion(MTA_DM_BITSTREAM_VERSION); - - // Run the game normally. - StartGame(m_strLocalNick, m_Server.GetPassword().c_str(), m_ServerType); - } - else - { - // Going to try connecting? Do this when the internal server has booted - // and we haven't started the connecting. - if (m_Server.IsReady() && m_iLocalConnectAttempts == 0) - { - g_pCore->ShowMessageBox(_("Local Server"), _("Connecting to local server..."), MB_ICON_INFO); - - // Connect - if (g_pNet->StartNetwork("localhost", 22010)) - { - // We're waiting for connection - m_iLocalConnectAttempts = 1; - m_ulTimeStart = CClientTime::GetTime(); - } - else - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD06"), _("Error connecting to server.")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - - // Timeout? - if (m_ulTimeStart != 0 && CClientTime::GetTime() >= m_ulTimeStart + 5000) - { - // Show timeout message and disconnect - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD07"), _("Connecting to local server timed out. See console for details.")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - } - - // If the game is loaded ... - if (m_pManager->IsGameLoaded()) - { - // Pulse the blended weather manager - m_pBlendedWeather->DoPulse(); - - // If we weren't ingame last frame; call the on ingame event - if (!m_bGameLoaded) - { - // Fix for gta not being focused sometimes - SetActiveWindow(g_pCore->GetHookedWindow()); - SetFocus(g_pCore->GetHookedWindow()); - - m_bGameLoaded = true; - Event_OnIngame(); - } - - // Check if the player is hitting the enter vehicle button - DoVehicleInKeyCheck(); - - // Pulse some stuff - m_pMovingObjectsManager->DoPulse(); - - // Get rid of our deleted elements - m_ElementDeleter.DoDeleteAll(); - m_pLuaManager->ProcessPendingDeleteList(); - - // Get rid of deleted GUI elements - g_pCore->GetGUI()->CleanDeadPool(); - - // Allow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); - - // Call onClientRender LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientRender", Arguments, false); - - // Disallow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); - - // Restore in case script forgets - g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); - - // Ensure replaced/restored textures for models in the GTA map are correct - g_pGame->FlushPendingRestreamIPL(); - - // Respawn objects in respawn pool - m_ObjectRespawner.DoRespawnAll(); - } - - // Are we connecting? - if (m_Status == CClientGame::STATUS_CONNECTING) - { - if (m_bErrorStartingLocal) - { - g_pCore->GetModManager()->RequestUnload(); - return; - } - - // Timed out? - if (!m_bWaitingForLocalConnect && ulCurrentTime >= m_ulTimeStart + NET_CONNECT_TIMEOUT) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD08"), _("Connection timed out"), "connect-timed-out", true); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - else if (m_Status == CClientGame::STATUS_JOINED) - { - // Pulse DownloadFiles if we're transferring stuff - GetResourceFileDownloadManager()->DoPulse(); - DownloadSingularResourceFiles(); - GetRemoteCalls()->ProcessQueuedFiles(); - } - - // Not waiting for local connect? - if (!m_bWaitingForLocalConnect) - { - // Trigger the ingame and connected event - if (!m_bTriggeredIngameAndConnected && m_pManager->IsGameLoaded() && g_pCore->IsConnected()) - { - m_bTriggeredIngameAndConnected = true; - Event_OnIngameAndConnected(); - - // Initialize the game - g_pCore->GetGame()->Initialize(); - } - - unsigned char ucError = g_pNet->GetConnectionError(); - - // Lost connection? - if (!g_pNet->IsConnected() && !m_bGracefulDisconnect && !m_bIsPlayingBack) - { - // See if we can figure out what specifically it was - if (ucError == 0) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD09"), _("Connection with the server was lost")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - else - { - SString strError; - SString strErrorCode; - switch (ucError) - { - case RID_RSA_PUBLIC_KEY_MISMATCH: - strError = _("Disconnected: unknown protocol error"); - strErrorCode = _E("CD10"); // encryption key mismatch - break; - case RID_REMOTE_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected remotely"); - strErrorCode = _E("CD11"); - break; - case RID_REMOTE_CONNECTION_LOST: - strError = _("Disconnected: connection lost remotely"); - strErrorCode = _E("CD12"); - break; - case RID_CONNECTION_BANNED: - strError = _("Disconnected: you are banned from this server"); - strErrorCode = _E("CD13"); - break; - case RID_NO_FREE_INCOMING_CONNECTIONS: - strError = _("Disconnected: the server is currently full"); - strErrorCode = _E("CD14"); - break; - case RID_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected from the server"); - strErrorCode = _E("CD15"); - break; - case RID_CONNECTION_LOST: - strError = _("Disconnected: connection to the server was lost"); - strErrorCode = _E("CD16"); - break; - case RID_INVALID_PASSWORD: - strError = _("Disconnected: invalid password specified"); - strErrorCode = _E("CD17"); - break; - default: - strError = _("Disconnected: connection was refused"); - strErrorCode = _E("CD18"); - break; - } - - // Display an error, reset the error status and exit - g_pCore->ShowNetErrorMessageBox(_("Error") + strErrorCode, strError); - g_pNet->SetConnectionError(0); - g_pCore->GetModManager()->RequestUnload(); - } - } - - // If we're in the verificating status - if (m_Status == CClientGame::STATUS_JOINING) - { - // Time out the verification if it takes too long - if (m_ulVerifyTimeStart != 0 && ulCurrentTime >= m_ulVerifyTimeStart + CLIENT_VERIFICATION_TIMEOUT) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD19"), _("MTA Client verification failed!")); - g_pCore->GetModManager()->RequestUnload(); - } - } - } - - // Check for radar input - m_pRadarMap->DoPulse(); - g_pCore->GetGraphics()->SetAspectRatioAdjustmentSuspended(m_pRadarMap->IsRadarShowing()); - - // Got a local player? - if (m_pLocalPlayer) - { - // Network updates - UpdateVehicleInOut(); - UpdatePlayerTarget(); - UpdatePlayerWeapons(); - // UpdateTrailers (); // Test: Does it always work without this check? - UpdateStunts(); - // Clear last damager if more than 2 seconds old - if (CClientTime::GetTime() - m_ulDamageTime > 2000) - { - m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageWeapon = 0xFF; - m_ucDamageBodyPiece = 0xFF; - } - DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); - } - - // Game hacks, restore certain variables - // game-speed changes after spawning - g_pGame->SetGameSpeed(m_fGameSpeed); - // money changes on death/getting into taxis - g_pGame->GetPlayerInfo()->SetPlayerMoney(m_lMoney); - // wanted to stop it changing on skin change etc - if (m_pLocalPlayer) - { - if (m_dwWanted != g_pGame->GetPlayerInfo()->GetWanted()->GetWantedLevel()) - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevelNoFlash(m_dwWanted); - } - // stop players dying from starvation - g_pGame->GetPlayerInfo()->SetLastTimeEaten(0); - // reset weapon logs (for preventing quickreload) - - // Update streaming - m_pManager->UpdateStreamers(); - - // Send screen shot data - ProcessDelayedSendList(); - - // Collect async task scheduler results - m_pAsyncTaskScheduler->CollectResults(); - - TIMING_CHECKPOINT("-CClientGame::DoPulses"); -} - -// Extrapolation test -void CClientGame::DoPulses2(bool bCalledFromIdle) -{ - bool bIsUsingAlternatePulseOrder = IsUsingAlternatePulseOrder(!bCalledFromIdle); - - // Figure out which pulses to do - bool bDoStandardPulses; - bool bDoVehicleManagerPulse; - - if (!bIsUsingAlternatePulseOrder) - { - // With std pulse order, do pulses when not called from idle - bDoStandardPulses = !bCalledFromIdle; - bDoVehicleManagerPulse = !bCalledFromIdle; - } - else - { - // With alt pulse order, do pulses when called from idle - bDoStandardPulses = bCalledFromIdle; - bDoVehicleManagerPulse = bCalledFromIdle; - - // Except when watching a remote synced vehicle - if (CClientVehicle* pTargetVehicle = DynamicCast(m_pCamera->GetTargetEntity())) - if (pTargetVehicle->GetControllingPlayer() != m_pPlayerManager->GetLocalPlayer()) - bDoVehicleManagerPulse = !bDoVehicleManagerPulse; - } - - if (bDoStandardPulses) - { - // Change to high precision so arguments in element data and events can - // be rounded to look more like what is expected - ChangeFloatPrecision(true); - - // Pulse the network interface - TIMING_CHECKPOINT("+NetPulse"); - g_pNet->DoPulse(); - TIMING_CHECKPOINT("-NetPulse"); - - // Change precision back, and check we are in low precision mode 4 sure - ChangeFloatPrecision(false); - assert(!IsHighFloatPrecision()); - } - - m_pManager->DoPulse(bDoStandardPulses, bDoVehicleManagerPulse); - - if (bDoStandardPulses) - { - m_pNetAPI->DoPulse(); - } -} - -void CClientGame::HandleException(CExceptionInformation* pExceptionInformation) -{ -} - -void CClientGame::HandleRadioNext(CControlFunctionBind*) -{ - if (g_pClientGame) - { - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); - if (pPlayer) - { - pPlayer->NextRadioChannel(); - } - } -} - -void CClientGame::HandleRadioPrevious(CControlFunctionBind*) -{ - if (g_pClientGame) - { - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); - if (pPlayer) - { - pPlayer->PreviousRadioChannel(); - } - } -} -bool CClientGame::IsNametagValid(const char* szNick) -{ - // Grab the size of the nametag. Check that it's not to long or short - size_t sizeNick = MbUTF8ToUTF16(szNick).size(); - if (sizeNick < MIN_PLAYER_NAMETAG_LENGTH || sizeNick > MAX_PLAYER_NAMETAG_LENGTH) - { - return false; - } - - // Check that each character is valid (Anything above 32) - unsigned char ucTemp; - for (size_t i = 0; i < sizeNick; i++) - { - ucTemp = szNick[i]; - if (ucTemp < 32) - { - return false; - } - } - - // nametag is valid, return true - return true; -} - -bool CClientGame::IsNickValid(const char* szNick) -{ - // Grab the size of the nick. Check that it's within the player - size_t sizeNick = strlen(szNick); - if (sizeNick < MIN_PLAYER_NICK_LENGTH || sizeNick > MAX_PLAYER_NICK_LENGTH) - { - return false; - } - - // Check that each character is valid (visible characters exluding space) - unsigned char ucTemp; - for (size_t i = 0; i < sizeNick; i++) - { - ucTemp = szNick[i]; - if (ucTemp < 33 || ucTemp > 126) - { - return false; - } - } - - // Nickname is valid, return true - return true; -} - -void CClientGame::ShowNetstat(int iCmd) -{ - bool bShow = (iCmd == 1) ? true : (iCmd == 0) ? false : !m_bShowNetstat; - - if (bShow && !m_bShowNetstat) - { - m_pNetworkStats->Reset(); - } - m_bShowNetstat = bShow; -} - -void CClientGame::ShowEaeg(bool) -{ - if (m_pLocalPlayer) - m_pLocalPlayer->SetStat(0x2329, 1.0f); -} - -#ifdef MTA_WEPSYNCDBG -void CClientGame::ShowWepdata(const char* szNick) -{ - CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); - if (pPlayer) - { - pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); - } -} -#endif - -#ifdef MTA_DEBUG - -void CClientGame::ShowWepdata(const char* szNick) -{ - CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); - if (pPlayer) - { - pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); - } -} - -void CClientGame::ShowPlayer(const char* szNick) -{ - m_pShowPlayer = m_pPlayerManager->Get(szNick); -} - -void CClientGame::ShowTasks(const char* szNick) -{ - m_pShowPlayerTasks = m_pPlayerManager->Get(szNick); -} - -void CClientGame::SetMimic(unsigned int uiMimicCount) -{ - // Check if we're within the max mimics boundary - if (uiMimicCount > MAX_MIMICS) - return; - - // Create neccessary players - while (m_Mimics.size() < uiMimicCount) - { - CClientPlayer* pPlayer = new CClientPlayer(m_pManager, static_cast(MAX_NET_PLAYERS_REAL + (int)m_Mimics.size())); - pPlayer->SetNick("Mimic"); - m_Mimics.push_back(pPlayer); - } - - // Destroy neccessary players - while (m_Mimics.size() > uiMimicCount) - { - CClientPlayer* pPlayer = m_Mimics.back(); - CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); - if (pVehicle) - delete pVehicle; - - delete pPlayer; - m_Mimics.pop_back(); - } -} - -#endif - -void CClientGame::DoVehicleInKeyCheck(void) -{ - // Grab the controller state - CControllerState cs; - g_pGame->GetPad()->GetCurrentControllerState(&cs); - static bool bButtonTriangleWasDown = false; - if (cs.ButtonTriangle) - { - if (!bButtonTriangleWasDown) - { - bButtonTriangleWasDown = true; - - // Process the hit - ProcessVehicleInOutKey(false); - } - } - else - { - bButtonTriangleWasDown = false; - } -} - -void CClientGame::UpdateVehicleInOut(void) -{ - // We got told by the server to animate into a certain vehicle? - if (m_VehicleInOutID != INVALID_ELEMENT_ID) - { - // Grab the vehicle we're getting in/out of - CDeathmatchVehicle* pInOutVehicle = static_cast(m_pVehicleManager->Get(m_VehicleInOutID)); - - // In or out? - if (m_bIsGettingOutOfVehicle) - { - // If we aren't working on leaving the car (he's eiter finished or cancelled/failed leaving) - if (!m_pLocalPlayer->IsLeavingVehicle()) - { - // Are we outside the car? - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - if (!pVehicle) - { - // Tell the server that we successfully left the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction = VEHICLE_NOTIFY_OUT; - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself out (so we're sure the records are correct) - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it, and damagable if we're syncing it - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - }*/ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - - // Reset the vehicle in out stuff so we're ready for another car entry/leave. - // Don't allow a new entry/leave until we've gotten the notify return packet - ElementID ReasonVehicleID = m_VehicleInOutID; - g_pClientGame->ResetVehicleInOut(); - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = ReasonVehicleID; - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_out"); -#endif - } - // Are we still inside the car? - else - { - // Warp us out now to keep in sync with the server - m_pLocalPlayer->RemoveFromVehicle(); - } - } - } - - // Are we getting into a vehicle? - else if (m_bIsGettingIntoVehicle) - { - // If we aren't working on entering the car (he's either finished or cancelled) - if (!m_pLocalPlayer->IsEnteringVehicle()) - { - // Is he in a vehicle now? - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - if (pVehicle) - { - // Tell the server that we successfully entered the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction; - - if (m_bIsJackingVehicle) - { - ucAction = static_cast(VEHICLE_NOTIFY_JACK); -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack"); -#endif - } - else - { - ucAction = static_cast(VEHICLE_NOTIFY_IN); -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in"); -#endif - } - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself in (so we're sure the records are correct) - pVehicle->AllowDoorRatioSetting(m_pLocalPlayer->m_ucEnteringDoor, true); - m_pLocalPlayer->WarpIntoVehicle(pVehicle, m_ucVehicleInOutSeat); - - /* - // Make it damagable - if ( pInOutVehicle ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - */ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - } - else - { - // Tell the server that we aborted entered the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction; - if (m_bIsJackingVehicle) - { - ucAction = static_cast(VEHICLE_NOTIFY_JACK_ABORT); - pBitStream->WriteBits(&ucAction, 4); - - // Did we start jacking them? - bool bAlreadyStartedJacking = false; - CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); - if (pVehicle) - { - CClientPed* pJackedPlayer = pVehicle->GetOccupant(); - if (pJackedPlayer) - { - // Jax: have we already started to jack the other player? - if (pJackedPlayer->IsGettingJacked()) - { - bAlreadyStartedJacking = true; - } - } - unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; - pBitStream->WriteBits(&ucDoor, 3); - SDoorOpenRatioSync door; - door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); - pBitStream->Write(&door); - } - pBitStream->WriteBit(bAlreadyStartedJacking); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack_abort"); -#endif - } - else - { - ucAction = static_cast(VEHICLE_NOTIFY_IN_ABORT); - pBitStream->WriteBits(&ucAction, 4); - CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); - if (pVehicle) - { - unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; - pBitStream->WriteBits(&ucDoor, 3); - SDoorOpenRatioSync door; - door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); - pBitStream->Write(&door); - } - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in_abort"); -#endif - } - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself out again (so we're sure the records are correct) - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it, and damagable if we're syncing it - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - } - */ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - } - - // Reset - // Don't allow a new entry/leave until we've gotten the notify return packet - ElementID ReasonID = m_VehicleInOutID; - ResetVehicleInOut(); - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = ReasonID; - } - } - } - else - { - // If we aren't getting jacked - if (!m_bIsGettingJacked) - { - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - - // Jax: this was commented, re-comment if it was there for a reason (..and give the reason!) - // Are we in a vehicle we aren't supposed to be in? - if (pVehicle && !pOccupiedVehicle) - { - g_pCore->GetConsole()->Print("You shouldn't be in this vehicle"); - m_pLocalPlayer->RemoveFromVehicle(); - } - - // Are we supposed to be in a vehicle? But aren't? - if (pOccupiedVehicle && !pVehicle) - { - // Jax: this happens when we try to warp into a streamed out vehicle, including when we use CClientVehicle::StreamInNow - // ..maybe we need a different way to detect bike falls? - - // Tell the server - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Vehicle id - pBitStream->Write(pOccupiedVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_NOTIFY_FELL_OFF); - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're not allowed to enter any vehicle before we get a confirm - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = pOccupiedVehicle->GetID(); - - // Remove him from the vehicle - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it - CDeathmatchVehicle* pInOutVehicle = static_cast < CDeathmatchVehicle* > ( pOccupiedVehicle ); - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - } - */ - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_fell_off"); -#endif - } - } - } - } -} - -void CClientGame::UpdatePlayerTarget(void) -{ - CControllerState ControllerState; - m_pLocalPlayer->GetControllerState(ControllerState); - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - - // Ignore the local player so we don't get hit - m_pLocalPlayer->WorldIgnore(true); - - // Run a process line of sight and look for an entity we target - CEntity* pColEntity = NULL; - CColPoint* pColPoint = NULL; - g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pColEntity); - - // Unignore the local player again - m_pLocalPlayer->WorldIgnore(false); - - // Kill the colpoint or we get a severe memoryleak - if (pColPoint) - pColPoint->Destroy(); - - if (pColEntity != m_pTargetedGameEntity) - { - m_pTargetedGameEntity = pColEntity; - - if (pColEntity) - { - m_pTargetedEntity = m_pManager->FindEntity(pColEntity); - } - else - m_pTargetedEntity = NULL; - - // Store the last targeted player's id - if (m_pTargetedEntity && m_pTargetedEntity->GetType() == CCLIENTPLAYER) - { - m_TargetedPlayerID = m_pTargetedEntity->GetID(); - } - else - m_TargetedPlayerID = INVALID_ELEMENT_ID; - - // Send the target - ElementID TargetID = INVALID_ELEMENT_ID; - if (m_pTargetedEntity && !m_pTargetedEntity->IsLocalEntity()) - { - TargetID = m_pTargetedEntity->GetID(); - } - - CBitStream bitStream; - bitStream.pBitStream->Write(TargetID); - m_pNetAPI->RPC(PLAYER_TARGET, bitStream.pBitStream); - - // Call our onClientPlayerTarget event - CLuaArguments Arguments; - if (m_pTargetedEntity) - Arguments.PushElement(m_pTargetedEntity); - else - Arguments.PushBoolean(false); - m_pLocalPlayer->CallEvent("onClientPlayerTarget", Arguments, true); - } -} - -void CClientGame::UpdatePlayerWeapons(void) -{ - // Check whether we changed weapon slots - eWeaponSlot currentSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - if (currentSlot != m_lastWeaponSlot) - { - CLuaArguments Arguments; - Arguments.PushNumber(m_lastWeaponSlot); - Arguments.PushNumber(currentSlot); - bool bCancelled = !m_pLocalPlayer->CallEvent("onClientPlayerWeaponSwitch", Arguments, true); - - if (bCancelled) - { - // Save the current ammo in clip - unsigned short usAmmoInClip = 0; - CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); - if (pWeapon) - usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); - - // Force it back to the old slot - m_pLocalPlayer->SetCurrentWeaponSlot(m_lastWeaponSlot); - - // Restore the ammo in clip that there was in that slot - if (usAmmoInClip > 0) - m_pLocalPlayer->GetWeapon()->SetAmmoInClip(usAmmoInClip); - } - else - { - CBitStream bitStream; - CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(); - NetBitStreamInterface& BitStream = *(bitStream.pBitStream); - SWeaponSlotSync slot; - - // Always send bit in case server is not in sync - if ((BitStream.Version() >= 0x44 && m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN) || BitStream.Version() >= 0x4D) - { - CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); - if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && - (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || - (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) - BitStream.WriteBit(true); - else - BitStream.WriteBit(false); - } - - if (pWeapon) - { - /* Send a packet to the server with info about the new weapon, - so the server stays in sync reliably */ - unsigned int uiSlot = static_cast(pWeapon->GetSlot()); - slot.data.uiSlot = uiSlot; - BitStream.Write(&slot); - - if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) - { - SWeaponAmmoSync ammo(pWeapon->GetType(), true, true); - ammo.data.usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); - ammo.data.usTotalAmmo = static_cast(pWeapon->GetAmmoTotal()); - BitStream.Write(&ammo); - } - } - else - { - slot.data.uiSlot = 0; - BitStream.Write(&slot); - } - - m_pNetAPI->RPC(PLAYER_WEAPON, bitStream.pBitStream); - m_lastWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - } - } -} - -void CClientGame::UpdateTrailers(void) -{ - // This function is here to re-attach trailers if they fall off - - unsigned long ulCurrentTime = GetTickCount32(); - - CClientVehicle * pVehicle = NULL, *pTrailer = NULL; - CVehicle * pGameVehicle = NULL, *pGameTrailer = NULL; - unsigned long ulIllegalTowBreakTime; - vector::const_iterator iterVehicles = m_pVehicleManager->StreamedBegin(); - for (; iterVehicles != m_pVehicleManager->StreamedEnd(); iterVehicles++) - { - pVehicle = *iterVehicles; - ulIllegalTowBreakTime = pVehicle->GetIllegalTowBreakTime(); - - // Do we have an illegal break? - if (ulIllegalTowBreakTime != 0) - { - // Has it been atleast 1 second since the break - if (ulCurrentTime > (ulIllegalTowBreakTime + 1000)) - { - // Try to re-attach them - CClientVehicle* pTowedBy = pVehicle->GetTowedByVehicle(); - if (pTowedBy) - { - // Little hack to keep illegaly detached trailers close to their tower - CVector vecPosition; - pVehicle->GetPosition(vecPosition); - pVehicle->SetPosition(vecPosition); - - pGameVehicle = pTowedBy->GetGameVehicle(); - pGameTrailer = pVehicle->GetGameVehicle(); - if (pGameVehicle && pGameTrailer) - { - // pGameTrailer->SetTowLink ( pGameVehicle ); - CVector vecRotation; - pTowedBy->GetRotationRadians(vecRotation); - pVehicle->SetRotationRadians(vecRotation); - pTowedBy->InternalSetTowLink(pVehicle); - } - } - - // Reset the break time, even if we couldnt re-attach it - pVehicle->SetIllegalTowBreakTime(0); - } - } - } -} - -void CClientGame::UpdateFireKey(void) -{ - if (m_pLocalPlayer) - { - SBindableGTAControl* pControl = g_pCore->GetKeyBinds()->GetBindableFromControl("fire"); - - // Is our 'fire' control enabled? - if (pControl->bEnabled) - { - // ** Satchel charge detonation ** - { - // Do we have a detonator in our hand? - if (m_pLocalPlayer->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_DETONATOR) - { - // Planted any satchels? - if (m_pLocalPlayer->CountProjectiles(WEAPONTYPE_REMOTE_SATCHEL_CHARGE) > 0) - { - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - - // Tell the server we want to detonate our satchels - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - g_pNet->SendPacket(PACKET_ID_DETONATE_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } - // Remove the detonator if we dont have any satchels planted - else - { - m_pLocalPlayer->RemoveWeapon(WEAPONTYPE_DETONATOR); - } - } - } - - // Has our control state been cut short? - if (!pControl->bState) - return; - - // ** Stealth kill ** - { - if (m_pLocalPlayer->IsStealthAiming()) - { - // Do we have a target ped? - CClientPed* pTargetPed = m_pLocalPlayer->GetTargetedPed(); - if (pTargetPed) - { - // Do we have a target player? - if (IS_PLAYER(pTargetPed)) - { - CClientPlayer* pTargetPlayer = static_cast(pTargetPed); - - // Is the targetted player on a team - CClientTeam* pTeam = pTargetPlayer->GetTeam(); - if (pTeam) - { - // Is this friendly-fire? - if (pTargetPlayer->IsOnMyTeam(m_pLocalPlayer) && !pTeam->GetFriendlyFire()) - { - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - return; - } - } - } - CPlayerPed* pGameTarget = static_cast(pTargetPed)->GetGamePlayer(); - if (pGameTarget) - { - // Would GTA let us stealth kill now? - if (m_pLocalPlayer->GetGamePlayer()->GetPedIntelligence()->TestForStealthKill(pGameTarget, false)) - { - // Grab our local position - CVector vecLocalPosition; - m_pLocalPlayer->GetPosition(vecLocalPosition); - - // Grab the target's position - CVector vecTargetPosition; - pTargetPed->GetPosition(vecTargetPosition); - - // Work out an angle between the players, and set this as we initiate our knife kill - float fAngle = AngleBetweenPoints2D(vecLocalPosition, vecTargetPosition); - m_pLocalPlayer->SetCurrentRotation(fAngle); - - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - CLuaArguments Arguments; - Arguments.PushElement(pTargetPed); - if (m_pLocalPlayer->CallEvent("onClientPlayerStealthKill", Arguments, false)) - { - if (pTargetPed->IsLocalEntity()) - { - CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, 4 /*WEAPONTYPE_KNIFE*/, 9 /*BODYPART_HEAD*/, true); - return; - } - - // Lets request a stealth kill - CBitStream bitStream; - bitStream.pBitStream->Write(pTargetPed->GetID()); - m_pNetAPI->RPC(REQUEST_STEALTH_KILL, bitStream.pBitStream); - } - else - { - return; - } - } - } - } - } - } - } - } -} - -void CClientGame::UpdateStunts(void) -{ - // * Two wheeler * - static unsigned long ulLastCarTwoWheelCounter = 0; - static float fLastCarTwoWheelDist = 0.0f; - unsigned long ulTemp = g_pGame->GetPlayerInfo()->GetCarTwoWheelCounter(); - // Did we start a stunt? - if (ulLastCarTwoWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("2wheeler"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastCarTwoWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("2wheeler"); - Arguments.PushNumber(ulLastCarTwoWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastCarTwoWheelCounter = ulTemp; - fLastCarTwoWheelDist = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); - - // * Wheelie * - static unsigned long ulLastBikeRearWheelCounter = 0; - static float fLastBikeRearWheelDist = 0.0f; - ulTemp = g_pGame->GetPlayerInfo()->GetBikeRearWheelCounter(); - // Did we start a stunt? - if (ulLastBikeRearWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("wheelie"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastBikeRearWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("wheelie"); - Arguments.PushNumber(ulLastBikeRearWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastBikeRearWheelCounter = ulTemp; - fLastBikeRearWheelDist = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); - - // * Stoppie * - static unsigned long ulLastBikeFrontWheelCounter = 0; - static float fLastBikeFrontWheelDist = 0.0f; - ulTemp = g_pGame->GetPlayerInfo()->GetBikeFrontWheelCounter(); - // Did we start a stunt? - if (ulLastBikeFrontWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("stoppie"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastBikeFrontWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("stoppie"); - Arguments.PushNumber(ulLastBikeFrontWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastBikeFrontWheelCounter = ulTemp; - fLastBikeFrontWheelDist = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); -} - -void CClientGame::StaticUpdateFireKey(CControlFunctionBind* pBind) -{ - g_pClientGame->UpdateFireKey(); -} - -void CClientGame::ChangeVehicleWeapon(bool bNext) -{ - if (m_pLocalPlayer && m_pLocalPlayer->GetRealOccupiedVehicle()) - { - eWeaponSlot currentWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - eWeaponSlot weaponSlot = currentWeaponSlot; - CWeapon* pWeapon = NULL; - while (!pWeapon || pWeapon->GetType() == WEAPONTYPE_UNARMED) - { - if (bNext) - { - if (weaponSlot == WEAPONSLOT_TYPE_DETONATOR) - { - weaponSlot = WEAPONSLOT_TYPE_UNARMED; - break; - } - - weaponSlot = (eWeaponSlot)(weaponSlot + 1); - - if (weaponSlot == currentWeaponSlot) - break; - - pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); - } - else - { - if (weaponSlot == WEAPONSLOT_TYPE_UNARMED) - { - if (weaponSlot != currentWeaponSlot) - break; - weaponSlot = WEAPONSLOT_TYPE_DETONATOR; - } - - weaponSlot = (eWeaponSlot)(weaponSlot - 1); - - if (weaponSlot == currentWeaponSlot) - break; - - pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); - } - } - if (pWeapon || weaponSlot == WEAPONSLOT_TYPE_UNARMED) - { - m_pLocalPlayer->SetCurrentWeaponSlot(weaponSlot); - } - } -} - -void CClientGame::ResetVehicleInOut(void) -{ - m_ulLastVehicleInOutTime = 0; - m_bIsGettingOutOfVehicle = false; - m_bIsGettingIntoVehicle = false; - m_bIsJackingVehicle = false; - m_bIsGettingJacked = false; - m_VehicleInOutID = INVALID_ELEMENT_ID; - m_ucVehicleInOutSeat = 0xFF; - m_bNoNewVehicleTask = false; - m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; - m_pGettingJackedBy = NULL; -} - -void CClientGame::SetAllDimensions(unsigned short usDimension) -{ - m_pManager->GetMarkerStreamer()->SetDimension(usDimension); - m_pManager->GetObjectStreamer()->SetDimension(usDimension); - m_pManager->GetObjectLodStreamer()->SetDimension(usDimension); - m_pManager->GetPickupStreamer()->SetDimension(usDimension); - m_pManager->GetPlayerStreamer()->SetDimension(usDimension); - m_pManager->GetRadarAreaManager()->SetDimension(usDimension); - m_pManager->GetVehicleStreamer()->SetDimension(usDimension); - m_pManager->GetRadarMarkerManager()->SetDimension(usDimension); - m_pManager->GetSoundManager()->SetDimension(usDimension); - m_pManager->GetPointLightsManager()->SetDimension(usDimension); - m_pManager->GetWaterManager()->SetDimension(usDimension); - m_pNametags->SetDimension(usDimension); - m_pCamera->SetDimension(usDimension); -} - -bool CClientGame::StaticKeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) -{ - return g_pClientGame->KeyStrokeHandler(strKey, bState, bIsConsoleInputKey); -} - -bool CClientGame::KeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) -{ - // Do we have a root yet? - if (m_pRootEntity) - { - // Ignore keydown/up pair if main menu is displayed, or console input will use the character - bool bIgnore = false; - if (bState) - { - auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; - bool isMouseKey = strKey.substr(0, 5) == "mouse"; - - if (g_pCore->IsMenuVisible() || (g_pCore->GetConsole()->IsInputActive() && bIsConsoleInputKey) || - (pFocusedBrowser && !pFocusedBrowser->IsLocal() && !isMouseKey)) - - bIgnore = true; // Ignore this keydown and the matching keyup - else - MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup - } - else - { - if (!MapContains(m_AllowKeyUpMap, strKey)) - bIgnore = true; // Ignore this keyup - else - MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup - } - - if (!bIgnore) - { - bool bAllow = true; - // Call our key-stroke event - CLuaArguments Arguments; - Arguments.PushString(strKey); - Arguments.PushBoolean(bState); - bAllow = m_pRootEntity->CallEvent("onClientKey", Arguments, false); - if (bState == true) - { - if (bAllow == false && strKey == "escape") - { - if (m_bLastKeyWasEscapeCancelled) - { - // Escape cannot be skipped twice - bAllow = true; - m_bLastKeyWasEscapeCancelled = false; - } - else - m_bLastKeyWasEscapeCancelled = true; - } - else - m_bLastKeyWasEscapeCancelled = false; - } - return bAllow; - } - } - m_bLastKeyWasEscapeCancelled = false; - return true; -} - -bool CClientGame::StaticCharacterKeyHandler(WPARAM wChar) -{ - return g_pClientGame->CharacterKeyHandler(wChar); -} - -bool CClientGame::CharacterKeyHandler(WPARAM wChar) -{ - // Do we have a root yet? - if (m_pRootEntity && g_pCore->IsMenuVisible() == false && g_pCore->GetConsole()->IsInputActive() == false) - { - // Cancel event if remote browser is focused - auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; - if (pFocusedBrowser && !pFocusedBrowser->IsLocal()) - return false; - - // Safe character? - if (wChar >= 32) - { - // Generate a null-terminating string for our character - wchar_t wUNICODE[2] = {wChar, '\0'}; - - // Convert our UTF character into an ANSI string - SString strANSI = UTF16ToMbUTF8(wUNICODE); - - // Call our character event - CLuaArguments Arguments; - Arguments.PushString(strANSI); - m_pRootEntity->CallEvent("onClientCharacter", Arguments, false); - } - } - - return false; -} - -void CClientGame::StaticProcessClientKeyBind(CKeyFunctionBind* pBind) -{ - g_pClientGame->ProcessClientKeyBind(pBind); -} - -void CClientGame::ProcessClientKeyBind(CKeyFunctionBind* pBind) -{ - m_pScriptKeyBinds->ProcessKey(pBind->boundKey->szKey, pBind->bHitState, SCRIPT_KEY_BIND_FUNCTION); -} - -void CClientGame::StaticProcessClientControlBind(CControlFunctionBind* pBind) -{ - g_pClientGame->ProcessClientControlBind(pBind); -} - -void CClientGame::ProcessClientControlBind(CControlFunctionBind* pBind) -{ - m_pScriptKeyBinds->ProcessKey(pBind->control->szControl, pBind->bHitState, SCRIPT_KEY_BIND_CONTROL_FUNCTION); -} - -void CClientGame::StaticProcessServerKeyBind(CKeyFunctionBind* pBind) -{ - g_pClientGame->ProcessServerKeyBind(pBind); -} - -void CClientGame::ProcessServerKeyBind(CKeyFunctionBind* pBind) -{ - const char* szName = pBind->boundKey->szKey; - unsigned char ucNameLength = (unsigned char)strlen(szName); - CBitStream bitStream; - bitStream.pBitStream->WriteBit(false); - bitStream.pBitStream->WriteBit(pBind->bHitState); - bitStream.pBitStream->Write(szName, ucNameLength); - m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); -} - -void CClientGame::StaticProcessServerControlBind(CControlFunctionBind* pBind) -{ - g_pClientGame->ProcessServerControlBind(pBind); -} - -void CClientGame::ProcessServerControlBind(CControlFunctionBind* pBind) -{ - const char* szName = pBind->control->szControl; - unsigned char ucNameLength = (unsigned char)strlen(szName); - CBitStream bitStream; - bitStream.pBitStream->WriteBit(true); - bitStream.pBitStream->WriteBit(pBind->bHitState); - bitStream.pBitStream->Write(szName, ucNameLength); - m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); -} - -bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - bool bCursorForcedVisible = g_pCore->IsCursorForcedVisible(); - bool bMenuVisible = g_pCore->IsMenuVisible(); - bool bConsoleVisible = g_pCore->GetConsole()->IsVisible(); - - if (bCursorForcedVisible) - { - if (!bMenuVisible && !bConsoleVisible) - { - if (m_bCursorEventsEnabled) - { - unsigned char ucButtonHit = 0xFF; - switch (uMsg) - { - case WM_LBUTTONDOWN: - ucButtonHit = 0; - break; - case WM_LBUTTONUP: - ucButtonHit = 1; - break; - case WM_MBUTTONDOWN: - ucButtonHit = 2; - break; - case WM_MBUTTONUP: - ucButtonHit = 3; - break; - case WM_RBUTTONDOWN: - ucButtonHit = 4; - break; - case WM_RBUTTONUP: - ucButtonHit = 5; - break; - } - if (ucButtonHit != 0xFF) - { - int iX = LOWORD(lParam); - int iY = HIWORD(lParam); - - CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); - - /* - // (IJs) why are these relative? it doesn't make sense - CVector2D vecCursorPosition ( ( ( float ) iX ) / vecResolution.fX, - ( ( float ) iY ) / vecResolution.fY ); - */ - - CVector2D vecCursorPosition((float)iX, (float)iY); - - CVector vecOrigin, vecTarget, vecScreen((float)iX, (float)iY, 300.0f); - g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); - - // Grab the camera position - CCamera* pCamera = g_pGame->GetCamera(); - CCam* pCam = pCamera->GetCam(pCamera->GetActiveCam()); - CMatrix matCamera; - pCamera->GetMatrix(&matCamera); - vecOrigin = matCamera.vPos; - - CColPoint* pColPoint = NULL; - CEntity* pGameEntity = NULL; - - // Grab the collision point/entity - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pGameEntity); - - CVector vecCollision; - ElementID CollisionEntityID = INVALID_ELEMENT_ID; - CClientEntity* pCollisionEntity = NULL; - if (bCollision && pColPoint) - { - vecCollision = pColPoint->GetPosition(); - if (pGameEntity) - { - CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity); - if (pEntity) - { - pCollisionEntity = pEntity; - if (!pEntity->IsLocalEntity()) - CollisionEntityID = pEntity->GetID(); - } - } - } - else - { - vecCollision = vecTarget; - } - - // Destroy the colpoint so we don't get a leak - if (pColPoint) - { - pColPoint->Destroy(); - } - - const char* szButton = NULL; - const char* szState = NULL; - switch (ucButtonHit) - { - case 0: - szButton = "left"; - szState = "down"; - break; - case 1: - szButton = "left"; - szState = "up"; - break; - case 2: - szButton = "middle"; - szState = "down"; - break; - case 3: - szButton = "middle"; - szState = "up"; - break; - case 4: - szButton = "right"; - szState = "down"; - break; - case 5: - szButton = "right"; - szState = "up"; - break; - } - if (szButton && szState) - { - if (std::isnan(vecCollision.fX)) - vecCollision.fX = 0; - if (std::isnan(vecCollision.fY)) - vecCollision.fY = 0; - if (std::isnan(vecCollision.fZ)) - vecCollision.fZ = 0; - - // Call the event for the client - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(vecCursorPosition.fX); - Arguments.PushNumber(vecCursorPosition.fY); - Arguments.PushNumber(vecCollision.fX); - Arguments.PushNumber(vecCollision.fY); - Arguments.PushNumber(vecCollision.fZ); - if (pCollisionEntity) - Arguments.PushElement(pCollisionEntity); - else - Arguments.PushBoolean(false); - m_pRootEntity->CallEvent("onClientClick", Arguments, false); - - // Send the button, cursor position, 3d position and the entity collided with - CBitStream bitStream; - - SMouseButtonSync button; - button.data.ucButton = ucButtonHit; - bitStream.pBitStream->Write(&button); - - bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fX)); - bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fY)); - - SPositionSync position(false); - position.data.vecPosition = vecCollision; - bitStream.pBitStream->Write(&position); - - if (CollisionEntityID != INVALID_ELEMENT_ID) - { - bitStream.pBitStream->WriteBit(true); - bitStream.pBitStream->Write(CollisionEntityID); - } - else - bitStream.pBitStream->WriteBit(false); - - m_pNetAPI->RPC(CURSOR_EVENT, bitStream.pBitStream); - - if (strcmp(szState, "down") == 0) - { - CVector2D vecDelta = m_vecLastCursorPosition - vecCursorPosition; - - if ((GetTickCount32() - m_ulLastClickTick) < DOUBLECLICK_TIMEOUT && vecDelta.Length() <= DOUBLECLICK_MOVE_THRESHOLD) - { - // Call the event for the client - CLuaArguments DoubleClickArguments; - DoubleClickArguments.PushString(szButton); - DoubleClickArguments.PushNumber(vecCursorPosition.fX); - DoubleClickArguments.PushNumber(vecCursorPosition.fY); - DoubleClickArguments.PushNumber(vecCollision.fX); - DoubleClickArguments.PushNumber(vecCollision.fY); - DoubleClickArguments.PushNumber(vecCollision.fZ); - if (pCollisionEntity) - DoubleClickArguments.PushElement(pCollisionEntity); - else - DoubleClickArguments.PushBoolean(false); - m_pRootEntity->CallEvent("onClientDoubleClick", DoubleClickArguments, false); - } - - m_ulLastClickTick = GetTickCount32(); - m_vecLastCursorPosition = vecCursorPosition; - } - - return true; - } - } - } - } - } - switch (uMsg) - { - case WM_MOUSEMOVE: - { - int iX = LOWORD(lParam), iY = HIWORD(lParam); - static int iPreviousX = 0, iPreviousY = 0; - if (iX != iPreviousX || iY != iPreviousY) - { - iPreviousX = iX, iPreviousY = iY; - - CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); - CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); - - CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); - g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); - - // Call the onClientCursorMove event - CLuaArguments Arguments; - Arguments.PushNumber((double)vecCursorPosition.fX); - Arguments.PushNumber((double)vecCursorPosition.fY); - Arguments.PushNumber((double)iX); - Arguments.PushNumber((double)iY); - Arguments.PushNumber((double)vecTarget.fX); - Arguments.PushNumber((double)vecTarget.fY); - Arguments.PushNumber((double)vecTarget.fZ); - m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); - } - break; - } - } - return false; -} - -CClientPlayer* CClientGame::GetClosestRemotePlayer(const CVector& vecPosition, float fMaxDistance) -{ - CClientPlayer* pClosest = NULL; - float fDistance = 0.0f, fTemp; - CVector vecTemp; - CClientPlayer* pPlayer; - vector::const_iterator iter = m_pPlayerManager->IterBegin(); - for (; iter != m_pPlayerManager->IterEnd(); ++iter) - { - pPlayer = *iter; - if (!pPlayer->IsLocalPlayer() && !pPlayer->IsDeadOnNetwork() && pPlayer->GetHealth() > 0) - { - // Ensure remote player is alive and sending position updates - ulong ulTimeSinceLastPuresync = CClientTime::GetTime() - pPlayer->GetLastPuresyncTime(); - if (ulTimeSinceLastPuresync < static_cast(g_TickRateSettings.iPureSync) * 2) - { - pPlayer->GetPosition(vecTemp); - fTemp = DistanceBetweenPoints3D(vecPosition, vecTemp); - if (fTemp < fMaxDistance) - { - if (!pClosest || fTemp < fDistance) - { - pClosest = pPlayer; - fDistance = fTemp; - } - } - } - } - } - return pClosest; -} - -void CClientGame::SetGameSpeed(float fSpeed) -{ - g_pGame->SetGameSpeed(fSpeed); - m_fGameSpeed = fSpeed; -} - -void CClientGame::SetMinuteDuration(unsigned long ulDelay) -{ - g_pGame->SetMinuteDuration(ulDelay); - m_ulMinuteDuration = ulDelay; -} - -void CClientGame::SetMoney(long lMoney, bool bInstant) -{ - g_pGame->GetPlayerInfo()->SetPlayerMoney(lMoney, bInstant); - m_lMoney = lMoney; -} - -void CClientGame::SetWanted(DWORD dwWanted) -{ - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(dwWanted); - m_dwWanted = dwWanted; -} - -void CClientGame::AddBuiltInEvents(void) -{ - // Resource events - m_Events.AddEvent("onClientResourceStart", "resource", NULL, false); - m_Events.AddEvent("onClientResourceStop", "resource", NULL, false); - - // Element events - m_Events.AddEvent("onClientElementDataChange", "name", NULL, false); - m_Events.AddEvent("onClientElementStreamIn", "", NULL, false); - m_Events.AddEvent("onClientElementStreamOut", "", NULL, false); - m_Events.AddEvent("onClientElementDestroy", "", NULL, false); - - // Player events - m_Events.AddEvent("onClientPlayerJoin", "", NULL, false); - m_Events.AddEvent("onClientPlayerQuit", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerTarget", "target", NULL, false); - m_Events.AddEvent("onClientPlayerSpawn", "team", NULL, false); - m_Events.AddEvent("onClientPlayerChangeNick", "oldNick", NULL, false); - m_Events.AddEvent("onClientPlayerVehicleEnter", "vehicle, seat", NULL, false); - m_Events.AddEvent("onClientPlayerVehicleExit", "vehicle, seat", NULL, false); - m_Events.AddEvent("onClientPlayerTask", "priority, slot, name", NULL, false); - m_Events.AddEvent("onClientPlayerWeaponSwitch", "previous, current", NULL, false); - m_Events.AddEvent("onClientPlayerStuntStart", "type", NULL, false); - m_Events.AddEvent("onClientPlayerStuntFinish", "type, time, distance", NULL, false); - m_Events.AddEvent("onClientPlayerRadioSwitch", "", NULL, false); - m_Events.AddEvent("onClientPlayerDamage", "attacker, weapon, bodypart", NULL, false); - m_Events.AddEvent("onClientPlayerWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); - m_Events.AddEvent("onClientPlayerWasted", "", NULL, false); - m_Events.AddEvent("onClientPlayerChoke", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceStart", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceStop", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoicePause", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceResumed", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerStealthKill", "target", NULL, false); - m_Events.AddEvent("onClientPlayerHitByWaterCannon", "vehicle", NULL, false); - m_Events.AddEvent("onClientPlayerHeliKilled", "heli", NULL, false); - m_Events.AddEvent("onClientPlayerPickupHit", "pickup, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPlayerPickupLeave", "pickup, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPlayerNetworkStatus", "type, ticks", NULL, false); - - // Ped events - m_Events.AddEvent("onClientPedDamage", "attacker, weapon, bodypart", NULL, false); - m_Events.AddEvent("onClientPedWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); - m_Events.AddEvent("onClientPedWasted", "", NULL, false); - m_Events.AddEvent("onClientPedChoke", "", NULL, false); - m_Events.AddEvent("onClientPedHeliKilled", "heli", NULL, false); - m_Events.AddEvent("onClientPedHitByWaterCannon", "vehicle", NULL, false); - - // Vehicle events - m_Events.AddEvent("onClientVehicleRespawn", "", NULL, false); - m_Events.AddEvent("onClientVehicleEnter", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleExit", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleStartEnter", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleStartExit", "player, seat", NULL, false); - m_Events.AddEvent("onClientTrailerAttach", "towedBy", NULL, false); - m_Events.AddEvent("onClientTrailerDetach", "towedBy", NULL, false); - m_Events.AddEvent("onClientVehicleExplode", "", NULL, false); - m_Events.AddEvent("onClientVehicleCollision", "collidedelement, damageImpulseMag, bodypart, x, y, z, velX, velY, velZ", NULL, false); - m_Events.AddEvent("onClientVehicleDamage", "attacker, weapon, loss, x, y, z, tyre", NULL, false); - m_Events.AddEvent("onClientVehicleNitroStateChange", "activated", NULL, false); - - // GUI events - m_Events.AddEvent("onClientGUIClick", "button, state, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIDoubleClick", "button, state, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIMouseDown", "button, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIMouseUp", "button, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIScroll", "element", NULL, false); - m_Events.AddEvent("onClientGUIChanged", "element", NULL, false); - m_Events.AddEvent("onClientGUIAccepted", "element", NULL, false); - // m_Events.AddEvent ( "onClientGUIClose", "element", NULL, false ); - // m_Events.AddEvent ( "onClientGUIKeyDown", "element", NULL, false ); - m_Events.AddEvent("onClientGUITabSwitched", "element", NULL, false); - m_Events.AddEvent("onClientGUIComboBoxAccepted", "element", NULL, false); - - // Input events - m_Events.AddEvent("onClientDoubleClick", "button, screenX, screenY, worldX, worldY, worldZ, element", NULL, false); - m_Events.AddEvent("onClientMouseMove", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseEnter", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseLeave", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseWheel", "", NULL, false); - m_Events.AddEvent("onClientGUIMove", "", NULL, false); - m_Events.AddEvent("onClientGUISize", "", NULL, false); - m_Events.AddEvent("onClientGUIFocus", "", NULL, false); - m_Events.AddEvent("onClientGUIBlur", "", NULL, false); - m_Events.AddEvent("onClientKey", "key, state", NULL, false); - m_Events.AddEvent("onClientCharacter", "character", NULL, false); - - // Console events - m_Events.AddEvent("onClientConsole", "text", NULL, false); - - // Chat events - m_Events.AddEvent("onClientChatMessage", "test, r, g, b", NULL, false); - - // Debug events - m_Events.AddEvent("onClientDebugMessage", "message, level, file, line", NULL, false); - - // Game events - m_Events.AddEvent("onClientPreRender", "", NULL, false); - m_Events.AddEvent("onClientHUDRender", "", NULL, false); - m_Events.AddEvent("onClientRender", "", NULL, false); - m_Events.AddEvent("onClientMinimize", "", NULL, false); - m_Events.AddEvent("onClientRestore", "", NULL, false); - - // Cursor events - m_Events.AddEvent("onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false); - m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); - - // Transfer box event - m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); - - // Marker events - m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); - - // Marker events - m_Events.AddEvent("onClientPickupHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPickupLeave", "entity, matchingDimension", NULL, false); - - // Col-shape events - m_Events.AddEvent("onClientColShapeHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientColShapeLeave", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientElementColShapeHit", "colShape, matchingDimension", NULL, false); - m_Events.AddEvent("onClientElementColShapeLeave", "colShape, matchingDimension", NULL, false); - - // Explosion events - m_Events.AddEvent("onClientExplosion", "x, y, z, type", NULL, false); - - // Projectile events - m_Events.AddEvent("onClientProjectileCreation", "creator", NULL, false); - - // Sound events - m_Events.AddEvent("onClientSoundStream", "success, length, streamName, error", NULL, false); - m_Events.AddEvent("onClientSoundFinishedDownload", "length", NULL, false); - m_Events.AddEvent("onClientSoundChangedMeta", "streamTitle", NULL, false); - m_Events.AddEvent("onClientSoundStarted", "reason", NULL, false); - m_Events.AddEvent("onClientSoundStopped", "reason", NULL, false); - m_Events.AddEvent("onClientSoundBeat", "time", NULL, false); - - // Object events - m_Events.AddEvent("onClientObjectDamage", "loss, attacker", NULL, false); - m_Events.AddEvent("onClientObjectBreak", "attacker", NULL, false); - - // Web events - m_Events.AddEvent("onClientBrowserWhitelistChange", "newPages", NULL, false); - m_Events.AddEvent("onClientBrowserCreated", "", NULL, false); - m_Events.AddEvent("onClientBrowserLoadingStart", "url, mainframe", NULL, false); - m_Events.AddEvent("onClientBrowserDocumentReady", "url", NULL, false); - m_Events.AddEvent("onClientBrowserLoadingFailed", "url, errorcode, errordescription", NULL, false); - m_Events.AddEvent("onClientBrowserNavigate", "url, isblocked", NULL, false); - m_Events.AddEvent("onClientBrowserPopup", "targeturl, openerurl, ispopup", NULL, false); - m_Events.AddEvent("onClientBrowserCursorChange", "cursor", NULL, false); - m_Events.AddEvent("onClientBrowserTooltip", "text", NULL, false); - m_Events.AddEvent("onClientBrowserInputFocusChanged", "gainedfocus", NULL, false); - m_Events.AddEvent("onClientBrowserResourceBlocked", "url, domain, reason", NULL, false); - - // Misc events - m_Events.AddEvent("onClientFileDownloadComplete", "fileName, success", NULL, false); - - m_Events.AddEvent("onClientWeaponFire", "ped, x, y, z", NULL, false); -} - -void CClientGame::DrawFPS(void) -{ - // Draw the background - float fResWidth = static_cast(g_pCore->GetGraphics()->GetViewportWidth()); - float fResHeight = static_cast(g_pCore->GetGraphics()->GetViewportHeight()); - g_pCore->GetGraphics()->DrawRectangle(0.75f * fResWidth, 0.22f * fResHeight, 0.25f * fResWidth, 0.04f * fResHeight, 0x78000000); - - static char x = 0; - static float fDisp = 0.0f; - if (x == 20) - { - x = 0; - fDisp = g_pGame->GetFPS(); - } - else - x++; - SString strBuffer("FrameRate: %4.2f\n", fDisp); - - // Print it - m_pDisplayManager->DrawText2D(strBuffer, CVector(0.76f, 0.23f, 0), 1.0f, 0xFFFFFFFF); -} - -#ifdef MTA_DEBUG - -void CClientGame::DrawTasks(CClientPlayer* pPlayer) -{ - CTask* pTask = NULL; - CTask* pSubTask = NULL; - - // Got a local player model - if (pPlayer) - { - CTaskManager* man = pPlayer->GetTaskManager(); - if (man == NULL) - return; - if ((unsigned long)man == 0xDDDDDDDD) - { - m_pDisplayManager->DrawText2D("HELP! MANAGER FUCKED", CVector(0.05f, 0.5f, 0), 1.0f); - return; - } - - // Grab the current task - SString strOutput; - SString strSubOutput; - - pTask = man->GetTask(TASK_PRIORITY_PHYSICAL_RESPONSE); - strOutput += SString("Physical Response: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_TEMP); - strOutput += SString("Event Response Temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_NONTEMP); - strOutput += SString("Event Response Non-temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_PRIMARY); - strOutput += SString("Primary: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_DEFAULT); - strOutput += SString("Default: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_ATTACK); - strOutput += SString("Secondary Attack: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_DUCK); - strOutput += SString("Secondary Duck: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_SAY); - strOutput += SString("Secondary Say: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX); - strOutput += SString("Secondary Facial Complex: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM); - strOutput += SString("Secondary Partial Anim: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_IK); - strOutput += SString("Secondary IK: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - m_pDisplayManager->DrawText2D(strOutput, CVector(0.05f, 0.5f, 0), 1.0f); - m_pDisplayManager->DrawText2D(strSubOutput, CVector(0.5f, 0.5f, 0), 1.0f); - } -} - -int iPlayerTask = 0; -void CClientGame::DrawPlayerDetails(CClientPlayer* pPlayer) -{ - // Get the info - CControllerState cs; - - pPlayer->GetControllerState(cs); - - CVector vecPosition; - pPlayer->GetPosition(vecPosition); - - float fRotation = pPlayer->GetCurrentRotation(); - float fCameraRotation = pPlayer->GetCameraRotation(); - float fHealth = pPlayer->GetHealth(); - bool bIsDucked = pPlayer->IsDucked(); - bool bWearingGoggles = pPlayer->IsWearingGoggles(); - bool bInVehicle = pPlayer->GetOccupiedVehicle() != NULL; - float fWeaponRange = 0.0f; - - unsigned char ucWeapon = 0; - unsigned char ucWeaponState = 0; - unsigned short usWeaponAmmo = 0; - CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); - if (pWeapon) - { - ucWeapon = static_cast(pWeapon->GetType()); - ucWeaponState = static_cast(pWeapon->GetState()); - usWeaponAmmo = static_cast(pWeapon->GetAmmoInClip()); - float fSkill = pPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(pWeapon->GetType())); - CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(pWeapon->GetType(), fSkill); - fWeaponRange = pWeaponInfo->GetWeaponRange(); - } - - float fAimX, fAimY; - pPlayer->GetAim(fAimX, fAimY); - const CVector& vecAimSource = pPlayer->GetAimSource(); - const CVector& vecAimTarget = pPlayer->GetAimTarget(); - unsigned char ucDrivebyAim = pPlayer->GetVehicleAimAnim(); - - g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x10DE1212, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x90DE1212, false); - - CTask* pPrimaryTask = pPlayer->GetCurrentPrimaryTask(); - int iPrimaryTask = pPrimaryTask ? pPrimaryTask->GetTaskType() : -1; - - // Copy the stuff - SString strBuffer( - "Orient:\n" - "Position: %f %f %f\n" - "Rotation/camera: %f %f\n" - "Health: %f\n" - "\n" - "Keys:\n" - "LeftShoulder1: %hi\n" - "RightShoulder1: %hi\n" - "ButtonSquare: %hi\n" - "ButtonCross: %hi\n" - "ButtonCircle: %hi\n" - "ShockButtonL: %hi\n" - "PedWalk: %hi\n" - "VehicleMouseLook: %hi\n" - "LeftStickX: %hi\n" - "LeftStickY: %hi\n" - "\n" - "Misc:\n" - "Primary task: %d\n" - "Ducked: %u\n" - "Goggles: %u\n" - "In vehicle: %u\n" - "Weapon: %u\n" - "Weapon state: %u\n" - "Weapon ammo: %u\n" - "Weapon range: %f\n" - "Aim: %f %f\n" - "Aim source: %f %f %f\n" - "Aim target: %f %f %f\n" - "Driveby aim: %u\n" - "Frozen: %u\n", - vecPosition.fX, vecPosition.fY, vecPosition.fZ, fRotation, fCameraRotation, fHealth, cs.LeftShoulder1, cs.RightShoulder1, cs.ButtonSquare, - cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.m_bPedWalk, cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, iPrimaryTask, bIsDucked, - bWearingGoggles, bInVehicle, ucWeapon, ucWeaponState, usWeaponAmmo, fWeaponRange, fAimX, fAimY, vecAimSource.fX, vecAimSource.fY, vecAimSource.fZ, - vecAimTarget.fX, vecAimTarget.fY, vecAimTarget.fZ, ucDrivebyAim, pPlayer->IsFrozen()); - - // Draw it - m_pDisplayManager->DrawText2D(strBuffer, CVector(0.45f, 0.05f, 0), 1.0f, 0xFFFFFFFF); -} - -void CClientGame::DrawWeaponsyncData(CClientPlayer* pPlayer) -{ - CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); - - if (pWeapon) - { - CVector vecSource; - CVector vecTarget; - - // red line: Draw their synced aim line - pPlayer->GetShotData(&vecSource, &vecTarget); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x10DE1212, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x90DE1212, false); - - // green line: Set muzzle as origin and perform a collision test for the target - CColPoint* pCollision; - CVector vecTemp; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecSource, &vecTarget, &pCollision, NULL); - if (pCollision) - { - if (bCollision) - { - CVector vecBullet = pCollision->GetPosition() - vecSource; - vecBullet.Normalize(); - CVector vecTarget = vecSource + (vecBullet * 200); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x1012DE12, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x9012DE12, false); - } - pCollision->Destroy(); - } - - if (m_pLocalPlayer != pPlayer) - { - // Draw information about their weapon state, total ammo and ammo in clip - CVector vecScreenPosition; - CVector vecPosition; - - pPlayer->GetPosition(vecPosition); - - vecPosition.fZ += 1.0f; - g_pCore->GetGraphics()->CalcScreenCoors(&vecPosition, &vecScreenPosition); - - SString strTemp; - int yoffset; - - yoffset = 0; - strTemp.Format("Ammo in clip: %d", pWeapon->GetAmmoInClip()); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); - - yoffset = 15; - strTemp.Format("State: %d", pWeapon->GetState()); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); - } - } -} - -void CClientGame::UpdateMimics(void) -{ - // Got a local player? - if (m_pLocalPlayer) - { - unsigned char ucWeaponType = 0; - unsigned char ucWeaponState = 0; - unsigned long ulWeaponAmmoInClip = 0; - eWeaponSlot weaponSlot = WEAPONSLOT_TYPE_UNARMED; - - CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(m_pLocalPlayer->GetCurrentWeaponSlot()); - if (pPlayerWeapon) - { - ucWeaponType = static_cast(pPlayerWeapon->GetType()); - ucWeaponState = static_cast(pPlayerWeapon->GetState()); - weaponSlot = pPlayerWeapon->GetSlot(); - ulWeaponAmmoInClip = pPlayerWeapon->GetAmmoInClip(); - } - - // Simulate lag (or not) - if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) - { - m_ulLastMimicLag = CClientTime::GetTime(); - - // Grab the local data - CControllerState Controller; - m_pLocalPlayer->GetControllerState(Controller); - CVector vecPosition; - m_pLocalPlayer->GetPosition(vecPosition); - float fRotation = m_pLocalPlayer->GetCurrentRotation(); - CVector vecMoveSpeed; - m_pLocalPlayer->GetMoveSpeed(vecMoveSpeed); - float fHealth = m_pLocalPlayer->GetHealth(); - float fArmor = m_pLocalPlayer->GetArmor(); - float fCameraRotation = g_pGame->GetCamera()->GetCameraRotation(); - bool bDucked = m_pLocalPlayer->IsDucked(); - bool bWearingGoggles = m_pLocalPlayer->IsWearingGoggles(true); - bool bHasJetpack = m_pLocalPlayer->HasJetPack(); - bool bChoking = m_pLocalPlayer->IsChoking(); - bool bSunbathing = m_pLocalPlayer->IsSunbathing(); - bool bDoingDriveby = m_pLocalPlayer->IsDoingGangDriveby(); - bool bStealthAiming = m_pLocalPlayer->IsStealthAiming(); - - // Is the current weapon goggles (44 or 45) or a camera (43), or a detonator (40), don't apply the fire key - if (weaponSlot == 11 || weaponSlot == 12 || ucWeaponType == 43) - Controller.ButtonCircle = 0; - - CClientVehicle* pVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - unsigned int uiSeat = m_pLocalPlayer->GetOccupiedVehicleSeat(); - - CShotSyncData* pShotSync = g_pMultiplayer->GetLocalShotSyncData(); - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - float fAimX = pShotSync->m_fArmDirectionX; - float fAimY = pShotSync->m_fArmDirectionY; - char cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; - bool bAkimboUp = g_pMultiplayer->GetAkimboTargetUp(); - - /* - static CClientMarker *pOriginCorona = NULL, *pTargetCorona = NULL; - if ( pOriginCorona == NULL ) - { - pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); - pOriginCorona->SetColor ( 0, 255, 0, 255 ); - pOriginCorona->SetSize ( 0.5f ); - } - else - pOriginCorona->SetPosition ( vecOrigin ); - - if ( pTargetCorona == NULL ) - { - pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); - pTargetCorona->SetColor ( 255, 0, 0, 255 ); - pTargetCorona->SetSize ( 0.5f ); - } - else - pTargetCorona->SetPosition ( vecTarget );*/ - - // Apply this to each of our mimic players - unsigned int uiMimicIndex = 0; - list::const_iterator iterMimics = m_Mimics.begin(); - for (; iterMimics != m_Mimics.end(); ++iterMimics, ++uiMimicIndex) - { - vecPosition.fX += 4.0f; - vecOrigin.fX += 4.0f; - vecTarget.fX += 4.0f; - - CClientPlayer* pMimic = *iterMimics; - - pMimic->SetHealth(fHealth); - pMimic->LockHealth(fHealth); - pMimic->SetArmor(fArmor); - pMimic->LockArmor(fArmor); - pMimic->SetWearingGoggles(bWearingGoggles); - pMimic->SetHasJetPack(bHasJetpack); - pMimic->SetChoking(bChoking); - pMimic->SetSunbathing(bSunbathing); - pMimic->SetDoingGangDriveby(bDoingDriveby); - pMimic->SetStealthAiming(bStealthAiming); - - Controller.ShockButtonL = 0; - - if (m_bMimicLag) - { - pMimic->SetTargetPosition(vecPosition, TICK_RATE); - pMimic->SetMoveSpeed(vecMoveSpeed); - pMimic->SetControllerState(Controller); - pMimic->SetTargetRotation(fRotation); - pMimic->SetCameraRotation(fCameraRotation); - pMimic->Duck(bDucked); - } - else - { - pMimic->SetPosition(vecPosition); - pMimic->SetMoveSpeed(vecMoveSpeed); - pMimic->SetTargetRotation(fRotation); - pMimic->SetCameraRotation(fCameraRotation); - pMimic->SetControllerState(Controller); - pMimic->Duck(bDucked); - } - - if (ucWeaponType != 0) - { - if (ucWeaponType == 44 || ucWeaponType == 45) - { - Controller.ButtonCircle = 0; - } - - if (m_bMimicLag) - { - pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); - pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); - - pMimic->AddChangeWeapon(TICK_RATE, weaponSlot, (unsigned char)ulWeaponAmmoInClip); - } - else - { - CWeapon* pPlayerWeapon = pMimic->GetWeapon(); - eWeaponType eCurrentWeapon = static_cast(ucWeaponType); - if ((pPlayerWeapon && pPlayerWeapon->GetType() != eCurrentWeapon) || !pPlayerWeapon) - { - pPlayerWeapon = pMimic->GiveWeapon(eCurrentWeapon, ulWeaponAmmoInClip); - if (pPlayerWeapon) - { - pPlayerWeapon->SetAsCurrentWeapon(); - } - } - - if (pPlayerWeapon) - { - pPlayerWeapon->SetAmmoTotal(9999); - pPlayerWeapon->SetAmmoInClip(ulWeaponAmmoInClip); - pPlayerWeapon->SetState(static_cast(ucWeaponState)); - } - pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); - pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); - } - } - else - { - pMimic->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); - } - - CClientVehicle* pMimicVehicle = pMimic->GetOccupiedVehicle(); - if (pVehicle) - { - unsigned int uiModel; - CVector vecPosition, vecRotationDegrees; - CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; - float fHealth; - - uiModel = pVehicle->GetModel(); - pVehicle->GetPosition(vecPosition); - pVehicle->GetRotationDegrees(vecRotationDegrees); - pVehicle->GetMoveSpeed(vecMoveSpeed); - pVehicle->GetTurnSpeed(vecTurnSpeed); - fHealth = pVehicle->GetHealth(); - - if (pMimicVehicle && pMimicVehicle->GetModel() != uiModel) - { - delete pMimicVehicle; - pMimicVehicle = NULL; - } - - vecPosition.fX += ((float)(uiMimicIndex + 1) * 10.0f); - - if (pMimicVehicle == NULL) - { - pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, uiModel, 0, 0); - pMimicVehicle->SetPosition(vecPosition); - - const SSlotStates& usUpgrades = pVehicle->GetUpgrades()->GetSlotStates(); - for (unsigned char uc = 0; uc < VEHICLE_UPGRADE_SLOTS; uc++) - { - if (usUpgrades[uc]) - { - pMimicVehicle->GetUpgrades()->AddUpgrade(usUpgrades[uc], true); - } - } - - m_vecLastMimicPos = vecPosition; - } - - if (m_bMimicLag) - { - pMimicVehicle->SetTargetPosition(vecPosition, TICK_RATE); - pMimicVehicle->SetTargetRotation(vecRotationDegrees, TICK_RATE); - pMimicVehicle->SetMoveSpeed(vecMoveSpeed); - pMimicVehicle->SetTurnSpeed(vecTurnSpeed); - } - else - { - pMimicVehicle->SetPosition(vecPosition); - pMimicVehicle->SetRotationDegrees(vecRotationDegrees); - pMimicVehicle->SetMoveSpeed(vecMoveSpeed); - pMimicVehicle->SetTurnSpeed(vecTurnSpeed); - } - pMimicVehicle->SetHealth(fHealth); - if (pMimic->GetOccupiedVehicle() != pMimicVehicle) - pMimic->WarpIntoVehicle(pMimicVehicle, uiSeat); - - unsigned int uiTrailerLoop = 0; - CClientVehicle* pTrailer = pVehicle->GetTowedVehicle(); - CClientVehicle* pMimicTrailer = NULL; - while (pTrailer) - { - uiModel = pTrailer->GetModel(); - pTrailer->GetPosition(vecPosition); - pTrailer->GetRotationDegrees(vecRotationDegrees); - pTrailer->GetMoveSpeed(vecMoveSpeed); - pTrailer->GetTurnSpeed(vecTurnSpeed); - fHealth = pTrailer->GetHealth(); - - pMimicTrailer = DynamicCast(CElementIDs::GetElement(static_cast(450 + uiMimicIndex + uiTrailerLoop))); - - if (pMimicTrailer && pMimicTrailer->GetModel() != uiModel) - { - delete pMimicTrailer; - pMimicTrailer = NULL; - } - - if (!pMimicTrailer) - { - pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, - static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); - pMimicVehicle->SetTowedVehicle(pMimicTrailer); - } - - pTrailer = pTrailer->GetTowedVehicle(); - pMimicTrailer = pMimicTrailer->GetTowedVehicle(); - uiTrailerLoop++; - } - if (pMimicTrailer) - { - if (pMimicTrailer->GetTowedByVehicle()) - { - pMimicTrailer->GetTowedByVehicle()->SetTowedVehicle(NULL); - } - } - } - else if (pMimicVehicle) - { - pMimic->RemoveFromVehicle(); - delete pMimicVehicle; - } - } - } - } -} - -void CClientGame::DoPaintballs(void) -{ - if (m_pLocalPlayer) - { - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - - CColPoint* pCollision = NULL; - CEntity* pCollisionEntity = NULL; - m_pLocalPlayer->WorldIgnore(true); - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionEntity); - m_pLocalPlayer->WorldIgnore(false); - - static list paintBalls; - if (paintBalls.size() >= 5) - { - CClientMarker* pCorona = paintBalls.back(); - delete pCorona; - paintBalls.pop_back(); - } - - CClientMarker* pCorona = new CClientMarker(m_pManager, INVALID_ELEMENT_ID, CClientMarker::MARKER_CORONA); - paintBalls.push_front(pCorona); - pCorona->SetSize(0.2f); - if (bCollision && pCollision) - { - pCorona->SetPosition(pCollision->GetPosition()); - pCorona->SetColor(SColorRGBA(255, 0, 0, 255)); - } - else - { - pCorona->SetPosition(vecTarget); - pCorona->SetColor(SColorRGBA(255, 255, 0, 255)); - } - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - } -} - -#endif - -void CClientGame::QuitPlayer(CClientPlayer* pPlayer, eQuitReason Reason) -{ - // Get the nick pointer and echo the quit message to the chat - const char* szNick = pPlayer->GetNick(); - const char* szReason = "Unknown"; - switch (Reason) - { - case QUIT_QUIT: - szReason = "Quit"; - break; - case QUIT_KICK: - szReason = "Kicked"; - break; - case QUIT_BAN: - szReason = "Banned"; - break; - case QUIT_CONNECTION_DESYNC: - szReason = "Bad Connection"; - break; - case QUIT_TIMEOUT: - szReason = "Timed Out"; - break; - } - - // In debug, make sure we don't look at this player's details -#ifdef MTA_DEBUG - if (m_pShowPlayer == pPlayer) - { - m_pShowPlayer = NULL; - } -#endif - - // Call our onClientPlayerQuit event - CLuaArguments Arguments; - Arguments.PushString(szReason); - pPlayer->CallEvent("onClientPlayerQuit", Arguments, true); - - // Detach the camera from this player if we're watching them - m_pManager->GetCamera()->UnreferencePlayer(pPlayer); - - // Was this player jacking us? - if (m_bIsGettingJacked && m_pGettingJackedBy == pPlayer) - { - ResetVehicleInOut(); - m_pLocalPlayer->RemoveFromVehicle(false); - m_pLocalPlayer->SetVehicleInOutState(VEHICLE_INOUT_NONE); - } - - // Delete the player - delete pPlayer; -} - -void CClientGame::Event_OnIngame(void) -{ - // Unpause the game - g_pGame->Pause(false); - - // Disable parts of the Hud - CHud* pHud = g_pGame->GetHud(); - pHud->SetComponentVisible(HUD_HELP_TEXT, false); - pHud->SetComponentVisible(HUD_VITAL_STATS, false); - pHud->SetComponentVisible(HUD_AREA_NAME, false); - - g_pMultiplayer->DeleteAndDisableGangTags(); - - // Switch off peds and traffic - SFixedArray vecs = {CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), - CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0)}; - g_pGame->GetPathFind()->SwitchRoadsOffInArea(&vecs[0], &vecs[1]); - g_pGame->GetPathFind()->SwitchPedRoadsOffInArea(&vecs[2], &vecs[3]); - g_pGame->GetPathFind()->SetPedDensity(0.0f); - g_pGame->GetPathFind()->SetVehicleDensity(0.0f); - - g_pGame->GetWorld()->ClearRemovedBuildingLists(); - g_pGame->GetWorld()->SetOcclusionsEnabled(true); - - g_pGame->ResetModelLodDistances(); - g_pGame->ResetAlphaTransparencies(); - - // Make sure we can access all areas - g_pGame->GetStats()->ModifyStat(CITIES_PASSED, 2.0); - - // This is to prevent the 'white arrows in checkpoints' bug (#274) - g_pGame->Get3DMarkers()->CreateMarker(87654, (e3DMarkerType)5, &vecs[4], 1, 0.2f, 0, 0, 0, 0); - - // Stop us getting 4 stars if we visit the SF or LV - // g_pGame->GetPlayerInfo()->GetWanted()->SetMaximumWantedLevel ( 0 ); - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(0); - - // Reset anything from last game - ResetMapInfo(); - g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level - g_pGame->GetWaterManager()->SetWaterDrawnLast(true); - m_pCamera->SetCameraClip(true, true); - - // Create a local player for us - m_pLocalPlayer = new CClientPlayer(m_pManager, m_LocalID, true); - if (m_pLocalPlayer) - { - // Set our parent the root entity - m_pLocalPlayer->SetParent(m_pRootEntity); - - // Give the local player our nickname - m_pLocalPlayer->SetNick(m_strLocalNick); - - // Freeze the player at some location we won't see - m_pLocalPlayer->SetHealth(100); - m_pLocalPlayer->SetPosition(CVector(0, 0, 0)); - m_pLocalPlayer->SetFrozen(true); - m_pLocalPlayer->ResetInterpolation(); - - // Reset him - m_pLocalPlayer->ResetStats(); - } - else - { - RaiseFatalError(2); - } - - // Make sure we never get tired - g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true); - - // Tell doggy we got the game running - WatchDogCompletedSection("L1"); -} - -void CClientGame::Event_OnIngameAndConnected(void) -{ - m_ulVerifyTimeStart = CClientTime::GetTime(); - - // Keep criminal records of how many times they've connected to servers - SetApplicationSettingInt("times-connected", GetApplicationSettingInt("times-connected") + 1); - if (m_ServerType == SERVER_TYPE_EDITOR) - SetApplicationSettingInt("times-connected-editor", GetApplicationSettingInt("times-connected-editor") + 1); - - // Notify the server telling we're ingame - m_pNetAPI->RPC(PLAYER_INGAME_NOTICE); -} - -bool CClientGame::StaticBreakTowLinkHandler(CVehicle* pTowingVehicle) -{ - return g_pClientGame->BreakTowLinkHandler(pTowingVehicle); -} - -void CClientGame::StaticDrawRadarAreasHandler(void) -{ - g_pClientGame->DrawRadarAreasHandler(); -} - -bool CClientGame::StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent) -{ - return g_pClientGame->DamageHandler(pDamagePed, pEvent); -} - -void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart) -{ - g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart); -} - -void CClientGame::StaticFireHandler(CFire* pFire) -{ - g_pClientGame->FireHandler(pFire); -} - -void CClientGame::StaticRender3DStuffHandler(void) -{ - g_pClientGame->Render3DStuffHandler(); -} - -void CClientGame::StaticPreRenderSkyHandler(void) -{ - g_pClientGame->PreRenderSkyHandler(); -} - -void CClientGame::StaticRenderHeliLightHandler() -{ - g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); -} - -bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) -{ - return g_pClientGame->ChokingHandler(ucWeaponType); -} - -void CClientGame::StaticCAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) -{ - g_pClientGame->CAnimBlendAssocDestructorHandler(pThis); -} - -CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) -{ - return g_pClientGame->AddAnimationHandler(pClump, animGroup, animID); -} - -CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) -{ - return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); -} - -bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) -{ - return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); -} - -bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, - int* pFlags, RpClump* pClump) -{ - return g_pClientGame->BlendAnimationHierarchyHandler(pAnimAssoc, pOutAnimHierarchy, pFlags, pClump); -} - -void CClientGame::StaticPreWorldProcessHandler(void) -{ - g_pClientGame->PreWorldProcessHandler(); -} - -void CClientGame::StaticPostWorldProcessHandler(void) -{ - g_pClientGame->PostWorldProcessHandler(); -} - -void CClientGame::StaticPreFxRenderHandler(void) -{ - g_pCore->OnPreFxRender(); -} - -void CClientGame::StaticPreHudRenderHandler(void) -{ - g_pCore->OnPreHUDRender(); -} - -bool CClientGame::StaticProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) -{ - return g_pClientGame->ProcessCollisionHandler(pThisInterface, pOtherInterface); -} - -bool CClientGame::StaticVehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, - float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, - CVector vecCollisionVelocity) -{ - return g_pClientGame->VehicleCollisionHandler(pCollidingVehicle, pCollidedVehicle, iModelIndex, fDamageImpulseMag, fCollidingDamageImpulseMag, usPieceType, - vecCollisionPos, vecCollisionVelocity); -} - -bool CClientGame::StaticVehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) -{ - return g_pClientGame->VehicleDamageHandler(pVehicleInterface, fLoss, pAttackerInterface, weaponType, vecDamagePos, ucTyre); -} - -bool CClientGame::StaticHeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) -{ - return g_pClientGame->HeliKillHandler(pHeliInterface, pHitInterface); -} - -bool CClientGame::StaticObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) -{ - return g_pClientGame->ObjectDamageHandler(pObjectInterface, fLoss, pAttackerInterface); -} - -bool CClientGame::StaticObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) -{ - return g_pClientGame->ObjectBreakHandler(pObjectInterface, pAttackerInterface); -} - -bool CClientGame::StaticWaterCannonHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) -{ - return g_pClientGame->WaterCannonHitHandler(pCannonVehicle, pHitPed); -} - -bool CClientGame::StaticVehicleFellThroughMapHandler(CVehicleSAInterface* pVehicle) -{ - return g_pClientGame->VehicleFellThroughMapHandler(pVehicle); -} - -void CClientGame::StaticGameObjectDestructHandler(CEntitySAInterface* pObject) -{ - g_pClientGame->GameObjectDestructHandler(pObject); -} - -void CClientGame::StaticGameVehicleDestructHandler(CEntitySAInterface* pVehicle) -{ - g_pClientGame->GameVehicleDestructHandler(pVehicle); -} - -void CClientGame::StaticGamePlayerDestructHandler(CEntitySAInterface* pPlayer) -{ - g_pClientGame->GamePlayerDestructHandler(pPlayer); -} - -void CClientGame::StaticGameProjectileDestructHandler(CEntitySAInterface* pProjectile) -{ - g_pClientGame->GameProjectileDestructHandler(pProjectile); -} - -void CClientGame::StaticGameModelRemoveHandler(ushort usModelId) -{ - g_pClientGame->GameModelRemoveHandler(usModelId); -} - -void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) -{ - if (pGameEntity) - { - // Map to client entity and pass to the texture replacer - CClientEntity* pClientEntity = g_pClientGame->GetGameEntityXRefManager()->FindClientEntity(pGameEntity); - if (pClientEntity) - { - int iTypeMask; - ushort usModelId = 0xFFFF; - switch (pClientEntity->GetType()) - { - case CCLIENTPED: - case CCLIENTPLAYER: - iTypeMask = TYPE_MASK_PED; - usModelId = (ushort) static_cast(pClientEntity)->GetModel(); - break; - case CCLIENTVEHICLE: - iTypeMask = TYPE_MASK_VEHICLE; - break; - case CCLIENTOBJECT: - iTypeMask = TYPE_MASK_OBJECT; - break; - default: - iTypeMask = TYPE_MASK_OTHER; - break; - } - g_pGame->GetRenderWare()->SetRenderingClientEntity(pClientEntity, usModelId, iTypeMask); - return; - } - } - - g_pGame->GetRenderWare()->SetRenderingClientEntity(NULL, 0xFFFF, TYPE_MASK_WORLD); -} - -void CClientGame::StaticTaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) -{ - g_pClientGame->TaskSimpleBeHitHandler(pPedAttacker, hitBodyPart, hitBodySide, weaponId); -} - -void CClientGame::StaticFxSystemDestructionHandler(void* pFxSAInterface) -{ - g_pClientGame->GetManager()->GetEffectManager()->SAEffectDestroyed(pFxSAInterface); -} - -AnimationId CClientGame::StaticDrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId) -{ - return g_pClientGame->DrivebyAnimationHandler(animGroup, animId); -} - -void CClientGame::DrawRadarAreasHandler(void) -{ - m_pRadarAreaManager->DoPulse(); -} - -bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle) -{ - CClientVehicle* pVehicle = m_pVehicleManager->Get(pTowedVehicle, false); - if (pVehicle) - { - // Check if this is a legal break - bool bLegal = ((pVehicle->GetControllingPlayer() == m_pLocalPlayer) || (m_pUnoccupiedVehicleSync->Exists(static_cast(pVehicle)))); - - // Not a legal break? - if (!bLegal) - { - // Save the time it broke (used in UpdateTrailers) - pVehicle->SetIllegalTowBreakTime(GetTickCount32()); - } - } - - // Allow it to break - return true; -} - -void CClientGame::FireHandler(CFire* pFire) -{ - // Disable spreading fires - pFire->SetNumGenerationsAllowed(0); -} - -void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) -{ - if (pProjectile->IsLocal()) - { - // Did the local player create this projectile? - if (m_pLocalPlayer && pProjectile->GetCreator() == m_pLocalPlayer) - { - // Physics says our projectile should start off at our velocity - CVector vecVelocity, vecPlayerVelocity; - pProjectile->GetVelocity(vecVelocity); - m_pLocalPlayer->GetMoveSpeed(vecPlayerVelocity); - vecVelocity += vecPlayerVelocity; - pProjectile->SetVelocity(vecVelocity); - } - - SendProjectileSync(pProjectile); - } - - // Renew the interior and dimension - if (pProjectile->GetCreator()) - { - pProjectile->SetInterior(pProjectile->GetCreator()->GetInterior()); - pProjectile->SetDimension(pProjectile->GetCreator()->GetDimension()); - } - - // Validate the projectile for our element tree - pProjectile->SetParent(m_pRootEntity); - - // Call our creation event - CLuaArguments Arguments; - Arguments.PushElement(pProjectile->GetCreator()); - pProjectile->CallEvent("onClientProjectileCreation", Arguments, true); -} - -void CClientGame::Render3DStuffHandler(void) -{ -} - -void CClientGame::PreRenderSkyHandler(void) -{ - g_pCore->GetGraphics()->GetRenderItemManager()->PreDrawWorld(); -} - -void CClientGame::PreWorldProcessHandler(void) -{ -} - -void CClientGame::PostWorldProcessHandler(void) -{ - m_pManager->GetMarkerManager()->DoPulse(); - m_pManager->GetPointLightsManager()->DoPulse(); - m_pManager->GetObjectManager()->DoPulse(); - - // Update frame time slice - uint uiCurrentTick = GetTickCount32(); - if (m_uiLastFrameTick) - { - m_uiFrameTimeSlice = uiCurrentTick - m_uiLastFrameTick; - m_uiFrameCount++; - - // Call onClientPreRender LUA event - CLuaArguments Arguments; - Arguments.PushNumber(m_uiFrameTimeSlice); - m_pRootEntity->CallEvent("onClientPreRender", Arguments, false); - } - m_uiLastFrameTick = uiCurrentTick; -} - -void CClientGame::IdleHandler(void) -{ - // If we are minimized we do the pulsing here - if (g_pCore->IsWindowMinimized()) - { - if (!m_bWasMinimized) - { - m_bWasMinimized = true; - // Call onClientMinimize LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); - - bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); - - // Apply mute on minimize options - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) - g_pGame->GetAudio()->SetMusicMasterVolume(0); - - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) - g_pGame->GetAudio()->SetEffectsMasterVolume(0); - - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) - m_pManager->GetSoundManager()->SetMinimizeMuted(true); - } - } - - // Ensure dummy progress graphic will be displayed when using alt pulse order - g_pCore->SetDummyProgressUpdateAlways(true); - - // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) - DoPulses2(true); - - g_pCore->SetDummyProgressUpdateAlways(false); -} - -bool CClientGame::ChokingHandler(unsigned char ucWeaponType) -{ - if (!m_pLocalPlayer) - return true; - CLuaArguments Arguments; - Arguments.PushNumber(ucWeaponType); - return m_pLocalPlayer->CallEvent("onClientPlayerChoke", Arguments, true); -} - -void CClientGame::CAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) -{ - // printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID); - RemoveAnimationAssociationFromMap(pThis); -} - -CAnimBlendAssociationSAInterface* CClientGame::AddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) -{ - // printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); - return nullptr; -} - -CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) -{ - // printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); - return nullptr; -} - -bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) -{ - bool isCustomAnimationToPlay = false; - CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); - auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); - auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); - auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); - auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); - - CClientPed* pClientPed = GetClientPedByClump(*pClump); - if (pClientPed != nullptr) - { - auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); - if (pReplacedAnimation != nullptr) - { - std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); - - // Play our custom animation instead of default - auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); - pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); - pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); - pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); - isCustomAnimationToPlay = true; - } - } - - if (!isCustomAnimationToPlay) - { - auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); - - // Play default internal animation - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); - } - return isCustomAnimationToPlay; -} - -bool CClientGame::BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags, - RpClump* pClump) -{ - bool isCustomAnimationToPlay = false; - CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); - CClientPed* pClientPed = GetClientPedByClump(*pClump); - if (pClientPed != nullptr) - { - if (pClientPed->IsNextAnimationCustom()) - { - std::shared_ptr pIFP = pClientPed->GetCustomAnimationIFP(); - if (pIFP) - { - const SString& strAnimationName = pClientPed->GetNextAnimationCustomName(); - auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy(strAnimationName); - if (pCustomAnimBlendHierarchy != nullptr) - { - std::shared_ptr pIFPAnimations = pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); - - pClientPed->SetCurrentAnimationCustom(true); - pClientPed->SetNextAnimationNormal(); - - if (pIFP->IsUnloading()) - { - pClientPed->DereferenceCustomAnimationBlock(); - } - *pOutAnimHierarchy = pCustomAnimBlendHierarchy; - isCustomAnimationToPlay = true; - return isCustomAnimationToPlay; - } - } - } - - pClientPed->SetCurrentAnimationCustom(false); - pClientPed->SetNextAnimationNormal(); - } - return isCustomAnimationToPlay; -} - -bool CClientGame::ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) -{ - if (pThisInterface == pOtherInterface) - return true; - - if (!m_BuiltCollisionMapThisFrame) - { - // Build a map of CPhysicalSAInterface*/CClientEntity*'s that have collision disabled - m_BuiltCollisionMapThisFrame = true; - m_CachedCollisionMap.clear(); - - std::map::iterator iter = m_AllDisabledCollisions.begin(); - for (; iter != m_AllDisabledCollisions.end(); ++iter) - { - CClientEntity* pEntity = iter->first; - CEntity* pGameEntity = pEntity->GetGameEntity(); - CEntitySAInterface* pInterface = pGameEntity ? pGameEntity->GetInterface() : NULL; - - if (pInterface) - m_CachedCollisionMap[pInterface] = pEntity; - } - } - - // Check both elements appear in the cached map before doing extra processing - std::map::iterator iter1 = m_CachedCollisionMap.find((CEntitySAInterface*)pThisInterface); - if (iter1 != m_CachedCollisionMap.end()) - { - std::map::iterator iter2 = m_CachedCollisionMap.find((CEntitySAInterface*)pOtherInterface); - if (iter2 != m_CachedCollisionMap.end()) - { - // Re-get the entity pointers using a safer method - CEntity* pGameEntity = g_pGame->GetPools()->GetEntity((DWORD*)pThisInterface); - CEntity* pGameColEntity = g_pGame->GetPools()->GetEntity((DWORD*)pOtherInterface); - - if (pGameEntity && pGameColEntity) - { - CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity, true); - CClientEntity* pColEntity = m_pManager->FindEntity(pGameColEntity, true); - - if (pEntity && pColEntity) - { - #if MTA_DEBUG - CClientEntity* ppThisEntity2 = iter1->second; - CClientEntity* ppOtherEntity2 = iter2->second; - // These should match, but its not essential. - assert(ppThisEntity2 == pEntity); - assert(ppOtherEntity2 == pColEntity); - #endif - if (!pEntity->IsCollidableWith(pColEntity)) - return false; - } - } - } - } - - return true; -} - -// -// On demand files -// -void CClientGame::DownloadSingularResourceFiles(void) -{ - if (!IsTransferringSingularFiles()) - return; - - if (!g_pNet->IsConnected()) - return; - - CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES); - if (!pHTTP->ProcessQueuedFiles()) - { - // Downloading - } - else - { - // Can't clear list until all files have been processed - if (m_pSingularFileDownloadManager->AllComplete()) - { - SetTransferringSingularFiles(false); - m_pSingularFileDownloadManager->ClearList(); - } - } -} - -// Get relevant death anim for animation purposes during death situation -void GetDeathAnim(CClientPed* pDamagedPed, CEventDamage* pEvent, AssocGroupId& outAnimGroup, AnimationId& outAnimID) -{ - if (pEvent) - { - pEvent->ComputeDeathAnim(pDamagedPed->GetGamePlayer(), false); - outAnimGroup = pEvent->GetAnimGroup(); - outAnimID = pEvent->GetAnimId(); - } - else - { - // Using same numbers as CClientGame::DoWastedCheck defaults - outAnimGroup = 0; - outAnimID = 15; - } -} - -// -// DamageHandler seems to be called 3 times for each bit of damage: -// -// pass 1 - preApplyDamage -// is pass 1 if: fDamage == zero && fCurrentHealth == fPreviousHealth -// returning false stops any damage being inflicted -// returning true applies damage and allows pass 2 -// pass 2 - postApplyDamage/preApplyAnim -// is pass 2 if: fDamage > zero && fCurrentHealth != fPreviousHealth -// returning false stops damage anim -// returning true allows damage anim and allows pass 3 -// pass 3 - postApplyAnim -// is pass 3 if: fDamage > zero && fCurrentHealth == fPreviousHealth -// returning false ?? -// returning true ?? -// -bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) -{ - // CEventDamage::AffectsPed: This is/can be called more than once for each bit of damage (and may not actually take any more health (even if we return - // true)) - - // Grab some data from the event - CEntity* pInflictor = pEvent->GetInflictingEntity(); - eWeaponType weaponUsed = pEvent->GetWeaponUsed(); - ePedPieceTypes hitZone = pEvent->GetPedPieceType(); - CWeaponInfo* pWeaponInfo = g_pGame->GetWeaponInfo(weaponUsed); - float fDamage = pEvent->GetDamageApplied(); - EDamageReasonType damageReason = pEvent->GetDamageReason(); - - /* Causes too much desync right now - // Is this shotgun damage? - if ( weaponUsed == WEAPONTYPE_SHOTGUN || weaponUsed == WEAPONTYPE_SPAS12_SHOTGUN ) - { - // Make the ped fall down - pEvent->MakePedFallDown (); - } */ - - // Grab the damaged ped - CClientPed* pDamagedPed = NULL; - if (pDamagePed) - pDamagedPed = m_pPedManager->Get(dynamic_cast(pDamagePed), true, true); - - // Grab the inflictor - CClientEntity* pInflictingEntity = NULL; - if (pInflictor) - pInflictingEntity = m_pManager->FindEntity(pInflictor, true); - - // If the damage was caused by an explosion - if (weaponUsed == WEAPONTYPE_EXPLOSION) - { - CClientEntity* pLastExplosionCreator = m_pManager->GetExplosionManager()->m_pLastCreator; - - // If we don't have an inflictor, look for the last explosion creator - if (!pInflictor && pLastExplosionCreator) - pInflictingEntity = pLastExplosionCreator; - - // Change the weapon used to whatever created the explosion - weaponUsed = m_pManager->GetExplosionManager()->m_LastWeaponType; - } - - // Do we have a damaged ped? - if (pDamagedPed) - { - /////////////////////////////////////////////////////////////////////////// - // - // Pass 1 stuff - // - // return false to stop any damage being inflicted - // - /////////////////////////////////////////////////////////////////////////// - - // Pass 1 checks for double shots - if (fDamage == 0.0f && damageReason != EDamageReason::PISTOL_WHIP) - { - // Only check for remote players - CClientPlayer* pInflictingPlayer = DynamicCast(pInflictingEntity); - if (pInflictingPlayer && !pInflictingPlayer->IsLocalPlayer()) - { - bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon - bool bBulletSyncWeapon = GetWeaponTypeUsesBulletSync(weaponUsed); - - if (bBulletSyncShot) - { - if (g_iDamageEventLimit == 0) - { - AddReportLog(5501, SString("2nd pass 1 for BulletSyncShot damage. weaponUsed:%d", weaponUsed)); - return false; - } - g_iDamageEventLimit--; - if (!bBulletSyncWeapon) - { - AddReportLog(5502, SString("BulletSyncShot but not bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); - return false; - } - } - else - { - if (bBulletSyncWeapon) - { - AddReportLog(5503, SString("not BulletSyncShot but bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); - return false; - } - } - } - } - - // Is the damaged ped a player? - if (IS_PLAYER(pDamagedPed)) - { - CClientPlayer* pDamagedPlayer = static_cast(pDamagedPed); - - // Do we have an inflicting entity? - if (pInflictingEntity) - { - // Grab the inflicting player - CClientPlayer* pInflictingPlayer = NULL; - - switch (pInflictingEntity->GetType()) - { - case CCLIENTPLAYER: - { - pInflictingPlayer = static_cast(pInflictingEntity); - break; - } - case CCLIENTVEHICLE: - { - CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); - if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) - { - CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); - if (pPed && pPed->GetType() == CCLIENTPLAYER) - pInflictingPlayer = static_cast(pPed); - } - break; - } - default: - break; - } - if (pInflictingPlayer) - { - // Is the damaged player on a team - CClientTeam* pTeam = pDamagedPlayer->GetTeam(); - if (pTeam) - { - // Is this friendly-fire from a team-mate? - if (pDamagedPlayer->IsOnMyTeam(pInflictingPlayer) && !pTeam->GetFriendlyFire() && pDamagedPlayer != pInflictingPlayer) - return false; - } - } - } - } - /////////////////////////////////////////////////////////////////////////// - // Pass 1 end - /////////////////////////////////////////////////////////////////////////// - - return ApplyPedDamageFromGame(weaponUsed, fDamage, hitZone, pDamagedPed, pInflictingEntity, pEvent); - } - - // No damage anim for fire - if (weaponUsed == WEAPONTYPE_FLAMETHROWER) - return false; - - // Allow the damage processing to continue - return true; -} - -// -// Check GTA stored health with our stored health and do stuff -// -bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, uchar hitZone, CClientPed* pDamagedPed, CClientEntity* pInflictingEntity, - CEventDamage* pEvent) -{ - float fPreviousHealth = pDamagedPed->m_fHealth; - float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); - float fPreviousArmor = pDamagedPed->m_fArmor; - float fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); - - // Have we taken any damage here? - if ((fPreviousHealth != fCurrentHealth || fPreviousArmor != fCurrentArmor) && fDamage != 0.0f) - { - /////////////////////////////////////////////////////////////////////////// - /// - // Pass 2 stuff - (GTA has applied the damage) - // - // return false to stop damage anim (incl. death task) - // - /////////////////////////////////////////////////////////////////////////// - - g_fApplyDamageLastAmount = fDamage; - g_ucApplyDamageLastHitZone = hitZone; - g_pApplyDamageLastDamagedPed = pDamagedPed; - - CLuaArguments Arguments; - if (pInflictingEntity) - Arguments.PushElement(pInflictingEntity); - else - Arguments.PushBoolean(false); - Arguments.PushNumber(static_cast(weaponUsed)); - Arguments.PushNumber(static_cast(hitZone)); - Arguments.PushNumber(fDamage); - - // Call our event - if ((IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPlayerDamage", Arguments, true)) || - (!IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPedDamage", Arguments, true))) - { - // Stop here if they cancelEvent it - if (pDamagedPed->IsLocalPlayer()) - { - // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) - fPreviousHealth = pDamagedPed->m_fHealth; - fPreviousArmor = pDamagedPed->m_fArmor; - } - pDamagedPed->GetGamePlayer()->SetHealth(fPreviousHealth); - pDamagedPed->GetGamePlayer()->SetArmor(fPreviousArmor); - return false; - } - - if (pDamagedPed->IsLocalPlayer()) - { - // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) - fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); - fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); - } - - bool bIsBeingShotWhilstAiming = (weaponUsed >= WEAPONTYPE_PISTOL && weaponUsed <= WEAPONTYPE_MINIGUN && pDamagedPed->IsUsingGun()); - bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); - - bool bAllowChoke = true; - // Is this is a remote player? - if (!pDamagedPed->IsLocalPlayer()) - { - // Don't allow GTA to start the choking task - if (weaponUsed == WEAPONTYPE_TEARGAS || weaponUsed == WEAPONTYPE_SPRAYCAN || weaponUsed == WEAPONTYPE_EXTINGUISHER) - bAllowChoke = false; - } - - // Check if their health or armor is locked, and if so prevent applying the damage locally - if (pDamagedPed->IsHealthLocked() || pDamagedPed->IsArmorLocked()) - { - // Restore health+armor - pDamagedPed->GetGamePlayer()->SetHealth(pDamagedPed->GetHealth()); - pDamagedPed->GetGamePlayer()->SetArmor(pDamagedPed->GetArmor()); - - if (bOldBehaviour) - { - // Don't play the animation if it's going to be a death one, or if it's going to interrupt aiming - if (fCurrentHealth == 0.0f || bIsBeingShotWhilstAiming) - return false; - - // Allow animation for remote players (if currently we don't need block choke) - return bAllowChoke; - } - - // No hit animation for remote players - return false; - } - - // Update our stored health/armor - pDamagedPed->m_fHealth = fCurrentHealth; - pDamagedPed->m_fArmor = fCurrentArmor; - - ElementID damagerID = INVALID_ELEMENT_ID; - if (pInflictingEntity && !pInflictingEntity->IsLocalEntity()) - damagerID = pInflictingEntity->GetID(); - - // Is it the local player? - if (pDamagedPed->IsLocalPlayer()) - { - // Update our stored damage stuff - m_ucDamageWeapon = static_cast(weaponUsed); - m_ucDamageBodyPiece = static_cast(hitZone); - m_pDamageEntity = pInflictingEntity; - m_ulDamageTime = CClientTime::GetTime(); - m_DamagerID = damagerID; - m_bDamageSent = false; - } - // Does this damage kill the player? - if (fCurrentHealth == 0.0f) - { - if (pDamagedPed->GetType() == CCLIENTPLAYER) - { - // Is the local player dying? - if (pDamagedPed->IsLocalPlayer() && fPreviousHealth > 0.0f) - { - // Grab our death animation - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - - // Check if we're dead - DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); - } - - // Allow GTA to kill us if we've fell to our death - if (pDamagedPed->IsLocalPlayer() && weaponUsed == WEAPONTYPE_FALL) - return true; - - // Don't let GTA start the death task - return false; - } - else - { - if (pDamagedPed->IsLocalEntity() && fPreviousHealth > 0.0f) - { - // Client-side ped - pDamagedPed->CallEvent("onClientPedWasted", Arguments, true); - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - pDamagedPed->Kill(weaponUsed, hitZone, false, false, animGroup, animID); - return true; - } - if (fPreviousHealth > 0.0f) - { - // Grab our death animation - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - - SendPedWastedPacket(pDamagedPed, damagerID, weaponUsed, hitZone, animGroup, animID); - } - } - } - - // Disallow choke task if it's necessary - if (!bAllowChoke) - return false; - - // Inhibit hit-by-gun animation for local player if required - if (bOldBehaviour) - if (pDamagedPed->IsLocalPlayer() && bIsBeingShotWhilstAiming) - return false; - - /////////////////////////////////////////////////////////////////////////// - // Pass 2 end - /////////////////////////////////////////////////////////////////////////// - } - - // No damage anim for fire - if (weaponUsed == WEAPONTYPE_FLAMETHROWER) - return false; - - // Allow the damage processing to continue - return true; -} - -void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, unsigned char ucBodyPart) -{ - CClientPed* pKilledPed = m_pPedManager->Get(dynamic_cast(pKilledPedSA), true, true); - - if (!pKilledPed) - return; - - // Not required for remote players. Local player is handled in DoPulses->DoWastedCheck - if (IS_PLAYER(pKilledPed)) - return; - - // Set the health to zero (this is safe as GTA will do it anyway in a few ticks) - pKilledPed->SetHealth(0.0f); - - // Call Lua - CLuaArguments Arguments; - Arguments.PushBoolean(false); - Arguments.PushNumber(ucDeathReason); - Arguments.PushNumber(ucBodyPart); - - pKilledPed->CallEvent("onClientPedWasted", Arguments, true); - - // Notify the server - SendPedWastedPacket(pKilledPed, INVALID_ELEMENT_ID, ucDeathReason, ucBodyPart); -} - -bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, - float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) -{ - if (pCollidingVehicle && pCollidedWith) - { - CVehicle* pColliderVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidingVehicle); - CClientEntity* pVehicleClientEntity = m_pManager->FindEntity(pColliderVehicle, true); - if (pVehicleClientEntity) - { - CClientVehicle* pClientVehicle = static_cast(pVehicleClientEntity); - - CEntity* pCollidedWithEntity = g_pGame->GetPools()->GetEntity((DWORD*)pCollidedWith); - CClientEntity* pCollidedWithClientEntity = NULL; - if (pCollidedWithEntity) - { - if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pCollidedWithVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithVehicle, true); - } - else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_OBJECT) - { - CObject* pCollidedWithObject = g_pGame->GetPools()->GetObject((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithObject, true); - } - else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pCollidedWithPed = g_pGame->GetPools()->GetPed((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithPed, true); - } - } - CLuaArguments Arguments; - if (pCollidedWithClientEntity) - { - Arguments.PushElement(pCollidedWithClientEntity); - } - else - { - Arguments.PushNil(); - } - Arguments.PushNumber(fDamageImpulseMag); - Arguments.PushNumber(usPieceType); - Arguments.PushNumber(vecCollisionPos.fX); - Arguments.PushNumber(vecCollisionPos.fY); - Arguments.PushNumber(vecCollisionPos.fZ); - Arguments.PushNumber(vecCollisionVelocity.fX); - Arguments.PushNumber(vecCollisionVelocity.fY); - Arguments.PushNumber(vecCollisionVelocity.fZ); - Arguments.PushNumber(fCollidingDamageImpulseMag); - Arguments.PushNumber(iModelIndex); - - pVehicleClientEntity->CallEvent("onClientVehicleCollision", Arguments, true); - // Alocate a BitStream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - // Make sure it created - if (pBitStream) - { - if (pBitStream->Version() >= 0x028) - { - // Sync Stuff - // if it's not a local vehicle + it collided with the local player - if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) - { - // is it below the anti spam threshold? - if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) - { - // if there is no controlling player - if (!pClientVehicle->GetControllingPlayer()) - { - CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); - // if We aren't already syncing the vehicle - if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) - { - // Write the vehicle ID - pBitStream->Write(pVehicleClientEntity->GetID()); - // Send! - g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, - PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); - // Reset our push time - pClientVehicle->ResetLastPushTime(); - } - } - } - } - } - g_pNet->DeallocateNetBitStream(pBitStream); - } - return true; - } - } - return false; -} - -bool CClientGame::HeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) -{ - if (pHeliInterface && pHitInterface) - { - // Get our heli and client heli - CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); - CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); - if (pHeli && pClientHeli && pClientHeli->AreHeliBladeCollisionsEnabled()) - { - // Get our ped and client ped - CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitInterface); - CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); - // Was our client ped valid - if (pClientPed) - { - // Get our heli and client heli - CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); - CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); - - // Iterate our "stored" cancel state and find the heli in question - std::pair::iterator, std::multimap::iterator> iterators = - m_HeliCollisionsMap.equal_range(pClientHeli); - std::multimap::const_iterator iter = iterators.first; - for (; iter != iterators.second; ++iter) - { - // If the Heli and ped collided within the clear rate return false - if ((*iter).first == pClientHeli && (*iter).second == pClientPed) - return false; - } - - CLuaArguments Arguments; - if (pClientHeli) - { - // Push our heli - Arguments.PushElement(pClientHeli); - } - else - { - Arguments.PushNil(); - } - - // Trigger our event - bool bContinue; - if (IS_PLAYER(pClientPed)) - bContinue = pClientPed->CallEvent("onClientPlayerHeliKilled", Arguments, true); - else - bContinue = pClientPed->CallEvent("onClientPedHeliKilled", Arguments, true); - - // Was our event cancelled - if (!bContinue) - { - // Add our heli and ped pair to the list - std::pair pair = std::pair(pClientHeli, pClientPed); - m_HeliCollisionsMap.insert(pair); - } - // Return if it was cancelled - return bContinue; - } - } - else - { - return false; - } - } - return true; -} - -bool CClientGame::VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) -{ - bool bAllowDamage = true; - CClientVehicle* pClientVehicle = GetGameEntityXRefManager()->FindClientVehicle(pVehicleInterface); - if (pClientVehicle) - { - CClientEntity* pClientAttacker = GetGameEntityXRefManager()->FindClientEntity(pAttackerInterface); - - // Compose arguments - // attacker, weapon, loss, damagepos, tyreIdx - CLuaArguments Arguments; - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - if (weaponType != WEAPONTYPE_INVALID) - Arguments.PushNumber(weaponType); - else - Arguments.PushNil(); - Arguments.PushNumber(fLoss); - Arguments.PushNumber(vecDamagePos.fX); - Arguments.PushNumber(vecDamagePos.fY); - Arguments.PushNumber(vecDamagePos.fZ); - if (ucTyre != UCHAR_INVALID_INDEX) - Arguments.PushNumber(ucTyre); - else - Arguments.PushNil(); - - if (!pClientVehicle->CallEvent("onClientVehicleDamage", Arguments, true)) - { - bAllowDamage = false; - } - } - - return bAllowDamage; -} - -bool CClientGame::ObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) -{ - if (pObjectInterface) - { - // Get our object and client object - CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); - CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); - - // Is our client vehicle valid? - if (pClientObject) - { - CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); - CClientEntity* pClientAttacker = NULL; - if (pAttacker) - { - if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); - } - else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerPed); - } - } - - CLuaArguments Arguments; - Arguments.PushNumber(fLoss); - - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - - return pClientObject->CallEvent("onClientObjectDamage", Arguments, true); - } - } - return true; -} - -bool CClientGame::ObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) -{ - if (pObjectInterface) - { - // Get our object and client object - CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); - CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); - - // Is our client vehicle valid? - if (pClientObject) - { - if (!pClientObject->IsBreakable(false)) - return false; - - // Apply to MTA's "internal storage", too - pClientObject->SetHealth(0.0f); - - CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); - CClientEntity* pClientAttacker = NULL; - if (pAttacker) - { - if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); - } - else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerPed); - } - } - - CLuaArguments Arguments; - - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - - return pClientObject->CallEvent("onClientObjectBreak", Arguments, true); - } - } - return true; -} - -bool CClientGame::WaterCannonHitHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) -{ - if (pCannonVehicle && pHitPed) - { - // Get our vehicle and client vehicle - CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCannonVehicle); - CClientVehicle* pCannonClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); - // Was our client vehicle valid - if (pCannonClientVehicle) - { - // Get our ped and client ped - CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitPed); - CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); - - CLuaArguments Arguments; - if (pClientPed) - { - // Push our ped - Arguments.PushElement(pClientPed); - } - else - { - Arguments.PushNil(); - } - - // Trigger our event - bool bContinue = true; - if (!IS_PLAYER(pClientPed)) - bContinue = pCannonClientVehicle->CallEvent("onClientPedHitByWaterCannon", Arguments, true); - else - bContinue = pCannonClientVehicle->CallEvent("onClientPlayerHitByWaterCannon", Arguments, true); - - // Return if it was cancelled - return bContinue; - } - } - return false; -} - -bool CClientGame::VehicleFellThroughMapHandler(CVehicleSAInterface* pVehicleInterface) -{ - if (pVehicleInterface) - { - // Get our vehicle and client vehicle - CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pVehicleInterface); - CClientVehicle* pClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); - if (pClientVehicle) - { - // handle or don't - return pClientVehicle->OnVehicleFallThroughMap(); - } - } - // unhandled - return false; -} - -// Validate known objects -void CClientGame::GameObjectDestructHandler(CEntitySAInterface* pObject) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pObject); -} - -void CClientGame::GameVehicleDestructHandler(CEntitySAInterface* pVehicle) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pVehicle); -} - -void CClientGame::GamePlayerDestructHandler(CEntitySAInterface* pPlayer) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pPlayer); -} - -void CClientGame::GameProjectileDestructHandler(CEntitySAInterface* pProjectile) -{ - CClientProjectile* pClientProjectile = m_pManager->GetProjectileManager()->Get(pProjectile); - // Happens when destroyElement is called rather than letting the projectile expire - // Normal code path is destruction from CProjectileSAInterface -> CProjectileSA -> CClientProjectile - // destroyElement is CClientProjectile -> CProjectileSA -> CProjectileSAInterface - // which means the CClientProjectile element is deleted when we get here - if (pClientProjectile) - CStaticFunctionDefinitions::DestroyElement(*pClientProjectile); -} - -void CClientGame::GameModelRemoveHandler(ushort usModelId) -{ - m_pGameEntityXRefManager->OnGameModelRemove(usModelId); -} - -void CClientGame::TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) -{ - bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); - if (bOldBehaviour) - return; - - CClientPed* pClientPedAttacker = DynamicCast(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedAttacker)); - - // Make sure cause was networked ped - if (pClientPedAttacker && !pClientPedAttacker->IsLocalEntity()) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write((ushort)TASK_SIMPLE_BE_HIT); - pBitStream->Write(pClientPedAttacker->GetID()); - pBitStream->Write((uchar)hitBodyPart); - pBitStream->Write((uchar)hitBodySide); - pBitStream->Write((uchar)weaponId); - g_pNet->SendPacket(PACKET_ID_PED_TASK, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -bool CClientGame::StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (g_pClientGame) - { - return g_pClientGame->ProcessMessage(hwnd, uMsg, wParam, lParam); - } - - return false; -} - -bool CClientGame::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (ProcessMessageForCursorEvents(hwnd, uMsg, wParam, lParam)) - { - return true; - } - - return false; -} - -void CClientGame::ProcessVehicleInOutKey(bool bPassenger) -{ - // Are we already sending an in/out request or not allowed to create a new in/out? - if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? - || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) - || m_bIsGettingJacked // Make sure we're not currently getting carjacked && - || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... - || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... - || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon - ) - { - return; - } - - // Reset the "is jacking" bit - m_bIsJackingVehicle = false; - - // Got a local player model? - if (!m_pLocalPlayer) - { - // No local player. Stop. - return; - } - - // If the player is in a vehicle we need to leave the vehicle. - CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - if (pOccupiedVehicle) - { - // Only let us leave the vehicle if: - // - we press F (as driver) - // - we press either F or G as a passenger - if (bPassenger && m_pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - // Driver pressed G, so stop. - return; - } - - // We're about to exit a vehicle - // Send an in request - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!pBitStream) - { - return; - } - - // Write the vehicle id to it and that we're requesting to get out of it - pBitStream->Write(pOccupiedVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_REQUEST_OUT); - pBitStream->WriteBits(&ucAction, 4); - - unsigned char ucDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pLocalPlayer->GetGamePlayer(), pOccupiedVehicle->GetGameVehicle()); - if (ucDoor >= 2 && ucDoor <= 5) - { - ucDoor -= 2; - pBitStream->WriteBits(&ucDoor, 2); - } - - // Send and destroy it - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're now exiting a vehicle - m_bIsGettingOutOfVehicle = true; - m_ulLastVehicleInOutTime = CClientTime::GetTime(); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_out"); -#endif - return; - } - - // - // We're going to enter a vehicle - // - - // If the Jump task is playing and we are in water - I know right - // Kill the task. - // - CTask* pTask = m_pLocalPlayer->GetCurrentPrimaryTask(); - if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter - { - CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, nullptr, nullptr, 20.0f); - if (pVehicle && - (pVehicle->IsInWater() || - m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) - { - m_pLocalPlayer->KillTask(3, true); // Kill jump task if we are about to warp in - } - } - - // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle' - // task will replace it and fuck it up! - // - if (m_pLocalPlayer->GetCurrentPrimaryTask()) - { - // We already have a primary task, so stop. - return; - } - - // Are we holding the aim_weapon key? - SBindableGTAControl* pBind = g_pCore->GetKeyBinds()->GetBindableFromControl("aim_weapon"); - if (pBind && pBind->bState) - { - // Stop because the player is probably using rshift + f/g - return; - } - - if (m_pLocalPlayer->IsClimbing() // Make sure we're not currently climbing - || m_pLocalPlayer->HasJetPack() // Make sure we don't have a jetpack - || m_pLocalPlayer->IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway - || m_pLocalPlayer->IsRunningAnimation() // Make sure we aren't running an animation - ) - { - return; - } - - // Grab the closest vehicle - unsigned int uiDoor = 0; - CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, &uiDoor, nullptr, 20.0f); - unsigned int uiSeat = uiDoor; - - if (bPassenger && uiDoor == 0) - { - // We're trying to enter as a passenger, yet our closest door - // is the driver's door. Force an enter for the passenger seat. - uiSeat = 1; - } - else if (!bPassenger) - { - // We want to drive. Force our seat to the driver's seat. - uiSeat = 0; - } - - if (!pVehicle || !pVehicle->IsEnterable()) - { - // Stop if there isn't a vehicle, or the vehicle is not enterable - return; - } - - // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly) - if (pVehicle->GetVehicleType() == CLIENTVEHICLE_BOAT && m_pLocalPlayer->GetContactEntity() != pVehicle) - { - return; - } - - // Call the onClientVehicleStartEnter event for remote players - // Local player triggered before sending packet in CClientGame - CLuaArguments Arguments; - Arguments.PushElement(m_pLocalPlayer); // player - Arguments.PushNumber(uiSeat); // seat - Arguments.PushNumber(uiDoor); // Door - - if (!pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true)) - { - // Event has been cancelled - return; - } - - // Send an in request - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!pBitStream) - { - return; - } - - // Write the vehicle id to it and that we're requesting to get into it - pBitStream->Write(pVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_REQUEST_IN); - unsigned char ucSeat = static_cast(uiSeat); - bool bIsOnWater = pVehicle->IsOnWater(); - unsigned char ucDoor = static_cast(uiDoor); - pBitStream->WriteBits(&ucAction, 4); - pBitStream->WriteBits(&ucSeat, 4); - pBitStream->WriteBit(bIsOnWater); - pBitStream->WriteBits(&ucDoor, 3); - - // Send and destroy it - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're now entering a vehicle - m_bIsGettingIntoVehicle = true; - m_ulLastVehicleInOutTime = CClientTime::GetTime(); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_in"); -#endif -} - -// Shot compensation (Jax): -// Positions the local player where he should of been on the shooting player's screen when he -// fired remotely. (the position we !reported! around the time he shot) -bool bShotCompensation = true; - -// Temporary pointers for pre- and post-functions -CVector vecWeaponFirePosition, vecRemoteWeaponFirePosition; -CPlayerPed* pWeaponFirePed = NULL; - -bool CClientGame::PreWeaponFire(CPlayerPed* pPlayerPed, bool bStopIfUsingBulletSync) -{ - pWeaponFirePed = pPlayerPed; - - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pWeaponFirePed) - { - CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); - - // Get the CClientNetPlayer class with the specified player ped - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(pWeaponFirePed, true); - - // Move both players to where they should be for shot compensation - if (pPlayer && !pPlayer->IsLocalPlayer()) - { - if (bStopIfUsingBulletSync && pPlayer->IsCurrentWeaponUsingBulletSync()) - return false; // Don't apply shot compensation & tell caller to not do bullet trace - - if (bShotCompensation) - { - if (!pVehicle || pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - // Warp back in time to where we were when this player shot (their latency) - - // We don't account for interpolation here, +250ms seems to work better - // ** Changed ajustment to +125ms as the position of this clients player on the firers screen - // has been changed. See CClientPed::UpdateTargetPosition() ** - CVector vecPosition; - unsigned short usLatency = (pPlayer->GetLatency() + 125); - g_pClientGame->m_pNetAPI->GetInterpolation(vecPosition, usLatency); - - // Move the entity back - if (pVehicle) - { - pVehicle->GetPosition(vecWeaponFirePosition); - pVehicle->SetPosition(vecPosition, false, false); - } - else - { - pLocalPlayer->GetPosition(vecWeaponFirePosition); - pLocalPlayer->SetPosition(vecPosition, false, false); - } - } - } - } - } - return true; -} - -void CClientGame::PostWeaponFire(void) -{ - // Send bullet sync with local damage info - if (g_bBulletFireVectorsValid) - { - g_bBulletFireVectorsValid = false; - CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer) - { - eWeaponType weaponType = pLocalPlayer->GetCurrentWeaponType(); - if (g_pClientGame->GetWeaponTypeUsesBulletSync(weaponType)) - { - g_pClientGame->GetNetAPI()->SendBulletSyncFire(weaponType, g_vecBulletFireStartPosition, g_vecBulletFireEndPosition, g_fApplyDamageLastAmount, - g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); - } - } - } - - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pWeaponFirePed) - { - CClientPed* pPed = g_pClientGame->GetPedManager()->Get(pWeaponFirePed, true, true); - if (pPed) - { - if (pPed->GetType() == CCLIENTPLAYER) - { - if (bShotCompensation) - { - // Restore compensated positions - if (!pPed->IsLocalPlayer()) - { - CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); - if (!pVehicle) - { - pLocalPlayer->SetPosition(vecWeaponFirePosition, false, false); - } - else if (pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - pVehicle->SetPosition(vecWeaponFirePosition, false, false); - } - } - } - } - - // Call some events - CWeapon* pWeapon = pPed->GetWeapon(); - if (pWeapon) - { - CVector vecCollision; - CClientEntity* pCollisionEntity = NULL; - - if (pPed->GetBulletImpactData(&pCollisionEntity, &vecCollision) == false) - { - CShotSyncData* pShotsyncData = pPed->m_shotSyncData; - CVector vecOrigin, vecTarget; - pPed->GetShotData(&vecOrigin, &vecTarget); - - CColPoint* pCollision = NULL; - CEntity* pCollisionGameEntity = NULL; - vecCollision = vecTarget; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionGameEntity); - if (bCollision && pCollision) - vecCollision = pCollision->GetPosition(); - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - - if (pCollisionGameEntity) - pCollisionEntity = g_pClientGame->m_pManager->FindEntity(pCollisionGameEntity); - } - else - { - pPed->ClearBulletImpactData(); - } - - // Call our lua event - CLuaArguments Arguments; - Arguments.PushNumber((double)pWeapon->GetType()); - Arguments.PushNumber((double)pWeapon->GetAmmoTotal()); - Arguments.PushNumber((double)pWeapon->GetAmmoInClip()); - Arguments.PushNumber((double)vecCollision.fX); - Arguments.PushNumber((double)vecCollision.fY); - Arguments.PushNumber((double)vecCollision.fZ); - if (pCollisionEntity) - Arguments.PushElement(pCollisionEntity); - else - Arguments.PushNil(); - - if (IS_PLAYER(pPed)) - { - CVector vecOrigin; - pPed->GetShotData(&vecOrigin); - Arguments.PushNumber((double)vecOrigin.fX); - Arguments.PushNumber((double)vecOrigin.fY); - Arguments.PushNumber((double)vecOrigin.fZ); - pPed->CallEvent("onClientPlayerWeaponFire", Arguments, true); - } - else - pPed->CallEvent("onClientPedWeaponFire", Arguments, true); - } - pPed->PostWeaponFire(); -#ifdef MTA_DEBUG - if (pPed->IsLocalPlayer() && g_pClientGame->m_bDoPaintballs) - { - g_pClientGame->DoPaintballs(); - } -#endif - } - } - pWeaponFirePed = NULL; -} - -void CClientGame::BulletImpact(CPed* pInitiator, CEntity* pVictim, const CVector* pStartPosition, const CVector* pEndPosition) -{ - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pInitiator) - { - // Find the client ped that initiated the bullet impact - CClientPed* pInitiatorPed = g_pClientGame->GetPedManager()->Get(dynamic_cast(pInitiator), true, true); - - if (pInitiatorPed) - { - // Calculate the collision of the bullet - CVector vecCollision; - CColPoint* pCollision = NULL; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(pStartPosition, pEndPosition, &pCollision, NULL); - if (bCollision && pCollision) - { - vecCollision = pCollision->GetPosition(); - } - else - { - // If we don't have a collision, use the end of the ray that the bullet is tracing. - vecCollision = *pEndPosition; - } - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - - // Find the client entity for the victim. - CClientEntity* pClientVictim = NULL; - if (pVictim) - { - pClientVictim = g_pClientGame->m_pManager->FindEntity(pVictim); - } - - // Store the data in the bullet fire initiator. - pInitiatorPed->SetBulletImpactData(pClientVictim, vecCollision); - } - } -} - -void CClientGame::BulletFire(CPed* pInitiator, const CVector* pStartPosition, const CVector* pEndPosition) -{ - g_bBulletFireVectorsValid = false; - g_fApplyDamageLastAmount = 0; - g_ucApplyDamageLastHitZone = 0; - g_pApplyDamageLastDamagedPed = NULL; - - // Got a local player model? - CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pLocalPlayer->GetGamePlayer() == pInitiator) - { - g_bBulletFireVectorsValid = true; - g_vecBulletFireStartPosition = *pStartPosition; - g_vecBulletFireEndPosition = *pEndPosition; - } -} - -bool CClientGame::StaticProcessPacket(unsigned char ucPacketID, NetBitStreamInterface& bitStream) -{ - if (g_pClientGame) - { - g_pCore->UpdateDummyProgress(); - g_pClientGame->GetManager()->GetPacketRecorder()->RecordPacket(ucPacketID, bitStream); - return g_pClientGame->m_pPacketHandler->ProcessPacket(ucPacketID, bitStream); - } - - return false; -} - -void CClientGame::SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin) -{ - SPositionSync position(false); - position.data.vecPosition = vecPosition; - - // Create the bitstream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write our origin id - if (pOrigin) - { - pBitStream->WriteBit(true); - pBitStream->Write(pOrigin->GetID()); - - // Convert position - CVector vecTemp; - pOrigin->GetPosition(vecTemp); - position.data.vecPosition -= vecTemp; - } - else - pBitStream->WriteBit(false); - - // Write the position and the type - pBitStream->Write(&position); - - SExplosionTypeSync explosionType; - explosionType.data.uiType = Type; - pBitStream->Write(&explosionType); - - // Destroy it - g_pNet->SendPacket(PACKET_ID_EXPLOSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -void CClientGame::SendFireSync(CFire* pFire) -{ -#ifdef MTA_DEBUG - CVector* vecPos = pFire->GetPosition(); - if (vecPos) - g_pCore->GetConsole()->Printf("we're sending fire: %f %f %f %f", pFire->GetStrength(), vecPos->fX, vecPos->fY, vecPos->fZ); - else - g_pCore->GetConsole()->Printf("we're sending a fire!"); -#endif -} - -void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) -{ - // Create the bitstream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - SPositionSync origin(false); - CClientEntity* pOriginSource = NULL; - eWeaponType weaponType = pProjectile->GetWeaponType(); - CClientEntity* pTarget = pProjectile->GetTargetEntity(); - origin.data.vecPosition = *pProjectile->GetOrigin(); - - // Is this a heatseaking missile with a target? sync it relative to the target - if (weaponType == WEAPONTYPE_ROCKET_HS && pTarget && !pTarget->IsLocalEntity()) - pOriginSource = pTarget; - - // Write the source of the projectile, if it has - if (pOriginSource) - { - CVector vecTemp; - pOriginSource->GetPosition(vecTemp); - origin.data.vecPosition -= vecTemp; - - pBitStream->WriteBit(true); - pBitStream->Write(pOriginSource->GetID()); - } - else - pBitStream->WriteBit(false); - - // Write the origin position - pBitStream->Write(&origin); - - // Write the creator weapon type - SWeaponTypeSync weaponTypeSync; - weaponTypeSync.data.ucWeaponType = static_cast(weaponType); - pBitStream->Write(&weaponTypeSync); - - // Write the projectile's model - if (pBitStream->Version() >= 0x4F) - if (pBitStream->Version() >= 0x52 || pOriginSource) // Fix possible error for 0x51 server - pBitStream->Write(pProjectile->GetModel()); - - switch (weaponType) - { - case WEAPONTYPE_GRENADE: - case WEAPONTYPE_TEARGAS: - case WEAPONTYPE_MOLOTOV: - case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: - { - SFloatSync<7, 17> projectileForce; - projectileForce.data.fValue = pProjectile->GetForce(); - pBitStream->Write(&projectileForce); - - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); - - break; - } - case WEAPONTYPE_ROCKET: - case WEAPONTYPE_ROCKET_HS: - { - if (pTarget) - { - pBitStream->WriteBit(true); - pBitStream->Write(pTarget->GetID()); - } - else - pBitStream->WriteBit(false); - - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); - - SRotationRadiansSync rotation(true); - pProjectile->GetRotationRadians(rotation.data.vecRotation); - pBitStream->Write(&rotation); - - break; - } - case WEAPONTYPE_FLARE: - case WEAPONTYPE_FREEFALL_BOMB: - break; - } - g_pNet->SendPacket(PACKET_ID_PROJECTILE, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - - // Destroy it - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -void CClientGame::ResetAmmoInClip(void) -{ - memset(&m_wasWeaponAmmoInClip[0], 0, sizeof(m_wasWeaponAmmoInClip)); -} - -void CClientGame::ResetMapInfo(void) -{ - // Restore some game stuff - // Keybinds - g_pCore->GetKeyBinds()->SetAllControlsEnabled(true, true, true); - - // Radarmap - m_pRadarMap->SetForcedState(false); - - // Camera - m_pCamera->FadeOut(0.0f, 0, 0, 0); - g_pGame->GetWorld()->SetCurrentArea(0); - m_pCamera->SetFocusToLocalPlayer(); - g_pGame->GetSettings()->ResetFieldOfViewFromScript(); - - // Dimension - SetAllDimensions(0); - - // Hud - g_pGame->GetHud()->SetComponentVisible(HUD_ALL, true); - // Disable area names as they are on load until camera unfades - g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); - g_pGame->GetHud()->SetComponentVisible(HUD_VITAL_STATS, false); - - m_bHudAreaNameDisabled = false; - - // Gravity - g_pMultiplayer->SetLocalPlayerGravity(DEFAULT_GRAVITY); - g_pMultiplayer->SetGlobalGravity(DEFAULT_GRAVITY); - g_pGame->SetGravity(DEFAULT_GRAVITY); - - // Gamespeed - SetGameSpeed(DEFAULT_GAME_SPEED); - - // Game minute duration - SetMinuteDuration(DEFAULT_MINUTE_DURATION); - - // Wanted-level - SetWanted(0); - - // Money - SetMoney(0, true); - - // Weather - m_pBlendedWeather->SetWeather(0); - - // Rain - g_pGame->GetWeather()->ResetAmountOfRain(); - - // Wind - g_pMultiplayer->RestoreWindVelocity(); - - // Far clip distance - g_pMultiplayer->RestoreFarClipDistance(); - - // Near clip distance - g_pMultiplayer->RestoreNearClipDistance(); - - // Fog distance - g_pMultiplayer->RestoreFogDistance(); - - // Vehicles LOD distance - g_pGame->GetSettings()->ResetVehiclesLODDistance(); - - // Peds LOD distance - g_pGame->GetSettings()->ResetPedsLODDistance(); - - // Sun color - g_pMultiplayer->ResetSunColor(); - - // Sun size - g_pMultiplayer->ResetSunSize(); - - // Sky-gradient - g_pMultiplayer->ResetSky(); - - // Heat haze - g_pMultiplayer->ResetHeatHaze(); - - // Water-colour - g_pMultiplayer->ResetWater(); - - // Water - GetManager()->GetWaterManager()->ResetWorldWaterLevel(); - - // Re-enable interior sounds and furniture - g_pMultiplayer->SetInteriorSoundsEnabled(true); - for (int i = 0; i <= 4; ++i) - g_pMultiplayer->SetInteriorFurnitureEnabled(i, true); - - // Clouds - g_pMultiplayer->SetCloudsEnabled(true); - g_pClientGame->SetCloudsEnabled(true); - - // Birds - g_pMultiplayer->DisableBirds(false); - g_pClientGame->SetBirdsEnabled(true); - - // Ambient sounds - g_pGame->GetAudio()->ResetAmbientSounds(); - - // World sounds - g_pGame->GetAudio()->ResetWorldSounds(); - - // Cheats - g_pGame->ResetCheats(); - - // Players - m_pPlayerManager->ResetAll(); - - // Jetpack max height - g_pGame->GetWorld()->SetJetpackMaxHeight(DEFAULT_JETPACK_MAXHEIGHT); - - // Aircraft max height - g_pGame->GetWorld()->SetAircraftMaxHeight(DEFAULT_AIRCRAFT_MAXHEIGHT); - - // Aircraft max velocity - g_pGame->GetWorld()->SetAircraftMaxVelocity(DEFAULT_AIRCRAFT_MAXVELOCITY); - - // Moon size - g_pMultiplayer->ResetMoonSize(); - - // Disable the change of any player stats - g_pMultiplayer->SetLocalStatsStatic(true); - - // Restore blur -#ifdef MTA_DEBUG - g_pGame->SetBlurLevel(0); -#else - g_pGame->SetBlurLevel(DEFAULT_BLUR_LEVEL); -#endif - - // Close all garages - CGarage* pGarage = NULL; - CGarages* pGarages = g_pCore->GetGame()->GetGarages(); - - for (unsigned char i = 0; (pGarage = pGarages->GetGarage(i)) != NULL; i++) - { - pGarage->SetOpen(false); - } - - // Player specific stuff - if (m_pLocalPlayer) - { - // Interior - m_pLocalPlayer->SetInterior(0); - - // Headless state - m_pLocalPlayer->SetHeadless(false); - - // Frozen state - m_pLocalPlayer->SetFrozen(false); - - // Voice - short sVoiceType, sVoiceID; - m_pLocalPlayer->GetModelInfo()->GetVoice(&sVoiceType, &sVoiceID); - m_pLocalPlayer->SetVoice(sVoiceType, sVoiceID); - - m_pLocalPlayer->DestroySatchelCharges(false, true); - // Tell the server we want to destroy our satchels - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - g_pNet->SendPacket(PACKET_ID_DESTROY_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, - AnimationId animID) -{ - if (Ped && Ped->GetHealth() == 0.0f) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write some death info - pBitStream->WriteCompressed(animGroup); - pBitStream->WriteCompressed(animID); - - pBitStream->Write(damagerID); - - SWeaponTypeSync weapon; - weapon.data.ucWeaponType = ucWeapon; - pBitStream->Write(&weapon); - - SBodypartSync bodyPart; - bodyPart.data.uiBodypart = ucBodyPiece; - pBitStream->Write(&bodyPart); - - // Write the position we died in - SPositionSync pos(false); - Ped->GetPosition(pos.data.vecPosition); - pBitStream->Write(&pos); - - pBitStream->Write(Ped->GetID()); - - // The ammo in our weapon and write the ammo total - CWeapon* pPlayerWeapon = Ped->GetWeapon(); - SWeaponAmmoSync ammo(ucWeapon, true, false); - ammo.data.usTotalAmmo = 0; - if (pPlayerWeapon) - ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); - pBitStream->Write(&ammo); - - // Send the packet - g_pNet->SendPacket(PACKET_ID_PED_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, AnimationId animID) -{ - // Are we not already marked as dead? and have we run out of health? - if (!m_pLocalPlayer->IsDeadOnNetwork() && m_pLocalPlayer->GetHealth() == 0.0f) - { - // Send the "i am dead" packet - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - m_pLocalPlayer->SetDeadOnNetwork(true); - - // Call the onClientPlayerWasted event - CClientEntity* pKiller = (damagerID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(damagerID) : NULL; - CLuaArguments Arguments; - if (pKiller) - Arguments.PushElement(pKiller); - else - Arguments.PushBoolean(false); - if (ucWeapon != 0xFF) - Arguments.PushNumber(ucWeapon); - else - Arguments.PushBoolean(false); - if (ucBodyPiece != 0xFF) - Arguments.PushNumber(ucBodyPiece); - else - Arguments.PushBoolean(false); - Arguments.PushBoolean(false); - m_pLocalPlayer->CallEvent("onClientPlayerWasted", Arguments, true); - - // Write some death info - pBitStream->WriteCompressed(animGroup); - pBitStream->WriteCompressed(animID); - - pBitStream->Write(damagerID); - - SWeaponTypeSync weapon; - weapon.data.ucWeaponType = ucWeapon; - pBitStream->Write(&weapon); - - SBodypartSync bodyPart; - bodyPart.data.uiBodypart = ucBodyPiece; - pBitStream->Write(&bodyPart); - - // Write the position we died in - SPositionSync pos(false); - m_pLocalPlayer->GetPosition(pos.data.vecPosition); - pBitStream->Write(&pos); - - // The ammo in our weapon and write the ammo total - CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(); - SWeaponAmmoSync ammo(ucWeapon, true, false); - ammo.data.usTotalAmmo = 0; - if (pPlayerWeapon) - ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); - pBitStream->Write(&ammo); - - // Send the packet - g_pNet->SendPacket(PACKET_ID_PLAYER_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -bool CClientGame::OnKeyDown(CGUIKeyEventArgs Args) -{ - return true; -} - -bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - const char* szState = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIClick", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseDoubleClick(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - const char* szState = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIDoubleClick", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIMouseDown", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseButtonUp(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIMouseUp", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseMove(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseMove", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseEnter(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - if (Args.pSwitchedWindow) - { - CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); - if (GetGUIManager()->Exists(pGUISwitchedElement)) - Arguments.PushElement(pGUISwitchedElement); - } - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseEnter", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseLeave(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - if (Args.pSwitchedWindow) - { - CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); - if (GetGUIManager()->Exists(pGUISwitchedElement)) - Arguments.PushElement(pGUISwitchedElement); - } - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseLeave", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseWheel(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.wheelChange); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseWheel", Arguments, true); - - return true; -} - -bool CClientGame::OnMove(CGUIElement* pElement) -{ - if (!pElement) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); - if (pGUIElement && GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientGUIMove", Arguments, true); - - return true; -} - -bool CClientGame::OnSize(CGUIElement* pElement) -{ - if (!pElement) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientGUISize", Arguments, true); - - return true; -} - -bool CClientGame::OnFocusGain(CGUIFocusEventArgs Args) -{ - if (!Args.pActivatedWindow) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pActivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pActivatedWindow); - - if (Args.pDeactivatedWindow) - { - CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); - if (GetGUIManager()->Exists(pDeactivatedGUIElement)) - pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); - } - - if (GetGUIManager()->Exists(pActivatedGUIElement)) - pActivatedGUIElement->CallEvent("onClientGUIFocus", Arguments, true); - - return true; -} - -bool CClientGame::OnFocusLoss(CGUIFocusEventArgs Args) -{ - if (!Args.pDeactivatedWindow) - return false; - - CLuaArguments Arguments; - - if (Args.pActivatedWindow) - { - // pDeactivatedWindow looses focus but an other window is now gaining it so we let CClientGame::OnFocusGain trigger both events in the right order - return true; - } - - CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); - if (GetGUIManager()->Exists(pDeactivatedGUIElement)) - pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); - - return true; -} - -// -// Display a progress dialog if a big packet is coming in -// -void CClientGame::NotifyBigPacketProgress(unsigned long ulBytesReceived, unsigned long ulTotalSize) -{ - // Should display progress box? - if (ulBytesReceived >= ulTotalSize || ulTotalSize < 50000) - { - if (m_bReceivingBigPacket) - { - // Switch off progress box - m_bReceivingBigPacket = false; - m_pBigPacketTransferBox->Hide(); - } - return; - } - - // Update progress box - if (!m_bReceivingBigPacket || m_ulBigPacketSize != ulTotalSize) - { - m_bReceivingBigPacket = true; - m_ulBigPacketSize = ulTotalSize; - m_pBigPacketTransferBox->Hide(); - m_pBigPacketTransferBox->AddToTotalSize(ulTotalSize); - m_pBigPacketTransferBox->Show(); - } - - m_pBigPacketTransferBox->DoPulse(); - m_pBigPacketTransferBox->SetInfo(std::min(ulTotalSize, ulBytesReceived), CTransferBox::PACKET); -} - -bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled) -{ - if (ucGlitch < NUM_GLITCHES && bEnabled != m_Glitches[ucGlitch]) - { - m_Glitches[ucGlitch] = bEnabled; - if (ucGlitch == GLITCH_QUICKRELOAD) - g_pMultiplayer->DisableQuickReload(!bEnabled); - if (ucGlitch == GLITCH_CLOSEDAMAGE) - g_pMultiplayer->DisableCloseRangeDamage(!bEnabled); - return true; - } - return false; -} - -bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) -{ - return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; -} - -bool CClientGame::SetCloudsEnabled(bool bEnabled) -{ - m_bCloudsEnabled = bEnabled; - return true; -} -bool CClientGame::GetCloudsEnabled(void) -{ - return m_bCloudsEnabled; -} - -bool CClientGame::SetBirdsEnabled(bool bEnabled) -{ - m_bBirdsEnabled = bEnabled; - return true; -} -bool CClientGame::GetBirdsEnabled(void) -{ - return m_bBirdsEnabled; -} - -#pragma code_seg(".text") -bool CClientGame::VerifySADataFiles(int iEnableClientChecks) -{ - int& iCheckStatus = g_pGame->GetCheckStatus(); - - if (!g_pGame->VerifySADataFileNames()) - iCheckStatus |= (1 << 11); - - __declspec(allocate(".text")) static char szVerifyData[][32] = {"data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", - "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", - "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", - "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", - "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", - "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", - "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", - "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", - "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", - "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", - "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", - "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74"}; - - CMD5Hasher hasher; - for (int i = 0; i < NUMELMS(szVerifyData); i += 2) - { - MD5 md5; - if (!hasher.Calculate(szVerifyData[i], md5) || memcmp(md5.data, szVerifyData[i + 1], 0x10)) - { - iCheckStatus |= (1 << i); - } - } - - if (iCheckStatus & iEnableClientChecks) - { - g_pCore->InitiateDataFilesFix(); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - return true; -} - -void CClientGame::InitVoice(bool bEnabled, unsigned int uiServerSampleRate, unsigned char ucQuality, unsigned int uiBitrate) -{ - if (m_pVoiceRecorder) - { - m_pVoiceRecorder->Init(bEnabled, uiServerSampleRate, ucQuality, uiBitrate); - } -} - -// -// If debug render mode is on, allow each element in range to draw some stuff -// -void CClientGame::DebugElementRender(void) -{ - if (!GetDevelopmentMode() || !GetShowCollision()) - return; - - CVector vecCameraPos; - m_pCamera->GetPosition(vecCameraPos); - float fDrawRadius = 200.f; - - // Get all entities within range - CClientEntityResult result; - GetClientSpatialDatabase()->SphereQuery(result, CSphere(vecCameraPos, fDrawRadius)); - - // For each entity found - for (CClientEntityResult::const_iterator it = result.begin(); it != result.end(); ++it) - { - CClientEntity* pEntity = *it; - if (pEntity->GetParent()) - pEntity->DebugRender(vecCameraPos, fDrawRadius); - } -} - -////////////////////////////////////////////////////////////////// -// Click -// -void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString& strTag, uint uiQuality, uint uiMaxBandwidth, uint uiMaxPacketSize, - CResource* pResource, uint uiServerSentTime) -{ - if (!pResource) - return; - - bool bAllowScreenUploadEnabled = 1; - g_pCore->GetCVars()->Get("allow_screen_upload", bAllowScreenUploadEnabled); - bool bWindowMinimized = g_pCore->IsWindowMinimized(); - - if (bWindowMinimized || !bAllowScreenUploadEnabled) - { - // If alt-tabbed or opt-out - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!bAllowScreenUploadEnabled) - pBitStream->Write((uchar)EPlayerScreenShotResult::DISABLED); - else - pBitStream->Write((uchar)EPlayerScreenShotResult::MINIMIZED); - pBitStream->Write(uiServerSentTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); - g_pNet->DeallocateNetBitStream(pBitStream); - } - else - { - // Do grab and send - SScreenShotArgs screenShotArgs; - screenShotArgs.uiMaxBandwidth = uiMaxBandwidth; - screenShotArgs.uiMaxPacketSize = uiMaxPacketSize; - screenShotArgs.usResourceNetId = pResource->GetNetID(); - screenShotArgs.strTag = strTag; - screenShotArgs.uiServerSentTime = uiServerSentTime; - m_ScreenShotArgList.push_back(screenShotArgs); - g_pCore->GetGraphics()->GetScreenGrabber()->QueueScreenShot(uiSizeX, uiSizeY, uiQuality, &CClientGame::StaticGottenPlayerScreenShot); - } -} - -////////////////////////////////////////////////////////////////// -// Callback from TakePlayerScreendsShot -// -void CClientGame::StaticGottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strError) -{ - if (g_pClientGame) - g_pClientGame->GottenPlayerScreenShot(pBuffer, uiTimeSpentInQueue, strError); -} - -////////////////////////////////////////////////////////////////// -// Break data into packets and put into delayed send list -// -void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strInError) -{ - SString strError = strInError; - - // Pop saved args - if (m_ScreenShotArgList.empty()) - return; - - SScreenShotArgs screenShotArgs = m_ScreenShotArgList.front(); - m_ScreenShotArgList.pop_front(); - const uint uiMaxBandwidth = Clamp(100, screenShotArgs.uiMaxBandwidth, 1000000); - const uint uiMaxPacketSize = Clamp(100, screenShotArgs.uiMaxPacketSize, 100000); - const ushort usResourceNetId = screenShotArgs.usResourceNetId; - const SString strTag = screenShotArgs.strTag; - const uint uiServerGrabTime = screenShotArgs.uiServerSentTime + uiTimeSpentInQueue; - - // Silently ignore if resource has been stopped - CResource* pResource = GetResourceManager()->GetResourceFromNetID(usResourceNetId); - if (!pResource) - return; - - // Validate buffer - if (strError.empty()) - { - if (!pBuffer || pBuffer->GetSize() == 0) - strError = "Buffer empty"; - } - - // Handle error - if (!strError.empty()) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write((uchar)EPlayerScreenShotResult::ERROR_); - pBitStream->Write(uiServerGrabTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - if (pBitStream->Version() >= 0x053) - pBitStream->WriteString(strError); - g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); - g_pNet->DeallocateNetBitStream(pBitStream); - return; - } - - // Calc constants stuff - const uint uiSendRate = Clamp(5, uiMaxBandwidth / uiMaxPacketSize, 20); - const long long llPacketInterval = 1000 / uiSendRate; - const uint uiTotalByteSize = pBuffer->GetSize(); - const char* pData = pBuffer->GetData(); - const uint uiBytesPerPart = std::min(std::min(std::max(100U, uiMaxBandwidth / uiSendRate), uiTotalByteSize), 30000U); - const uint uiNumParts = std::max(1U, (uiTotalByteSize + uiBytesPerPart - 1) / uiBytesPerPart); - - // Calc variables stuff - CTickCount tickCount = CTickCount::Now() + CTickCount(llPacketInterval); - uint uiBytesRemaining = uiTotalByteSize; - m_usNextScreenShotId++; - - // Make each packet - for (uint i = 0; i < uiNumParts; i++) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - - ushort usPartNumber = i; - ushort usBytesThisPart = std::min(uiBytesRemaining, uiBytesPerPart); - assert(usBytesThisPart != 0); - - pBitStream->Write((uchar)EPlayerScreenShotResult::SUCCESS); - pBitStream->Write(m_usNextScreenShotId); - pBitStream->Write(usPartNumber); - pBitStream->Write(usBytesThisPart); - pBitStream->Write(pData, usBytesThisPart); - - // Write more info if first part - if (usPartNumber == 0) - { - pBitStream->Write(uiServerGrabTime); - pBitStream->Write(uiTotalByteSize); - pBitStream->Write((ushort)uiNumParts); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - } - - // Add to delay send list - SDelayedPacketInfo delayedPacketInfo; - delayedPacketInfo.useTickCount = tickCount; - delayedPacketInfo.ucPacketID = PACKET_ID_PLAYER_SCREENSHOT; - delayedPacketInfo.pBitStream = pBitStream; - delayedPacketInfo.packetPriority = PACKET_PRIORITY_LOW; - delayedPacketInfo.packetReliability = PACKET_RELIABILITY_RELIABLE_ORDERED; - delayedPacketInfo.packetOrdering = PACKET_ORDERING_DATA_TRANSFER; - m_DelayedSendList.push_back(delayedPacketInfo); - - // Increment stuff - pData += usBytesThisPart; - uiBytesRemaining -= usBytesThisPart; - tickCount += CTickCount(llPacketInterval); - } - - assert(uiBytesRemaining == 0); -} - -////////////////////////////////////////////////////////////////// -// Process delay send list -// -void CClientGame::ProcessDelayedSendList(void) -{ - CTickCount tickCount = CTickCount::Now(); - - while (!m_DelayedSendList.empty()) - { - SDelayedPacketInfo& info = m_DelayedSendList.front(); - if (info.useTickCount > tickCount) - break; - - g_pNet->SendPacket(info.ucPacketID, info.pBitStream, info.packetPriority, info.packetReliability, info.packetOrdering); - g_pNet->DeallocateNetBitStream(info.pBitStream); - m_DelayedSendList.pop_front(); - } -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetWeaponTypesUsingBulletSync -// -// Set whether the local player will send bulletsync messages for the supplied weapon type -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetWeaponTypesUsingBulletSync(const std::set& weaponTypesUsingBulletSync) -{ - m_weaponTypesUsingBulletSync = weaponTypesUsingBulletSync; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::GetWeaponTypeUsesBulletSync -// -// Get whether the local player should send bulletsync messages for the supplied weapon type -// -////////////////////////////////////////////////////////////////// -bool CClientGame::GetWeaponTypeUsesBulletSync(eWeaponType weaponType) -{ - return MapContains(m_weaponTypesUsingBulletSync, weaponType); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetDevelopmentMode -// -// Special mode which enables commands such as showcol and showsound -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetDevelopmentMode(bool bEnable, bool bEnableWeb) -{ - m_bDevelopmentMode = bEnable; - - if (m_bDevelopmentMode) - g_pGame->GetAudio()->SetWorldSoundHandler(CClientGame::StaticWorldSoundHandler); - else - g_pGame->GetAudio()->SetWorldSoundHandler(NULL); - - if (g_pCore->IsWebCoreLoaded()) - g_pCore->GetWebCore()->SetTestModeEnabled(bEnableWeb); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::StaticWorldSoundHandler -// -// Handle callback from CAudioSA when a world sound is played -// -////////////////////////////////////////////////////////////////// -void CClientGame::StaticWorldSoundHandler(uint uiGroup, uint uiIndex) -{ - g_pClientGame->WorldSoundHandler(uiGroup, uiIndex); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::WorldSoundHandler -// -// Handle callback from CAudioSA when a world sound is played -// -////////////////////////////////////////////////////////////////// -void CClientGame::WorldSoundHandler(uint uiGroup, uint uiIndex) -{ - if (m_bShowSound) - m_pScriptDebugging->LogInformation(NULL, "%s - World sound group:%d index:%d", *GetLocalTimeString(false, true), uiGroup, uiIndex); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::IsUsingAlternatePulseOrder -// -// Returns true if should be using alternate pulse order -// -////////////////////////////////////////////////////////////////// -bool CClientGame::IsUsingAlternatePulseOrder(bool bAdvanceDelayCounter) -{ - if (m_MiscGameSettings.bUseAltPulseOrder) - { - // Only actually start using alternate pulse order after 100 frames - if (m_uiAltPulseOrderCounter >= 100) - return true; - else if (bAdvanceDelayCounter) - m_uiAltPulseOrderCounter++; - } - - return false; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::OutputServerInfo -// -// Output info about the connected server for player -// -////////////////////////////////////////////////////////////////// -void CClientGame::OutputServerInfo(void) -{ - SString strTotalOutput; - strTotalOutput += SString("Server info for %s", g_pNet->GetConnectedServer(true)); - strTotalOutput += "\n"; - strTotalOutput += SString("Ver: %s\n", *GetServerVersionSortable()); - strTotalOutput += SString("AC: %s\n", *m_strACInfo); - - { - SString strVoice; - if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) - strVoice += SString("Enabled - Sample rate:%d Quality:%d", m_pVoiceRecorder->GetSampleRate(), m_pVoiceRecorder->GetSampleQuality()); - else - strVoice += "Disabled"; - - strTotalOutput += SString("Voice: %s\n", *strVoice); - } - - { - SString strEnabledGlitches; - const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", - "Bad driveby hitboxes", "Quick stand"}; - for (uint i = 0; i < NUM_GLITCHES; i++) - { - if (IsGlitchEnabled(i)) - { - if (!strEnabledGlitches.empty()) - strEnabledGlitches += ", "; - if (i < NUMELMS(szGlitchNames)) - strEnabledGlitches += szGlitchNames[i]; - else - strEnabledGlitches += SString("Unknown(#%d)", i + 1); - } - } - if (strEnabledGlitches.empty()) - strEnabledGlitches = "None"; - strTotalOutput += SString("Glitches: %s\n", *strEnabledGlitches); - } - - { - SString strEnabledBulletSync; - for (std::set::iterator iter = m_weaponTypesUsingBulletSync.begin(); iter != m_weaponTypesUsingBulletSync.end(); ++iter) - { - eWeaponType weaponType = *iter; - if (!strEnabledBulletSync.empty()) - strEnabledBulletSync += ","; - strEnabledBulletSync += SString("%d", weaponType); - } - if (strEnabledBulletSync.empty()) - strEnabledBulletSync = "None"; - strTotalOutput += SString("Bullet sync weapons: %s\n", *strEnabledBulletSync); - } - - { - SString strVehExtrapolate; - if (m_VehExtrapolateSettings.bEnabled) - strVehExtrapolate += SString("Amount:%d%% (LimitMs:%d)", m_VehExtrapolateSettings.iScalePercent, m_VehExtrapolateSettings.iMaxMs); - else - strVehExtrapolate += "Disabled"; - - strTotalOutput += SString("Vehicle extrapolation: %s\n", *strVehExtrapolate); - } - - { - SString strTickRates; - strTickRates += SString("Plr:%d Cam:%d Ped:%d UnocVeh:%d KeyRot:%d KeyJoy:%d", g_TickRateSettings.iPureSync, g_TickRateSettings.iCamSync, - g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, - g_TickRateSettings.iKeySyncAnalogMove); - - strTotalOutput += SString("Tick rates: %s\n", *strTickRates); - } - - { - SString strSyncerDists; - strSyncerDists += SString("Ped:%d UnoccupiedVehicle:%d ", g_TickRateSettings.iPedSyncerDistance, g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); - - strTotalOutput += SString("Syncer distances: %s\n", *strSyncerDists); - } - - g_pCore->GetConsole()->Print(strTotalOutput); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::TellServerSomethingImportant -// -// Report misc important warnings/errors to the current server -// -////////////////////////////////////////////////////////////////// -void CClientGame::TellServerSomethingImportant(uint uiId, const SString& strMessage, uint uiSendLimitForThisId) -{ - g_pCore->GetConsole()->Print(strMessage); - AddReportLog(3400 + uiId, strMessage + g_pNet->GetConnectedServer(true), 10); - - if (uiSendLimitForThisId) - { - uint& uiCount = MapGet(m_SentMessageIds, uiId); - if (uiCount++ >= uiSendLimitForThisId) - return; - } - - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->WriteString(SString("%d,%s", uiId, *strMessage)); - g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE); - g_pNet->DeallocateNetBitStream(pBitStream); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::ChangeFloatPrecision -// -// Manage the change to high floating point precision -// -////////////////////////////////////////////////////////////////// -void CClientGame::ChangeFloatPrecision(bool bHigh) -{ - if (bHigh) - { - // Switch to 53 bit floating point precision on the first call - if (m_uiPrecisionCallDepth++ == 0) - _controlfp(_PC_53, MCW_PC); - } - else - { - // Even though is should never happen, m_uiPrecisionCallDepth is sometimes zero here - dassert(m_uiPrecisionCallDepth != 0); - if (m_uiPrecisionCallDepth != 0) - m_uiPrecisionCallDepth--; - // Switch back to 24 bit floating point precision on the last call - if (m_uiPrecisionCallDepth == 0) - _controlfp(_PC_24, MCW_PC); - } -} - -bool CClientGame::IsHighFloatPrecision(void) const -{ - return m_uiPrecisionCallDepth != 0; -} - -AnimationId CClientGame::DrivebyAnimationHandler(AnimationId animId, AssocGroupId animGroupId) -{ - // Only apply if all clients support the fix - if (!GetMiscGameSettings().bAllowBadDrivebyHitboxFix) - return animId; - - // If the glitch is enabled, don't apply the fix - if (IsGlitchEnabled(GLITCH_BADDRIVEBYHITBOX)) - return animId; - - // Bad animations are 232 and 236 of assoc group 72 - if (animGroupId != 72) - return animId; - - if (animId == 232) - return 235; - else if (animId == 236) - return 231; - - return animId; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetFileCacheRoot -// -// Figure out which directory to use for the client resource file cache -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetFileCacheRoot(void) -{ - if (g_pCore->GetCVars()->GetValue("share_file_cache") == false) - { - // Not sharing, so use current mod directory - m_strFileCacheRoot = GetModRoot(); - AddReportLog(7410, SString("CClientGame::SetFileCacheRoot - Not shared '%s'", *m_strFileCacheRoot)); - } - else - { - // Get shared directory - SString strFileCachePath = GetCommonRegistryValue("", "File Cache Path"); - // Check exists - if (!strFileCachePath.empty() && DirectoryExists(strFileCachePath)) - { - // Check writable - SString strTestFileName = PathJoin(strFileCachePath, "resources", "_test.tmp"); - if (FileSave(strTestFileName, "x")) - { - FileDelete(strTestFileName); - strTestFileName = PathJoin(strFileCachePath, "priv", "_test.tmp"); - if (FileSave(strTestFileName, "x")) - { - FileDelete(strTestFileName); - // Use shared directory - m_strFileCacheRoot = strFileCachePath; - AddReportLog(7411, SString("CClientGame::SetFileCacheRoot - Is shared '%s'", *m_strFileCacheRoot)); - return; - } - } - } - - // Otherwise set this install mod directory as shared - m_strFileCacheRoot = GetModRoot(); - SetCommonRegistryValue("", "File Cache Path", m_strFileCacheRoot); - - if (strFileCachePath.empty()) - AddReportLog(7412, SString("CClientGame::SetFileCacheRoot - Initial setting '%s'", *m_strFileCacheRoot)); - else - AddReportLog(7413, SString("CClientGame::SetFileCacheRoot - Change shared from '%s' to '%s'", *strFileCachePath, *m_strFileCacheRoot)); - } -} - -bool CClientGame::TriggerBrowserRequestResultEvent(const std::unordered_set& newPages) -{ - CLuaArguments Arguments; - CLuaArguments LuaTable; - int i = 0; - - for (auto& domain : newPages) - { - LuaTable.PushNumber(++i); - LuaTable.PushString(domain); - } - Arguments.PushTable(&LuaTable); - - return GetRootEntity()->CallEvent("onClientBrowserWhitelistChange", Arguments, false); -} - -void CClientGame::RestreamModel(unsigned short usModel) -{ - // Is this a vehicle ID? - if (CClientVehicleManager::IsValidModel(usModel)) - { - // Stream the vehicles of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetVehicleManager()->RestreamVehicles(usModel); - } - - // Is this an object ID? - else if (CClientObjectManager::IsValidModel(usModel)) - { - if (CClientPedManager::IsValidWeaponModel(usModel)) - { - // Stream the weapon of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamWeapon(usModel); - m_pManager->GetPickupManager()->RestreamPickups(usModel); - } - // Stream the objects of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetObjectManager()->RestreamObjects(usModel); - g_pGame->GetModelInfo(usModel)->RestreamIPL(); - } - // Is this an ped ID? - else if (CClientPlayerManager::IsValidModel(usModel)) - { - // Stream the ped of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamPeds(usModel); - } - else - - // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect - if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) - m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); -} - -void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) -{ - m_mapOfIfpPointers[u32BlockNameHash] = pIFP; -} - -std::shared_ptr CClientGame::GetIFPPointerFromMap(const unsigned int u32BlockNameHash) -{ - auto it = m_mapOfIfpPointers.find(u32BlockNameHash); - if (it != m_mapOfIfpPointers.end()) - { - return it->second; - } - return nullptr; -} - -void CClientGame::RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash) -{ - m_mapOfIfpPointers.erase(u32BlockNameHash); -} - -void CClientGame::InsertPedPointerToSet(CClientPed* pPed) -{ - m_setOfPedPointers.insert(pPed); -} - -void CClientGame::RemovePedPointerFromSet(CClientPed* pPed) -{ - m_setOfPedPointers.erase(pPed); -} - -CClientPed* CClientGame::GetClientPedByClump(const RpClump& Clump) -{ - for (auto& pPed : m_setOfPedPointers) - { - CEntity* pEntity = pPed->GetGameEntity(); - if (pEntity != nullptr) - { - if (pEntity->GetRpClump() != nullptr) - { - const RpClump& entityClump = *pEntity->GetRpClump(); - if (std::addressof(entityClump) == std::addressof(Clump)) - { - return pPed; - } - } - } - } - return nullptr; -} - -void CClientGame::OnClientIFPUnload(const std::shared_ptr& IFP) -{ - IFP->MarkAsUnloading(); - for (auto& pPed : m_setOfPedPointers) - { - // Remove IFP animations from replaced animations of peds/players - pPed->RestoreAnimations(IFP); - - // Make sure that streamed in pulses or changing model does not accidently - // play our custom animation. We can do that by making the custom animation - // untriggerable - if (pPed->GetCustomAnimationBlockNameHash() == IFP->GetBlockNameHash()) - { - if (pPed->IsCustomAnimationPlaying()) - { - pPed->SetCustomAnimationUntriggerable(); - } - - // Important! As we are using a shared_ptr, we need to decrement the reference counter - // by setting the shared_ptr to nullptr, this will avoid memory leak - if (!pPed->IsNextAnimationCustom() && pPed->IsCurrentAnimationCustom()) - { - pPed->DereferenceCustomAnimationBlock(); - } - } - } -} - -void CClientGame::InsertAnimationAssociationToMap(CAnimBlendAssociationSAInterface* pAnimAssociation, const std::shared_ptr& pIFPAnimations) -{ - m_mapOfCustomAnimationAssociations[pAnimAssociation] = pIFPAnimations; -} - -void CClientGame::RemoveAnimationAssociationFromMap(CAnimBlendAssociationSAInterface* pAnimAssociation) -{ - m_mapOfCustomAnimationAssociations.erase(pAnimAssociation); -} +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CClientGame.cpp + * PURPOSE: Client game manager + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include +#include "game/CAnimBlendAssocGroup.h" +#include "game/CAnimBlendAssociation.h" +#include "game/CAnimBlendHierarchy.h" + +SString StringZeroPadout(const SString& strInput, uint uiPadoutSize) +{ + SString strResult = strInput; + while (strResult.length() < uiPadoutSize) + strResult += '\0'; + return strResult; +} + +using SharedUtil::CalcMTASAPath; +using std::list; +using std::vector; + +// Hide the "conversion from 'unsigned long' to 'DWORD*' of greater size" warning +#pragma warning(disable:4312) + +// Used within this file by the packet handler to grab the this pointer of CClientGame +extern CClientGame* g_pClientGame; +extern int g_iDamageEventLimit; +float g_fApplyDamageLastAmount; +uchar g_ucApplyDamageLastHitZone; +CClientPed* g_pApplyDamageLastDamagedPed; +bool g_bBulletFireVectorsValid; +CVector g_vecBulletFireStartPosition; +CVector g_vecBulletFireEndPosition; + +#define DEFAULT_GRAVITY 0.008f +#define DEFAULT_GAME_SPEED 1.0f +#define DEFAULT_BLUR_LEVEL 36 +#define DEFAULT_JETPACK_MAXHEIGHT 100 +#define DEFAULT_AIRCRAFT_MAXHEIGHT 800 +#define DEFAULT_AIRCRAFT_MAXVELOCITY 1.5f +#define DEFAULT_MINUTE_DURATION 1000 +#define DOUBLECLICK_TIMEOUT 330 +#define DOUBLECLICK_MOVE_THRESHOLD 10.0f + +CClientGame::CClientGame(bool bLocalPlay) +{ + // Init the global var with ourself + g_pClientGame = this; + + // Packet handler + m_pPacketHandler = new CPacketHandler(); + + // Init + m_bLocalPlay = bLocalPlay; + m_bErrorStartingLocal = false; + m_iLocalConnectAttempts = 0; + m_Status = CClientGame::STATUS_CONNECTING; + m_ulVerifyTimeStart = 0; + m_ulLastClickTick = 0; + m_pLocalPlayer = NULL; + m_LocalID = INVALID_ELEMENT_ID; + m_bShowNametags = true; + m_bWaitingForLocalConnect = false; + m_bShowRadar = false; + m_bGameLoaded = false; + m_bTriggeredIngameAndConnected = false; + m_bGracefulDisconnect = false; + m_ulLastVehicleInOutTime = 0; + m_bIsGettingOutOfVehicle = false; + m_bIsGettingIntoVehicle = false; + m_bIsGettingJacked = false; + m_bIsJackingVehicle = false; + m_VehicleInOutID = INVALID_ELEMENT_ID; + m_pGettingJackedBy = NULL; + m_ucVehicleInOutSeat = 0xFF; + m_pTargetedEntity = NULL; + m_TargetedPlayerID = INVALID_ELEMENT_ID; + m_pDamageEntity = NULL; + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageBodyPiece = 0xFF; + m_ucDamageWeapon = 0xFF; + m_ulDamageTime = 0; + m_bDamageSent = true; + m_bShowNetstat = false; + m_bShowFPS = false; + m_bHudAreaNameDisabled = false; + m_fGameSpeed = 1.0f; + m_lMoney = 0; + m_dwWanted = 0; + m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) + ResetAmmoInClip(); + + m_bNoNewVehicleTask = false; + m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; + + m_bCursorEventsEnabled = false; + m_bInitiallyFadedOut = true; + + m_bIsPlayingBack = false; + m_bFirstPlaybackFrame = false; + + // Setup game glitch defaults ( false = disabled ). Remember to update these serverside if you alter them! + m_Glitches[GLITCH_QUICKRELOAD] = false; + g_pMultiplayer->DisableQuickReload(true); + m_Glitches[GLITCH_FASTFIRE] = false; + m_Glitches[GLITCH_FASTMOVE] = false; + m_Glitches[GLITCH_CROUCHBUG] = false; + m_Glitches[GLITCH_CLOSEDAMAGE] = false; + g_pMultiplayer->DisableCloseRangeDamage(true); + m_Glitches[GLITCH_HITANIM] = false; + m_Glitches[GLITCH_FASTSPRINT] = false; + m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; + m_Glitches[GLITCH_QUICKSTAND] = false; + g_pMultiplayer->DisableBadDrivebyHitboxes(true); + + // Remove Night & Thermal vision view (if enabled). + g_pMultiplayer->SetNightVisionEnabled(false); + g_pMultiplayer->SetThermalVisionEnabled(false); + + m_bCloudsEnabled = true; + + m_bBirdsEnabled = true; + + m_bWasMinimized = false; + + // Grab the mod path + m_strModRoot = g_pCore->GetModInstallRoot("deathmatch"); + + // Figure out which directory to use for the client resource file cache + SetFileCacheRoot(); + + // Override CGUI's global events + g_pCore->GetGUI()->SetKeyDownHandler(INPUT_MOD, GUI_CALLBACK_KEY(&CClientGame::OnKeyDown, this)); + g_pCore->GetGUI()->SetMouseClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseClick, this)); + g_pCore->GetGUI()->SetMouseDoubleClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseDoubleClick, this)); + g_pCore->GetGUI()->SetMouseButtonDownHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonDown, this)); + g_pCore->GetGUI()->SetMouseButtonUpHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonUp, this)); + g_pCore->GetGUI()->SetMouseMoveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseMove, this)); + g_pCore->GetGUI()->SetMouseEnterHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseEnter, this)); + g_pCore->GetGUI()->SetMouseLeaveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseLeave, this)); + g_pCore->GetGUI()->SetMouseWheelHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseWheel, this)); + g_pCore->GetGUI()->SetMovedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnMove, this)); + g_pCore->GetGUI()->SetSizedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnSize, this)); + g_pCore->GetGUI()->SetFocusGainedHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusGain, this)); + g_pCore->GetGUI()->SetFocusLostHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusLoss, this)); + g_pCore->GetGUI()->SelectInputHandlers(INPUT_MOD); + + // Startup "entities from root" optimization for getElementsByType + CClientEntity::StartupEntitiesFromRoot(); + + // Startup game entity tracking manager + m_pGameEntityXRefManager = NewGameEntityXRefManager(); + m_pModelCacheManager = NewClientModelCacheManager(); + + // Initialize our root entity with an invalid id, we dont know the true id until map-start + m_pRootEntity = new CClientDummy(NULL, INVALID_ELEMENT_ID, "root"); + m_pRootEntity->MakeSystemEntity(); + + m_pDebugHookManager = new CDebugHookManager(); + + // Movings objects manager + m_pMovingObjectsManager = new CMovingObjectsManager(); + + // Create the manager and grab the most important pointers + m_pManager = new CClientManager; + m_pCamera = m_pManager->GetCamera(); + m_pMarkerManager = m_pManager->GetMarkerManager(); + m_pObjectManager = m_pManager->GetObjectManager(); + m_pPickupManager = m_pManager->GetPickupManager(); + m_pPlayerManager = m_pManager->GetPlayerManager(); + m_pRadarAreaManager = m_pManager->GetRadarAreaManager(); + m_pDisplayManager = m_pManager->GetDisplayManager(); + m_pVehicleManager = m_pManager->GetVehicleManager(); + m_pRadarMarkerManager = m_pManager->GetRadarMarkerManager(); + m_pPathManager = m_pManager->GetPathManager(); + m_pTeamManager = m_pManager->GetTeamManager(); + m_pPedManager = m_pManager->GetPedManager(); + m_pGUIManager = m_pManager->GetGUIManager(); + m_pResourceManager = m_pManager->GetResourceManager(); + m_pProjectileManager = m_pManager->GetProjectileManager(); + m_pLocalServer = NULL; + + m_pLatentTransferManager = new CLatentTransferManager(); + m_pZoneNames = new CZoneNames; + m_pScriptKeyBinds = new CScriptKeyBinds; + m_pRemoteCalls = new CRemoteCalls(); + m_pResourceFileDownloadManager = new CResourceFileDownloadManager(); + + // Create our net API + m_pNetAPI = new CNetAPI(m_pManager); + m_pNetworkStats = new CNetworkStats(m_pDisplayManager); + m_pSyncDebug = new CSyncDebug(m_pManager); + + // Create our blended weather class + m_pBlendedWeather = new CBlendedWeather; + + // Create our RPC class + m_pRPCFunctions = new CRPCFunctions(this); + + // Our management classes + m_pUnoccupiedVehicleSync = new CUnoccupiedVehicleSync(m_pVehicleManager); + m_pPedSync = new CPedSync(m_pPedManager); +#ifdef WITH_OBJECT_SYNC + m_pObjectSync = new CObjectSync(m_pObjectManager); +#endif + m_pNametags = new CNametags(m_pManager); + m_pRadarMap = new CRadarMap(m_pManager); + + // Set the screenshot path + /* This is now done in CCore, to maintain a global screenshot path + SString strScreenShotPath = SString::Printf ( "%s\\screenshots", m_szModRoot ); + g_pCore->SetScreenShotPath ( strScreenShotPath ); + */ + + // Create the transfer boxes (GUI) + m_pTransferBox = new CTransferBox(); + m_pBigPacketTransferBox = new CTransferBox(); + + // Store the time we started on + if (bLocalPlay) + m_ulTimeStart = 0; + else + m_ulTimeStart = CClientTime::GetTime(); + + // MTA Voice + m_pVoiceRecorder = new CVoiceRecorder(); + + // Singular file download manager + m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); + + // Register the message and the net packet handler + g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); + g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); + g_pMultiplayer->SetBulletImpactHandler(CClientGame::BulletImpact); + g_pMultiplayer->SetBulletFireHandler(CClientGame::BulletFire); + g_pMultiplayer->SetExplosionHandler(CClientExplosionManager::Hook_StaticExplosionCreation); + g_pMultiplayer->SetBreakTowLinkHandler(CClientGame::StaticBreakTowLinkHandler); + g_pMultiplayer->SetDrawRadarAreasHandler(CClientGame::StaticDrawRadarAreasHandler); + g_pMultiplayer->SetDamageHandler(CClientGame::StaticDamageHandler); + g_pMultiplayer->SetDeathHandler(CClientGame::StaticDeathHandler); + g_pMultiplayer->SetFireHandler(CClientGame::StaticFireHandler); + g_pMultiplayer->SetProjectileStopHandler(CClientProjectileManager::Hook_StaticProjectileAllow); + g_pMultiplayer->SetProjectileHandler(CClientProjectileManager::Hook_StaticProjectileCreation); + g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); + g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); + g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); + g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); + g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); + g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); + g_pMultiplayer->SetPreFxRenderHandler(CClientGame::StaticPreFxRenderHandler); + g_pMultiplayer->SetPreHudRenderHandler(CClientGame::StaticPreHudRenderHandler); + g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(CClientGame::StaticCAnimBlendAssocDestructorHandler); + g_pMultiplayer->SetAddAnimationHandler(CClientGame::StaticAddAnimationHandler); + g_pMultiplayer->SetAddAnimationAndSyncHandler(CClientGame::StaticAddAnimationAndSyncHandler); + g_pMultiplayer->SetAssocGroupCopyAnimationHandler(CClientGame::StaticAssocGroupCopyAnimationHandler); + g_pMultiplayer->SetBlendAnimationHierarchyHandler(CClientGame::StaticBlendAnimationHierarchyHandler); + g_pMultiplayer->SetProcessCollisionHandler(CClientGame::StaticProcessCollisionHandler); + g_pMultiplayer->SetVehicleCollisionHandler(CClientGame::StaticVehicleCollisionHandler); + g_pMultiplayer->SetVehicleDamageHandler(CClientGame::StaticVehicleDamageHandler); + g_pMultiplayer->SetHeliKillHandler(CClientGame::StaticHeliKillHandler); + g_pMultiplayer->SetObjectDamageHandler(CClientGame::StaticObjectDamageHandler); + g_pMultiplayer->SetObjectBreakHandler(CClientGame::StaticObjectBreakHandler); + g_pMultiplayer->SetWaterCannonHitHandler(CClientGame::StaticWaterCannonHandler); + g_pMultiplayer->SetVehicleFellThroughMapHandler(CClientGame::StaticVehicleFellThroughMapHandler); + g_pMultiplayer->SetGameObjectDestructHandler(CClientGame::StaticGameObjectDestructHandler); + g_pMultiplayer->SetGameVehicleDestructHandler(CClientGame::StaticGameVehicleDestructHandler); + g_pMultiplayer->SetGamePlayerDestructHandler(CClientGame::StaticGamePlayerDestructHandler); + g_pMultiplayer->SetGameProjectileDestructHandler(CClientGame::StaticGameProjectileDestructHandler); + g_pMultiplayer->SetGameModelRemoveHandler(CClientGame::StaticGameModelRemoveHandler); + g_pMultiplayer->SetGameEntityRenderHandler(CClientGame::StaticGameEntityRenderHandler); + g_pMultiplayer->SetFxSystemDestructionHandler(CClientGame::StaticFxSystemDestructionHandler); + g_pMultiplayer->SetDrivebyAnimationHandler(CClientGame::StaticDrivebyAnimationHandler); + g_pGame->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); + g_pGame->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); + g_pGame->SetTaskSimpleBeHitHandler(CClientGame::StaticTaskSimpleBeHitHandler); + g_pCore->SetMessageProcessor(CClientGame::StaticProcessMessage); + g_pCore->GetKeyBinds()->SetKeyStrokeHandler(CClientGame::StaticKeyStrokeHandler); + g_pCore->GetKeyBinds()->SetCharacterKeyHandler(CClientGame::StaticCharacterKeyHandler); + g_pNet->RegisterPacketHandler(CClientGame::StaticProcessPacket); + + m_pLuaManager = new CLuaManager(this); + m_pScriptDebugging = new CScriptDebugging(m_pLuaManager); + m_pScriptDebugging->SetLogfile(CalcMTASAPath("mta\\logs\\clientscript.log"), 3); + + CStaticFunctionDefinitions(m_pLuaManager, &m_Events, g_pCore, g_pGame, this, m_pManager); + CLuaFunctionDefs::Initialize(m_pLuaManager, m_pScriptDebugging, this); + CLuaDefs::Initialize(this, m_pLuaManager, m_pScriptDebugging); + + // Start async task scheduler + m_pAsyncTaskScheduler = new SharedUtil::CAsyncTaskScheduler(2); + + // Disable the enter/exit vehicle key button (we want to handle this button ourselves) + g_pMultiplayer->DisableEnterExitVehicleKey(true); + + // Disable GTA's pickup processing as we want to confirm the hits with the server + m_pPickupManager->SetPickupProcessingDisabled(true); + + // Key-bind for fire-key (for handling satchels and stealth-kills) + g_pCore->GetKeyBinds()->AddControlFunction("fire", CClientGame::StaticUpdateFireKey, true); + + // Init big packet progress vars + m_bReceivingBigPacket = false; + m_ulBigPacketSize = 0; + m_ulBigPacketBytesReceivedBase = 0; + + m_bBeingDeleted = false; + + #if defined (MTA_DEBUG) || defined (MTA_BETA) + m_bShowSyncingInfo = false; + #endif + + #ifdef MTA_DEBUG + m_pShowPlayer = m_pShowPlayerTasks = NULL; + m_bMimicLag = false; + m_ulLastMimicLag = 0; + m_bDoPaintballs = false; + m_bShowInterpolation = false; + #endif + + // Add our lua events + AddBuiltInEvents(); + + // Init debugger class + m_Foo.Init(this); + + // Load some stuff from the core config + float fScale; + g_pCore->GetCVars()->Get("text_scale", fScale); + CClientTextDisplay::SetGlobalScale(fScale); + + // Reset async loading script settings to default + g_pGame->SetAsyncLoadingFromScript(true, false); + + // Reset test mode script settings to default + g_pCore->GetGraphics()->GetRenderItemManager()->SetTestMode(DX_TEST_MODE_NONE); +} + +CClientGame::~CClientGame(void) +{ + m_bBeingDeleted = true; + // Stop all explosions. Unfortunately this doesn't fix the crash + // if a vehicle is destroyed while it explodes. + g_pGame->GetExplosionManager()->RemoveAllExplosions(); + + // Reset camera shaking + g_pGame->GetCamera()->SetShakeForce(0.0f); + + // Stop playing the continious sounds + // if the game was loaded. This is done by + // playing these special IDS. + if (m_bGameLoaded) + { + g_pGame->GetAudio()->PlayFrontEndSound(35); + g_pGame->GetAudio()->PlayFrontEndSound(48); + } + + // Reset the GUI input mode + g_pCore->GetGUI()->SetGUIInputMode(INPUTMODE_NO_BINDS_ON_EDIT); + + // Reset CGUI's global events + g_pCore->GetGUI()->ClearInputHandlers(INPUT_MOD); + + // Destroy mimics + #ifdef MTA_DEBUG + list::const_iterator iterMimics = m_Mimics.begin(); + for (; iterMimics != m_Mimics.end(); iterMimics++) + { + CClientPlayer* pPlayer = *iterMimics; + CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); + if (pVehicle) + delete pVehicle; + + delete pPlayer; + } + #endif + + // Hide the transfer box incase it is showing + m_pTransferBox->Hide(); + m_pBigPacketTransferBox->Hide(); + + // Stop async task scheduler + SAFE_DELETE(m_pAsyncTaskScheduler); + + SAFE_DELETE(m_pVoiceRecorder); + + // Singular file download manager + SAFE_DELETE(m_pSingularFileDownloadManager); + + // NULL the message/net stuff + g_pMultiplayer->SetPreContextSwitchHandler(NULL); + g_pMultiplayer->SetPostContextSwitchHandler(NULL); + g_pMultiplayer->SetPreWeaponFireHandler(NULL); + g_pMultiplayer->SetPostWeaponFireHandler(NULL); + g_pMultiplayer->SetBulletImpactHandler(NULL); + g_pMultiplayer->SetBulletFireHandler(NULL); + g_pMultiplayer->SetExplosionHandler(NULL); + g_pMultiplayer->SetBreakTowLinkHandler(NULL); + g_pMultiplayer->SetDrawRadarAreasHandler(NULL); + g_pMultiplayer->SetDamageHandler(NULL); + g_pMultiplayer->SetFireHandler(NULL); + g_pMultiplayer->SetProjectileStopHandler(NULL); + g_pMultiplayer->SetProjectileHandler(NULL); + g_pMultiplayer->SetProcessCamHandler(nullptr); + g_pMultiplayer->SetRender3DStuffHandler(NULL); + g_pMultiplayer->SetPreRenderSkyHandler(NULL); + g_pMultiplayer->SetRenderHeliLightHandler(nullptr); + g_pMultiplayer->SetChokingHandler(NULL); + g_pMultiplayer->SetPreWorldProcessHandler(NULL); + g_pMultiplayer->SetPostWorldProcessHandler(NULL); + g_pMultiplayer->SetPreFxRenderHandler(NULL); + g_pMultiplayer->SetPreHudRenderHandler(NULL); + g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(NULL); + g_pMultiplayer->SetAddAnimationHandler(NULL); + g_pMultiplayer->SetAddAnimationAndSyncHandler(NULL); + g_pMultiplayer->SetAssocGroupCopyAnimationHandler(NULL); + g_pMultiplayer->SetBlendAnimationHierarchyHandler(NULL); + g_pMultiplayer->SetProcessCollisionHandler(NULL); + g_pMultiplayer->SetVehicleCollisionHandler(NULL); + g_pMultiplayer->SetVehicleDamageHandler(NULL); + g_pMultiplayer->SetHeliKillHandler(NULL); + g_pMultiplayer->SetObjectDamageHandler(NULL); + g_pMultiplayer->SetObjectBreakHandler(NULL); + g_pMultiplayer->SetWaterCannonHitHandler(NULL); + g_pMultiplayer->SetGameObjectDestructHandler(NULL); + g_pMultiplayer->SetGameVehicleDestructHandler(NULL); + g_pMultiplayer->SetGamePlayerDestructHandler(NULL); + g_pMultiplayer->SetGameProjectileDestructHandler(NULL); + g_pMultiplayer->SetGameModelRemoveHandler(NULL); + g_pMultiplayer->SetGameEntityRenderHandler(NULL); + g_pMultiplayer->SetDrivebyAnimationHandler(nullptr); + g_pGame->SetPreWeaponFireHandler(NULL); + g_pGame->SetPostWeaponFireHandler(NULL); + g_pGame->SetTaskSimpleBeHitHandler(NULL); + g_pGame->GetAudio()->SetWorldSoundHandler(NULL); + g_pCore->SetMessageProcessor(NULL); + g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); + g_pCore->GetKeyBinds()->SetCharacterKeyHandler(NULL); + g_pNet->StopNetwork(); + g_pNet->RegisterPacketHandler(NULL); + CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); + pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessClientKeyBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessClientControlBind); + pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessServerKeyBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessServerControlBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticUpdateFireKey); + pKeyBinds->SetAllControlsEnabled(true, true, true); + g_pCore->ForceCursorVisible(false); + SetCursorEventsEnabled(false); + + // Destroy our stuff + SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop + SAFE_DELETE(m_pNametags); + SAFE_DELETE(m_pSyncDebug); + SAFE_DELETE(m_pNetworkStats); + SAFE_DELETE(m_pNetAPI); + SAFE_DELETE(m_pRPCFunctions); + SAFE_DELETE(m_pUnoccupiedVehicleSync); + SAFE_DELETE(m_pPedSync); +#ifdef WITH_OBJECT_SYNC + SAFE_DELETE(m_pObjectSync); +#endif + SAFE_DELETE(m_pBlendedWeather); + SAFE_DELETE(m_pMovingObjectsManager); + SAFE_DELETE(m_pRadarMap); + SAFE_DELETE(m_pRemoteCalls); + SAFE_DELETE(m_pLuaManager); + SAFE_DELETE(m_pLatentTransferManager); + SAFE_DELETE(m_pResourceFileDownloadManager); + + SAFE_DELETE(m_pRootEntity); + + SAFE_DELETE(m_pModelCacheManager); + SAFE_DELETE(m_pGameEntityXRefManager); + SAFE_DELETE(m_pZoneNames); + SAFE_DELETE(m_pScriptKeyBinds); + + // Delete the scriptdebugger + SAFE_DELETE(m_pScriptDebugging); + + // Delete the transfer boxes + SAFE_DELETE(m_pTransferBox); + SAFE_DELETE(m_pBigPacketTransferBox); + + SAFE_DELETE(m_pLocalServer); + SAFE_DELETE(m_pDebugHookManager); + + // Packet handler + SAFE_DELETE(m_pPacketHandler); + + // Delete PerfStatManager + delete CClientPerfStatManager::GetSingleton(); + + // NULL the global CClientGame var + g_pClientGame = NULL; + m_bBeingDeleted = false; +} + +/* +bool CClientGame::StartGame ( void ) // for an offline game (e.g. editor) +{ + m_Status = STATUS_OFFLINE; + g_pCore->SetOfflineMod ( true ); // hide chatbox etc + g_pCore->SetConnected ( true ); // not sure, but its required :) + g_pCore->HideMainMenu (); // duh + + // If the game isn't started, start it + if ( g_pGame->GetSystemState () == 7 ) + { + g_pGame->StartGame (); + } + return true; +} +*/ + +#include +//#define _CRTDBG_CHECK_EVERY_16_DF 0x00100000 /* check heap every 16 heap ops */ +//#define _CRTDBG_CHECK_EVERY_128_DF 0x00800000 /* check heap every 128 heap ops */ +//#define _CRTDBG_CHECK_EVERY_1024_DF 0x04000000 /* check heap every 1024 heap ops */ + +void CClientGame::EnablePacketRecorder(const char* szFilename) +{ + m_pManager->GetPacketRecorder()->StartRecord(szFilename, true); +} + +void CClientGame::StartPlayback(void) +{ + // strcpy ( m_szNick, "Playback" ); + + m_bIsPlayingBack = true; + m_bFirstPlaybackFrame = true; + m_pManager->GetPacketRecorder()->SetPacketHandler(CClientGame::StaticProcessPacket); + + if (!m_pManager->IsGameLoaded()) + { + g_pGame->StartGame(); + } +} + +bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerType Type) +{ + m_ServerType = Type; + // int dbg = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ); + // dbg |= _CRTDBG_ALLOC_MEM_DF; + // dbg |= _CRTDBG_CHECK_ALWAYS_DF; + // dbg |= _CRTDBG_DELAY_FREE_MEM_DF; + // dbg |= _CRTDBG_LEAK_CHECK_DF; + //_CrtSetDbgFlag(dbg); + + // Verify that the nickname is valid + if (!IsNickValid(szNick)) + { + g_pCore->ShowMessageBox(_("Error") + _E("CD01"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + // Store our nickname + m_strLocalNick.AssignLeft(szNick, MAX_PLAYER_NICK_LENGTH); + + // Are we connected? + if (g_pNet->IsConnected() || m_bIsPlayingBack) + { + // Hide the console when connecting.. + if (g_pCore->GetConsole()->IsVisible()) + g_pCore->GetConsole()->SetVisible(false); + + // Display the status box + g_pCore->ShowMessageBox(_("CONNECTING"), _("Entering the game ..."), MB_ICON_INFO); + + // Send the initial data to the server + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Hash the password if neccessary + MD5 Password; + memset(Password.data, 0, sizeof(MD5)); + if (szPassword) + { + // Is it long enough? + size_t sizePassword = strlen(szPassword); + if (sizePassword > 0) + { + // Hash the password and put it in the struct + CMD5Hasher Hasher; + Hasher.Calculate(szPassword, sizePassword, Password); + } + } + + // Append version information + pBitStream->Write(static_cast(MTA_DM_NETCODE_VERSION)); + pBitStream->Write(static_cast(MTA_DM_VERSION)); + pBitStream->Write(static_cast(MTA_DM_BITSTREAM_VERSION)); + + SString strPlayerVersion("%d.%d.%d-%d.%05d.%d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, + MTASA_VERSION_BUILD, g_pNet->GetNetRev()); + pBitStream->WriteString(strPlayerVersion); + + pBitStream->WriteBit(g_pCore->IsOptionalUpdateInfoRequired(g_pNet->GetConnectedServer(true))); + + pBitStream->Write(static_cast(g_pGame->GetGameVersion())); + + // Append user details + SString strTemp = StringZeroPadout(m_strLocalNick, MAX_PLAYER_NICK_LENGTH); + pBitStream->Write(strTemp.c_str(), MAX_PLAYER_NICK_LENGTH); + pBitStream->Write(reinterpret_cast(Password.data), sizeof(MD5)); + + // Append community information (Removed) + std::string strUser; + pBitStream->Write(strUser.c_str(), MAX_SERIAL_LENGTH); + + // Send the packet as joindata + g_pNet->SendPacket(PACKET_ID_PLAYER_JOINDATA, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + return true; + } + } + else + { + g_pCore->ShowMessageBox(_("Error") + _E("CD02"), _("Not connected; please use Quick Connect or the 'connect' command to connect to a server."), + MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + } + + return false; +} + +void CClientGame::SetupLocalGame(eServerType Type) +{ + SString strConfig = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; + m_bWaitingForLocalConnect = true; + if (!m_pLocalServer) + m_pLocalServer = new CLocalServer(strConfig); +} + +bool CClientGame::StartLocalGame(eServerType Type, const char* szPassword) +{ + // Verify that the nickname is valid + std::string strNick; + g_pCore->GetCVars()->Get("nick", strNick); + + if (!IsNickValid(strNick.c_str())) + { + g_pCore->ShowMessageBox(_("Error") + _E("CD03"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + m_bWaitingForLocalConnect = false; + m_ServerType = Type; + SString strTemp = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; + + SAFE_DELETE(m_pLocalServer); + + // Store our nickname + m_strLocalNick.AssignLeft(strNick.c_str(), MAX_PLAYER_NICK_LENGTH); + + // Got a server? + if (m_bLocalPlay) + { + // Start the server locally + if (!m_Server.Start(strTemp)) + { + m_bWaitingForLocalConnect = true; + m_bErrorStartingLocal = true; + g_pCore->ShowMessageBox(_("Error") + _E("CD04"), _("The server is not installed"), MB_ICON_ERROR | MB_BUTTON_OK); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + if (szPassword) + m_Server.SetPassword(szPassword); + + // Display the status box<<<<< + m_OnCancelLocalGameClick = GUI_CALLBACK(&CClientGame::OnCancelLocalGameClick, this); + g_pCore->ShowMessageBox(_("Local Server"), _("Starting local server ..."), MB_BUTTON_CANCEL | MB_ICON_INFO, &m_OnCancelLocalGameClick); + } + else + { + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + // We're waiting for connection + m_bWaitingForLocalConnect = true; + return true; +} + +bool CClientGame::OnCancelLocalGameClick(CGUIElement* pElement) +{ + if (m_bLocalPlay && m_bWaitingForLocalConnect) + { + g_pCore->RemoveMessageBox(); + g_pCore->GetModManager()->RequestUnload(); + return true; + } + return false; +} + +void CClientGame::DoPulsePreFrame(void) +{ + if (m_Status == CClientGame::STATUS_JOINED) + { + if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) + { + m_pVoiceRecorder->DoPulse(); + } + } +} + +void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRenderTargets) +{ + // Allow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); + + // If appropriate, call onClientRestore + if (bDidUnminimize) + { + CLuaArguments Arguments; + Arguments.PushBoolean(bDidRecreateRenderTargets); + m_pRootEntity->CallEvent("onClientRestore", Arguments, false); + m_bWasMinimized = false; + + // Reverse any mute on minimize effects + g_pGame->GetAudio()->SetEffectsMasterVolume(g_pGame->GetSettings()->GetSFXVolume()); + g_pGame->GetAudio()->SetMusicMasterVolume(g_pGame->GetSettings()->GetRadioVolume()); + m_pManager->GetSoundManager()->SetMinimizeMuted(false); + } + + // Call onClientHUDRender LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientHUDRender", Arguments, false); + + // Disallow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); + + // Restore in case script forgets + g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); + + DebugElementRender(); +} + +void CClientGame::DoPulsePostFrame(void) +{ + TIMING_CHECKPOINT("+CClientGame::DoPulsePostFrame"); + #ifdef DEBUG_KEYSTATES + // Get the controller state + CControllerState cs; + g_pGame->GetPad()->GetCurrentControllerState(&cs); + + SString strBuffer; + strBuffer = SString::Printf( + "LeftShoulder1: %u\n" + "LeftShoulder2: %u\n" + "RightShoulder1: %u\n" + "RightShoulder2: %u\n" + "DPadUp: %u\n" + "DPadDown: %u\n" + "DPadLeft: %u\n" + "DPadRight: %u\n" + "Start: %u\n" + "Select: %u\n" + "ButtonSquare: %u\n" + "ButtonTriangle: %u\n" + "ButtonCross: %u\n" + "ButtonCircle: %u\n" + "ShockButtonL: %u\n" + "ShockButtonR: %u\n" + "PedWalk: %u\n", + cs.LeftShoulder1, cs.LeftShoulder2, cs.RightShoulder1, cs.RightShoulder2, cs.DPadUp, cs.DPadDown, cs.DPadLeft, cs.DPadRight, cs.Start, cs.Select, + cs.ButtonSquare, cs.ButtonTriangle, cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.ShockButtonR, cs.m_bPedWalk); + + g_pCore->GetGraphics()->DrawTextTTF(300, 10, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); + + strBuffer = SString::Printf( + "VehicleMouseLook: %u\n" + "LeftStickX: %u\n" + "LeftStickY: %u\n" + "RightStickX: %u\n" + "RightStickY: %u", + cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, cs.RightStickX, cs.RightStickY); + + g_pCore->GetGraphics()->DrawTextTTF(300, 320, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); + #endif + + UpdateModuleTickCount64(); + + if (m_pManager->IsGameLoaded()) + { + // Pulse the nametags before anything that changes player positions, we'll be 1 frame behind, but so is the camera + // If nametags are enabled, pulse the nametag manager + if (m_bShowNametags) + { + m_pNametags->DoPulse(); + } + + // Sync debug + m_pSyncDebug->OnPulse(); + + // Also eventually draw FPS + if (m_bShowFPS) + { + DrawFPS(); + } + + CGraphicsInterface* pGraphics = g_pCore->GetGraphics(); + unsigned int uiHeight = pGraphics->GetViewportHeight(); + unsigned int uiWidth = pGraphics->GetViewportWidth(); + + // Draw a little star in the corner if async is on + if (g_pGame->IsASyncLoadingEnabled(true)) + { + unsigned int uiPosY = g_pGame->IsASyncLoadingEnabled() ? uiHeight - 7 : uiHeight - 12; + pGraphics->DrawString(uiWidth - 5, uiPosY, 0x80ffffff, 1, "*"); + } + + // Draw notice text if dx test mode is enabled + if (g_pCore->GetGraphics()->GetRenderItemManager()->GetTestMode()) + { + unsigned int uiPosY = uiHeight - 30; + pGraphics->DrawString(uiWidth - 155, uiPosY, 0x40ffffff, 1, "dx test mode enabled"); + } + + // Draw notice text if diagnostic mode enabled + EDiagnosticDebugType diagnosticDebug = g_pCore->GetDiagnosticDebug(); + if (diagnosticDebug == EDiagnosticDebug::LOG_TIMING_0000) + { + unsigned int uiPosY = uiHeight - 30; + pGraphics->DrawString(uiWidth - 185, uiPosY, 0xffffff00, 1, "Debug setting: #0000 Log timing"); + } + + // Draw network trouble message if required + if (m_pNetAPI->IsNetworkTrouble()) + { + int iPosX = uiWidth / 2; // Half way across + int iPosY = uiHeight * 45 / 100; // 45/100 down + g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, + DT_NOCLIP | DT_CENTER); + } + + // Adjust the streaming memory limit. + unsigned int uiStreamingMemoryPrev; + g_pCore->GetCVars()->Get("streaming_memory", uiStreamingMemoryPrev); + uint uiStreamingMemory = SharedUtil::Clamp(g_pCore->GetMinStreamingMemory(), uiStreamingMemoryPrev, g_pCore->GetMaxStreamingMemory()); + if (uiStreamingMemory != uiStreamingMemoryPrev) + g_pCore->GetCVars()->Set("streaming_memory", uiStreamingMemory); + + int iStreamingMemoryBytes = static_cast(uiStreamingMemory) * 1024 * 1024; + if (g_pMultiplayer->GetLimits()->GetStreamingMemory() != iStreamingMemoryBytes) + g_pMultiplayer->GetLimits()->SetStreamingMemory(iStreamingMemoryBytes); + + // If we're in debug mode and are supposed to show task data, do it + #ifdef MTA_DEBUG + if (m_pShowPlayerTasks) + { + DrawTasks(m_pShowPlayerTasks); + } + + if (m_pShowPlayer) + { + DrawPlayerDetails(m_pShowPlayer); + } + + std::vector::const_iterator iter = m_pPlayerManager->IterBegin(); + for (; iter != m_pPlayerManager->IterEnd(); ++iter) + { + CClientPlayer* pPlayer = *iter; + if (pPlayer->IsStreamedIn() && pPlayer->IsShowingWepdata()) + DrawWeaponsyncData(pPlayer); + } + #endif + + #if defined (MTA_DEBUG) || defined (MTA_BETA) + if (m_bShowSyncingInfo) + { + // Draw the header boxz + CVector vecPosition = CVector(0.05f, 0.32f, 0); + m_pDisplayManager->DrawText2D("Syncing vehicles:", vecPosition, 1.0f, 0xFFFFFFFF); + + // Print each vehicle we're syncing + CDeathmatchVehicle* pVehicle; + list::const_iterator iter = m_pUnoccupiedVehicleSync->IterBegin(); + for (; iter != m_pUnoccupiedVehicleSync->IterEnd(); iter++) + { + vecPosition.fY += 0.03f; + pVehicle = *iter; + + SString strBuffer("ID: %u (%s)", pVehicle->GetID(), pVehicle->GetNamePointer()); + + m_pDisplayManager->DrawText2D(strBuffer, vecPosition, 1.0f, 0xFFFFFFFF); + } + } + #endif + // Heli Clear time + if (m_LastClearTime.Get() > HeliKill_List_Clear_Rate) + { + // Clear our list now + m_HeliCollisionsMap.clear(); + m_LastClearTime.Reset(); + } + + CClientPerfStatManager::GetSingleton()->DoPulse(); + } + + m_pRadarMap->DoRender(); + m_pManager->DoRender(); + DoPulses(); + + // If we're supposed to show netstat, draw them infront of everything else + if (m_bShowNetstat) + { + m_pNetworkStats->Draw(); + } +} + +void CClientGame::DoPulses(void) +{ + TIMING_CHECKPOINT("-CClientGame::DoPulsePostFrame"); + + g_pCore->ApplyFrameRateLimit(); + + TIMING_CHECKPOINT("+CClientGame::DoPulses"); + + m_BuiltCollisionMapThisFrame = false; + + if (m_bIsPlayingBack && m_bFirstPlaybackFrame && m_pManager->IsGameLoaded()) + { + g_pCore->GetConsole()->Printf("First playback frame, starting"); + m_pManager->GetPacketRecorder()->StartPlayback("log.rec", false); + m_bFirstPlaybackFrame = false; + } + + // Call debug code if debug mode + m_Foo.DoPulse(); + + // Output stuff from our internal server eventually + m_Server.DoPulse(); + + if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED && GetTickCount64_() - m_llLastTransgressionTime > 60000) + { + uint uiLevel = 0; + uint uiInform = 0; + SString strMessage; + + // Is the player a cheater? + if (!m_pManager->GetAntiCheat().PerformChecks()) + { + uiLevel = 1; + uiInform = 2; + } + else + { + strMessage = g_pNet->GetNextBuffer(); + if (strMessage.length()) + { + uiLevel = atoi(strMessage.SplitLeft(":", &strMessage)); + uiInform = atoi(strMessage.SplitLeft(":", &strMessage)); + } + } + + // Send message to the server + if (uiLevel) + { + SString strPrefix = (uiInform == 2) ? "AC" : (uiInform == 1) ? "VF" : "SD"; + SString strMessageCombo = SString("%s #%d %s", *strPrefix, uiLevel, strMessage.c_str()).TrimEnd(" "); + m_llLastTransgressionTime = GetTickCount64_(); + AddReportLog(3100, strMessageCombo + SString(" (%d)", uiInform)); + + if (uiInform > 0) + { + // The server will use the whole message as supplied here + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write(uiLevel); + pBitStream->WriteString(strMessageCombo); + g_pNet->SendPacket(PACKET_ID_PLAYER_TRANSGRESSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + else + { + // Otherwise, disconnect here + AddReportLog(7105, SString("Core - Kicked (%s)", *strMessageCombo)); + g_pCore->ShowMessageBox(_("Error") + _E("CD05"), SString(_("You were kicked from the game ( %s )"), *strMessageCombo), + MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + } + + // Send diagnostic info + if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED) + { + // Retrieve data + SString strMessage = g_pNet->GetDiagnosticStatus(); + + // Send to the server if changed + if (strMessage != m_strLastDiagnosticStatus) + { + m_strLastDiagnosticStatus = strMessage; + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->WriteString(strMessage); + g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } + + // Pulse the network interface + + // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) + DoPulses2(false); + + m_pUnoccupiedVehicleSync->DoPulse(); + m_pPedSync->DoPulse(); +#ifdef WITH_OBJECT_SYNC + m_pObjectSync->DoPulse(); +#endif + m_pLatentTransferManager->DoPulse(); + m_pLuaManager->DoPulse(); + m_pScriptDebugging->UpdateLogOutput(); + + GetModelCacheManager()->DoPulse(); + + #ifdef MTA_DEBUG + UpdateMimics(); + #endif + + // Grab the current time + unsigned long ulCurrentTime = CClientTime::GetTime(); + + // Waiting for a connect? + if (m_bWaitingForLocalConnect) + { + // Connected? + if (g_pNet->IsConnected()) + { + // No longer waiting for connect + m_bWaitingForLocalConnect = false; + + // Assume local server has the same bitstream version + g_pNet->SetServerBitStreamVersion(MTA_DM_BITSTREAM_VERSION); + + // Run the game normally. + StartGame(m_strLocalNick, m_Server.GetPassword().c_str(), m_ServerType); + } + else + { + // Going to try connecting? Do this when the internal server has booted + // and we haven't started the connecting. + if (m_Server.IsReady() && m_iLocalConnectAttempts == 0) + { + g_pCore->ShowMessageBox(_("Local Server"), _("Connecting to local server..."), MB_ICON_INFO); + + // Connect + if (g_pNet->StartNetwork("localhost", 22010)) + { + // We're waiting for connection + m_iLocalConnectAttempts = 1; + m_ulTimeStart = CClientTime::GetTime(); + } + else + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD06"), _("Error connecting to server.")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + + // Timeout? + if (m_ulTimeStart != 0 && CClientTime::GetTime() >= m_ulTimeStart + 5000) + { + // Show timeout message and disconnect + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD07"), _("Connecting to local server timed out. See console for details.")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + } + + // If the game is loaded ... + if (m_pManager->IsGameLoaded()) + { + // Pulse the blended weather manager + m_pBlendedWeather->DoPulse(); + + // If we weren't ingame last frame; call the on ingame event + if (!m_bGameLoaded) + { + // Fix for gta not being focused sometimes + SetActiveWindow(g_pCore->GetHookedWindow()); + SetFocus(g_pCore->GetHookedWindow()); + + m_bGameLoaded = true; + Event_OnIngame(); + } + + // Check if the player is hitting the enter vehicle button + DoVehicleInKeyCheck(); + + // Pulse some stuff + m_pMovingObjectsManager->DoPulse(); + + // Get rid of our deleted elements + m_ElementDeleter.DoDeleteAll(); + m_pLuaManager->ProcessPendingDeleteList(); + + // Get rid of deleted GUI elements + g_pCore->GetGUI()->CleanDeadPool(); + + // Allow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); + + // Call onClientRender LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientRender", Arguments, false); + + // Disallow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); + + // Restore in case script forgets + g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); + + // Ensure replaced/restored textures for models in the GTA map are correct + g_pGame->FlushPendingRestreamIPL(); + + // Respawn objects in respawn pool + m_ObjectRespawner.DoRespawnAll(); + } + + // Are we connecting? + if (m_Status == CClientGame::STATUS_CONNECTING) + { + if (m_bErrorStartingLocal) + { + g_pCore->GetModManager()->RequestUnload(); + return; + } + + // Timed out? + if (!m_bWaitingForLocalConnect && ulCurrentTime >= m_ulTimeStart + NET_CONNECT_TIMEOUT) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD08"), _("Connection timed out"), "connect-timed-out", true); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + else if (m_Status == CClientGame::STATUS_JOINED) + { + // Pulse DownloadFiles if we're transferring stuff + GetResourceFileDownloadManager()->DoPulse(); + DownloadSingularResourceFiles(); + GetRemoteCalls()->ProcessQueuedFiles(); + } + + // Not waiting for local connect? + if (!m_bWaitingForLocalConnect) + { + // Trigger the ingame and connected event + if (!m_bTriggeredIngameAndConnected && m_pManager->IsGameLoaded() && g_pCore->IsConnected()) + { + m_bTriggeredIngameAndConnected = true; + Event_OnIngameAndConnected(); + + // Initialize the game + g_pCore->GetGame()->Initialize(); + } + + unsigned char ucError = g_pNet->GetConnectionError(); + + // Lost connection? + if (!g_pNet->IsConnected() && !m_bGracefulDisconnect && !m_bIsPlayingBack) + { + // See if we can figure out what specifically it was + if (ucError == 0) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD09"), _("Connection with the server was lost")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + else + { + SString strError; + SString strErrorCode; + switch (ucError) + { + case RID_RSA_PUBLIC_KEY_MISMATCH: + strError = _("Disconnected: unknown protocol error"); + strErrorCode = _E("CD10"); // encryption key mismatch + break; + case RID_REMOTE_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected remotely"); + strErrorCode = _E("CD11"); + break; + case RID_REMOTE_CONNECTION_LOST: + strError = _("Disconnected: connection lost remotely"); + strErrorCode = _E("CD12"); + break; + case RID_CONNECTION_BANNED: + strError = _("Disconnected: you are banned from this server"); + strErrorCode = _E("CD13"); + break; + case RID_NO_FREE_INCOMING_CONNECTIONS: + strError = _("Disconnected: the server is currently full"); + strErrorCode = _E("CD14"); + break; + case RID_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected from the server"); + strErrorCode = _E("CD15"); + break; + case RID_CONNECTION_LOST: + strError = _("Disconnected: connection to the server was lost"); + strErrorCode = _E("CD16"); + break; + case RID_INVALID_PASSWORD: + strError = _("Disconnected: invalid password specified"); + strErrorCode = _E("CD17"); + break; + default: + strError = _("Disconnected: connection was refused"); + strErrorCode = _E("CD18"); + break; + } + + // Display an error, reset the error status and exit + g_pCore->ShowNetErrorMessageBox(_("Error") + strErrorCode, strError); + g_pNet->SetConnectionError(0); + g_pCore->GetModManager()->RequestUnload(); + } + } + + // If we're in the verificating status + if (m_Status == CClientGame::STATUS_JOINING) + { + // Time out the verification if it takes too long + if (m_ulVerifyTimeStart != 0 && ulCurrentTime >= m_ulVerifyTimeStart + CLIENT_VERIFICATION_TIMEOUT) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD19"), _("MTA Client verification failed!")); + g_pCore->GetModManager()->RequestUnload(); + } + } + } + + // Check for radar input + m_pRadarMap->DoPulse(); + g_pCore->GetGraphics()->SetAspectRatioAdjustmentSuspended(m_pRadarMap->IsRadarShowing()); + + // Got a local player? + if (m_pLocalPlayer) + { + // Network updates + UpdateVehicleInOut(); + UpdatePlayerTarget(); + UpdatePlayerWeapons(); + // UpdateTrailers (); // Test: Does it always work without this check? + UpdateStunts(); + // Clear last damager if more than 2 seconds old + if (CClientTime::GetTime() - m_ulDamageTime > 2000) + { + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageWeapon = 0xFF; + m_ucDamageBodyPiece = 0xFF; + } + DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); + } + + // Game hacks, restore certain variables + // game-speed changes after spawning + g_pGame->SetGameSpeed(m_fGameSpeed); + // money changes on death/getting into taxis + g_pGame->GetPlayerInfo()->SetPlayerMoney(m_lMoney); + // wanted to stop it changing on skin change etc + if (m_pLocalPlayer) + { + if (m_dwWanted != g_pGame->GetPlayerInfo()->GetWanted()->GetWantedLevel()) + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevelNoFlash(m_dwWanted); + } + // stop players dying from starvation + g_pGame->GetPlayerInfo()->SetLastTimeEaten(0); + // reset weapon logs (for preventing quickreload) + + // Update streaming + m_pManager->UpdateStreamers(); + + // Send screen shot data + ProcessDelayedSendList(); + + // Collect async task scheduler results + m_pAsyncTaskScheduler->CollectResults(); + + TIMING_CHECKPOINT("-CClientGame::DoPulses"); +} + +// Extrapolation test +void CClientGame::DoPulses2(bool bCalledFromIdle) +{ + bool bIsUsingAlternatePulseOrder = IsUsingAlternatePulseOrder(!bCalledFromIdle); + + // Figure out which pulses to do + bool bDoStandardPulses; + bool bDoVehicleManagerPulse; + + if (!bIsUsingAlternatePulseOrder) + { + // With std pulse order, do pulses when not called from idle + bDoStandardPulses = !bCalledFromIdle; + bDoVehicleManagerPulse = !bCalledFromIdle; + } + else + { + // With alt pulse order, do pulses when called from idle + bDoStandardPulses = bCalledFromIdle; + bDoVehicleManagerPulse = bCalledFromIdle; + + // Except when watching a remote synced vehicle + if (CClientVehicle* pTargetVehicle = DynamicCast(m_pCamera->GetTargetEntity())) + if (pTargetVehicle->GetControllingPlayer() != m_pPlayerManager->GetLocalPlayer()) + bDoVehicleManagerPulse = !bDoVehicleManagerPulse; + } + + if (bDoStandardPulses) + { + // Change to high precision so arguments in element data and events can + // be rounded to look more like what is expected + ChangeFloatPrecision(true); + + // Pulse the network interface + TIMING_CHECKPOINT("+NetPulse"); + g_pNet->DoPulse(); + TIMING_CHECKPOINT("-NetPulse"); + + // Change precision back, and check we are in low precision mode 4 sure + ChangeFloatPrecision(false); + assert(!IsHighFloatPrecision()); + } + + m_pManager->DoPulse(bDoStandardPulses, bDoVehicleManagerPulse); + + if (bDoStandardPulses) + { + m_pNetAPI->DoPulse(); + } +} + +void CClientGame::HandleException(CExceptionInformation* pExceptionInformation) +{ +} + +void CClientGame::HandleRadioNext(CControlFunctionBind*) +{ + if (g_pClientGame) + { + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); + if (pPlayer) + { + pPlayer->NextRadioChannel(); + } + } +} + +void CClientGame::HandleRadioPrevious(CControlFunctionBind*) +{ + if (g_pClientGame) + { + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); + if (pPlayer) + { + pPlayer->PreviousRadioChannel(); + } + } +} +bool CClientGame::IsNametagValid(const char* szNick) +{ + // Grab the size of the nametag. Check that it's not to long or short + size_t sizeNick = MbUTF8ToUTF16(szNick).size(); + if (sizeNick < MIN_PLAYER_NAMETAG_LENGTH || sizeNick > MAX_PLAYER_NAMETAG_LENGTH) + { + return false; + } + + // Check that each character is valid (Anything above 32) + unsigned char ucTemp; + for (size_t i = 0; i < sizeNick; i++) + { + ucTemp = szNick[i]; + if (ucTemp < 32) + { + return false; + } + } + + // nametag is valid, return true + return true; +} + +bool CClientGame::IsNickValid(const char* szNick) +{ + // Grab the size of the nick. Check that it's within the player + size_t sizeNick = strlen(szNick); + if (sizeNick < MIN_PLAYER_NICK_LENGTH || sizeNick > MAX_PLAYER_NICK_LENGTH) + { + return false; + } + + // Check that each character is valid (visible characters exluding space) + unsigned char ucTemp; + for (size_t i = 0; i < sizeNick; i++) + { + ucTemp = szNick[i]; + if (ucTemp < 33 || ucTemp > 126) + { + return false; + } + } + + // Nickname is valid, return true + return true; +} + +void CClientGame::ShowNetstat(int iCmd) +{ + bool bShow = (iCmd == 1) ? true : (iCmd == 0) ? false : !m_bShowNetstat; + + if (bShow && !m_bShowNetstat) + { + m_pNetworkStats->Reset(); + } + m_bShowNetstat = bShow; +} + +void CClientGame::ShowEaeg(bool) +{ + if (m_pLocalPlayer) + m_pLocalPlayer->SetStat(0x2329, 1.0f); +} + +#ifdef MTA_WEPSYNCDBG +void CClientGame::ShowWepdata(const char* szNick) +{ + CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); + if (pPlayer) + { + pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); + } +} +#endif + +#ifdef MTA_DEBUG + +void CClientGame::ShowWepdata(const char* szNick) +{ + CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); + if (pPlayer) + { + pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); + } +} + +void CClientGame::ShowPlayer(const char* szNick) +{ + m_pShowPlayer = m_pPlayerManager->Get(szNick); +} + +void CClientGame::ShowTasks(const char* szNick) +{ + m_pShowPlayerTasks = m_pPlayerManager->Get(szNick); +} + +void CClientGame::SetMimic(unsigned int uiMimicCount) +{ + // Check if we're within the max mimics boundary + if (uiMimicCount > MAX_MIMICS) + return; + + // Create neccessary players + while (m_Mimics.size() < uiMimicCount) + { + CClientPlayer* pPlayer = new CClientPlayer(m_pManager, static_cast(MAX_NET_PLAYERS_REAL + (int)m_Mimics.size())); + pPlayer->SetNick("Mimic"); + m_Mimics.push_back(pPlayer); + } + + // Destroy neccessary players + while (m_Mimics.size() > uiMimicCount) + { + CClientPlayer* pPlayer = m_Mimics.back(); + CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); + if (pVehicle) + delete pVehicle; + + delete pPlayer; + m_Mimics.pop_back(); + } +} + +#endif + +void CClientGame::DoVehicleInKeyCheck(void) +{ + // Grab the controller state + CControllerState cs; + g_pGame->GetPad()->GetCurrentControllerState(&cs); + static bool bButtonTriangleWasDown = false; + if (cs.ButtonTriangle) + { + if (!bButtonTriangleWasDown) + { + bButtonTriangleWasDown = true; + + // Process the hit + ProcessVehicleInOutKey(false); + } + } + else + { + bButtonTriangleWasDown = false; + } +} + +void CClientGame::UpdateVehicleInOut(void) +{ + // We got told by the server to animate into a certain vehicle? + if (m_VehicleInOutID != INVALID_ELEMENT_ID) + { + // Grab the vehicle we're getting in/out of + CDeathmatchVehicle* pInOutVehicle = static_cast(m_pVehicleManager->Get(m_VehicleInOutID)); + + // In or out? + if (m_bIsGettingOutOfVehicle) + { + // If we aren't working on leaving the car (he's eiter finished or cancelled/failed leaving) + if (!m_pLocalPlayer->IsLeavingVehicle()) + { + // Are we outside the car? + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + if (!pVehicle) + { + // Tell the server that we successfully left the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction = VEHICLE_NOTIFY_OUT; + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself out (so we're sure the records are correct) + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it, and damagable if we're syncing it + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + }*/ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + + // Reset the vehicle in out stuff so we're ready for another car entry/leave. + // Don't allow a new entry/leave until we've gotten the notify return packet + ElementID ReasonVehicleID = m_VehicleInOutID; + g_pClientGame->ResetVehicleInOut(); + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = ReasonVehicleID; + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_out"); +#endif + } + // Are we still inside the car? + else + { + // Warp us out now to keep in sync with the server + m_pLocalPlayer->RemoveFromVehicle(); + } + } + } + + // Are we getting into a vehicle? + else if (m_bIsGettingIntoVehicle) + { + // If we aren't working on entering the car (he's either finished or cancelled) + if (!m_pLocalPlayer->IsEnteringVehicle()) + { + // Is he in a vehicle now? + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + if (pVehicle) + { + // Tell the server that we successfully entered the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction; + + if (m_bIsJackingVehicle) + { + ucAction = static_cast(VEHICLE_NOTIFY_JACK); +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack"); +#endif + } + else + { + ucAction = static_cast(VEHICLE_NOTIFY_IN); +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in"); +#endif + } + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself in (so we're sure the records are correct) + pVehicle->AllowDoorRatioSetting(m_pLocalPlayer->m_ucEnteringDoor, true); + m_pLocalPlayer->WarpIntoVehicle(pVehicle, m_ucVehicleInOutSeat); + + /* + // Make it damagable + if ( pInOutVehicle ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + */ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + } + else + { + // Tell the server that we aborted entered the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction; + if (m_bIsJackingVehicle) + { + ucAction = static_cast(VEHICLE_NOTIFY_JACK_ABORT); + pBitStream->WriteBits(&ucAction, 4); + + // Did we start jacking them? + bool bAlreadyStartedJacking = false; + CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); + if (pVehicle) + { + CClientPed* pJackedPlayer = pVehicle->GetOccupant(); + if (pJackedPlayer) + { + // Jax: have we already started to jack the other player? + if (pJackedPlayer->IsGettingJacked()) + { + bAlreadyStartedJacking = true; + } + } + unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; + pBitStream->WriteBits(&ucDoor, 3); + SDoorOpenRatioSync door; + door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); + pBitStream->Write(&door); + } + pBitStream->WriteBit(bAlreadyStartedJacking); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack_abort"); +#endif + } + else + { + ucAction = static_cast(VEHICLE_NOTIFY_IN_ABORT); + pBitStream->WriteBits(&ucAction, 4); + CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); + if (pVehicle) + { + unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; + pBitStream->WriteBits(&ucDoor, 3); + SDoorOpenRatioSync door; + door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); + pBitStream->Write(&door); + } + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in_abort"); +#endif + } + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself out again (so we're sure the records are correct) + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it, and damagable if we're syncing it + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + } + */ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + } + + // Reset + // Don't allow a new entry/leave until we've gotten the notify return packet + ElementID ReasonID = m_VehicleInOutID; + ResetVehicleInOut(); + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = ReasonID; + } + } + } + else + { + // If we aren't getting jacked + if (!m_bIsGettingJacked) + { + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + + // Jax: this was commented, re-comment if it was there for a reason (..and give the reason!) + // Are we in a vehicle we aren't supposed to be in? + if (pVehicle && !pOccupiedVehicle) + { + g_pCore->GetConsole()->Print("You shouldn't be in this vehicle"); + m_pLocalPlayer->RemoveFromVehicle(); + } + + // Are we supposed to be in a vehicle? But aren't? + if (pOccupiedVehicle && !pVehicle) + { + // Jax: this happens when we try to warp into a streamed out vehicle, including when we use CClientVehicle::StreamInNow + // ..maybe we need a different way to detect bike falls? + + // Tell the server + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Vehicle id + pBitStream->Write(pOccupiedVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_NOTIFY_FELL_OFF); + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're not allowed to enter any vehicle before we get a confirm + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = pOccupiedVehicle->GetID(); + + // Remove him from the vehicle + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it + CDeathmatchVehicle* pInOutVehicle = static_cast < CDeathmatchVehicle* > ( pOccupiedVehicle ); + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + } + */ + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_fell_off"); +#endif + } + } + } + } +} + +void CClientGame::UpdatePlayerTarget(void) +{ + CControllerState ControllerState; + m_pLocalPlayer->GetControllerState(ControllerState); + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + + // Ignore the local player so we don't get hit + m_pLocalPlayer->WorldIgnore(true); + + // Run a process line of sight and look for an entity we target + CEntity* pColEntity = NULL; + CColPoint* pColPoint = NULL; + g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pColEntity); + + // Unignore the local player again + m_pLocalPlayer->WorldIgnore(false); + + // Kill the colpoint or we get a severe memoryleak + if (pColPoint) + pColPoint->Destroy(); + + if (pColEntity != m_pTargetedGameEntity) + { + m_pTargetedGameEntity = pColEntity; + + if (pColEntity) + { + m_pTargetedEntity = m_pManager->FindEntity(pColEntity); + } + else + m_pTargetedEntity = NULL; + + // Store the last targeted player's id + if (m_pTargetedEntity && m_pTargetedEntity->GetType() == CCLIENTPLAYER) + { + m_TargetedPlayerID = m_pTargetedEntity->GetID(); + } + else + m_TargetedPlayerID = INVALID_ELEMENT_ID; + + // Send the target + ElementID TargetID = INVALID_ELEMENT_ID; + if (m_pTargetedEntity && !m_pTargetedEntity->IsLocalEntity()) + { + TargetID = m_pTargetedEntity->GetID(); + } + + CBitStream bitStream; + bitStream.pBitStream->Write(TargetID); + m_pNetAPI->RPC(PLAYER_TARGET, bitStream.pBitStream); + + // Call our onClientPlayerTarget event + CLuaArguments Arguments; + if (m_pTargetedEntity) + Arguments.PushElement(m_pTargetedEntity); + else + Arguments.PushBoolean(false); + m_pLocalPlayer->CallEvent("onClientPlayerTarget", Arguments, true); + } +} + +void CClientGame::UpdatePlayerWeapons(void) +{ + // Check whether we changed weapon slots + eWeaponSlot currentSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + if (currentSlot != m_lastWeaponSlot) + { + CLuaArguments Arguments; + Arguments.PushNumber(m_lastWeaponSlot); + Arguments.PushNumber(currentSlot); + bool bCancelled = !m_pLocalPlayer->CallEvent("onClientPlayerWeaponSwitch", Arguments, true); + + if (bCancelled) + { + // Save the current ammo in clip + unsigned short usAmmoInClip = 0; + CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); + if (pWeapon) + usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); + + // Force it back to the old slot + m_pLocalPlayer->SetCurrentWeaponSlot(m_lastWeaponSlot); + + // Restore the ammo in clip that there was in that slot + if (usAmmoInClip > 0) + m_pLocalPlayer->GetWeapon()->SetAmmoInClip(usAmmoInClip); + } + else + { + CBitStream bitStream; + CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(); + NetBitStreamInterface& BitStream = *(bitStream.pBitStream); + SWeaponSlotSync slot; + + // Always send bit in case server is not in sync + if ((BitStream.Version() >= 0x44 && m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN) || BitStream.Version() >= 0x4D) + { + CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); + if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && + (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || + (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) + BitStream.WriteBit(true); + else + BitStream.WriteBit(false); + } + + if (pWeapon) + { + /* Send a packet to the server with info about the new weapon, + so the server stays in sync reliably */ + unsigned int uiSlot = static_cast(pWeapon->GetSlot()); + slot.data.uiSlot = uiSlot; + BitStream.Write(&slot); + + if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) + { + SWeaponAmmoSync ammo(pWeapon->GetType(), true, true); + ammo.data.usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); + ammo.data.usTotalAmmo = static_cast(pWeapon->GetAmmoTotal()); + BitStream.Write(&ammo); + } + } + else + { + slot.data.uiSlot = 0; + BitStream.Write(&slot); + } + + m_pNetAPI->RPC(PLAYER_WEAPON, bitStream.pBitStream); + m_lastWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + } + } +} + +void CClientGame::UpdateTrailers(void) +{ + // This function is here to re-attach trailers if they fall off + + unsigned long ulCurrentTime = GetTickCount32(); + + CClientVehicle * pVehicle = NULL, *pTrailer = NULL; + CVehicle * pGameVehicle = NULL, *pGameTrailer = NULL; + unsigned long ulIllegalTowBreakTime; + vector::const_iterator iterVehicles = m_pVehicleManager->StreamedBegin(); + for (; iterVehicles != m_pVehicleManager->StreamedEnd(); iterVehicles++) + { + pVehicle = *iterVehicles; + ulIllegalTowBreakTime = pVehicle->GetIllegalTowBreakTime(); + + // Do we have an illegal break? + if (ulIllegalTowBreakTime != 0) + { + // Has it been atleast 1 second since the break + if (ulCurrentTime > (ulIllegalTowBreakTime + 1000)) + { + // Try to re-attach them + CClientVehicle* pTowedBy = pVehicle->GetTowedByVehicle(); + if (pTowedBy) + { + // Little hack to keep illegaly detached trailers close to their tower + CVector vecPosition; + pVehicle->GetPosition(vecPosition); + pVehicle->SetPosition(vecPosition); + + pGameVehicle = pTowedBy->GetGameVehicle(); + pGameTrailer = pVehicle->GetGameVehicle(); + if (pGameVehicle && pGameTrailer) + { + // pGameTrailer->SetTowLink ( pGameVehicle ); + CVector vecRotation; + pTowedBy->GetRotationRadians(vecRotation); + pVehicle->SetRotationRadians(vecRotation); + pTowedBy->InternalSetTowLink(pVehicle); + } + } + + // Reset the break time, even if we couldnt re-attach it + pVehicle->SetIllegalTowBreakTime(0); + } + } + } +} + +void CClientGame::UpdateFireKey(void) +{ + if (m_pLocalPlayer) + { + SBindableGTAControl* pControl = g_pCore->GetKeyBinds()->GetBindableFromControl("fire"); + + // Is our 'fire' control enabled? + if (pControl->bEnabled) + { + // ** Satchel charge detonation ** + { + // Do we have a detonator in our hand? + if (m_pLocalPlayer->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_DETONATOR) + { + // Planted any satchels? + if (m_pLocalPlayer->CountProjectiles(WEAPONTYPE_REMOTE_SATCHEL_CHARGE) > 0) + { + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + + // Tell the server we want to detonate our satchels + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + g_pNet->SendPacket(PACKET_ID_DETONATE_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } + // Remove the detonator if we dont have any satchels planted + else + { + m_pLocalPlayer->RemoveWeapon(WEAPONTYPE_DETONATOR); + } + } + } + + // Has our control state been cut short? + if (!pControl->bState) + return; + + // ** Stealth kill ** + { + if (m_pLocalPlayer->IsStealthAiming()) + { + // Do we have a target ped? + CClientPed* pTargetPed = m_pLocalPlayer->GetTargetedPed(); + if (pTargetPed) + { + // Do we have a target player? + if (IS_PLAYER(pTargetPed)) + { + CClientPlayer* pTargetPlayer = static_cast(pTargetPed); + + // Is the targetted player on a team + CClientTeam* pTeam = pTargetPlayer->GetTeam(); + if (pTeam) + { + // Is this friendly-fire? + if (pTargetPlayer->IsOnMyTeam(m_pLocalPlayer) && !pTeam->GetFriendlyFire()) + { + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + return; + } + } + } + CPlayerPed* pGameTarget = static_cast(pTargetPed)->GetGamePlayer(); + if (pGameTarget) + { + // Would GTA let us stealth kill now? + if (m_pLocalPlayer->GetGamePlayer()->GetPedIntelligence()->TestForStealthKill(pGameTarget, false)) + { + // Grab our local position + CVector vecLocalPosition; + m_pLocalPlayer->GetPosition(vecLocalPosition); + + // Grab the target's position + CVector vecTargetPosition; + pTargetPed->GetPosition(vecTargetPosition); + + // Work out an angle between the players, and set this as we initiate our knife kill + float fAngle = AngleBetweenPoints2D(vecLocalPosition, vecTargetPosition); + m_pLocalPlayer->SetCurrentRotation(fAngle); + + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + CLuaArguments Arguments; + Arguments.PushElement(pTargetPed); + if (m_pLocalPlayer->CallEvent("onClientPlayerStealthKill", Arguments, false)) + { + if (pTargetPed->IsLocalEntity()) + { + CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, 4 /*WEAPONTYPE_KNIFE*/, 9 /*BODYPART_HEAD*/, true); + return; + } + + // Lets request a stealth kill + CBitStream bitStream; + bitStream.pBitStream->Write(pTargetPed->GetID()); + m_pNetAPI->RPC(REQUEST_STEALTH_KILL, bitStream.pBitStream); + } + else + { + return; + } + } + } + } + } + } + } + } +} + +void CClientGame::UpdateStunts(void) +{ + // * Two wheeler * + static unsigned long ulLastCarTwoWheelCounter = 0; + static float fLastCarTwoWheelDist = 0.0f; + unsigned long ulTemp = g_pGame->GetPlayerInfo()->GetCarTwoWheelCounter(); + // Did we start a stunt? + if (ulLastCarTwoWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("2wheeler"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastCarTwoWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("2wheeler"); + Arguments.PushNumber(ulLastCarTwoWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastCarTwoWheelCounter = ulTemp; + fLastCarTwoWheelDist = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); + + // * Wheelie * + static unsigned long ulLastBikeRearWheelCounter = 0; + static float fLastBikeRearWheelDist = 0.0f; + ulTemp = g_pGame->GetPlayerInfo()->GetBikeRearWheelCounter(); + // Did we start a stunt? + if (ulLastBikeRearWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("wheelie"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastBikeRearWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("wheelie"); + Arguments.PushNumber(ulLastBikeRearWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastBikeRearWheelCounter = ulTemp; + fLastBikeRearWheelDist = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); + + // * Stoppie * + static unsigned long ulLastBikeFrontWheelCounter = 0; + static float fLastBikeFrontWheelDist = 0.0f; + ulTemp = g_pGame->GetPlayerInfo()->GetBikeFrontWheelCounter(); + // Did we start a stunt? + if (ulLastBikeFrontWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("stoppie"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastBikeFrontWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("stoppie"); + Arguments.PushNumber(ulLastBikeFrontWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastBikeFrontWheelCounter = ulTemp; + fLastBikeFrontWheelDist = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); +} + +void CClientGame::StaticUpdateFireKey(CControlFunctionBind* pBind) +{ + g_pClientGame->UpdateFireKey(); +} + +void CClientGame::ChangeVehicleWeapon(bool bNext) +{ + if (m_pLocalPlayer && m_pLocalPlayer->GetRealOccupiedVehicle()) + { + eWeaponSlot currentWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + eWeaponSlot weaponSlot = currentWeaponSlot; + CWeapon* pWeapon = NULL; + while (!pWeapon || pWeapon->GetType() == WEAPONTYPE_UNARMED) + { + if (bNext) + { + if (weaponSlot == WEAPONSLOT_TYPE_DETONATOR) + { + weaponSlot = WEAPONSLOT_TYPE_UNARMED; + break; + } + + weaponSlot = (eWeaponSlot)(weaponSlot + 1); + + if (weaponSlot == currentWeaponSlot) + break; + + pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); + } + else + { + if (weaponSlot == WEAPONSLOT_TYPE_UNARMED) + { + if (weaponSlot != currentWeaponSlot) + break; + weaponSlot = WEAPONSLOT_TYPE_DETONATOR; + } + + weaponSlot = (eWeaponSlot)(weaponSlot - 1); + + if (weaponSlot == currentWeaponSlot) + break; + + pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); + } + } + if (pWeapon || weaponSlot == WEAPONSLOT_TYPE_UNARMED) + { + m_pLocalPlayer->SetCurrentWeaponSlot(weaponSlot); + } + } +} + +void CClientGame::ResetVehicleInOut(void) +{ + m_ulLastVehicleInOutTime = 0; + m_bIsGettingOutOfVehicle = false; + m_bIsGettingIntoVehicle = false; + m_bIsJackingVehicle = false; + m_bIsGettingJacked = false; + m_VehicleInOutID = INVALID_ELEMENT_ID; + m_ucVehicleInOutSeat = 0xFF; + m_bNoNewVehicleTask = false; + m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; + m_pGettingJackedBy = NULL; +} + +void CClientGame::SetAllDimensions(unsigned short usDimension) +{ + m_pManager->GetMarkerStreamer()->SetDimension(usDimension); + m_pManager->GetObjectStreamer()->SetDimension(usDimension); + m_pManager->GetObjectLodStreamer()->SetDimension(usDimension); + m_pManager->GetPickupStreamer()->SetDimension(usDimension); + m_pManager->GetPlayerStreamer()->SetDimension(usDimension); + m_pManager->GetRadarAreaManager()->SetDimension(usDimension); + m_pManager->GetVehicleStreamer()->SetDimension(usDimension); + m_pManager->GetRadarMarkerManager()->SetDimension(usDimension); + m_pManager->GetSoundManager()->SetDimension(usDimension); + m_pManager->GetPointLightsManager()->SetDimension(usDimension); + m_pManager->GetWaterManager()->SetDimension(usDimension); + m_pNametags->SetDimension(usDimension); + m_pCamera->SetDimension(usDimension); +} + +bool CClientGame::StaticKeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) +{ + return g_pClientGame->KeyStrokeHandler(strKey, bState, bIsConsoleInputKey); +} + +bool CClientGame::KeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) +{ + // Do we have a root yet? + if (m_pRootEntity) + { + // Ignore keydown/up pair if main menu is displayed, or console input will use the character + bool bIgnore = false; + if (bState) + { + auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; + bool isMouseKey = strKey.substr(0, 5) == "mouse"; + + if (g_pCore->IsMenuVisible() || (g_pCore->GetConsole()->IsInputActive() && bIsConsoleInputKey) || + (pFocusedBrowser && !pFocusedBrowser->IsLocal() && !isMouseKey)) + + bIgnore = true; // Ignore this keydown and the matching keyup + else + MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup + } + else + { + if (!MapContains(m_AllowKeyUpMap, strKey)) + bIgnore = true; // Ignore this keyup + else + MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup + } + + if (!bIgnore) + { + bool bAllow = true; + // Call our key-stroke event + CLuaArguments Arguments; + Arguments.PushString(strKey); + Arguments.PushBoolean(bState); + bAllow = m_pRootEntity->CallEvent("onClientKey", Arguments, false); + if (bState == true) + { + if (bAllow == false && strKey == "escape") + { + if (m_bLastKeyWasEscapeCancelled) + { + // Escape cannot be skipped twice + bAllow = true; + m_bLastKeyWasEscapeCancelled = false; + } + else + m_bLastKeyWasEscapeCancelled = true; + } + else + m_bLastKeyWasEscapeCancelled = false; + } + return bAllow; + } + } + m_bLastKeyWasEscapeCancelled = false; + return true; +} + +bool CClientGame::StaticCharacterKeyHandler(WPARAM wChar) +{ + return g_pClientGame->CharacterKeyHandler(wChar); +} + +bool CClientGame::CharacterKeyHandler(WPARAM wChar) +{ + // Do we have a root yet? + if (m_pRootEntity && g_pCore->IsMenuVisible() == false && g_pCore->GetConsole()->IsInputActive() == false) + { + // Cancel event if remote browser is focused + auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; + if (pFocusedBrowser && !pFocusedBrowser->IsLocal()) + return false; + + // Safe character? + if (wChar >= 32) + { + // Generate a null-terminating string for our character + wchar_t wUNICODE[2] = {wChar, '\0'}; + + // Convert our UTF character into an ANSI string + SString strANSI = UTF16ToMbUTF8(wUNICODE); + + // Call our character event + CLuaArguments Arguments; + Arguments.PushString(strANSI); + m_pRootEntity->CallEvent("onClientCharacter", Arguments, false); + } + } + + return false; +} + +void CClientGame::StaticProcessClientKeyBind(CKeyFunctionBind* pBind) +{ + g_pClientGame->ProcessClientKeyBind(pBind); +} + +void CClientGame::ProcessClientKeyBind(CKeyFunctionBind* pBind) +{ + m_pScriptKeyBinds->ProcessKey(pBind->boundKey->szKey, pBind->bHitState, SCRIPT_KEY_BIND_FUNCTION); +} + +void CClientGame::StaticProcessClientControlBind(CControlFunctionBind* pBind) +{ + g_pClientGame->ProcessClientControlBind(pBind); +} + +void CClientGame::ProcessClientControlBind(CControlFunctionBind* pBind) +{ + m_pScriptKeyBinds->ProcessKey(pBind->control->szControl, pBind->bHitState, SCRIPT_KEY_BIND_CONTROL_FUNCTION); +} + +void CClientGame::StaticProcessServerKeyBind(CKeyFunctionBind* pBind) +{ + g_pClientGame->ProcessServerKeyBind(pBind); +} + +void CClientGame::ProcessServerKeyBind(CKeyFunctionBind* pBind) +{ + const char* szName = pBind->boundKey->szKey; + unsigned char ucNameLength = (unsigned char)strlen(szName); + CBitStream bitStream; + bitStream.pBitStream->WriteBit(false); + bitStream.pBitStream->WriteBit(pBind->bHitState); + bitStream.pBitStream->Write(szName, ucNameLength); + m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); +} + +void CClientGame::StaticProcessServerControlBind(CControlFunctionBind* pBind) +{ + g_pClientGame->ProcessServerControlBind(pBind); +} + +void CClientGame::ProcessServerControlBind(CControlFunctionBind* pBind) +{ + const char* szName = pBind->control->szControl; + unsigned char ucNameLength = (unsigned char)strlen(szName); + CBitStream bitStream; + bitStream.pBitStream->WriteBit(true); + bitStream.pBitStream->WriteBit(pBind->bHitState); + bitStream.pBitStream->Write(szName, ucNameLength); + m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); +} + +bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + bool bCursorForcedVisible = g_pCore->IsCursorForcedVisible(); + bool bMenuVisible = g_pCore->IsMenuVisible(); + bool bConsoleVisible = g_pCore->GetConsole()->IsVisible(); + + if (bCursorForcedVisible) + { + if (!bMenuVisible && !bConsoleVisible) + { + if (m_bCursorEventsEnabled) + { + unsigned char ucButtonHit = 0xFF; + switch (uMsg) + { + case WM_LBUTTONDOWN: + ucButtonHit = 0; + break; + case WM_LBUTTONUP: + ucButtonHit = 1; + break; + case WM_MBUTTONDOWN: + ucButtonHit = 2; + break; + case WM_MBUTTONUP: + ucButtonHit = 3; + break; + case WM_RBUTTONDOWN: + ucButtonHit = 4; + break; + case WM_RBUTTONUP: + ucButtonHit = 5; + break; + } + if (ucButtonHit != 0xFF) + { + int iX = LOWORD(lParam); + int iY = HIWORD(lParam); + + CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); + + /* + // (IJs) why are these relative? it doesn't make sense + CVector2D vecCursorPosition ( ( ( float ) iX ) / vecResolution.fX, + ( ( float ) iY ) / vecResolution.fY ); + */ + + CVector2D vecCursorPosition((float)iX, (float)iY); + + CVector vecOrigin, vecTarget, vecScreen((float)iX, (float)iY, 300.0f); + g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); + + // Grab the camera position + CCamera* pCamera = g_pGame->GetCamera(); + CCam* pCam = pCamera->GetCam(pCamera->GetActiveCam()); + CMatrix matCamera; + pCamera->GetMatrix(&matCamera); + vecOrigin = matCamera.vPos; + + CColPoint* pColPoint = NULL; + CEntity* pGameEntity = NULL; + + // Grab the collision point/entity + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pGameEntity); + + CVector vecCollision; + ElementID CollisionEntityID = INVALID_ELEMENT_ID; + CClientEntity* pCollisionEntity = NULL; + if (bCollision && pColPoint) + { + vecCollision = pColPoint->GetPosition(); + if (pGameEntity) + { + CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity); + if (pEntity) + { + pCollisionEntity = pEntity; + if (!pEntity->IsLocalEntity()) + CollisionEntityID = pEntity->GetID(); + } + } + } + else + { + vecCollision = vecTarget; + } + + // Destroy the colpoint so we don't get a leak + if (pColPoint) + { + pColPoint->Destroy(); + } + + const char* szButton = NULL; + const char* szState = NULL; + switch (ucButtonHit) + { + case 0: + szButton = "left"; + szState = "down"; + break; + case 1: + szButton = "left"; + szState = "up"; + break; + case 2: + szButton = "middle"; + szState = "down"; + break; + case 3: + szButton = "middle"; + szState = "up"; + break; + case 4: + szButton = "right"; + szState = "down"; + break; + case 5: + szButton = "right"; + szState = "up"; + break; + } + if (szButton && szState) + { + if (std::isnan(vecCollision.fX)) + vecCollision.fX = 0; + if (std::isnan(vecCollision.fY)) + vecCollision.fY = 0; + if (std::isnan(vecCollision.fZ)) + vecCollision.fZ = 0; + + // Call the event for the client + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(vecCursorPosition.fX); + Arguments.PushNumber(vecCursorPosition.fY); + Arguments.PushNumber(vecCollision.fX); + Arguments.PushNumber(vecCollision.fY); + Arguments.PushNumber(vecCollision.fZ); + if (pCollisionEntity) + Arguments.PushElement(pCollisionEntity); + else + Arguments.PushBoolean(false); + m_pRootEntity->CallEvent("onClientClick", Arguments, false); + + // Send the button, cursor position, 3d position and the entity collided with + CBitStream bitStream; + + SMouseButtonSync button; + button.data.ucButton = ucButtonHit; + bitStream.pBitStream->Write(&button); + + bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fX)); + bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fY)); + + SPositionSync position(false); + position.data.vecPosition = vecCollision; + bitStream.pBitStream->Write(&position); + + if (CollisionEntityID != INVALID_ELEMENT_ID) + { + bitStream.pBitStream->WriteBit(true); + bitStream.pBitStream->Write(CollisionEntityID); + } + else + bitStream.pBitStream->WriteBit(false); + + m_pNetAPI->RPC(CURSOR_EVENT, bitStream.pBitStream); + + if (strcmp(szState, "down") == 0) + { + CVector2D vecDelta = m_vecLastCursorPosition - vecCursorPosition; + + if ((GetTickCount32() - m_ulLastClickTick) < DOUBLECLICK_TIMEOUT && vecDelta.Length() <= DOUBLECLICK_MOVE_THRESHOLD) + { + // Call the event for the client + CLuaArguments DoubleClickArguments; + DoubleClickArguments.PushString(szButton); + DoubleClickArguments.PushNumber(vecCursorPosition.fX); + DoubleClickArguments.PushNumber(vecCursorPosition.fY); + DoubleClickArguments.PushNumber(vecCollision.fX); + DoubleClickArguments.PushNumber(vecCollision.fY); + DoubleClickArguments.PushNumber(vecCollision.fZ); + if (pCollisionEntity) + DoubleClickArguments.PushElement(pCollisionEntity); + else + DoubleClickArguments.PushBoolean(false); + m_pRootEntity->CallEvent("onClientDoubleClick", DoubleClickArguments, false); + } + + m_ulLastClickTick = GetTickCount32(); + m_vecLastCursorPosition = vecCursorPosition; + } + + return true; + } + } + } + } + } + switch (uMsg) + { + case WM_MOUSEMOVE: + { + int iX = LOWORD(lParam), iY = HIWORD(lParam); + static int iPreviousX = 0, iPreviousY = 0; + if (iX != iPreviousX || iY != iPreviousY) + { + iPreviousX = iX, iPreviousY = iY; + + CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); + CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); + + CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); + g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); + + // Call the onClientCursorMove event + CLuaArguments Arguments; + Arguments.PushNumber((double)vecCursorPosition.fX); + Arguments.PushNumber((double)vecCursorPosition.fY); + Arguments.PushNumber((double)iX); + Arguments.PushNumber((double)iY); + Arguments.PushNumber((double)vecTarget.fX); + Arguments.PushNumber((double)vecTarget.fY); + Arguments.PushNumber((double)vecTarget.fZ); + m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); + } + break; + } + } + return false; +} + +CClientPlayer* CClientGame::GetClosestRemotePlayer(const CVector& vecPosition, float fMaxDistance) +{ + CClientPlayer* pClosest = NULL; + float fDistance = 0.0f, fTemp; + CVector vecTemp; + CClientPlayer* pPlayer; + vector::const_iterator iter = m_pPlayerManager->IterBegin(); + for (; iter != m_pPlayerManager->IterEnd(); ++iter) + { + pPlayer = *iter; + if (!pPlayer->IsLocalPlayer() && !pPlayer->IsDeadOnNetwork() && pPlayer->GetHealth() > 0) + { + // Ensure remote player is alive and sending position updates + ulong ulTimeSinceLastPuresync = CClientTime::GetTime() - pPlayer->GetLastPuresyncTime(); + if (ulTimeSinceLastPuresync < static_cast(g_TickRateSettings.iPureSync) * 2) + { + pPlayer->GetPosition(vecTemp); + fTemp = DistanceBetweenPoints3D(vecPosition, vecTemp); + if (fTemp < fMaxDistance) + { + if (!pClosest || fTemp < fDistance) + { + pClosest = pPlayer; + fDistance = fTemp; + } + } + } + } + } + return pClosest; +} + +void CClientGame::SetGameSpeed(float fSpeed) +{ + g_pGame->SetGameSpeed(fSpeed); + m_fGameSpeed = fSpeed; +} + +void CClientGame::SetMinuteDuration(unsigned long ulDelay) +{ + g_pGame->SetMinuteDuration(ulDelay); + m_ulMinuteDuration = ulDelay; +} + +void CClientGame::SetMoney(long lMoney, bool bInstant) +{ + g_pGame->GetPlayerInfo()->SetPlayerMoney(lMoney, bInstant); + m_lMoney = lMoney; +} + +void CClientGame::SetWanted(DWORD dwWanted) +{ + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(dwWanted); + m_dwWanted = dwWanted; +} + +void CClientGame::AddBuiltInEvents(void) +{ + // Resource events + m_Events.AddEvent("onClientResourceStart", "resource", NULL, false); + m_Events.AddEvent("onClientResourceStop", "resource", NULL, false); + + // Element events + m_Events.AddEvent("onClientElementDataChange", "name", NULL, false); + m_Events.AddEvent("onClientElementStreamIn", "", NULL, false); + m_Events.AddEvent("onClientElementStreamOut", "", NULL, false); + m_Events.AddEvent("onClientElementDestroy", "", NULL, false); + + // Player events + m_Events.AddEvent("onClientPlayerJoin", "", NULL, false); + m_Events.AddEvent("onClientPlayerQuit", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerTarget", "target", NULL, false); + m_Events.AddEvent("onClientPlayerSpawn", "team", NULL, false); + m_Events.AddEvent("onClientPlayerChangeNick", "oldNick", NULL, false); + m_Events.AddEvent("onClientPlayerVehicleEnter", "vehicle, seat", NULL, false); + m_Events.AddEvent("onClientPlayerVehicleExit", "vehicle, seat", NULL, false); + m_Events.AddEvent("onClientPlayerTask", "priority, slot, name", NULL, false); + m_Events.AddEvent("onClientPlayerWeaponSwitch", "previous, current", NULL, false); + m_Events.AddEvent("onClientPlayerStuntStart", "type", NULL, false); + m_Events.AddEvent("onClientPlayerStuntFinish", "type, time, distance", NULL, false); + m_Events.AddEvent("onClientPlayerRadioSwitch", "", NULL, false); + m_Events.AddEvent("onClientPlayerDamage", "attacker, weapon, bodypart", NULL, false); + m_Events.AddEvent("onClientPlayerWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPlayerWasted", "", NULL, false); + m_Events.AddEvent("onClientPlayerChoke", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceStart", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceStop", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoicePause", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceResumed", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerStealthKill", "target", NULL, false); + m_Events.AddEvent("onClientPlayerHitByWaterCannon", "vehicle", NULL, false); + m_Events.AddEvent("onClientPlayerHeliKilled", "heli", NULL, false); + m_Events.AddEvent("onClientPlayerPickupHit", "pickup, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPlayerPickupLeave", "pickup, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPlayerNetworkStatus", "type, ticks", NULL, false); + + // Ped events + m_Events.AddEvent("onClientPedDamage", "attacker, weapon, bodypart", NULL, false); + m_Events.AddEvent("onClientPedWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPedWasted", "", NULL, false); + m_Events.AddEvent("onClientPedChoke", "", NULL, false); + m_Events.AddEvent("onClientPedHeliKilled", "heli", NULL, false); + m_Events.AddEvent("onClientPedHitByWaterCannon", "vehicle", NULL, false); + + // Vehicle events + m_Events.AddEvent("onClientVehicleRespawn", "", NULL, false); + m_Events.AddEvent("onClientVehicleEnter", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleExit", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleStartEnter", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleStartExit", "player, seat", NULL, false); + m_Events.AddEvent("onClientTrailerAttach", "towedBy", NULL, false); + m_Events.AddEvent("onClientTrailerDetach", "towedBy", NULL, false); + m_Events.AddEvent("onClientVehicleExplode", "", NULL, false); + m_Events.AddEvent("onClientVehicleCollision", "collidedelement, damageImpulseMag, bodypart, x, y, z, velX, velY, velZ", NULL, false); + m_Events.AddEvent("onClientVehicleDamage", "attacker, weapon, loss, x, y, z, tyre", NULL, false); + m_Events.AddEvent("onClientVehicleNitroStateChange", "activated", NULL, false); + + // GUI events + m_Events.AddEvent("onClientGUIClick", "button, state, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIDoubleClick", "button, state, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIMouseDown", "button, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIMouseUp", "button, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIScroll", "element", NULL, false); + m_Events.AddEvent("onClientGUIChanged", "element", NULL, false); + m_Events.AddEvent("onClientGUIAccepted", "element", NULL, false); + // m_Events.AddEvent ( "onClientGUIClose", "element", NULL, false ); + // m_Events.AddEvent ( "onClientGUIKeyDown", "element", NULL, false ); + m_Events.AddEvent("onClientGUITabSwitched", "element", NULL, false); + m_Events.AddEvent("onClientGUIComboBoxAccepted", "element", NULL, false); + + // Input events + m_Events.AddEvent("onClientDoubleClick", "button, screenX, screenY, worldX, worldY, worldZ, element", NULL, false); + m_Events.AddEvent("onClientMouseMove", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseEnter", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseLeave", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseWheel", "", NULL, false); + m_Events.AddEvent("onClientGUIMove", "", NULL, false); + m_Events.AddEvent("onClientGUISize", "", NULL, false); + m_Events.AddEvent("onClientGUIFocus", "", NULL, false); + m_Events.AddEvent("onClientGUIBlur", "", NULL, false); + m_Events.AddEvent("onClientKey", "key, state", NULL, false); + m_Events.AddEvent("onClientCharacter", "character", NULL, false); + + // Console events + m_Events.AddEvent("onClientConsole", "text", NULL, false); + + // Chat events + m_Events.AddEvent("onClientChatMessage", "test, r, g, b", NULL, false); + + // Debug events + m_Events.AddEvent("onClientDebugMessage", "message, level, file, line", NULL, false); + + // Game events + m_Events.AddEvent("onClientPreRender", "", NULL, false); + m_Events.AddEvent("onClientHUDRender", "", NULL, false); + m_Events.AddEvent("onClientRender", "", NULL, false); + m_Events.AddEvent("onClientMinimize", "", NULL, false); + m_Events.AddEvent("onClientRestore", "", NULL, false); + + // Cursor events + m_Events.AddEvent("onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false); + m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); + + // Transfer box event + m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); + + // Marker events + m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); + + // Marker events + m_Events.AddEvent("onClientPickupHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPickupLeave", "entity, matchingDimension", NULL, false); + + // Col-shape events + m_Events.AddEvent("onClientColShapeHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientColShapeLeave", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientElementColShapeHit", "colShape, matchingDimension", NULL, false); + m_Events.AddEvent("onClientElementColShapeLeave", "colShape, matchingDimension", NULL, false); + + // Explosion events + m_Events.AddEvent("onClientExplosion", "x, y, z, type", NULL, false); + + // Projectile events + m_Events.AddEvent("onClientProjectileCreation", "creator", NULL, false); + + // Sound events + m_Events.AddEvent("onClientSoundStream", "success, length, streamName, error", NULL, false); + m_Events.AddEvent("onClientSoundFinishedDownload", "length", NULL, false); + m_Events.AddEvent("onClientSoundChangedMeta", "streamTitle", NULL, false); + m_Events.AddEvent("onClientSoundStarted", "reason", NULL, false); + m_Events.AddEvent("onClientSoundStopped", "reason", NULL, false); + m_Events.AddEvent("onClientSoundBeat", "time", NULL, false); + + // Object events + m_Events.AddEvent("onClientObjectDamage", "loss, attacker", NULL, false); + m_Events.AddEvent("onClientObjectBreak", "attacker", NULL, false); + + // Web events + m_Events.AddEvent("onClientBrowserWhitelistChange", "newPages", NULL, false); + m_Events.AddEvent("onClientBrowserCreated", "", NULL, false); + m_Events.AddEvent("onClientBrowserLoadingStart", "url, mainframe", NULL, false); + m_Events.AddEvent("onClientBrowserDocumentReady", "url", NULL, false); + m_Events.AddEvent("onClientBrowserLoadingFailed", "url, errorcode, errordescription", NULL, false); + m_Events.AddEvent("onClientBrowserNavigate", "url, isblocked", NULL, false); + m_Events.AddEvent("onClientBrowserPopup", "targeturl, openerurl, ispopup", NULL, false); + m_Events.AddEvent("onClientBrowserCursorChange", "cursor", NULL, false); + m_Events.AddEvent("onClientBrowserTooltip", "text", NULL, false); + m_Events.AddEvent("onClientBrowserInputFocusChanged", "gainedfocus", NULL, false); + m_Events.AddEvent("onClientBrowserResourceBlocked", "url, domain, reason", NULL, false); + + // Misc events + m_Events.AddEvent("onClientFileDownloadComplete", "fileName, success", NULL, false); + + m_Events.AddEvent("onClientWeaponFire", "ped, x, y, z", NULL, false); +} + +void CClientGame::DrawFPS(void) +{ + // Draw the background + float fResWidth = static_cast(g_pCore->GetGraphics()->GetViewportWidth()); + float fResHeight = static_cast(g_pCore->GetGraphics()->GetViewportHeight()); + g_pCore->GetGraphics()->DrawRectangle(0.75f * fResWidth, 0.22f * fResHeight, 0.25f * fResWidth, 0.04f * fResHeight, 0x78000000); + + static char x = 0; + static float fDisp = 0.0f; + if (x == 20) + { + x = 0; + fDisp = g_pGame->GetFPS(); + } + else + x++; + SString strBuffer("FrameRate: %4.2f\n", fDisp); + + // Print it + m_pDisplayManager->DrawText2D(strBuffer, CVector(0.76f, 0.23f, 0), 1.0f, 0xFFFFFFFF); +} + +#ifdef MTA_DEBUG + +void CClientGame::DrawTasks(CClientPlayer* pPlayer) +{ + CTask* pTask = NULL; + CTask* pSubTask = NULL; + + // Got a local player model + if (pPlayer) + { + CTaskManager* man = pPlayer->GetTaskManager(); + if (man == NULL) + return; + if ((unsigned long)man == 0xDDDDDDDD) + { + m_pDisplayManager->DrawText2D("HELP! MANAGER FUCKED", CVector(0.05f, 0.5f, 0), 1.0f); + return; + } + + // Grab the current task + SString strOutput; + SString strSubOutput; + + pTask = man->GetTask(TASK_PRIORITY_PHYSICAL_RESPONSE); + strOutput += SString("Physical Response: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_TEMP); + strOutput += SString("Event Response Temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_NONTEMP); + strOutput += SString("Event Response Non-temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_PRIMARY); + strOutput += SString("Primary: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_DEFAULT); + strOutput += SString("Default: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_ATTACK); + strOutput += SString("Secondary Attack: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_DUCK); + strOutput += SString("Secondary Duck: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_SAY); + strOutput += SString("Secondary Say: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX); + strOutput += SString("Secondary Facial Complex: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM); + strOutput += SString("Secondary Partial Anim: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_IK); + strOutput += SString("Secondary IK: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + m_pDisplayManager->DrawText2D(strOutput, CVector(0.05f, 0.5f, 0), 1.0f); + m_pDisplayManager->DrawText2D(strSubOutput, CVector(0.5f, 0.5f, 0), 1.0f); + } +} + +int iPlayerTask = 0; +void CClientGame::DrawPlayerDetails(CClientPlayer* pPlayer) +{ + // Get the info + CControllerState cs; + + pPlayer->GetControllerState(cs); + + CVector vecPosition; + pPlayer->GetPosition(vecPosition); + + float fRotation = pPlayer->GetCurrentRotation(); + float fCameraRotation = pPlayer->GetCameraRotation(); + float fHealth = pPlayer->GetHealth(); + bool bIsDucked = pPlayer->IsDucked(); + bool bWearingGoggles = pPlayer->IsWearingGoggles(); + bool bInVehicle = pPlayer->GetOccupiedVehicle() != NULL; + float fWeaponRange = 0.0f; + + unsigned char ucWeapon = 0; + unsigned char ucWeaponState = 0; + unsigned short usWeaponAmmo = 0; + CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); + if (pWeapon) + { + ucWeapon = static_cast(pWeapon->GetType()); + ucWeaponState = static_cast(pWeapon->GetState()); + usWeaponAmmo = static_cast(pWeapon->GetAmmoInClip()); + float fSkill = pPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(pWeapon->GetType())); + CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(pWeapon->GetType(), fSkill); + fWeaponRange = pWeaponInfo->GetWeaponRange(); + } + + float fAimX, fAimY; + pPlayer->GetAim(fAimX, fAimY); + const CVector& vecAimSource = pPlayer->GetAimSource(); + const CVector& vecAimTarget = pPlayer->GetAimTarget(); + unsigned char ucDrivebyAim = pPlayer->GetVehicleAimAnim(); + + g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x10DE1212, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x90DE1212, false); + + CTask* pPrimaryTask = pPlayer->GetCurrentPrimaryTask(); + int iPrimaryTask = pPrimaryTask ? pPrimaryTask->GetTaskType() : -1; + + // Copy the stuff + SString strBuffer( + "Orient:\n" + "Position: %f %f %f\n" + "Rotation/camera: %f %f\n" + "Health: %f\n" + "\n" + "Keys:\n" + "LeftShoulder1: %hi\n" + "RightShoulder1: %hi\n" + "ButtonSquare: %hi\n" + "ButtonCross: %hi\n" + "ButtonCircle: %hi\n" + "ShockButtonL: %hi\n" + "PedWalk: %hi\n" + "VehicleMouseLook: %hi\n" + "LeftStickX: %hi\n" + "LeftStickY: %hi\n" + "\n" + "Misc:\n" + "Primary task: %d\n" + "Ducked: %u\n" + "Goggles: %u\n" + "In vehicle: %u\n" + "Weapon: %u\n" + "Weapon state: %u\n" + "Weapon ammo: %u\n" + "Weapon range: %f\n" + "Aim: %f %f\n" + "Aim source: %f %f %f\n" + "Aim target: %f %f %f\n" + "Driveby aim: %u\n" + "Frozen: %u\n", + vecPosition.fX, vecPosition.fY, vecPosition.fZ, fRotation, fCameraRotation, fHealth, cs.LeftShoulder1, cs.RightShoulder1, cs.ButtonSquare, + cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.m_bPedWalk, cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, iPrimaryTask, bIsDucked, + bWearingGoggles, bInVehicle, ucWeapon, ucWeaponState, usWeaponAmmo, fWeaponRange, fAimX, fAimY, vecAimSource.fX, vecAimSource.fY, vecAimSource.fZ, + vecAimTarget.fX, vecAimTarget.fY, vecAimTarget.fZ, ucDrivebyAim, pPlayer->IsFrozen()); + + // Draw it + m_pDisplayManager->DrawText2D(strBuffer, CVector(0.45f, 0.05f, 0), 1.0f, 0xFFFFFFFF); +} + +void CClientGame::DrawWeaponsyncData(CClientPlayer* pPlayer) +{ + CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); + + if (pWeapon) + { + CVector vecSource; + CVector vecTarget; + + // red line: Draw their synced aim line + pPlayer->GetShotData(&vecSource, &vecTarget); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x10DE1212, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x90DE1212, false); + + // green line: Set muzzle as origin and perform a collision test for the target + CColPoint* pCollision; + CVector vecTemp; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecSource, &vecTarget, &pCollision, NULL); + if (pCollision) + { + if (bCollision) + { + CVector vecBullet = pCollision->GetPosition() - vecSource; + vecBullet.Normalize(); + CVector vecTarget = vecSource + (vecBullet * 200); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x1012DE12, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x9012DE12, false); + } + pCollision->Destroy(); + } + + if (m_pLocalPlayer != pPlayer) + { + // Draw information about their weapon state, total ammo and ammo in clip + CVector vecScreenPosition; + CVector vecPosition; + + pPlayer->GetPosition(vecPosition); + + vecPosition.fZ += 1.0f; + g_pCore->GetGraphics()->CalcScreenCoors(&vecPosition, &vecScreenPosition); + + SString strTemp; + int yoffset; + + yoffset = 0; + strTemp.Format("Ammo in clip: %d", pWeapon->GetAmmoInClip()); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + + yoffset = 15; + strTemp.Format("State: %d", pWeapon->GetState()); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + } + } +} + +void CClientGame::UpdateMimics(void) +{ + // Got a local player? + if (m_pLocalPlayer) + { + unsigned char ucWeaponType = 0; + unsigned char ucWeaponState = 0; + unsigned long ulWeaponAmmoInClip = 0; + eWeaponSlot weaponSlot = WEAPONSLOT_TYPE_UNARMED; + + CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(m_pLocalPlayer->GetCurrentWeaponSlot()); + if (pPlayerWeapon) + { + ucWeaponType = static_cast(pPlayerWeapon->GetType()); + ucWeaponState = static_cast(pPlayerWeapon->GetState()); + weaponSlot = pPlayerWeapon->GetSlot(); + ulWeaponAmmoInClip = pPlayerWeapon->GetAmmoInClip(); + } + + // Simulate lag (or not) + if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) + { + m_ulLastMimicLag = CClientTime::GetTime(); + + // Grab the local data + CControllerState Controller; + m_pLocalPlayer->GetControllerState(Controller); + CVector vecPosition; + m_pLocalPlayer->GetPosition(vecPosition); + float fRotation = m_pLocalPlayer->GetCurrentRotation(); + CVector vecMoveSpeed; + m_pLocalPlayer->GetMoveSpeed(vecMoveSpeed); + float fHealth = m_pLocalPlayer->GetHealth(); + float fArmor = m_pLocalPlayer->GetArmor(); + float fCameraRotation = g_pGame->GetCamera()->GetCameraRotation(); + bool bDucked = m_pLocalPlayer->IsDucked(); + bool bWearingGoggles = m_pLocalPlayer->IsWearingGoggles(true); + bool bHasJetpack = m_pLocalPlayer->HasJetPack(); + bool bChoking = m_pLocalPlayer->IsChoking(); + bool bSunbathing = m_pLocalPlayer->IsSunbathing(); + bool bDoingDriveby = m_pLocalPlayer->IsDoingGangDriveby(); + bool bStealthAiming = m_pLocalPlayer->IsStealthAiming(); + + // Is the current weapon goggles (44 or 45) or a camera (43), or a detonator (40), don't apply the fire key + if (weaponSlot == 11 || weaponSlot == 12 || ucWeaponType == 43) + Controller.ButtonCircle = 0; + + CClientVehicle* pVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + unsigned int uiSeat = m_pLocalPlayer->GetOccupiedVehicleSeat(); + + CShotSyncData* pShotSync = g_pMultiplayer->GetLocalShotSyncData(); + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + float fAimX = pShotSync->m_fArmDirectionX; + float fAimY = pShotSync->m_fArmDirectionY; + char cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; + bool bAkimboUp = g_pMultiplayer->GetAkimboTargetUp(); + + /* + static CClientMarker *pOriginCorona = NULL, *pTargetCorona = NULL; + if ( pOriginCorona == NULL ) + { + pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); + pOriginCorona->SetColor ( 0, 255, 0, 255 ); + pOriginCorona->SetSize ( 0.5f ); + } + else + pOriginCorona->SetPosition ( vecOrigin ); + + if ( pTargetCorona == NULL ) + { + pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); + pTargetCorona->SetColor ( 255, 0, 0, 255 ); + pTargetCorona->SetSize ( 0.5f ); + } + else + pTargetCorona->SetPosition ( vecTarget );*/ + + // Apply this to each of our mimic players + unsigned int uiMimicIndex = 0; + list::const_iterator iterMimics = m_Mimics.begin(); + for (; iterMimics != m_Mimics.end(); ++iterMimics, ++uiMimicIndex) + { + vecPosition.fX += 4.0f; + vecOrigin.fX += 4.0f; + vecTarget.fX += 4.0f; + + CClientPlayer* pMimic = *iterMimics; + + pMimic->SetHealth(fHealth); + pMimic->LockHealth(fHealth); + pMimic->SetArmor(fArmor); + pMimic->LockArmor(fArmor); + pMimic->SetWearingGoggles(bWearingGoggles); + pMimic->SetHasJetPack(bHasJetpack); + pMimic->SetChoking(bChoking); + pMimic->SetSunbathing(bSunbathing); + pMimic->SetDoingGangDriveby(bDoingDriveby); + pMimic->SetStealthAiming(bStealthAiming); + + Controller.ShockButtonL = 0; + + if (m_bMimicLag) + { + pMimic->SetTargetPosition(vecPosition, TICK_RATE); + pMimic->SetMoveSpeed(vecMoveSpeed); + pMimic->SetControllerState(Controller); + pMimic->SetTargetRotation(fRotation); + pMimic->SetCameraRotation(fCameraRotation); + pMimic->Duck(bDucked); + } + else + { + pMimic->SetPosition(vecPosition); + pMimic->SetMoveSpeed(vecMoveSpeed); + pMimic->SetTargetRotation(fRotation); + pMimic->SetCameraRotation(fCameraRotation); + pMimic->SetControllerState(Controller); + pMimic->Duck(bDucked); + } + + if (ucWeaponType != 0) + { + if (ucWeaponType == 44 || ucWeaponType == 45) + { + Controller.ButtonCircle = 0; + } + + if (m_bMimicLag) + { + pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); + pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); + + pMimic->AddChangeWeapon(TICK_RATE, weaponSlot, (unsigned char)ulWeaponAmmoInClip); + } + else + { + CWeapon* pPlayerWeapon = pMimic->GetWeapon(); + eWeaponType eCurrentWeapon = static_cast(ucWeaponType); + if ((pPlayerWeapon && pPlayerWeapon->GetType() != eCurrentWeapon) || !pPlayerWeapon) + { + pPlayerWeapon = pMimic->GiveWeapon(eCurrentWeapon, ulWeaponAmmoInClip); + if (pPlayerWeapon) + { + pPlayerWeapon->SetAsCurrentWeapon(); + } + } + + if (pPlayerWeapon) + { + pPlayerWeapon->SetAmmoTotal(9999); + pPlayerWeapon->SetAmmoInClip(ulWeaponAmmoInClip); + pPlayerWeapon->SetState(static_cast(ucWeaponState)); + } + pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); + pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); + } + } + else + { + pMimic->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); + } + + CClientVehicle* pMimicVehicle = pMimic->GetOccupiedVehicle(); + if (pVehicle) + { + unsigned int uiModel; + CVector vecPosition, vecRotationDegrees; + CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; + float fHealth; + + uiModel = pVehicle->GetModel(); + pVehicle->GetPosition(vecPosition); + pVehicle->GetRotationDegrees(vecRotationDegrees); + pVehicle->GetMoveSpeed(vecMoveSpeed); + pVehicle->GetTurnSpeed(vecTurnSpeed); + fHealth = pVehicle->GetHealth(); + + if (pMimicVehicle && pMimicVehicle->GetModel() != uiModel) + { + delete pMimicVehicle; + pMimicVehicle = NULL; + } + + vecPosition.fX += ((float)(uiMimicIndex + 1) * 10.0f); + + if (pMimicVehicle == NULL) + { + pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, uiModel, 0, 0); + pMimicVehicle->SetPosition(vecPosition); + + const SSlotStates& usUpgrades = pVehicle->GetUpgrades()->GetSlotStates(); + for (unsigned char uc = 0; uc < VEHICLE_UPGRADE_SLOTS; uc++) + { + if (usUpgrades[uc]) + { + pMimicVehicle->GetUpgrades()->AddUpgrade(usUpgrades[uc], true); + } + } + + m_vecLastMimicPos = vecPosition; + } + + if (m_bMimicLag) + { + pMimicVehicle->SetTargetPosition(vecPosition, TICK_RATE); + pMimicVehicle->SetTargetRotation(vecRotationDegrees, TICK_RATE); + pMimicVehicle->SetMoveSpeed(vecMoveSpeed); + pMimicVehicle->SetTurnSpeed(vecTurnSpeed); + } + else + { + pMimicVehicle->SetPosition(vecPosition); + pMimicVehicle->SetRotationDegrees(vecRotationDegrees); + pMimicVehicle->SetMoveSpeed(vecMoveSpeed); + pMimicVehicle->SetTurnSpeed(vecTurnSpeed); + } + pMimicVehicle->SetHealth(fHealth); + if (pMimic->GetOccupiedVehicle() != pMimicVehicle) + pMimic->WarpIntoVehicle(pMimicVehicle, uiSeat); + + unsigned int uiTrailerLoop = 0; + CClientVehicle* pTrailer = pVehicle->GetTowedVehicle(); + CClientVehicle* pMimicTrailer = NULL; + while (pTrailer) + { + uiModel = pTrailer->GetModel(); + pTrailer->GetPosition(vecPosition); + pTrailer->GetRotationDegrees(vecRotationDegrees); + pTrailer->GetMoveSpeed(vecMoveSpeed); + pTrailer->GetTurnSpeed(vecTurnSpeed); + fHealth = pTrailer->GetHealth(); + + pMimicTrailer = DynamicCast(CElementIDs::GetElement(static_cast(450 + uiMimicIndex + uiTrailerLoop))); + + if (pMimicTrailer && pMimicTrailer->GetModel() != uiModel) + { + delete pMimicTrailer; + pMimicTrailer = NULL; + } + + if (!pMimicTrailer) + { + pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, + static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); + pMimicVehicle->SetTowedVehicle(pMimicTrailer); + } + + pTrailer = pTrailer->GetTowedVehicle(); + pMimicTrailer = pMimicTrailer->GetTowedVehicle(); + uiTrailerLoop++; + } + if (pMimicTrailer) + { + if (pMimicTrailer->GetTowedByVehicle()) + { + pMimicTrailer->GetTowedByVehicle()->SetTowedVehicle(NULL); + } + } + } + else if (pMimicVehicle) + { + pMimic->RemoveFromVehicle(); + delete pMimicVehicle; + } + } + } + } +} + +void CClientGame::DoPaintballs(void) +{ + if (m_pLocalPlayer) + { + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + + CColPoint* pCollision = NULL; + CEntity* pCollisionEntity = NULL; + m_pLocalPlayer->WorldIgnore(true); + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionEntity); + m_pLocalPlayer->WorldIgnore(false); + + static list paintBalls; + if (paintBalls.size() >= 5) + { + CClientMarker* pCorona = paintBalls.back(); + delete pCorona; + paintBalls.pop_back(); + } + + CClientMarker* pCorona = new CClientMarker(m_pManager, INVALID_ELEMENT_ID, CClientMarker::MARKER_CORONA); + paintBalls.push_front(pCorona); + pCorona->SetSize(0.2f); + if (bCollision && pCollision) + { + pCorona->SetPosition(pCollision->GetPosition()); + pCorona->SetColor(SColorRGBA(255, 0, 0, 255)); + } + else + { + pCorona->SetPosition(vecTarget); + pCorona->SetColor(SColorRGBA(255, 255, 0, 255)); + } + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + } +} + +#endif + +void CClientGame::QuitPlayer(CClientPlayer* pPlayer, eQuitReason Reason) +{ + // Get the nick pointer and echo the quit message to the chat + const char* szNick = pPlayer->GetNick(); + const char* szReason = "Unknown"; + switch (Reason) + { + case QUIT_QUIT: + szReason = "Quit"; + break; + case QUIT_KICK: + szReason = "Kicked"; + break; + case QUIT_BAN: + szReason = "Banned"; + break; + case QUIT_CONNECTION_DESYNC: + szReason = "Bad Connection"; + break; + case QUIT_TIMEOUT: + szReason = "Timed Out"; + break; + } + + // In debug, make sure we don't look at this player's details +#ifdef MTA_DEBUG + if (m_pShowPlayer == pPlayer) + { + m_pShowPlayer = NULL; + } +#endif + + // Call our onClientPlayerQuit event + CLuaArguments Arguments; + Arguments.PushString(szReason); + pPlayer->CallEvent("onClientPlayerQuit", Arguments, true); + + // Detach the camera from this player if we're watching them + m_pManager->GetCamera()->UnreferencePlayer(pPlayer); + + // Was this player jacking us? + if (m_bIsGettingJacked && m_pGettingJackedBy == pPlayer) + { + ResetVehicleInOut(); + m_pLocalPlayer->RemoveFromVehicle(false); + m_pLocalPlayer->SetVehicleInOutState(VEHICLE_INOUT_NONE); + } + + // Delete the player + delete pPlayer; +} + +void CClientGame::Event_OnIngame(void) +{ + // Unpause the game + g_pGame->Pause(false); + + // Disable parts of the Hud + CHud* pHud = g_pGame->GetHud(); + pHud->SetComponentVisible(HUD_HELP_TEXT, false); + pHud->SetComponentVisible(HUD_VITAL_STATS, false); + pHud->SetComponentVisible(HUD_AREA_NAME, false); + + g_pMultiplayer->DeleteAndDisableGangTags(); + + // Switch off peds and traffic + SFixedArray vecs = {CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), + CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0)}; + g_pGame->GetPathFind()->SwitchRoadsOffInArea(&vecs[0], &vecs[1]); + g_pGame->GetPathFind()->SwitchPedRoadsOffInArea(&vecs[2], &vecs[3]); + g_pGame->GetPathFind()->SetPedDensity(0.0f); + g_pGame->GetPathFind()->SetVehicleDensity(0.0f); + + g_pGame->GetWorld()->ClearRemovedBuildingLists(); + g_pGame->GetWorld()->SetOcclusionsEnabled(true); + + g_pGame->ResetModelLodDistances(); + g_pGame->ResetAlphaTransparencies(); + + // Make sure we can access all areas + g_pGame->GetStats()->ModifyStat(CITIES_PASSED, 2.0); + + // This is to prevent the 'white arrows in checkpoints' bug (#274) + g_pGame->Get3DMarkers()->CreateMarker(87654, (e3DMarkerType)5, &vecs[4], 1, 0.2f, 0, 0, 0, 0); + + // Stop us getting 4 stars if we visit the SF or LV + // g_pGame->GetPlayerInfo()->GetWanted()->SetMaximumWantedLevel ( 0 ); + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(0); + + // Reset anything from last game + ResetMapInfo(); + g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level + g_pGame->GetWaterManager()->SetWaterDrawnLast(true); + m_pCamera->SetCameraClip(true, true); + + // Create a local player for us + m_pLocalPlayer = new CClientPlayer(m_pManager, m_LocalID, true); + if (m_pLocalPlayer) + { + // Set our parent the root entity + m_pLocalPlayer->SetParent(m_pRootEntity); + + // Give the local player our nickname + m_pLocalPlayer->SetNick(m_strLocalNick); + + // Freeze the player at some location we won't see + m_pLocalPlayer->SetHealth(100); + m_pLocalPlayer->SetPosition(CVector(0, 0, 0)); + m_pLocalPlayer->SetFrozen(true); + m_pLocalPlayer->ResetInterpolation(); + + // Reset him + m_pLocalPlayer->ResetStats(); + } + else + { + RaiseFatalError(2); + } + + // Make sure we never get tired + g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true); + + // Tell doggy we got the game running + WatchDogCompletedSection("L1"); +} + +void CClientGame::Event_OnIngameAndConnected(void) +{ + m_ulVerifyTimeStart = CClientTime::GetTime(); + + // Keep criminal records of how many times they've connected to servers + SetApplicationSettingInt("times-connected", GetApplicationSettingInt("times-connected") + 1); + if (m_ServerType == SERVER_TYPE_EDITOR) + SetApplicationSettingInt("times-connected-editor", GetApplicationSettingInt("times-connected-editor") + 1); + + // Notify the server telling we're ingame + m_pNetAPI->RPC(PLAYER_INGAME_NOTICE); +} + +bool CClientGame::StaticBreakTowLinkHandler(CVehicle* pTowingVehicle) +{ + return g_pClientGame->BreakTowLinkHandler(pTowingVehicle); +} + +void CClientGame::StaticDrawRadarAreasHandler(void) +{ + g_pClientGame->DrawRadarAreasHandler(); +} + +bool CClientGame::StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent) +{ + return g_pClientGame->DamageHandler(pDamagePed, pEvent); +} + +void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart) +{ + g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart); +} + +void CClientGame::StaticFireHandler(CFire* pFire) +{ + g_pClientGame->FireHandler(pFire); +} + +void CClientGame::StaticRender3DStuffHandler(void) +{ + g_pClientGame->Render3DStuffHandler(); +} + +void CClientGame::StaticPreRenderSkyHandler(void) +{ + g_pClientGame->PreRenderSkyHandler(); +} + +void CClientGame::StaticRenderHeliLightHandler() +{ + g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); +} + +bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) +{ + return g_pClientGame->ChokingHandler(ucWeaponType); +} + +void CClientGame::StaticCAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) +{ + g_pClientGame->CAnimBlendAssocDestructorHandler(pThis); +} + +CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) +{ + return g_pClientGame->AddAnimationHandler(pClump, animGroup, animID); +} + +CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, + AssocGroupId animGroup, AnimationId animID) +{ + return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); +} + +bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) +{ + return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); +} + +bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, + int* pFlags, RpClump* pClump) +{ + return g_pClientGame->BlendAnimationHierarchyHandler(pAnimAssoc, pOutAnimHierarchy, pFlags, pClump); +} + +void CClientGame::StaticPreWorldProcessHandler(void) +{ + g_pClientGame->PreWorldProcessHandler(); +} + +void CClientGame::StaticPostWorldProcessHandler(void) +{ + g_pClientGame->PostWorldProcessHandler(); +} + +void CClientGame::StaticPreFxRenderHandler(void) +{ + g_pCore->OnPreFxRender(); +} + +void CClientGame::StaticPreHudRenderHandler(void) +{ + g_pCore->OnPreHUDRender(); +} + +bool CClientGame::StaticProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) +{ + return g_pClientGame->ProcessCollisionHandler(pThisInterface, pOtherInterface); +} + +bool CClientGame::StaticVehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, + float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, + CVector vecCollisionVelocity) +{ + return g_pClientGame->VehicleCollisionHandler(pCollidingVehicle, pCollidedVehicle, iModelIndex, fDamageImpulseMag, fCollidingDamageImpulseMag, usPieceType, + vecCollisionPos, vecCollisionVelocity); +} + +bool CClientGame::StaticVehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, + const CVector& vecDamagePos, uchar ucTyre) +{ + return g_pClientGame->VehicleDamageHandler(pVehicleInterface, fLoss, pAttackerInterface, weaponType, vecDamagePos, ucTyre); +} + +bool CClientGame::StaticHeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) +{ + return g_pClientGame->HeliKillHandler(pHeliInterface, pHitInterface); +} + +bool CClientGame::StaticObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) +{ + return g_pClientGame->ObjectDamageHandler(pObjectInterface, fLoss, pAttackerInterface); +} + +bool CClientGame::StaticObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) +{ + return g_pClientGame->ObjectBreakHandler(pObjectInterface, pAttackerInterface); +} + +bool CClientGame::StaticWaterCannonHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) +{ + return g_pClientGame->WaterCannonHitHandler(pCannonVehicle, pHitPed); +} + +bool CClientGame::StaticVehicleFellThroughMapHandler(CVehicleSAInterface* pVehicle) +{ + return g_pClientGame->VehicleFellThroughMapHandler(pVehicle); +} + +void CClientGame::StaticGameObjectDestructHandler(CEntitySAInterface* pObject) +{ + g_pClientGame->GameObjectDestructHandler(pObject); +} + +void CClientGame::StaticGameVehicleDestructHandler(CEntitySAInterface* pVehicle) +{ + g_pClientGame->GameVehicleDestructHandler(pVehicle); +} + +void CClientGame::StaticGamePlayerDestructHandler(CEntitySAInterface* pPlayer) +{ + g_pClientGame->GamePlayerDestructHandler(pPlayer); +} + +void CClientGame::StaticGameProjectileDestructHandler(CEntitySAInterface* pProjectile) +{ + g_pClientGame->GameProjectileDestructHandler(pProjectile); +} + +void CClientGame::StaticGameModelRemoveHandler(ushort usModelId) +{ + g_pClientGame->GameModelRemoveHandler(usModelId); +} + +void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) +{ + if (pGameEntity) + { + // Map to client entity and pass to the texture replacer + CClientEntity* pClientEntity = g_pClientGame->GetGameEntityXRefManager()->FindClientEntity(pGameEntity); + if (pClientEntity) + { + int iTypeMask; + ushort usModelId = 0xFFFF; + switch (pClientEntity->GetType()) + { + case CCLIENTPED: + case CCLIENTPLAYER: + iTypeMask = TYPE_MASK_PED; + usModelId = (ushort) static_cast(pClientEntity)->GetModel(); + break; + case CCLIENTVEHICLE: + iTypeMask = TYPE_MASK_VEHICLE; + break; + case CCLIENTOBJECT: + iTypeMask = TYPE_MASK_OBJECT; + break; + default: + iTypeMask = TYPE_MASK_OTHER; + break; + } + g_pGame->GetRenderWare()->SetRenderingClientEntity(pClientEntity, usModelId, iTypeMask); + return; + } + } + + g_pGame->GetRenderWare()->SetRenderingClientEntity(NULL, 0xFFFF, TYPE_MASK_WORLD); +} + +void CClientGame::StaticTaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) +{ + g_pClientGame->TaskSimpleBeHitHandler(pPedAttacker, hitBodyPart, hitBodySide, weaponId); +} + +void CClientGame::StaticFxSystemDestructionHandler(void* pFxSAInterface) +{ + g_pClientGame->GetManager()->GetEffectManager()->SAEffectDestroyed(pFxSAInterface); +} + +AnimationId CClientGame::StaticDrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId) +{ + return g_pClientGame->DrivebyAnimationHandler(animGroup, animId); +} + +void CClientGame::DrawRadarAreasHandler(void) +{ + m_pRadarAreaManager->DoPulse(); +} + +bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle) +{ + CClientVehicle* pVehicle = m_pVehicleManager->Get(pTowedVehicle, false); + if (pVehicle) + { + // Check if this is a legal break + bool bLegal = ((pVehicle->GetControllingPlayer() == m_pLocalPlayer) || (m_pUnoccupiedVehicleSync->Exists(static_cast(pVehicle)))); + + // Not a legal break? + if (!bLegal) + { + // Save the time it broke (used in UpdateTrailers) + pVehicle->SetIllegalTowBreakTime(GetTickCount32()); + } + } + + // Allow it to break + return true; +} + +void CClientGame::FireHandler(CFire* pFire) +{ + // Disable spreading fires + pFire->SetNumGenerationsAllowed(0); +} + +void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) +{ + if (pProjectile->IsLocal()) + { + // Did the local player create this projectile? + if (m_pLocalPlayer && pProjectile->GetCreator() == m_pLocalPlayer) + { + // Physics says our projectile should start off at our velocity + CVector vecVelocity, vecPlayerVelocity; + pProjectile->GetVelocity(vecVelocity); + m_pLocalPlayer->GetMoveSpeed(vecPlayerVelocity); + vecVelocity += vecPlayerVelocity; + pProjectile->SetVelocity(vecVelocity); + } + + SendProjectileSync(pProjectile); + } + + // Renew the interior and dimension + if (pProjectile->GetCreator()) + { + pProjectile->SetInterior(pProjectile->GetCreator()->GetInterior()); + pProjectile->SetDimension(pProjectile->GetCreator()->GetDimension()); + } + + // Validate the projectile for our element tree + pProjectile->SetParent(m_pRootEntity); + + // Call our creation event + CLuaArguments Arguments; + Arguments.PushElement(pProjectile->GetCreator()); + pProjectile->CallEvent("onClientProjectileCreation", Arguments, true); +} + +void CClientGame::Render3DStuffHandler(void) +{ +} + +void CClientGame::PreRenderSkyHandler(void) +{ + g_pCore->GetGraphics()->GetRenderItemManager()->PreDrawWorld(); +} + +void CClientGame::PreWorldProcessHandler(void) +{ +} + +void CClientGame::PostWorldProcessHandler(void) +{ + m_pManager->GetMarkerManager()->DoPulse(); + m_pManager->GetPointLightsManager()->DoPulse(); + m_pManager->GetObjectManager()->DoPulse(); + + // Update frame time slice + uint uiCurrentTick = GetTickCount32(); + if (m_uiLastFrameTick) + { + m_uiFrameTimeSlice = uiCurrentTick - m_uiLastFrameTick; + m_uiFrameCount++; + + // Call onClientPreRender LUA event + CLuaArguments Arguments; + Arguments.PushNumber(m_uiFrameTimeSlice); + m_pRootEntity->CallEvent("onClientPreRender", Arguments, false); + } + m_uiLastFrameTick = uiCurrentTick; +} + +void CClientGame::IdleHandler(void) +{ + // If we are minimized we do the pulsing here + if (g_pCore->IsWindowMinimized()) + { + if (!m_bWasMinimized) + { + m_bWasMinimized = true; + // Call onClientMinimize LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); + + bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); + + // Apply mute on minimize options + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) + g_pGame->GetAudio()->SetMusicMasterVolume(0); + + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) + g_pGame->GetAudio()->SetEffectsMasterVolume(0); + + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) + m_pManager->GetSoundManager()->SetMinimizeMuted(true); + } + } + + // Ensure dummy progress graphic will be displayed when using alt pulse order + g_pCore->SetDummyProgressUpdateAlways(true); + + // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) + DoPulses2(true); + + g_pCore->SetDummyProgressUpdateAlways(false); +} + +bool CClientGame::ChokingHandler(unsigned char ucWeaponType) +{ + if (!m_pLocalPlayer) + return true; + CLuaArguments Arguments; + Arguments.PushNumber(ucWeaponType); + return m_pLocalPlayer->CallEvent("onClientPlayerChoke", Arguments, true); +} + +void CClientGame::CAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) +{ + // printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID); + RemoveAnimationAssociationFromMap(pThis); +} + +CAnimBlendAssociationSAInterface* CClientGame::AddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) +{ + // printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); + return nullptr; +} + +CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, + AssocGroupId animGroup, AnimationId animID) +{ + // printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); + return nullptr; +} + +bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) +{ + bool isCustomAnimationToPlay = false; + CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); + auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); + auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); + auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); + auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); + + CClientPed* pClientPed = GetClientPedByClump(*pClump); + if (pClientPed != nullptr) + { + auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); + if (pReplacedAnimation != nullptr) + { + std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); + InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); + + // Play our custom animation instead of default + auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); + pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); + pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); + pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); + isCustomAnimationToPlay = true; + } + } + + if (!isCustomAnimationToPlay) + { + auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); + + // Play default internal animation + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); + } + return isCustomAnimationToPlay; +} + +bool CClientGame::BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags, + RpClump* pClump) +{ + bool isCustomAnimationToPlay = false; + CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); + CClientPed* pClientPed = GetClientPedByClump(*pClump); + if (pClientPed != nullptr) + { + if (pClientPed->IsNextAnimationCustom()) + { + std::shared_ptr pIFP = pClientPed->GetCustomAnimationIFP(); + if (pIFP) + { + const SString& strAnimationName = pClientPed->GetNextAnimationCustomName(); + auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy(strAnimationName); + if (pCustomAnimBlendHierarchy != nullptr) + { + std::shared_ptr pIFPAnimations = pIFP->GetIFPAnimationsPointer(); + InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); + + pClientPed->SetCurrentAnimationCustom(true); + pClientPed->SetNextAnimationNormal(); + + if (pIFP->IsUnloading()) + { + pClientPed->DereferenceCustomAnimationBlock(); + } + *pOutAnimHierarchy = pCustomAnimBlendHierarchy; + isCustomAnimationToPlay = true; + return isCustomAnimationToPlay; + } + } + } + + pClientPed->SetCurrentAnimationCustom(false); + pClientPed->SetNextAnimationNormal(); + } + return isCustomAnimationToPlay; +} + +bool CClientGame::ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) +{ + if (pThisInterface == pOtherInterface) + return true; + + if (!m_BuiltCollisionMapThisFrame) + { + // Build a map of CPhysicalSAInterface*/CClientEntity*'s that have collision disabled + m_BuiltCollisionMapThisFrame = true; + m_CachedCollisionMap.clear(); + + std::map::iterator iter = m_AllDisabledCollisions.begin(); + for (; iter != m_AllDisabledCollisions.end(); ++iter) + { + CClientEntity* pEntity = iter->first; + CEntity* pGameEntity = pEntity->GetGameEntity(); + CEntitySAInterface* pInterface = pGameEntity ? pGameEntity->GetInterface() : NULL; + + if (pInterface) + m_CachedCollisionMap[pInterface] = pEntity; + } + } + + // Check both elements appear in the cached map before doing extra processing + std::map::iterator iter1 = m_CachedCollisionMap.find((CEntitySAInterface*)pThisInterface); + if (iter1 != m_CachedCollisionMap.end()) + { + std::map::iterator iter2 = m_CachedCollisionMap.find((CEntitySAInterface*)pOtherInterface); + if (iter2 != m_CachedCollisionMap.end()) + { + // Re-get the entity pointers using a safer method + CEntity* pGameEntity = g_pGame->GetPools()->GetEntity((DWORD*)pThisInterface); + CEntity* pGameColEntity = g_pGame->GetPools()->GetEntity((DWORD*)pOtherInterface); + + if (pGameEntity && pGameColEntity) + { + CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity, true); + CClientEntity* pColEntity = m_pManager->FindEntity(pGameColEntity, true); + + if (pEntity && pColEntity) + { + #if MTA_DEBUG + CClientEntity* ppThisEntity2 = iter1->second; + CClientEntity* ppOtherEntity2 = iter2->second; + // These should match, but its not essential. + assert(ppThisEntity2 == pEntity); + assert(ppOtherEntity2 == pColEntity); + #endif + if (!pEntity->IsCollidableWith(pColEntity)) + return false; + } + } + } + } + + return true; +} + +// +// On demand files +// +void CClientGame::DownloadSingularResourceFiles(void) +{ + if (!IsTransferringSingularFiles()) + return; + + if (!g_pNet->IsConnected()) + return; + + CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES); + if (!pHTTP->ProcessQueuedFiles()) + { + // Downloading + } + else + { + // Can't clear list until all files have been processed + if (m_pSingularFileDownloadManager->AllComplete()) + { + SetTransferringSingularFiles(false); + m_pSingularFileDownloadManager->ClearList(); + } + } +} + +// Get relevant death anim for animation purposes during death situation +void GetDeathAnim(CClientPed* pDamagedPed, CEventDamage* pEvent, AssocGroupId& outAnimGroup, AnimationId& outAnimID) +{ + if (pEvent) + { + pEvent->ComputeDeathAnim(pDamagedPed->GetGamePlayer(), false); + outAnimGroup = pEvent->GetAnimGroup(); + outAnimID = pEvent->GetAnimId(); + } + else + { + // Using same numbers as CClientGame::DoWastedCheck defaults + outAnimGroup = 0; + outAnimID = 15; + } +} + +// +// DamageHandler seems to be called 3 times for each bit of damage: +// +// pass 1 - preApplyDamage +// is pass 1 if: fDamage == zero && fCurrentHealth == fPreviousHealth +// returning false stops any damage being inflicted +// returning true applies damage and allows pass 2 +// pass 2 - postApplyDamage/preApplyAnim +// is pass 2 if: fDamage > zero && fCurrentHealth != fPreviousHealth +// returning false stops damage anim +// returning true allows damage anim and allows pass 3 +// pass 3 - postApplyAnim +// is pass 3 if: fDamage > zero && fCurrentHealth == fPreviousHealth +// returning false ?? +// returning true ?? +// +bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) +{ + // CEventDamage::AffectsPed: This is/can be called more than once for each bit of damage (and may not actually take any more health (even if we return + // true)) + + // Grab some data from the event + CEntity* pInflictor = pEvent->GetInflictingEntity(); + eWeaponType weaponUsed = pEvent->GetWeaponUsed(); + ePedPieceTypes hitZone = pEvent->GetPedPieceType(); + CWeaponInfo* pWeaponInfo = g_pGame->GetWeaponInfo(weaponUsed); + float fDamage = pEvent->GetDamageApplied(); + EDamageReasonType damageReason = pEvent->GetDamageReason(); + + /* Causes too much desync right now + // Is this shotgun damage? + if ( weaponUsed == WEAPONTYPE_SHOTGUN || weaponUsed == WEAPONTYPE_SPAS12_SHOTGUN ) + { + // Make the ped fall down + pEvent->MakePedFallDown (); + } */ + + // Grab the damaged ped + CClientPed* pDamagedPed = NULL; + if (pDamagePed) + pDamagedPed = m_pPedManager->Get(dynamic_cast(pDamagePed), true, true); + + // Grab the inflictor + CClientEntity* pInflictingEntity = NULL; + if (pInflictor) + pInflictingEntity = m_pManager->FindEntity(pInflictor, true); + + // If the damage was caused by an explosion + if (weaponUsed == WEAPONTYPE_EXPLOSION) + { + CClientEntity* pLastExplosionCreator = m_pManager->GetExplosionManager()->m_pLastCreator; + + // If we don't have an inflictor, look for the last explosion creator + if (!pInflictor && pLastExplosionCreator) + pInflictingEntity = pLastExplosionCreator; + + // Change the weapon used to whatever created the explosion + weaponUsed = m_pManager->GetExplosionManager()->m_LastWeaponType; + } + + // Do we have a damaged ped? + if (pDamagedPed) + { + /////////////////////////////////////////////////////////////////////////// + // + // Pass 1 stuff + // + // return false to stop any damage being inflicted + // + /////////////////////////////////////////////////////////////////////////// + + // Pass 1 checks for double shots + if (fDamage == 0.0f && damageReason != EDamageReason::PISTOL_WHIP) + { + // Only check for remote players + CClientPlayer* pInflictingPlayer = DynamicCast(pInflictingEntity); + if (pInflictingPlayer && !pInflictingPlayer->IsLocalPlayer()) + { + bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon + bool bBulletSyncWeapon = GetWeaponTypeUsesBulletSync(weaponUsed); + + if (bBulletSyncShot) + { + if (g_iDamageEventLimit == 0) + { + AddReportLog(5501, SString("2nd pass 1 for BulletSyncShot damage. weaponUsed:%d", weaponUsed)); + return false; + } + g_iDamageEventLimit--; + if (!bBulletSyncWeapon) + { + AddReportLog(5502, SString("BulletSyncShot but not bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); + return false; + } + } + else + { + if (bBulletSyncWeapon) + { + AddReportLog(5503, SString("not BulletSyncShot but bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); + return false; + } + } + } + } + + // Is the damaged ped a player? + if (IS_PLAYER(pDamagedPed)) + { + CClientPlayer* pDamagedPlayer = static_cast(pDamagedPed); + + // Do we have an inflicting entity? + if (pInflictingEntity) + { + // Grab the inflicting player + CClientPlayer* pInflictingPlayer = NULL; + + switch (pInflictingEntity->GetType()) + { + case CCLIENTPLAYER: + { + pInflictingPlayer = static_cast(pInflictingEntity); + break; + } + case CCLIENTVEHICLE: + { + CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); + if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) + { + CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); + if (pPed && pPed->GetType() == CCLIENTPLAYER) + pInflictingPlayer = static_cast(pPed); + } + break; + } + default: + break; + } + if (pInflictingPlayer) + { + // Is the damaged player on a team + CClientTeam* pTeam = pDamagedPlayer->GetTeam(); + if (pTeam) + { + // Is this friendly-fire from a team-mate? + if (pDamagedPlayer->IsOnMyTeam(pInflictingPlayer) && !pTeam->GetFriendlyFire() && pDamagedPlayer != pInflictingPlayer) + return false; + } + } + } + } + /////////////////////////////////////////////////////////////////////////// + // Pass 1 end + /////////////////////////////////////////////////////////////////////////// + + return ApplyPedDamageFromGame(weaponUsed, fDamage, hitZone, pDamagedPed, pInflictingEntity, pEvent); + } + + // No damage anim for fire + if (weaponUsed == WEAPONTYPE_FLAMETHROWER) + return false; + + // Allow the damage processing to continue + return true; +} + +// +// Check GTA stored health with our stored health and do stuff +// +bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, uchar hitZone, CClientPed* pDamagedPed, CClientEntity* pInflictingEntity, + CEventDamage* pEvent) +{ + float fPreviousHealth = pDamagedPed->m_fHealth; + float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); + float fPreviousArmor = pDamagedPed->m_fArmor; + float fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); + + // Have we taken any damage here? + if ((fPreviousHealth != fCurrentHealth || fPreviousArmor != fCurrentArmor) && fDamage != 0.0f) + { + /////////////////////////////////////////////////////////////////////////// + /// + // Pass 2 stuff - (GTA has applied the damage) + // + // return false to stop damage anim (incl. death task) + // + /////////////////////////////////////////////////////////////////////////// + + g_fApplyDamageLastAmount = fDamage; + g_ucApplyDamageLastHitZone = hitZone; + g_pApplyDamageLastDamagedPed = pDamagedPed; + + CLuaArguments Arguments; + if (pInflictingEntity) + Arguments.PushElement(pInflictingEntity); + else + Arguments.PushBoolean(false); + Arguments.PushNumber(static_cast(weaponUsed)); + Arguments.PushNumber(static_cast(hitZone)); + Arguments.PushNumber(fDamage); + + // Call our event + if ((IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPlayerDamage", Arguments, true)) || + (!IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPedDamage", Arguments, true))) + { + // Stop here if they cancelEvent it + if (pDamagedPed->IsLocalPlayer()) + { + // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) + fPreviousHealth = pDamagedPed->m_fHealth; + fPreviousArmor = pDamagedPed->m_fArmor; + } + pDamagedPed->GetGamePlayer()->SetHealth(fPreviousHealth); + pDamagedPed->GetGamePlayer()->SetArmor(fPreviousArmor); + return false; + } + + if (pDamagedPed->IsLocalPlayer()) + { + // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) + fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); + fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); + } + + bool bIsBeingShotWhilstAiming = (weaponUsed >= WEAPONTYPE_PISTOL && weaponUsed <= WEAPONTYPE_MINIGUN && pDamagedPed->IsUsingGun()); + bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); + + bool bAllowChoke = true; + // Is this is a remote player? + if (!pDamagedPed->IsLocalPlayer()) + { + // Don't allow GTA to start the choking task + if (weaponUsed == WEAPONTYPE_TEARGAS || weaponUsed == WEAPONTYPE_SPRAYCAN || weaponUsed == WEAPONTYPE_EXTINGUISHER) + bAllowChoke = false; + } + + // Check if their health or armor is locked, and if so prevent applying the damage locally + if (pDamagedPed->IsHealthLocked() || pDamagedPed->IsArmorLocked()) + { + // Restore health+armor + pDamagedPed->GetGamePlayer()->SetHealth(pDamagedPed->GetHealth()); + pDamagedPed->GetGamePlayer()->SetArmor(pDamagedPed->GetArmor()); + + if (bOldBehaviour) + { + // Don't play the animation if it's going to be a death one, or if it's going to interrupt aiming + if (fCurrentHealth == 0.0f || bIsBeingShotWhilstAiming) + return false; + + // Allow animation for remote players (if currently we don't need block choke) + return bAllowChoke; + } + + // No hit animation for remote players + return false; + } + + // Update our stored health/armor + pDamagedPed->m_fHealth = fCurrentHealth; + pDamagedPed->m_fArmor = fCurrentArmor; + + ElementID damagerID = INVALID_ELEMENT_ID; + if (pInflictingEntity && !pInflictingEntity->IsLocalEntity()) + damagerID = pInflictingEntity->GetID(); + + // Is it the local player? + if (pDamagedPed->IsLocalPlayer()) + { + // Update our stored damage stuff + m_ucDamageWeapon = static_cast(weaponUsed); + m_ucDamageBodyPiece = static_cast(hitZone); + m_pDamageEntity = pInflictingEntity; + m_ulDamageTime = CClientTime::GetTime(); + m_DamagerID = damagerID; + m_bDamageSent = false; + } + // Does this damage kill the player? + if (fCurrentHealth == 0.0f) + { + if (pDamagedPed->GetType() == CCLIENTPLAYER) + { + // Is the local player dying? + if (pDamagedPed->IsLocalPlayer() && fPreviousHealth > 0.0f) + { + // Grab our death animation + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + + // Check if we're dead + DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); + } + + // Allow GTA to kill us if we've fell to our death + if (pDamagedPed->IsLocalPlayer() && weaponUsed == WEAPONTYPE_FALL) + return true; + + // Don't let GTA start the death task + return false; + } + else + { + if (pDamagedPed->IsLocalEntity() && fPreviousHealth > 0.0f) + { + // Client-side ped + pDamagedPed->CallEvent("onClientPedWasted", Arguments, true); + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + pDamagedPed->Kill(weaponUsed, hitZone, false, false, animGroup, animID); + return true; + } + if (fPreviousHealth > 0.0f) + { + // Grab our death animation + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + + SendPedWastedPacket(pDamagedPed, damagerID, weaponUsed, hitZone, animGroup, animID); + } + } + } + + // Disallow choke task if it's necessary + if (!bAllowChoke) + return false; + + // Inhibit hit-by-gun animation for local player if required + if (bOldBehaviour) + if (pDamagedPed->IsLocalPlayer() && bIsBeingShotWhilstAiming) + return false; + + /////////////////////////////////////////////////////////////////////////// + // Pass 2 end + /////////////////////////////////////////////////////////////////////////// + } + + // No damage anim for fire + if (weaponUsed == WEAPONTYPE_FLAMETHROWER) + return false; + + // Allow the damage processing to continue + return true; +} + +void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, unsigned char ucBodyPart) +{ + CClientPed* pKilledPed = m_pPedManager->Get(dynamic_cast(pKilledPedSA), true, true); + + if (!pKilledPed) + return; + + // Not required for remote players. Local player is handled in DoPulses->DoWastedCheck + if (IS_PLAYER(pKilledPed)) + return; + + // Set the health to zero (this is safe as GTA will do it anyway in a few ticks) + pKilledPed->SetHealth(0.0f); + + // Call Lua + CLuaArguments Arguments; + Arguments.PushBoolean(false); + Arguments.PushNumber(ucDeathReason); + Arguments.PushNumber(ucBodyPart); + + pKilledPed->CallEvent("onClientPedWasted", Arguments, true); + + // Notify the server + SendPedWastedPacket(pKilledPed, INVALID_ELEMENT_ID, ucDeathReason, ucBodyPart); +} + +bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, + float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) +{ + if (pCollidingVehicle && pCollidedWith) + { + CVehicle* pColliderVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidingVehicle); + CClientEntity* pVehicleClientEntity = m_pManager->FindEntity(pColliderVehicle, true); + if (pVehicleClientEntity) + { + CClientVehicle* pClientVehicle = static_cast(pVehicleClientEntity); + + CEntity* pCollidedWithEntity = g_pGame->GetPools()->GetEntity((DWORD*)pCollidedWith); + CClientEntity* pCollidedWithClientEntity = NULL; + if (pCollidedWithEntity) + { + if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pCollidedWithVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithVehicle, true); + } + else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_OBJECT) + { + CObject* pCollidedWithObject = g_pGame->GetPools()->GetObject((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithObject, true); + } + else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pCollidedWithPed = g_pGame->GetPools()->GetPed((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithPed, true); + } + } + CLuaArguments Arguments; + if (pCollidedWithClientEntity) + { + Arguments.PushElement(pCollidedWithClientEntity); + } + else + { + Arguments.PushNil(); + } + Arguments.PushNumber(fDamageImpulseMag); + Arguments.PushNumber(usPieceType); + Arguments.PushNumber(vecCollisionPos.fX); + Arguments.PushNumber(vecCollisionPos.fY); + Arguments.PushNumber(vecCollisionPos.fZ); + Arguments.PushNumber(vecCollisionVelocity.fX); + Arguments.PushNumber(vecCollisionVelocity.fY); + Arguments.PushNumber(vecCollisionVelocity.fZ); + Arguments.PushNumber(fCollidingDamageImpulseMag); + Arguments.PushNumber(iModelIndex); + + pVehicleClientEntity->CallEvent("onClientVehicleCollision", Arguments, true); + // Alocate a BitStream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + // Make sure it created + if (pBitStream) + { + if (pBitStream->Version() >= 0x028) + { + // Sync Stuff + // if it's not a local vehicle + it collided with the local player + if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) + { + // is it below the anti spam threshold? + if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) + { + // if there is no controlling player + if (!pClientVehicle->GetControllingPlayer()) + { + CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); + // if We aren't already syncing the vehicle + if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) + { + // Write the vehicle ID + pBitStream->Write(pVehicleClientEntity->GetID()); + // Send! + g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, + PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); + // Reset our push time + pClientVehicle->ResetLastPushTime(); + } + } + } + } + } + g_pNet->DeallocateNetBitStream(pBitStream); + } + return true; + } + } + return false; +} + +bool CClientGame::HeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) +{ + if (pHeliInterface && pHitInterface) + { + // Get our heli and client heli + CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); + CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); + if (pHeli && pClientHeli && pClientHeli->AreHeliBladeCollisionsEnabled()) + { + // Get our ped and client ped + CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitInterface); + CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); + // Was our client ped valid + if (pClientPed) + { + // Get our heli and client heli + CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); + CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); + + // Iterate our "stored" cancel state and find the heli in question + std::pair::iterator, std::multimap::iterator> iterators = + m_HeliCollisionsMap.equal_range(pClientHeli); + std::multimap::const_iterator iter = iterators.first; + for (; iter != iterators.second; ++iter) + { + // If the Heli and ped collided within the clear rate return false + if ((*iter).first == pClientHeli && (*iter).second == pClientPed) + return false; + } + + CLuaArguments Arguments; + if (pClientHeli) + { + // Push our heli + Arguments.PushElement(pClientHeli); + } + else + { + Arguments.PushNil(); + } + + // Trigger our event + bool bContinue; + if (IS_PLAYER(pClientPed)) + bContinue = pClientPed->CallEvent("onClientPlayerHeliKilled", Arguments, true); + else + bContinue = pClientPed->CallEvent("onClientPedHeliKilled", Arguments, true); + + // Was our event cancelled + if (!bContinue) + { + // Add our heli and ped pair to the list + std::pair pair = std::pair(pClientHeli, pClientPed); + m_HeliCollisionsMap.insert(pair); + } + // Return if it was cancelled + return bContinue; + } + } + else + { + return false; + } + } + return true; +} + +bool CClientGame::VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, + const CVector& vecDamagePos, uchar ucTyre) +{ + bool bAllowDamage = true; + CClientVehicle* pClientVehicle = GetGameEntityXRefManager()->FindClientVehicle(pVehicleInterface); + if (pClientVehicle) + { + CClientEntity* pClientAttacker = GetGameEntityXRefManager()->FindClientEntity(pAttackerInterface); + + // Compose arguments + // attacker, weapon, loss, damagepos, tyreIdx + CLuaArguments Arguments; + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + if (weaponType != WEAPONTYPE_INVALID) + Arguments.PushNumber(weaponType); + else + Arguments.PushNil(); + Arguments.PushNumber(fLoss); + Arguments.PushNumber(vecDamagePos.fX); + Arguments.PushNumber(vecDamagePos.fY); + Arguments.PushNumber(vecDamagePos.fZ); + if (ucTyre != UCHAR_INVALID_INDEX) + Arguments.PushNumber(ucTyre); + else + Arguments.PushNil(); + + if (!pClientVehicle->CallEvent("onClientVehicleDamage", Arguments, true)) + { + bAllowDamage = false; + } + } + + return bAllowDamage; +} + +bool CClientGame::ObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) +{ + if (pObjectInterface) + { + // Get our object and client object + CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); + CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); + + // Is our client vehicle valid? + if (pClientObject) + { + CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); + CClientEntity* pClientAttacker = NULL; + if (pAttacker) + { + if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); + } + else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerPed); + } + } + + CLuaArguments Arguments; + Arguments.PushNumber(fLoss); + + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + + return pClientObject->CallEvent("onClientObjectDamage", Arguments, true); + } + } + return true; +} + +bool CClientGame::ObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) +{ + if (pObjectInterface) + { + // Get our object and client object + CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); + CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); + + // Is our client vehicle valid? + if (pClientObject) + { + if (!pClientObject->IsBreakable(false)) + return false; + + // Apply to MTA's "internal storage", too + pClientObject->SetHealth(0.0f); + + CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); + CClientEntity* pClientAttacker = NULL; + if (pAttacker) + { + if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); + } + else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerPed); + } + } + + CLuaArguments Arguments; + + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + + return pClientObject->CallEvent("onClientObjectBreak", Arguments, true); + } + } + return true; +} + +bool CClientGame::WaterCannonHitHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) +{ + if (pCannonVehicle && pHitPed) + { + // Get our vehicle and client vehicle + CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCannonVehicle); + CClientVehicle* pCannonClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); + // Was our client vehicle valid + if (pCannonClientVehicle) + { + // Get our ped and client ped + CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitPed); + CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); + + CLuaArguments Arguments; + if (pClientPed) + { + // Push our ped + Arguments.PushElement(pClientPed); + } + else + { + Arguments.PushNil(); + } + + // Trigger our event + bool bContinue = true; + if (!IS_PLAYER(pClientPed)) + bContinue = pCannonClientVehicle->CallEvent("onClientPedHitByWaterCannon", Arguments, true); + else + bContinue = pCannonClientVehicle->CallEvent("onClientPlayerHitByWaterCannon", Arguments, true); + + // Return if it was cancelled + return bContinue; + } + } + return false; +} + +bool CClientGame::VehicleFellThroughMapHandler(CVehicleSAInterface* pVehicleInterface) +{ + if (pVehicleInterface) + { + // Get our vehicle and client vehicle + CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pVehicleInterface); + CClientVehicle* pClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); + if (pClientVehicle) + { + // handle or don't + return pClientVehicle->OnVehicleFallThroughMap(); + } + } + // unhandled + return false; +} + +// Validate known objects +void CClientGame::GameObjectDestructHandler(CEntitySAInterface* pObject) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pObject); +} + +void CClientGame::GameVehicleDestructHandler(CEntitySAInterface* pVehicle) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pVehicle); +} + +void CClientGame::GamePlayerDestructHandler(CEntitySAInterface* pPlayer) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pPlayer); +} + +void CClientGame::GameProjectileDestructHandler(CEntitySAInterface* pProjectile) +{ + CClientProjectile* pClientProjectile = m_pManager->GetProjectileManager()->Get(pProjectile); + // Happens when destroyElement is called rather than letting the projectile expire + // Normal code path is destruction from CProjectileSAInterface -> CProjectileSA -> CClientProjectile + // destroyElement is CClientProjectile -> CProjectileSA -> CProjectileSAInterface + // which means the CClientProjectile element is deleted when we get here + if (pClientProjectile) + CStaticFunctionDefinitions::DestroyElement(*pClientProjectile); +} + +void CClientGame::GameModelRemoveHandler(ushort usModelId) +{ + m_pGameEntityXRefManager->OnGameModelRemove(usModelId); +} + +void CClientGame::TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) +{ + bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); + if (bOldBehaviour) + return; + + CClientPed* pClientPedAttacker = DynamicCast(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedAttacker)); + + // Make sure cause was networked ped + if (pClientPedAttacker && !pClientPedAttacker->IsLocalEntity()) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write((ushort)TASK_SIMPLE_BE_HIT); + pBitStream->Write(pClientPedAttacker->GetID()); + pBitStream->Write((uchar)hitBodyPart); + pBitStream->Write((uchar)hitBodySide); + pBitStream->Write((uchar)weaponId); + g_pNet->SendPacket(PACKET_ID_PED_TASK, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +bool CClientGame::StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (g_pClientGame) + { + return g_pClientGame->ProcessMessage(hwnd, uMsg, wParam, lParam); + } + + return false; +} + +bool CClientGame::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (ProcessMessageForCursorEvents(hwnd, uMsg, wParam, lParam)) + { + return true; + } + + return false; +} + +void CClientGame::ProcessVehicleInOutKey(bool bPassenger) +{ + // Are we already sending an in/out request or not allowed to create a new in/out? + if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? + || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) + || m_bIsGettingJacked // Make sure we're not currently getting carjacked && + || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... + || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... + || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon + ) + { + return; + } + + // Reset the "is jacking" bit + m_bIsJackingVehicle = false; + + // Got a local player model? + if (!m_pLocalPlayer) + { + // No local player. Stop. + return; + } + + // If the player is in a vehicle we need to leave the vehicle. + CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + if (pOccupiedVehicle) + { + // Only let us leave the vehicle if: + // - we press F (as driver) + // - we press either F or G as a passenger + if (bPassenger && m_pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + // Driver pressed G, so stop. + return; + } + + // We're about to exit a vehicle + // Send an in request + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!pBitStream) + { + return; + } + + // Write the vehicle id to it and that we're requesting to get out of it + pBitStream->Write(pOccupiedVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_REQUEST_OUT); + pBitStream->WriteBits(&ucAction, 4); + + unsigned char ucDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pLocalPlayer->GetGamePlayer(), pOccupiedVehicle->GetGameVehicle()); + if (ucDoor >= 2 && ucDoor <= 5) + { + ucDoor -= 2; + pBitStream->WriteBits(&ucDoor, 2); + } + + // Send and destroy it + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're now exiting a vehicle + m_bIsGettingOutOfVehicle = true; + m_ulLastVehicleInOutTime = CClientTime::GetTime(); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_out"); +#endif + return; + } + + // + // We're going to enter a vehicle + // + + // If the Jump task is playing and we are in water - I know right + // Kill the task. + // + CTask* pTask = m_pLocalPlayer->GetCurrentPrimaryTask(); + if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter + { + CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, nullptr, nullptr, 20.0f); + if (pVehicle && + (pVehicle->IsInWater() || + m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) + { + m_pLocalPlayer->KillTask(3, true); // Kill jump task if we are about to warp in + } + } + + // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle' + // task will replace it and fuck it up! + // + if (m_pLocalPlayer->GetCurrentPrimaryTask()) + { + // We already have a primary task, so stop. + return; + } + + // Are we holding the aim_weapon key? + SBindableGTAControl* pBind = g_pCore->GetKeyBinds()->GetBindableFromControl("aim_weapon"); + if (pBind && pBind->bState) + { + // Stop because the player is probably using rshift + f/g + return; + } + + if (m_pLocalPlayer->IsClimbing() // Make sure we're not currently climbing + || m_pLocalPlayer->HasJetPack() // Make sure we don't have a jetpack + || m_pLocalPlayer->IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway + || m_pLocalPlayer->IsRunningAnimation() // Make sure we aren't running an animation + ) + { + return; + } + + // Grab the closest vehicle + unsigned int uiDoor = 0; + CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, &uiDoor, nullptr, 20.0f); + unsigned int uiSeat = uiDoor; + + if (bPassenger && uiDoor == 0) + { + // We're trying to enter as a passenger, yet our closest door + // is the driver's door. Force an enter for the passenger seat. + uiSeat = 1; + } + else if (!bPassenger) + { + // We want to drive. Force our seat to the driver's seat. + uiSeat = 0; + } + + if (!pVehicle || !pVehicle->IsEnterable()) + { + // Stop if there isn't a vehicle, or the vehicle is not enterable + return; + } + + // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly) + if (pVehicle->GetVehicleType() == CLIENTVEHICLE_BOAT && m_pLocalPlayer->GetContactEntity() != pVehicle) + { + return; + } + + // Call the onClientVehicleStartEnter event for remote players + // Local player triggered before sending packet in CClientGame + CLuaArguments Arguments; + Arguments.PushElement(m_pLocalPlayer); // player + Arguments.PushNumber(uiSeat); // seat + Arguments.PushNumber(uiDoor); // Door + + if (!pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true)) + { + // Event has been cancelled + return; + } + + // Send an in request + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!pBitStream) + { + return; + } + + // Write the vehicle id to it and that we're requesting to get into it + pBitStream->Write(pVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_REQUEST_IN); + unsigned char ucSeat = static_cast(uiSeat); + bool bIsOnWater = pVehicle->IsOnWater(); + unsigned char ucDoor = static_cast(uiDoor); + pBitStream->WriteBits(&ucAction, 4); + pBitStream->WriteBits(&ucSeat, 4); + pBitStream->WriteBit(bIsOnWater); + pBitStream->WriteBits(&ucDoor, 3); + + // Send and destroy it + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're now entering a vehicle + m_bIsGettingIntoVehicle = true; + m_ulLastVehicleInOutTime = CClientTime::GetTime(); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_in"); +#endif +} + +// Shot compensation (Jax): +// Positions the local player where he should of been on the shooting player's screen when he +// fired remotely. (the position we !reported! around the time he shot) +bool bShotCompensation = true; + +// Temporary pointers for pre- and post-functions +CVector vecWeaponFirePosition, vecRemoteWeaponFirePosition; +CPlayerPed* pWeaponFirePed = NULL; + +bool CClientGame::PreWeaponFire(CPlayerPed* pPlayerPed, bool bStopIfUsingBulletSync) +{ + pWeaponFirePed = pPlayerPed; + + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pWeaponFirePed) + { + CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); + + // Get the CClientNetPlayer class with the specified player ped + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(pWeaponFirePed, true); + + // Move both players to where they should be for shot compensation + if (pPlayer && !pPlayer->IsLocalPlayer()) + { + if (bStopIfUsingBulletSync && pPlayer->IsCurrentWeaponUsingBulletSync()) + return false; // Don't apply shot compensation & tell caller to not do bullet trace + + if (bShotCompensation) + { + if (!pVehicle || pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + // Warp back in time to where we were when this player shot (their latency) + + // We don't account for interpolation here, +250ms seems to work better + // ** Changed ajustment to +125ms as the position of this clients player on the firers screen + // has been changed. See CClientPed::UpdateTargetPosition() ** + CVector vecPosition; + unsigned short usLatency = (pPlayer->GetLatency() + 125); + g_pClientGame->m_pNetAPI->GetInterpolation(vecPosition, usLatency); + + // Move the entity back + if (pVehicle) + { + pVehicle->GetPosition(vecWeaponFirePosition); + pVehicle->SetPosition(vecPosition, false, false); + } + else + { + pLocalPlayer->GetPosition(vecWeaponFirePosition); + pLocalPlayer->SetPosition(vecPosition, false, false); + } + } + } + } + } + return true; +} + +void CClientGame::PostWeaponFire(void) +{ + // Send bullet sync with local damage info + if (g_bBulletFireVectorsValid) + { + g_bBulletFireVectorsValid = false; + CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer) + { + eWeaponType weaponType = pLocalPlayer->GetCurrentWeaponType(); + if (g_pClientGame->GetWeaponTypeUsesBulletSync(weaponType)) + { + g_pClientGame->GetNetAPI()->SendBulletSyncFire(weaponType, g_vecBulletFireStartPosition, g_vecBulletFireEndPosition, g_fApplyDamageLastAmount, + g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); + } + } + } + + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pWeaponFirePed) + { + CClientPed* pPed = g_pClientGame->GetPedManager()->Get(pWeaponFirePed, true, true); + if (pPed) + { + if (pPed->GetType() == CCLIENTPLAYER) + { + if (bShotCompensation) + { + // Restore compensated positions + if (!pPed->IsLocalPlayer()) + { + CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); + if (!pVehicle) + { + pLocalPlayer->SetPosition(vecWeaponFirePosition, false, false); + } + else if (pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + pVehicle->SetPosition(vecWeaponFirePosition, false, false); + } + } + } + } + + // Call some events + CWeapon* pWeapon = pPed->GetWeapon(); + if (pWeapon) + { + CVector vecCollision; + CClientEntity* pCollisionEntity = NULL; + + if (pPed->GetBulletImpactData(&pCollisionEntity, &vecCollision) == false) + { + CShotSyncData* pShotsyncData = pPed->m_shotSyncData; + CVector vecOrigin, vecTarget; + pPed->GetShotData(&vecOrigin, &vecTarget); + + CColPoint* pCollision = NULL; + CEntity* pCollisionGameEntity = NULL; + vecCollision = vecTarget; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionGameEntity); + if (bCollision && pCollision) + vecCollision = pCollision->GetPosition(); + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + + if (pCollisionGameEntity) + pCollisionEntity = g_pClientGame->m_pManager->FindEntity(pCollisionGameEntity); + } + else + { + pPed->ClearBulletImpactData(); + } + + // Call our lua event + CLuaArguments Arguments; + Arguments.PushNumber((double)pWeapon->GetType()); + Arguments.PushNumber((double)pWeapon->GetAmmoTotal()); + Arguments.PushNumber((double)pWeapon->GetAmmoInClip()); + Arguments.PushNumber((double)vecCollision.fX); + Arguments.PushNumber((double)vecCollision.fY); + Arguments.PushNumber((double)vecCollision.fZ); + if (pCollisionEntity) + Arguments.PushElement(pCollisionEntity); + else + Arguments.PushNil(); + + if (IS_PLAYER(pPed)) + { + CVector vecOrigin; + pPed->GetShotData(&vecOrigin); + Arguments.PushNumber((double)vecOrigin.fX); + Arguments.PushNumber((double)vecOrigin.fY); + Arguments.PushNumber((double)vecOrigin.fZ); + pPed->CallEvent("onClientPlayerWeaponFire", Arguments, true); + } + else + pPed->CallEvent("onClientPedWeaponFire", Arguments, true); + } + pPed->PostWeaponFire(); +#ifdef MTA_DEBUG + if (pPed->IsLocalPlayer() && g_pClientGame->m_bDoPaintballs) + { + g_pClientGame->DoPaintballs(); + } +#endif + } + } + pWeaponFirePed = NULL; +} + +void CClientGame::BulletImpact(CPed* pInitiator, CEntity* pVictim, const CVector* pStartPosition, const CVector* pEndPosition) +{ + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pInitiator) + { + // Find the client ped that initiated the bullet impact + CClientPed* pInitiatorPed = g_pClientGame->GetPedManager()->Get(dynamic_cast(pInitiator), true, true); + + if (pInitiatorPed) + { + // Calculate the collision of the bullet + CVector vecCollision; + CColPoint* pCollision = NULL; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(pStartPosition, pEndPosition, &pCollision, NULL); + if (bCollision && pCollision) + { + vecCollision = pCollision->GetPosition(); + } + else + { + // If we don't have a collision, use the end of the ray that the bullet is tracing. + vecCollision = *pEndPosition; + } + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + + // Find the client entity for the victim. + CClientEntity* pClientVictim = NULL; + if (pVictim) + { + pClientVictim = g_pClientGame->m_pManager->FindEntity(pVictim); + } + + // Store the data in the bullet fire initiator. + pInitiatorPed->SetBulletImpactData(pClientVictim, vecCollision); + } + } +} + +void CClientGame::BulletFire(CPed* pInitiator, const CVector* pStartPosition, const CVector* pEndPosition) +{ + g_bBulletFireVectorsValid = false; + g_fApplyDamageLastAmount = 0; + g_ucApplyDamageLastHitZone = 0; + g_pApplyDamageLastDamagedPed = NULL; + + // Got a local player model? + CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pLocalPlayer->GetGamePlayer() == pInitiator) + { + g_bBulletFireVectorsValid = true; + g_vecBulletFireStartPosition = *pStartPosition; + g_vecBulletFireEndPosition = *pEndPosition; + } +} + +bool CClientGame::StaticProcessPacket(unsigned char ucPacketID, NetBitStreamInterface& bitStream) +{ + if (g_pClientGame) + { + g_pCore->UpdateDummyProgress(); + g_pClientGame->GetManager()->GetPacketRecorder()->RecordPacket(ucPacketID, bitStream); + return g_pClientGame->m_pPacketHandler->ProcessPacket(ucPacketID, bitStream); + } + + return false; +} + +void CClientGame::SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin) +{ + SPositionSync position(false); + position.data.vecPosition = vecPosition; + + // Create the bitstream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write our origin id + if (pOrigin) + { + pBitStream->WriteBit(true); + pBitStream->Write(pOrigin->GetID()); + + // Convert position + CVector vecTemp; + pOrigin->GetPosition(vecTemp); + position.data.vecPosition -= vecTemp; + } + else + pBitStream->WriteBit(false); + + // Write the position and the type + pBitStream->Write(&position); + + SExplosionTypeSync explosionType; + explosionType.data.uiType = Type; + pBitStream->Write(&explosionType); + + // Destroy it + g_pNet->SendPacket(PACKET_ID_EXPLOSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +void CClientGame::SendFireSync(CFire* pFire) +{ +#ifdef MTA_DEBUG + CVector* vecPos = pFire->GetPosition(); + if (vecPos) + g_pCore->GetConsole()->Printf("we're sending fire: %f %f %f %f", pFire->GetStrength(), vecPos->fX, vecPos->fY, vecPos->fZ); + else + g_pCore->GetConsole()->Printf("we're sending a fire!"); +#endif +} + +void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) +{ + // Create the bitstream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + SPositionSync origin(false); + CClientEntity* pOriginSource = NULL; + eWeaponType weaponType = pProjectile->GetWeaponType(); + CClientEntity* pTarget = pProjectile->GetTargetEntity(); + origin.data.vecPosition = *pProjectile->GetOrigin(); + + // Is this a heatseaking missile with a target? sync it relative to the target + if (weaponType == WEAPONTYPE_ROCKET_HS && pTarget && !pTarget->IsLocalEntity()) + pOriginSource = pTarget; + + // Write the source of the projectile, if it has + if (pOriginSource) + { + CVector vecTemp; + pOriginSource->GetPosition(vecTemp); + origin.data.vecPosition -= vecTemp; + + pBitStream->WriteBit(true); + pBitStream->Write(pOriginSource->GetID()); + } + else + pBitStream->WriteBit(false); + + // Write the origin position + pBitStream->Write(&origin); + + // Write the creator weapon type + SWeaponTypeSync weaponTypeSync; + weaponTypeSync.data.ucWeaponType = static_cast(weaponType); + pBitStream->Write(&weaponTypeSync); + + // Write the projectile's model + if (pBitStream->Version() >= 0x4F) + if (pBitStream->Version() >= 0x52 || pOriginSource) // Fix possible error for 0x51 server + pBitStream->Write(pProjectile->GetModel()); + + switch (weaponType) + { + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_TEARGAS: + case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: + { + SFloatSync<7, 17> projectileForce; + projectileForce.data.fValue = pProjectile->GetForce(); + pBitStream->Write(&projectileForce); + + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); + + break; + } + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKET_HS: + { + if (pTarget) + { + pBitStream->WriteBit(true); + pBitStream->Write(pTarget->GetID()); + } + else + pBitStream->WriteBit(false); + + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); + + SRotationRadiansSync rotation(true); + pProjectile->GetRotationRadians(rotation.data.vecRotation); + pBitStream->Write(&rotation); + + break; + } + case WEAPONTYPE_FLARE: + case WEAPONTYPE_FREEFALL_BOMB: + break; + } + g_pNet->SendPacket(PACKET_ID_PROJECTILE, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + + // Destroy it + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +void CClientGame::ResetAmmoInClip(void) +{ + memset(&m_wasWeaponAmmoInClip[0], 0, sizeof(m_wasWeaponAmmoInClip)); +} + +void CClientGame::ResetMapInfo(void) +{ + // Restore some game stuff + // Keybinds + g_pCore->GetKeyBinds()->SetAllControlsEnabled(true, true, true); + + // Radarmap + m_pRadarMap->SetForcedState(false); + + // Camera + m_pCamera->FadeOut(0.0f, 0, 0, 0); + g_pGame->GetWorld()->SetCurrentArea(0); + m_pCamera->SetFocusToLocalPlayer(); + g_pGame->GetSettings()->ResetFieldOfViewFromScript(); + + // Dimension + SetAllDimensions(0); + + // Hud + g_pGame->GetHud()->SetComponentVisible(HUD_ALL, true); + // Disable area names as they are on load until camera unfades + g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); + g_pGame->GetHud()->SetComponentVisible(HUD_VITAL_STATS, false); + + m_bHudAreaNameDisabled = false; + + // Gravity + g_pMultiplayer->SetLocalPlayerGravity(DEFAULT_GRAVITY); + g_pMultiplayer->SetGlobalGravity(DEFAULT_GRAVITY); + g_pGame->SetGravity(DEFAULT_GRAVITY); + + // Gamespeed + SetGameSpeed(DEFAULT_GAME_SPEED); + + // Game minute duration + SetMinuteDuration(DEFAULT_MINUTE_DURATION); + + // Wanted-level + SetWanted(0); + + // Money + SetMoney(0, true); + + // Weather + m_pBlendedWeather->SetWeather(0); + + // Rain + g_pGame->GetWeather()->ResetAmountOfRain(); + + // Wind + g_pMultiplayer->RestoreWindVelocity(); + + // Far clip distance + g_pMultiplayer->RestoreFarClipDistance(); + + // Near clip distance + g_pMultiplayer->RestoreNearClipDistance(); + + // Fog distance + g_pMultiplayer->RestoreFogDistance(); + + // Vehicles LOD distance + g_pGame->GetSettings()->ResetVehiclesLODDistance(); + + // Peds LOD distance + g_pGame->GetSettings()->ResetPedsLODDistance(); + + // Sun color + g_pMultiplayer->ResetSunColor(); + + // Sun size + g_pMultiplayer->ResetSunSize(); + + // Sky-gradient + g_pMultiplayer->ResetSky(); + + // Heat haze + g_pMultiplayer->ResetHeatHaze(); + + // Water-colour + g_pMultiplayer->ResetWater(); + + // Water + GetManager()->GetWaterManager()->ResetWorldWaterLevel(); + + // Re-enable interior sounds and furniture + g_pMultiplayer->SetInteriorSoundsEnabled(true); + for (int i = 0; i <= 4; ++i) + g_pMultiplayer->SetInteriorFurnitureEnabled(i, true); + + // Clouds + g_pMultiplayer->SetCloudsEnabled(true); + g_pClientGame->SetCloudsEnabled(true); + + // Birds + g_pMultiplayer->DisableBirds(false); + g_pClientGame->SetBirdsEnabled(true); + + // Ambient sounds + g_pGame->GetAudio()->ResetAmbientSounds(); + + // World sounds + g_pGame->GetAudio()->ResetWorldSounds(); + + // Cheats + g_pGame->ResetCheats(); + + // Players + m_pPlayerManager->ResetAll(); + + // Jetpack max height + g_pGame->GetWorld()->SetJetpackMaxHeight(DEFAULT_JETPACK_MAXHEIGHT); + + // Aircraft max height + g_pGame->GetWorld()->SetAircraftMaxHeight(DEFAULT_AIRCRAFT_MAXHEIGHT); + + // Aircraft max velocity + g_pGame->GetWorld()->SetAircraftMaxVelocity(DEFAULT_AIRCRAFT_MAXVELOCITY); + + // Moon size + g_pMultiplayer->ResetMoonSize(); + + // Disable the change of any player stats + g_pMultiplayer->SetLocalStatsStatic(true); + + // Restore blur +#ifdef MTA_DEBUG + g_pGame->SetBlurLevel(0); +#else + g_pGame->SetBlurLevel(DEFAULT_BLUR_LEVEL); +#endif + + // Close all garages + CGarage* pGarage = NULL; + CGarages* pGarages = g_pCore->GetGame()->GetGarages(); + + for (unsigned char i = 0; (pGarage = pGarages->GetGarage(i)) != NULL; i++) + { + pGarage->SetOpen(false); + } + + // Player specific stuff + if (m_pLocalPlayer) + { + // Interior + m_pLocalPlayer->SetInterior(0); + + // Headless state + m_pLocalPlayer->SetHeadless(false); + + // Frozen state + m_pLocalPlayer->SetFrozen(false); + + // Voice + short sVoiceType, sVoiceID; + m_pLocalPlayer->GetModelInfo()->GetVoice(&sVoiceType, &sVoiceID); + m_pLocalPlayer->SetVoice(sVoiceType, sVoiceID); + + m_pLocalPlayer->DestroySatchelCharges(false, true); + // Tell the server we want to destroy our satchels + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + g_pNet->SendPacket(PACKET_ID_DESTROY_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, + AnimationId animID) +{ + if (Ped && Ped->GetHealth() == 0.0f) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write some death info + pBitStream->WriteCompressed(animGroup); + pBitStream->WriteCompressed(animID); + + pBitStream->Write(damagerID); + + SWeaponTypeSync weapon; + weapon.data.ucWeaponType = ucWeapon; + pBitStream->Write(&weapon); + + SBodypartSync bodyPart; + bodyPart.data.uiBodypart = ucBodyPiece; + pBitStream->Write(&bodyPart); + + // Write the position we died in + SPositionSync pos(false); + Ped->GetPosition(pos.data.vecPosition); + pBitStream->Write(&pos); + + pBitStream->Write(Ped->GetID()); + + // The ammo in our weapon and write the ammo total + CWeapon* pPlayerWeapon = Ped->GetWeapon(); + SWeaponAmmoSync ammo(ucWeapon, true, false); + ammo.data.usTotalAmmo = 0; + if (pPlayerWeapon) + ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); + pBitStream->Write(&ammo); + + // Send the packet + g_pNet->SendPacket(PACKET_ID_PED_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, AnimationId animID) +{ + // Are we not already marked as dead? and have we run out of health? + if (!m_pLocalPlayer->IsDeadOnNetwork() && m_pLocalPlayer->GetHealth() == 0.0f) + { + // Send the "i am dead" packet + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + m_pLocalPlayer->SetDeadOnNetwork(true); + + // Call the onClientPlayerWasted event + CClientEntity* pKiller = (damagerID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(damagerID) : NULL; + CLuaArguments Arguments; + if (pKiller) + Arguments.PushElement(pKiller); + else + Arguments.PushBoolean(false); + if (ucWeapon != 0xFF) + Arguments.PushNumber(ucWeapon); + else + Arguments.PushBoolean(false); + if (ucBodyPiece != 0xFF) + Arguments.PushNumber(ucBodyPiece); + else + Arguments.PushBoolean(false); + Arguments.PushBoolean(false); + m_pLocalPlayer->CallEvent("onClientPlayerWasted", Arguments, true); + + // Write some death info + pBitStream->WriteCompressed(animGroup); + pBitStream->WriteCompressed(animID); + + pBitStream->Write(damagerID); + + SWeaponTypeSync weapon; + weapon.data.ucWeaponType = ucWeapon; + pBitStream->Write(&weapon); + + SBodypartSync bodyPart; + bodyPart.data.uiBodypart = ucBodyPiece; + pBitStream->Write(&bodyPart); + + // Write the position we died in + SPositionSync pos(false); + m_pLocalPlayer->GetPosition(pos.data.vecPosition); + pBitStream->Write(&pos); + + // The ammo in our weapon and write the ammo total + CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(); + SWeaponAmmoSync ammo(ucWeapon, true, false); + ammo.data.usTotalAmmo = 0; + if (pPlayerWeapon) + ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); + pBitStream->Write(&ammo); + + // Send the packet + g_pNet->SendPacket(PACKET_ID_PLAYER_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +bool CClientGame::OnKeyDown(CGUIKeyEventArgs Args) +{ + return true; +} + +bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + const char* szState = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIClick", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseDoubleClick(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + const char* szState = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIDoubleClick", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIMouseDown", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseButtonUp(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIMouseUp", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseMove(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseMove", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseEnter(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + if (Args.pSwitchedWindow) + { + CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); + if (GetGUIManager()->Exists(pGUISwitchedElement)) + Arguments.PushElement(pGUISwitchedElement); + } + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseEnter", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseLeave(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + if (Args.pSwitchedWindow) + { + CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); + if (GetGUIManager()->Exists(pGUISwitchedElement)) + Arguments.PushElement(pGUISwitchedElement); + } + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseLeave", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseWheel(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.wheelChange); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseWheel", Arguments, true); + + return true; +} + +bool CClientGame::OnMove(CGUIElement* pElement) +{ + if (!pElement) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); + if (pGUIElement && GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientGUIMove", Arguments, true); + + return true; +} + +bool CClientGame::OnSize(CGUIElement* pElement) +{ + if (!pElement) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientGUISize", Arguments, true); + + return true; +} + +bool CClientGame::OnFocusGain(CGUIFocusEventArgs Args) +{ + if (!Args.pActivatedWindow) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pActivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pActivatedWindow); + + if (Args.pDeactivatedWindow) + { + CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); + if (GetGUIManager()->Exists(pDeactivatedGUIElement)) + pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); + } + + if (GetGUIManager()->Exists(pActivatedGUIElement)) + pActivatedGUIElement->CallEvent("onClientGUIFocus", Arguments, true); + + return true; +} + +bool CClientGame::OnFocusLoss(CGUIFocusEventArgs Args) +{ + if (!Args.pDeactivatedWindow) + return false; + + CLuaArguments Arguments; + + if (Args.pActivatedWindow) + { + // pDeactivatedWindow looses focus but an other window is now gaining it so we let CClientGame::OnFocusGain trigger both events in the right order + return true; + } + + CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); + if (GetGUIManager()->Exists(pDeactivatedGUIElement)) + pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); + + return true; +} + +// +// Display a progress dialog if a big packet is coming in +// +void CClientGame::NotifyBigPacketProgress(unsigned long ulBytesReceived, unsigned long ulTotalSize) +{ + // Should display progress box? + if (ulBytesReceived >= ulTotalSize || ulTotalSize < 50000) + { + if (m_bReceivingBigPacket) + { + // Switch off progress box + m_bReceivingBigPacket = false; + m_pBigPacketTransferBox->Hide(); + } + return; + } + + // Update progress box + if (!m_bReceivingBigPacket || m_ulBigPacketSize != ulTotalSize) + { + m_bReceivingBigPacket = true; + m_ulBigPacketSize = ulTotalSize; + m_pBigPacketTransferBox->Hide(); + m_pBigPacketTransferBox->AddToTotalSize(ulTotalSize); + m_pBigPacketTransferBox->Show(); + } + + m_pBigPacketTransferBox->DoPulse(); + m_pBigPacketTransferBox->SetInfo(std::min(ulTotalSize, ulBytesReceived), CTransferBox::PACKET); +} + +bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled) +{ + if (ucGlitch < NUM_GLITCHES && bEnabled != m_Glitches[ucGlitch]) + { + m_Glitches[ucGlitch] = bEnabled; + if (ucGlitch == GLITCH_QUICKRELOAD) + g_pMultiplayer->DisableQuickReload(!bEnabled); + if (ucGlitch == GLITCH_CLOSEDAMAGE) + g_pMultiplayer->DisableCloseRangeDamage(!bEnabled); + return true; + } + return false; +} + +bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) +{ + return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; +} + +bool CClientGame::SetCloudsEnabled(bool bEnabled) +{ + m_bCloudsEnabled = bEnabled; + return true; +} +bool CClientGame::GetCloudsEnabled(void) +{ + return m_bCloudsEnabled; +} + +bool CClientGame::SetBirdsEnabled(bool bEnabled) +{ + m_bBirdsEnabled = bEnabled; + return true; +} +bool CClientGame::GetBirdsEnabled(void) +{ + return m_bBirdsEnabled; +} + +#pragma code_seg(".text") +bool CClientGame::VerifySADataFiles(int iEnableClientChecks) +{ + int& iCheckStatus = g_pGame->GetCheckStatus(); + + if (!g_pGame->VerifySADataFileNames()) + iCheckStatus |= (1 << 11); + + __declspec(allocate(".text")) static char szVerifyData[][32] = {"data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", + "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", + "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", + "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", + "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", + "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", + "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", + "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", + "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", + "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", + "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", + "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74"}; + + CMD5Hasher hasher; + for (int i = 0; i < NUMELMS(szVerifyData); i += 2) + { + MD5 md5; + if (!hasher.Calculate(szVerifyData[i], md5) || memcmp(md5.data, szVerifyData[i + 1], 0x10)) + { + iCheckStatus |= (1 << i); + } + } + + if (iCheckStatus & iEnableClientChecks) + { + g_pCore->InitiateDataFilesFix(); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + return true; +} + +void CClientGame::InitVoice(bool bEnabled, unsigned int uiServerSampleRate, unsigned char ucQuality, unsigned int uiBitrate) +{ + if (m_pVoiceRecorder) + { + m_pVoiceRecorder->Init(bEnabled, uiServerSampleRate, ucQuality, uiBitrate); + } +} + +// +// If debug render mode is on, allow each element in range to draw some stuff +// +void CClientGame::DebugElementRender(void) +{ + if (!GetDevelopmentMode() || !GetShowCollision()) + return; + + CVector vecCameraPos; + m_pCamera->GetPosition(vecCameraPos); + float fDrawRadius = 200.f; + + // Get all entities within range + CClientEntityResult result; + GetClientSpatialDatabase()->SphereQuery(result, CSphere(vecCameraPos, fDrawRadius)); + + // For each entity found + for (CClientEntityResult::const_iterator it = result.begin(); it != result.end(); ++it) + { + CClientEntity* pEntity = *it; + if (pEntity->GetParent()) + pEntity->DebugRender(vecCameraPos, fDrawRadius); + } +} + +////////////////////////////////////////////////////////////////// +// Click +// +void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString& strTag, uint uiQuality, uint uiMaxBandwidth, uint uiMaxPacketSize, + CResource* pResource, uint uiServerSentTime) +{ + if (!pResource) + return; + + bool bAllowScreenUploadEnabled = 1; + g_pCore->GetCVars()->Get("allow_screen_upload", bAllowScreenUploadEnabled); + bool bWindowMinimized = g_pCore->IsWindowMinimized(); + + if (bWindowMinimized || !bAllowScreenUploadEnabled) + { + // If alt-tabbed or opt-out + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!bAllowScreenUploadEnabled) + pBitStream->Write((uchar)EPlayerScreenShotResult::DISABLED); + else + pBitStream->Write((uchar)EPlayerScreenShotResult::MINIMIZED); + pBitStream->Write(uiServerSentTime); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); + g_pNet->DeallocateNetBitStream(pBitStream); + } + else + { + // Do grab and send + SScreenShotArgs screenShotArgs; + screenShotArgs.uiMaxBandwidth = uiMaxBandwidth; + screenShotArgs.uiMaxPacketSize = uiMaxPacketSize; + screenShotArgs.usResourceNetId = pResource->GetNetID(); + screenShotArgs.strTag = strTag; + screenShotArgs.uiServerSentTime = uiServerSentTime; + m_ScreenShotArgList.push_back(screenShotArgs); + g_pCore->GetGraphics()->GetScreenGrabber()->QueueScreenShot(uiSizeX, uiSizeY, uiQuality, &CClientGame::StaticGottenPlayerScreenShot); + } +} + +////////////////////////////////////////////////////////////////// +// Callback from TakePlayerScreendsShot +// +void CClientGame::StaticGottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strError) +{ + if (g_pClientGame) + g_pClientGame->GottenPlayerScreenShot(pBuffer, uiTimeSpentInQueue, strError); +} + +////////////////////////////////////////////////////////////////// +// Break data into packets and put into delayed send list +// +void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strInError) +{ + SString strError = strInError; + + // Pop saved args + if (m_ScreenShotArgList.empty()) + return; + + SScreenShotArgs screenShotArgs = m_ScreenShotArgList.front(); + m_ScreenShotArgList.pop_front(); + const uint uiMaxBandwidth = Clamp(100, screenShotArgs.uiMaxBandwidth, 1000000); + const uint uiMaxPacketSize = Clamp(100, screenShotArgs.uiMaxPacketSize, 100000); + const ushort usResourceNetId = screenShotArgs.usResourceNetId; + const SString strTag = screenShotArgs.strTag; + const uint uiServerGrabTime = screenShotArgs.uiServerSentTime + uiTimeSpentInQueue; + + // Silently ignore if resource has been stopped + CResource* pResource = GetResourceManager()->GetResourceFromNetID(usResourceNetId); + if (!pResource) + return; + + // Validate buffer + if (strError.empty()) + { + if (!pBuffer || pBuffer->GetSize() == 0) + strError = "Buffer empty"; + } + + // Handle error + if (!strError.empty()) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write((uchar)EPlayerScreenShotResult::ERROR_); + pBitStream->Write(uiServerGrabTime); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + if (pBitStream->Version() >= 0x053) + pBitStream->WriteString(strError); + g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); + g_pNet->DeallocateNetBitStream(pBitStream); + return; + } + + // Calc constants stuff + const uint uiSendRate = Clamp(5, uiMaxBandwidth / uiMaxPacketSize, 20); + const long long llPacketInterval = 1000 / uiSendRate; + const uint uiTotalByteSize = pBuffer->GetSize(); + const char* pData = pBuffer->GetData(); + const uint uiBytesPerPart = std::min(std::min(std::max(100U, uiMaxBandwidth / uiSendRate), uiTotalByteSize), 30000U); + const uint uiNumParts = std::max(1U, (uiTotalByteSize + uiBytesPerPart - 1) / uiBytesPerPart); + + // Calc variables stuff + CTickCount tickCount = CTickCount::Now() + CTickCount(llPacketInterval); + uint uiBytesRemaining = uiTotalByteSize; + m_usNextScreenShotId++; + + // Make each packet + for (uint i = 0; i < uiNumParts; i++) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + + ushort usPartNumber = i; + ushort usBytesThisPart = std::min(uiBytesRemaining, uiBytesPerPart); + assert(usBytesThisPart != 0); + + pBitStream->Write((uchar)EPlayerScreenShotResult::SUCCESS); + pBitStream->Write(m_usNextScreenShotId); + pBitStream->Write(usPartNumber); + pBitStream->Write(usBytesThisPart); + pBitStream->Write(pData, usBytesThisPart); + + // Write more info if first part + if (usPartNumber == 0) + { + pBitStream->Write(uiServerGrabTime); + pBitStream->Write(uiTotalByteSize); + pBitStream->Write((ushort)uiNumParts); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + } + + // Add to delay send list + SDelayedPacketInfo delayedPacketInfo; + delayedPacketInfo.useTickCount = tickCount; + delayedPacketInfo.ucPacketID = PACKET_ID_PLAYER_SCREENSHOT; + delayedPacketInfo.pBitStream = pBitStream; + delayedPacketInfo.packetPriority = PACKET_PRIORITY_LOW; + delayedPacketInfo.packetReliability = PACKET_RELIABILITY_RELIABLE_ORDERED; + delayedPacketInfo.packetOrdering = PACKET_ORDERING_DATA_TRANSFER; + m_DelayedSendList.push_back(delayedPacketInfo); + + // Increment stuff + pData += usBytesThisPart; + uiBytesRemaining -= usBytesThisPart; + tickCount += CTickCount(llPacketInterval); + } + + assert(uiBytesRemaining == 0); +} + +////////////////////////////////////////////////////////////////// +// Process delay send list +// +void CClientGame::ProcessDelayedSendList(void) +{ + CTickCount tickCount = CTickCount::Now(); + + while (!m_DelayedSendList.empty()) + { + SDelayedPacketInfo& info = m_DelayedSendList.front(); + if (info.useTickCount > tickCount) + break; + + g_pNet->SendPacket(info.ucPacketID, info.pBitStream, info.packetPriority, info.packetReliability, info.packetOrdering); + g_pNet->DeallocateNetBitStream(info.pBitStream); + m_DelayedSendList.pop_front(); + } +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetWeaponTypesUsingBulletSync +// +// Set whether the local player will send bulletsync messages for the supplied weapon type +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetWeaponTypesUsingBulletSync(const std::set& weaponTypesUsingBulletSync) +{ + m_weaponTypesUsingBulletSync = weaponTypesUsingBulletSync; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::GetWeaponTypeUsesBulletSync +// +// Get whether the local player should send bulletsync messages for the supplied weapon type +// +////////////////////////////////////////////////////////////////// +bool CClientGame::GetWeaponTypeUsesBulletSync(eWeaponType weaponType) +{ + return MapContains(m_weaponTypesUsingBulletSync, weaponType); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetDevelopmentMode +// +// Special mode which enables commands such as showcol and showsound +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetDevelopmentMode(bool bEnable, bool bEnableWeb) +{ + m_bDevelopmentMode = bEnable; + + if (m_bDevelopmentMode) + g_pGame->GetAudio()->SetWorldSoundHandler(CClientGame::StaticWorldSoundHandler); + else + g_pGame->GetAudio()->SetWorldSoundHandler(NULL); + + if (g_pCore->IsWebCoreLoaded()) + g_pCore->GetWebCore()->SetTestModeEnabled(bEnableWeb); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::StaticWorldSoundHandler +// +// Handle callback from CAudioSA when a world sound is played +// +////////////////////////////////////////////////////////////////// +void CClientGame::StaticWorldSoundHandler(uint uiGroup, uint uiIndex) +{ + g_pClientGame->WorldSoundHandler(uiGroup, uiIndex); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::WorldSoundHandler +// +// Handle callback from CAudioSA when a world sound is played +// +////////////////////////////////////////////////////////////////// +void CClientGame::WorldSoundHandler(uint uiGroup, uint uiIndex) +{ + if (m_bShowSound) + m_pScriptDebugging->LogInformation(NULL, "%s - World sound group:%d index:%d", *GetLocalTimeString(false, true), uiGroup, uiIndex); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::IsUsingAlternatePulseOrder +// +// Returns true if should be using alternate pulse order +// +////////////////////////////////////////////////////////////////// +bool CClientGame::IsUsingAlternatePulseOrder(bool bAdvanceDelayCounter) +{ + if (m_MiscGameSettings.bUseAltPulseOrder) + { + // Only actually start using alternate pulse order after 100 frames + if (m_uiAltPulseOrderCounter >= 100) + return true; + else if (bAdvanceDelayCounter) + m_uiAltPulseOrderCounter++; + } + + return false; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::OutputServerInfo +// +// Output info about the connected server for player +// +////////////////////////////////////////////////////////////////// +void CClientGame::OutputServerInfo(void) +{ + SString strTotalOutput; + strTotalOutput += SString("Server info for %s", g_pNet->GetConnectedServer(true)); + strTotalOutput += "\n"; + strTotalOutput += SString("Ver: %s\n", *GetServerVersionSortable()); + strTotalOutput += SString("AC: %s\n", *m_strACInfo); + + { + SString strVoice; + if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) + strVoice += SString("Enabled - Sample rate:%d Quality:%d", m_pVoiceRecorder->GetSampleRate(), m_pVoiceRecorder->GetSampleQuality()); + else + strVoice += "Disabled"; + + strTotalOutput += SString("Voice: %s\n", *strVoice); + } + + { + SString strEnabledGlitches; + const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", + "Bad driveby hitboxes", "Quick stand"}; + for (uint i = 0; i < NUM_GLITCHES; i++) + { + if (IsGlitchEnabled(i)) + { + if (!strEnabledGlitches.empty()) + strEnabledGlitches += ", "; + if (i < NUMELMS(szGlitchNames)) + strEnabledGlitches += szGlitchNames[i]; + else + strEnabledGlitches += SString("Unknown(#%d)", i + 1); + } + } + if (strEnabledGlitches.empty()) + strEnabledGlitches = "None"; + strTotalOutput += SString("Glitches: %s\n", *strEnabledGlitches); + } + + { + SString strEnabledBulletSync; + for (std::set::iterator iter = m_weaponTypesUsingBulletSync.begin(); iter != m_weaponTypesUsingBulletSync.end(); ++iter) + { + eWeaponType weaponType = *iter; + if (!strEnabledBulletSync.empty()) + strEnabledBulletSync += ","; + strEnabledBulletSync += SString("%d", weaponType); + } + if (strEnabledBulletSync.empty()) + strEnabledBulletSync = "None"; + strTotalOutput += SString("Bullet sync weapons: %s\n", *strEnabledBulletSync); + } + + { + SString strVehExtrapolate; + if (m_VehExtrapolateSettings.bEnabled) + strVehExtrapolate += SString("Amount:%d%% (LimitMs:%d)", m_VehExtrapolateSettings.iScalePercent, m_VehExtrapolateSettings.iMaxMs); + else + strVehExtrapolate += "Disabled"; + + strTotalOutput += SString("Vehicle extrapolation: %s\n", *strVehExtrapolate); + } + + { + SString strTickRates; + strTickRates += SString("Plr:%d Cam:%d Ped:%d UnocVeh:%d KeyRot:%d KeyJoy:%d", g_TickRateSettings.iPureSync, g_TickRateSettings.iCamSync, + g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, + g_TickRateSettings.iKeySyncAnalogMove); + + strTotalOutput += SString("Tick rates: %s\n", *strTickRates); + } + + { + SString strSyncerDists; + strSyncerDists += SString("Ped:%d UnoccupiedVehicle:%d ", g_TickRateSettings.iPedSyncerDistance, g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); + + strTotalOutput += SString("Syncer distances: %s\n", *strSyncerDists); + } + + g_pCore->GetConsole()->Print(strTotalOutput); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::TellServerSomethingImportant +// +// Report misc important warnings/errors to the current server +// +////////////////////////////////////////////////////////////////// +void CClientGame::TellServerSomethingImportant(uint uiId, const SString& strMessage, uint uiSendLimitForThisId) +{ + g_pCore->GetConsole()->Print(strMessage); + AddReportLog(3400 + uiId, strMessage + g_pNet->GetConnectedServer(true), 10); + + if (uiSendLimitForThisId) + { + uint& uiCount = MapGet(m_SentMessageIds, uiId); + if (uiCount++ >= uiSendLimitForThisId) + return; + } + + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->WriteString(SString("%d,%s", uiId, *strMessage)); + g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE); + g_pNet->DeallocateNetBitStream(pBitStream); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::ChangeFloatPrecision +// +// Manage the change to high floating point precision +// +////////////////////////////////////////////////////////////////// +void CClientGame::ChangeFloatPrecision(bool bHigh) +{ + if (bHigh) + { + // Switch to 53 bit floating point precision on the first call + if (m_uiPrecisionCallDepth++ == 0) + _controlfp(_PC_53, MCW_PC); + } + else + { + // Even though is should never happen, m_uiPrecisionCallDepth is sometimes zero here + dassert(m_uiPrecisionCallDepth != 0); + if (m_uiPrecisionCallDepth != 0) + m_uiPrecisionCallDepth--; + // Switch back to 24 bit floating point precision on the last call + if (m_uiPrecisionCallDepth == 0) + _controlfp(_PC_24, MCW_PC); + } +} + +bool CClientGame::IsHighFloatPrecision(void) const +{ + return m_uiPrecisionCallDepth != 0; +} + +AnimationId CClientGame::DrivebyAnimationHandler(AnimationId animId, AssocGroupId animGroupId) +{ + // Only apply if all clients support the fix + if (!GetMiscGameSettings().bAllowBadDrivebyHitboxFix) + return animId; + + // If the glitch is enabled, don't apply the fix + if (IsGlitchEnabled(GLITCH_BADDRIVEBYHITBOX)) + return animId; + + // Bad animations are 232 and 236 of assoc group 72 + if (animGroupId != 72) + return animId; + + if (animId == 232) + return 235; + else if (animId == 236) + return 231; + + return animId; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetFileCacheRoot +// +// Figure out which directory to use for the client resource file cache +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetFileCacheRoot(void) +{ + if (g_pCore->GetCVars()->GetValue("share_file_cache") == false) + { + // Not sharing, so use current mod directory + m_strFileCacheRoot = GetModRoot(); + AddReportLog(7410, SString("CClientGame::SetFileCacheRoot - Not shared '%s'", *m_strFileCacheRoot)); + } + else + { + // Get shared directory + SString strFileCachePath = GetCommonRegistryValue("", "File Cache Path"); + // Check exists + if (!strFileCachePath.empty() && DirectoryExists(strFileCachePath)) + { + // Check writable + SString strTestFileName = PathJoin(strFileCachePath, "resources", "_test.tmp"); + if (FileSave(strTestFileName, "x")) + { + FileDelete(strTestFileName); + strTestFileName = PathJoin(strFileCachePath, "priv", "_test.tmp"); + if (FileSave(strTestFileName, "x")) + { + FileDelete(strTestFileName); + // Use shared directory + m_strFileCacheRoot = strFileCachePath; + AddReportLog(7411, SString("CClientGame::SetFileCacheRoot - Is shared '%s'", *m_strFileCacheRoot)); + return; + } + } + } + + // Otherwise set this install mod directory as shared + m_strFileCacheRoot = GetModRoot(); + SetCommonRegistryValue("", "File Cache Path", m_strFileCacheRoot); + + if (strFileCachePath.empty()) + AddReportLog(7412, SString("CClientGame::SetFileCacheRoot - Initial setting '%s'", *m_strFileCacheRoot)); + else + AddReportLog(7413, SString("CClientGame::SetFileCacheRoot - Change shared from '%s' to '%s'", *strFileCachePath, *m_strFileCacheRoot)); + } +} + +bool CClientGame::TriggerBrowserRequestResultEvent(const std::unordered_set& newPages) +{ + CLuaArguments Arguments; + CLuaArguments LuaTable; + int i = 0; + + for (auto& domain : newPages) + { + LuaTable.PushNumber(++i); + LuaTable.PushString(domain); + } + Arguments.PushTable(&LuaTable); + + return GetRootEntity()->CallEvent("onClientBrowserWhitelistChange", Arguments, false); +} + +void CClientGame::RestreamModel(unsigned short usModel) +{ + // Is this a vehicle ID? + if (CClientVehicleManager::IsValidModel(usModel)) + { + // Stream the vehicles of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetVehicleManager()->RestreamVehicles(usModel); + } + + // Is this an object ID? + else if (CClientObjectManager::IsValidModel(usModel)) + { + if (CClientPedManager::IsValidWeaponModel(usModel)) + { + // Stream the weapon of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetPedManager()->RestreamWeapon(usModel); + m_pManager->GetPickupManager()->RestreamPickups(usModel); + } + // Stream the objects of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetObjectManager()->RestreamObjects(usModel); + g_pGame->GetModelInfo(usModel)->RestreamIPL(); + } + // Is this an ped ID? + else if (CClientPlayerManager::IsValidModel(usModel)) + { + // Stream the ped of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetPedManager()->RestreamPeds(usModel); + } + else + + // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect + if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) + m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); +} + +void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) +{ + m_mapOfIfpPointers[u32BlockNameHash] = pIFP; +} + +std::shared_ptr CClientGame::GetIFPPointerFromMap(const unsigned int u32BlockNameHash) +{ + auto it = m_mapOfIfpPointers.find(u32BlockNameHash); + if (it != m_mapOfIfpPointers.end()) + { + return it->second; + } + return nullptr; +} + +void CClientGame::RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash) +{ + m_mapOfIfpPointers.erase(u32BlockNameHash); +} + +void CClientGame::InsertPedPointerToSet(CClientPed* pPed) +{ + m_setOfPedPointers.insert(pPed); +} + +void CClientGame::RemovePedPointerFromSet(CClientPed* pPed) +{ + m_setOfPedPointers.erase(pPed); +} + +CClientPed* CClientGame::GetClientPedByClump(const RpClump& Clump) +{ + for (auto& pPed : m_setOfPedPointers) + { + CEntity* pEntity = pPed->GetGameEntity(); + if (pEntity != nullptr) + { + if (pEntity->GetRpClump() != nullptr) + { + const RpClump& entityClump = *pEntity->GetRpClump(); + if (std::addressof(entityClump) == std::addressof(Clump)) + { + return pPed; + } + } + } + } + return nullptr; +} + +void CClientGame::OnClientIFPUnload(const std::shared_ptr& IFP) +{ + IFP->MarkAsUnloading(); + for (auto& pPed : m_setOfPedPointers) + { + // Remove IFP animations from replaced animations of peds/players + pPed->RestoreAnimations(IFP); + + // Make sure that streamed in pulses or changing model does not accidently + // play our custom animation. We can do that by making the custom animation + // untriggerable + if (pPed->GetCustomAnimationBlockNameHash() == IFP->GetBlockNameHash()) + { + if (pPed->IsCustomAnimationPlaying()) + { + pPed->SetCustomAnimationUntriggerable(); + } + + // Important! As we are using a shared_ptr, we need to decrement the reference counter + // by setting the shared_ptr to nullptr, this will avoid memory leak + if (!pPed->IsNextAnimationCustom() && pPed->IsCurrentAnimationCustom()) + { + pPed->DereferenceCustomAnimationBlock(); + } + } + } +} + +void CClientGame::InsertAnimationAssociationToMap(CAnimBlendAssociationSAInterface* pAnimAssociation, const std::shared_ptr& pIFPAnimations) +{ + m_mapOfCustomAnimationAssociations[pAnimAssociation] = pIFPAnimations; +} + +void CClientGame::RemoveAnimationAssociationFromMap(CAnimBlendAssociationSAInterface* pAnimAssociation) +{ + m_mapOfCustomAnimationAssociations.erase(pAnimAssociation); +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index d98579e147f..9445398f4cb 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -1,3877 +1,3887 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto - * LICENSE: See LICENSE in the top level directory - * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp - * PURPOSE: Lua definitions class - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#include "StdInc.h" - -void CLuaGUIDefs::LoadFunctions(void) -{ - CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); - CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); - CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); - CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); - - CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); - CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); - CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); - CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); - CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); - CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); - - CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); - CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); - CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); - - CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); - CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); - CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); - CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); - CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); - CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); - CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); - CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); - CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); - CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); - CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); - CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); - CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); - CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); - CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); - CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); - - CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); - CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); - CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); - CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); - CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); - - CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); - CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); - CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); - CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); - CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); - CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); - CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); - CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); - CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); - CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); - CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); - CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); - CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); - CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); - CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); - CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); - CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); - CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); - CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); - CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); - CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); - CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); - - CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); - CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); - CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); - CLuaCFunctions::AddFunction("guiSetText", GUISetText); - CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); - CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); - CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); - CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); - - CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); - CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); - - CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); - - CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); - CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); - CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); - CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); - CLuaCFunctions::AddFunction("guiGetText", GUIGetText); - CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); - CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); - CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); - CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); - CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); - - CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); - - CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); - CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); - - CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); - - CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); - CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); - CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); - CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); - CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); - CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); - - CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); - CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); - CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); - CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); - CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); - CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); - - CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); - CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); - - CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); - CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); - - CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); - - CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); - CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); - CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); - CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); - CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); - CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); - CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); -} - -void CLuaGUIDefs::AddClass(lua_State* luaVM) -{ - AddGuiElementClass(luaVM); - AddGuiFontClass(luaVM); - AddGuiWindowClass(luaVM); - AddGuiButtonClass(luaVM); - AddGuiEditClass(luaVM); - AddGuiLabelClass(luaVM); - AddGuiMemoClass(luaVM); - AddGuiImageClass(luaVM); - AddGuiComboBoxClass(luaVM); - AddGuiCheckBoxClass(luaVM); - AddGuiRadioButtonClass(luaVM); - AddGuiScrollPaneClass(luaVM); - AddGuiScrollBarClass(luaVM); - AddGuiProgressBarClass(luaVM); - AddGuiGridlistClass(luaVM); - AddGuiTabPanelClass(luaVM); - AddGuiTabClass(luaVM); -} - -// TODO: vector class -void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "bringToFront", "guiBringToFront"); - lua_classfunction(luaVM, "moveToBack", "guiMoveToBack"); - - lua_classfunction(luaVM, "isChatBoxInputActive", "isChatBoxInputActive"); - lua_classfunction(luaVM, "isConsoleActive", "isConsoleActive"); - lua_classfunction(luaVM, "isDebugViewActive", "isDebugViewActive"); - lua_classfunction(luaVM, "setDebugViewActive", "setDebugViewActive"); - lua_classfunction(luaVM, "isMainMenuActive", "isMainMenuActive"); - lua_classfunction(luaVM, "isMTAWindowActive", "isMTAWindowActive"); - lua_classfunction(luaVM, "isTransferBoxActive", "isTransferBoxActive"); - lua_classfunction(luaVM, "isInputEnabled", "guiGetInputEnabled"); - lua_classfunction(luaVM, "getInputMode", "guiGetInputMode"); - lua_classfunction(luaVM, "getCursorType", "guiGetCursorType"); - - lua_classfunction(luaVM, "getScreenSize", "guiGetScreenSize"); - lua_classfunction(luaVM, "getProperties", "guiGetProperties"); - lua_classfunction(luaVM, "getAlpha", "guiGetAlpha"); - lua_classfunction(luaVM, "getFont", "guiGetFont"); - lua_classfunction(luaVM, "getEnabled", "guiGetEnabled"); - lua_classfunction(luaVM, "getVisible", "guiGetVisible"); - lua_classfunction(luaVM, "getText", "guiGetText"); - lua_classfunction(luaVM, "getPosition", "guiGetPosition"); - lua_classfunction(luaVM, "getSize", "guiGetSize"); - lua_classfunction(luaVM, "getProperty", "guiGetProperty"); - - lua_classfunction(luaVM, "setInputEnabled", "guiSetInputEnabled"); - lua_classfunction(luaVM, "setAlpha", "guiSetAlpha"); - lua_classfunction(luaVM, "setEnabled", "guiSetEnabled"); - lua_classfunction(luaVM, "setFont", "guiSetFont"); - lua_classfunction(luaVM, "setVisible", "guiSetVisible"); - lua_classfunction(luaVM, "setText", "guiSetText"); - lua_classfunction(luaVM, "setInputMode", "guiSetInputMode"); - lua_classfunction(luaVM, "setProperty", "guiSetProperty"); - lua_classfunction(luaVM, "setPosition", "guiSetPosition"); - lua_classfunction(luaVM, "setSize", "guiSetSize"); - - lua_classvariable(luaVM, "chatBoxInputActive", NULL, "isChatBoxInputActive"); - lua_classvariable(luaVM, "consoleActive", NULL, "isConsoleActive"); - lua_classvariable(luaVM, "debugViewActive", "setDebugViewActive", "isDebugViewActive"); - lua_classvariable(luaVM, "mainMenuActive", NULL, "isMainMenuActive"); - lua_classvariable(luaVM, "mtaWindowActive", NULL, "isMTAWindowActive"); - lua_classvariable(luaVM, "transferBoxActive", NULL, "isTransferBoxActive"); - lua_classvariable(luaVM, "inputEnabled", "guiSetInputEnabled", "guiGetInputEnabled"); - lua_classvariable(luaVM, "inputMode", "guiGetInputMode", "guiSetInputMode"); - lua_classvariable(luaVM, "cursorAlpha", "setCursorAlpha", "getCursorAlpha"); - lua_classvariable(luaVM, "cursorType", NULL, "guiGetCursorType"); - lua_classvariable(luaVM, "font", "guiSetFont", "guiGetFont"); - lua_classvariable(luaVM, "visible", "guiSetVisible", "guiGetVisible"); - lua_classvariable(luaVM, "properties", NULL, "guiGetProperties"); - lua_classvariable(luaVM, "alpha", "guiSetAlpha", "guiGetAlpha"); - lua_classvariable(luaVM, "enabled", "guiSetEnabled", "guiGetEnabled"); - lua_classvariable(luaVM, "text", "guiSetText", "guiGetText"); - lua_classvariable(luaVM, "size", "guiSetSize", "guiGetSize"); - lua_classvariable(luaVM, "position", "guiSetPosition", "guiGetPosition"); - lua_classvariable(luaVM, "screenSize", NULL, "guiGetScreenSize"); - // lua_classvariable ( luaVM, "property" "guiSetProperty", "guiGetProperty" ); todo: .property[name] = value - - lua_registerclass(luaVM, "GuiElement", "Element"); -} - -void CLuaGUIDefs::AddGuiWindowClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateWindow"); - lua_classfunction(luaVM, "setMovable", "guiWindowSetMovable"); - lua_classfunction(luaVM, "setSizable", "guiWindowSetSizable"); - - lua_classvariable(luaVM, "movable", "guiWindowSetMovable", NULL); - lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", NULL); - - lua_registerclass(luaVM, "GuiWindow", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiButtonClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateButton"); - - lua_registerclass(luaVM, "GuiButton", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateEdit"); - lua_classfunction(luaVM, "getCaretIndex", "guiEditGetCaretIndex"); - lua_classfunction(luaVM, "setCaretIndex", "guiEditSetCaretIndex"); - lua_classfunction(luaVM, "setReadOnly", "guiEditSetReadOnly"); - lua_classfunction(luaVM, "setMasked", "guiEditSetMasked"); - lua_classfunction(luaVM, "setMaxLength", "guiEditSetMaxLength"); - - lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); - lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", "guiEditIsReadOnly"); - lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); - lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); - - lua_registerclass(luaVM, "GuiEdit", "GuiElement"); -} - -// TODO: specials -void CLuaGUIDefs::AddGuiLabelClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateLabel"); - - lua_classfunction(luaVM, "getFontHeight", "guiLabelGetFontHeight"); - lua_classfunction(luaVM, "getTextExtent", "guiLabelGetTextExtent"); - lua_classfunction(luaVM, "getColor", "guiLabelGetColor"); - - lua_classfunction(luaVM, "setColor", "guiLabelSetColor"); - lua_classfunction(luaVM, "setHorizontalAlign", "guiLabelSetHorizontalAlign"); - lua_classfunction(luaVM, "setVerticalAlign", "guiLabelSetVerticalAlign"); - - lua_classvariable(luaVM, "horizontalAlign", "guiLabelSetHorizontalAlign", NULL); - lua_classvariable(luaVM, "verticalAlign", "guiLabelSetVerticalAlign", NULL); - lua_classvariable(luaVM, "fontHeight", NULL, "guiLabelGetFontHeight"); - lua_classvariable(luaVM, "textExtent", NULL, "guiLabelGetTextExtent"); - // lua_classvariable ( luaVM, "color", "guiLabelGetColor", "guiLabelSetColor" ); - - lua_registerclass(luaVM, "GuiLabel", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiMemoClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateMemo"); - - lua_classfunction(luaVM, "getCaretIndex", "guiMemoGetCaretIndex"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); - - lua_classfunction(luaVM, "setCaretIndex", "guiMemoSetCaretIndex"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiMemoSetVerticalScrollPosition"); - lua_classfunction(luaVM, "setReadOnly", "guiMemoSetReadOnly"); - - lua_classvariable(luaVM, "caretIndex", "guiMemoSetCaretIndex", "guiMemoGetCaretIndex"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiMemoSetVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); - lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", "guiMemoIsReadOnly"); - - lua_registerclass(luaVM, "GuiMemo", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiImageClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateStaticImage"); - lua_classfunction(luaVM, "loadImage", "guiStaticImageLoadImage"); - - lua_classvariable(luaVM, "image", "guiStaticImageLoadImage", NULL); - - lua_registerclass(luaVM, "GuiStaticImage", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiComboBoxClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateComboBox"); - lua_classfunction(luaVM, "addItem", "guiComboBoxAddItem"); - lua_classfunction(luaVM, "clear", "guiComboBoxClear"); - lua_classfunction(luaVM, "removeItem", "guiComboBoxRemoveItem"); - - lua_classfunction(luaVM, "getSelected", "guiComboBoxGetSelected"); - lua_classfunction(luaVM, "getItemText", "guiComboBoxGetItemText"); - - lua_classfunction(luaVM, "setItemText", "guiComboBoxSetItemText"); - lua_classfunction(luaVM, "setSelected", "guiComboBoxSetSelected"); - - lua_classvariable(luaVM, "selected", "guiComboBoxSetSelected", "guiComboBoxGetSelected"); - - lua_registerclass(luaVM, "GuiComboBox", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiCheckBoxClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateCheckBox"); - - lua_classfunction(luaVM, "getSelected", "guiCheckBoxGetSelected"); - - lua_classfunction(luaVM, "setSelected", "guiCheckBoxSetSelected"); - - lua_classvariable(luaVM, "selected", "guiCheckBoxSetSelected", "guiCheckBoxGetSelected"); - - lua_registerclass(luaVM, "GuiCheckBox", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiRadioButtonClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateRadioButton"); - - lua_classfunction(luaVM, "getSelected", "guiRadioButtonGetSelected"); - - lua_classfunction(luaVM, "setSelected", "guiRadioButtonSetSelected"); - - lua_classvariable(luaVM, "selected", "guiRadioButtonSetSelected", "guiRadioButtonGetSelected"); - - lua_registerclass(luaVM, "GuiRadioButton", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiScrollPaneClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateScrollPane"); - - lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); - - lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition"); - lua_classfunction(luaVM, "setScrollBars", "guiScrollPaneSetScrollBars"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition"); - - lua_classvariable(luaVM, "horizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); - - lua_registerclass(luaVM, "GuiScrollPane", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiScrollBarClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateScrollBar"); - - lua_classfunction(luaVM, "getScrollPosition", "guiScrollBarGetScrollPosition"); - - lua_classfunction(luaVM, "setScrollPosition", "guiScrollBarSetScrollPosition"); - - lua_classvariable(luaVM, "scrollPosition", "guiScrollBarSetScrollPosition", "guiScrollBarGetScrollPosition"); - - lua_registerclass(luaVM, "GuiScrollBar", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiProgressBarClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateProgressBar"); - - lua_classfunction(luaVM, "getProgress", "guiProgressBarGetProgress"); - - lua_classfunction(luaVM, "setProgress", "guiProgressBarSetProgress"); - - lua_classvariable(luaVM, "progress", "guiProgressBarSetProgress", "guiProgressBarGetProgress"); - - lua_registerclass(luaVM, "GuiProgressBar", "GuiElement"); -} - -// TODO: special tables -void CLuaGUIDefs::AddGuiGridlistClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateGridList"); - lua_classfunction(luaVM, "addColumn", "guiGridListAddColumn"); - lua_classfunction(luaVM, "addRow", "guiGridListAddRow"); - lua_classfunction(luaVM, "autoSizeColumn", "guiGridListAutoSizeColumn"); - lua_classfunction(luaVM, "clear", "guiGridListClear"); - lua_classfunction(luaVM, "insertRowAfter", "guiGridListInsertRowAfter"); - lua_classfunction(luaVM, "removeColumn", "guiGridListRemoveColumn"); - lua_classfunction(luaVM, "removeRow", "guiGridListRemoveRow"); - - lua_classfunction(luaVM, "getItemData", "guiGridListGetItemData"); - lua_classfunction(luaVM, "getItemText", "guiGridListGetItemText"); - lua_classfunction(luaVM, "getRowCount", "guiGridListGetRowCount"); - lua_classfunction(luaVM, "getSelectedItem", "guiGridListGetSelectedItem"); - lua_classfunction(luaVM, "getItemColor", "guiGridListGetItemColor"); - lua_classfunction(luaVM, "getColumnTitle", "guiGridListGetColumnTitle"); - lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); - lua_classfunction(luaVM, "getSelectedCount", "guiGridListGetSelectedCount"); - lua_classfunction(luaVM, "getSelectedItems", "guiGridListGetSelectedItems"); - lua_classfunction(luaVM, "getColumnCount", "guiGridListGetColumnCount"); - - lua_classfunction(luaVM, "setItemData", "guiGridListSetItemData"); - lua_classfunction(luaVM, "setItemText", "guiGridListSetItemText"); - lua_classfunction(luaVM, "setScrollBars", "guiGridListSetScrollBars"); - lua_classfunction(luaVM, "setSelectedItem", "guiGridListSetSelectedItem"); - lua_classfunction(luaVM, "setSelectionMode", "guiGridListSetSelectionMode"); - lua_classfunction(luaVM, "setSortingEnabled", "guiGridListSetSortingEnabled"); - lua_classfunction(luaVM, "setColumnWidth", "guiGridListSetColumnWidth"); - lua_classfunction(luaVM, "setItemColor", "guiGridListSetItemColor"); - lua_classfunction(luaVM, "setColumnTitle", "guiGridListSetColumnTitle"); - lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiGridListSetHorizontalScrollPosition"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiGridListSetVerticalScrollPosition"); - - lua_classvariable(luaVM, "rowCount", NULL, "guiGridListGetRowCount"); - lua_classvariable(luaVM, "selectedCount", NULL, "guiGridListGetSelectedCount"); - lua_classvariable(luaVM, "selectedItems", NULL, "guiGridListGetSelectedItems"); - lua_classvariable(luaVM, "columnCount", NULL, "guiGridListGetColumnCount"); - lua_classvariable(luaVM, "selectionMode", "guiGridListSetSelectionMode", NULL); - lua_classvariable(luaVM, "sortingEnabled", "guiGridListSetSortingEnabled", NULL); - lua_classvariable(luaVM, "horizontalScrollPosition", "guiGridListSetHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiGridListGetVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); - // lua_classvariable ( luaVM, "selectedItem", NULL, "guiGridListGetSelectedItem" ); table - // lua_classvariable ( luaVM, "selectedItem", "guiGridListSetSelectedItem", NULL ); .selectedItem[column] = row (row in column) table - // lua_classvariable ( luaVM, "itemColor", "setItemColor", "getItemColor" ); table - // lua_classvariable ( luaVM, "columnTitle", "setColumnTitle", "getColumnTitle" ); table - - lua_registerclass(luaVM, "GuiGridList", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiTabPanelClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateTabPanel"); - - lua_classfunction(luaVM, "getSelectedTab", "guiGetSelectedTab"); - - lua_classfunction(luaVM, "setSelectedTab", "guiSetSelectedTab"); - - lua_classvariable(luaVM, "selectedTab", "guiSetSelectedTab", "guiGetSelectedTab"); - - lua_registerclass(luaVM, "GuiTabPanel", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiTabClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateTab"); - lua_classfunction(luaVM, "delete", "guiDeleteTab"); - - lua_registerclass(luaVM, "GuiTab", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiFontClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateFont"); - - lua_registerclass(luaVM, "GuiFont", "Element"); -} - -int CLuaGUIDefs::GUIGetInputEnabled(lua_State* luaVM) -{ - lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIGetInputEnabled()); - return 1; -} - -int CLuaGUIDefs::GUISetInputEnabled(lua_State* luaVM) -{ - // bool guiSetInputEnabled ( bool enabled ) - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetInputMode(enabled ? INPUTMODE_NO_BINDS : INPUTMODE_ALLOW_BINDS); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetInputMode(lua_State* luaVM) -{ - // bool guiSetInputMode ( string mode ) - eInputMode mode; - - CScriptArgReader argStream(luaVM); - argStream.ReadEnumString(mode); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetInputMode(mode); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetInputMode(lua_State* luaVM) -{ - eInputMode mode = CStaticFunctionDefinitions::GUIGetInputMode(); - lua_pushstring(luaVM, EnumToString(mode)); - return 1; -} - -int CLuaGUIDefs::GUIIsChatBoxInputActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsChatInputEnabled()); - return 1; -} - -int CLuaGUIDefs::GUIIsConsoleActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->GetConsole()->IsVisible()); - return 1; -} - -int CLuaGUIDefs::GUIIsDebugViewActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsDebugVisible()); - return 1; -} - -int CLuaGUIDefs::GUISetDebugViewActive(lua_State* luaVM) -{ - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - g_pCore->SetDebugVisible(enabled); - - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIIsMainMenuActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsMenuVisible()); - return 1; -} - -int CLuaGUIDefs::GUIIsMTAWindowActive(lua_State* luaVM) -{ - bool bActive = - (g_pCore->IsChatInputEnabled() || g_pCore->IsMenuVisible() || g_pCore->GetConsole()->IsVisible() || g_pClientGame->GetTransferBox()->IsVisible()); - - lua_pushboolean(luaVM, bActive); - return 1; -} - -int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); - return 1; -} - -int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) -{ - bool bEnabled; - CScriptArgReader argStream(luaVM); - argStream.ReadBool(bEnabled); - - if (!argStream.HasErrors()) - { - g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - return 1; -} - -int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); - return 1; -} - -int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) -{ - // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) - CVector2D position; - CVector2D size; - SString titleBarText; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(titleBarText); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateWindow(*pLuaMain, position, size, titleBarText, relative); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateLabel(lua_State* luaVM) -{ - // element guiCreateLabel ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateLabel(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateStaticImage(lua_State* luaVM) -{ - // element guiCreateStaticImage ( float x, float y, float width, float height, string path, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString path; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(path); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CResource* pResource = pLuaMain->GetResource(); - SString strPath; - if (CResourceManager::ParseResourcePathInput(path, pResource, &strPath)) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateStaticImage(*pLuaMain, position, size, strPath, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - else - argStream.SetCustomError(path, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateButton(lua_State* luaVM) -{ - // element guiCreateButton ( float x, float y, float width, float height, string text, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateButton(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateProgressBar(lua_State* luaVM) -{ - // element guiCreateProgressBar ( float x, float y, float width, float height, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateProgressBar(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateCheckBox(lua_State* luaVM) -{ - // element guiCreateCheckBox ( float x, float y, float width, float height, string text, bool selected, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool selected; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(selected); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateCheckBox(*pLuaMain, position, size, text, selected, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateRadioButton(lua_State* luaVM) -{ - // element guiCreateRadioButton ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateRadioButton(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateEdit(lua_State* luaVM) -{ - // gui-edit guiCreateEdit ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateEdit(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateMemo(lua_State* luaVM) -{ - // gui-memo guiCreateMemo ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateMemo(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateGridList(lua_State* luaVM) -{ - // element guiCreateGridList ( float x, float y, float width, float height, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateGridList(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateScrollPane(lua_State* luaVM) -{ - // element guiCreateScrollPane( float x, float y, float width, float height, bool relative, [gui-element parent = nil]) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollPane(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateScrollBar(lua_State* luaVM) -{ - // gui-scrollbar guiCreateScrollBar ( float x, float y, float width, float height, bool horizontal, bool relative, [gui-element parent = nil]) - CVector2D position; - CVector2D size; - bool horizontal; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(horizontal); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollBar(*pLuaMain, position, size, horizontal, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateTabPanel(lua_State* luaVM) -{ - // element guiCreateTabPanel ( float x, float y, float width, float height, bool relative, [element parent = nil ] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTabPanel(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIStaticImageLoadImage(lua_State* luaVM) -{ - // bool guiStaticImageLoadImage ( element theElement, string filename ) - CClientGUIElement* theElement; - SString filename; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadString(filename); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CResource* pResource = pLuaMain->GetResource(); - SString strPath; - if (CResourceManager::ParseResourcePathInput(filename, pResource, &strPath)) - { - if (CStaticFunctionDefinitions::GUIStaticImageLoadImage(*theElement, strPath)) - { - lua_pushboolean(luaVM, true); - return 1; - } - else - argStream.SetCustomError(filename, "Error loading image"); - } - else - argStream.SetCustomError(filename, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIStaticImageGetNativeSize(lua_State* luaVM) -{ - // bool guiStaticImageGetNativeSize ( element theElement, string filename ) - CClientGUIElement* theElement; - CVector2D vecSize; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - if (CStaticFunctionDefinitions::GUIStaticImageGetNativeSize(*theElement, vecSize)) - { - lua_pushnumber(luaVM, vecSize.fX); - lua_pushnumber(luaVM, vecSize.fY); - return 2; - } - - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateTab(lua_State* luaVM) -{ - // element guiCreateTab ( string text, element parent ) - SString text; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadString(text); - argStream.ReadUserData(parent); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTab(*pLuaMain, text, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetSelectedTab(lua_State* luaVM) -{ - // element guiGetSelectedTab ( element tabPanel ) - CClientGUIElement* tabPanel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabPanel); - - if (!argStream.HasErrors()) - { - CClientGUIElement* pTab = CStaticFunctionDefinitions::GUIGetSelectedTab(*tabPanel); - lua_pushelement(luaVM, pTab); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetSelectedTab(lua_State* luaVM) -{ - // bool guiSetSelectedTab ( element tabPanel, element theTab ) - CClientGUIElement* tabPanel; - CClientGUIElement* theTab; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabPanel); - argStream.ReadUserData(theTab); - - if (!argStream.HasErrors()) - { - if (CStaticFunctionDefinitions::GUISetSelectedTab(*tabPanel, *theTab)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIDeleteTab(lua_State* luaVM) -{ - // bool guiDeleteTab ( element tabToDelete, element tabPanel ) - CClientGUIElement* tabToDelete; - CClientGUIElement* tabPanel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabToDelete); - argStream.ReadUserData(tabPanel); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - if (CStaticFunctionDefinitions::GUIDeleteTab(*pLuaMain, tabToDelete, tabPanel)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetText(lua_State* luaVM) -{ - // bool guiSetText ( element guiElement, string text ) - CClientGUIElement* guiElement; - SString text; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(text); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetText(*guiElement, text); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetFont(lua_State* luaVM) -{ - // bool guiSetFont ( element guiElement, mixed font ) - CClientGUIElement* guiElement; - SString strFontName; - CClientGuiFont* pGuiFontElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - MixedReadGuiFontString(argStream, strFontName, "default-normal", pGuiFontElement); - - if (!argStream.HasErrors()) - { - if (guiElement->SetFont(strFontName, pGuiFontElement)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIBringToFront(lua_State* luaVM) -{ - // bool guiBringToFront ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - if (CStaticFunctionDefinitions::GUIBringToFront(*guiElement)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMoveToBack(lua_State* luaVM) -{ - // bool guiMoveToBack( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMoveToBack(*guiElement); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIRadioButtonSetSelected(lua_State* luaVM) -{ - // bool guiRadioButtonSetSelected ( element guiRadioButton, bool state ) - CClientGUIElement* guiRadioButton; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiRadioButton); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIRadioButtonSetSelected(*guiRadioButton, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICheckBoxSetSelected(lua_State* luaVM) -{ - // bool guiCheckBoxSetSelected ( element theCheckbox, bool state ) - CClientGUIElement* theCheckbox; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theCheckbox); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUICheckBoxSetSelected(*theCheckbox, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIRadioButtonGetSelected(lua_State* luaVM) -{ - // bool guiRadioButtonGetSelected( element guiRadioButton ) - CClientGUIElement* guiRadioButton; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiRadioButton); - - if (!argStream.HasErrors()) - { - bool bResult = static_cast(guiRadioButton->GetCGUIElement())->GetSelected(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICheckBoxGetSelected(lua_State* luaVM) -{ - // bool guiCheckBoxGetSelected ( element theCheckbox ) - CClientGUIElement* theCheckbox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theCheckbox); - - if (!argStream.HasErrors()) - { - bool bResult = static_cast(theCheckbox->GetCGUIElement())->GetSelected(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIProgressBarSetProgress(lua_State* luaVM) -{ - // bool guiProgressBarSetProgress ( progressBar theProgressbar, float progress ) - CClientGUIElement* theProgressbar; - float progress; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theProgressbar); - argStream.ReadNumber(progress); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIProgressBarSetProgress(*theProgressbar, static_cast(progress)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollBarSetScrollPosition(lua_State* luaVM) -{ - // bool guiScrollBarSetScrollPosition ( gui-scrollBar theScrollBar, float amount ) - CClientGUIElement* theScrollBar; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollBar); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollBarSetScrollPosition(*theScrollBar, static_cast(amount)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetHorizontalScrollPosition(lua_State* luaVM) -{ - // bool guiScrollPaneSetHorizontalScrollPosition ( gui-scrollPane theScrollPane, float amount ) - CClientGUIElement* theScrollPane; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetHorizontalScrollPosition(*theScrollPane, amount); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiScrollPaneSetVerticalScrollPosition ( gui-scrollPane theScrollPane, float amount ) - CClientGUIElement* theScrollPane; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetVerticalScrollPosition(*theScrollPane, amount); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIProgressBarGetProgress(lua_State* luaVM) -{ - // float guiProgressBarGetProgress ( progressBar theProgressbar ); - CClientGUIElement* theProgressbar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theProgressbar); - - if (!argStream.HasErrors()) - { - int iProgress = (int)(static_cast(theProgressbar->GetCGUIElement())->GetProgress() * 100.0f + 0.5f); - lua_pushnumber(luaVM, iProgress); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneGetHorizontalScrollPosition(lua_State* luaVM) -{ - // float guiScrollPaneGetHorizontalScrollPosition ( gui-scrollPane theScrollPane ) - CClientGUIElement* theScrollPane; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - - if (!argStream.HasErrors()) - { - float fPos = static_cast(theScrollPane->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiScrollPaneGetVerticalScrollPosition ( gui-scrollPane theScrollPane ) - CClientGUIElement* theScrollPane; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - - if (!argStream.HasErrors()) - { - float fPos = static_cast(theScrollPane->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollBarGetScrollPosition(lua_State* luaVM) -{ - // float guiScrollBarGetScrollPosition ( gui-scrollBar theScrollBar ) - CClientGUIElement* theScrollBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollBar); - - if (!argStream.HasErrors()) - { - int iPos = (int)(static_cast(theScrollBar->GetCGUIElement())->GetScrollPosition() * 100.0f); - lua_pushnumber(luaVM, iPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetText(lua_State* luaVM) -{ - // string guiGetText ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - SString strText = guiElement->GetCGUIElement()->GetText(); - lua_pushstring(luaVM, strText); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetFont(lua_State* luaVM) -{ - // string,font guiGetFont ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - CClientGuiFont* pGuiFontElement; - SString strFontName = guiElement->GetFont(&pGuiFontElement); - - if (strFontName != "") - lua_pushstring(luaVM, strFontName); - else - lua_pushnil(luaVM); - lua_pushelement(luaVM, pGuiFontElement); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetSize(lua_State* luaVM) -{ - // float float guiGetSize ( element theElement, bool relative ) - CClientGUIElement* theElement; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CVector2D Size; - theElement->GetCGUIElement()->GetSize(Size, relative); - - lua_pushnumber(luaVM, Size.fX); - lua_pushnumber(luaVM, Size.fY); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetScreenSize(lua_State* luaVM) -{ - const CVector2D Size = CStaticFunctionDefinitions::GUIGetScreenSize(); - - lua_pushnumber(luaVM, Size.fX); - lua_pushnumber(luaVM, Size.fY); - return 2; -} - -int CLuaGUIDefs::GUIGetPosition(lua_State* luaVM) -{ - // float, float guiGetPosition ( element guiElement, bool relative ) - CClientGUIElement* guiElement; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CVector2D Pos; - guiElement->GetCGUIElement()->GetPosition(Pos, relative); - - lua_pushnumber(luaVM, Pos.fX); - lua_pushnumber(luaVM, Pos.fY); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetAlpha(lua_State* luaVM) -{ - // bool guiSetAlpha ( element guielement, float alpha ) - CClientGUIElement* guiElement; - float alpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(alpha); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetAlpha(*guiElement, Clamp(0.0f, alpha, 1.0f)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetAlpha(lua_State* luaVM) -{ - // int guiGetAlpha ( element guiElement [, bool effectiveAlpha = false] ) - CClientGUIElement* guiElement; - bool bEffectiveAlpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(bEffectiveAlpha, false); - - if (!argStream.HasErrors()) - { - float fAlpha = !bEffectiveAlpha ? guiElement->GetCGUIElement()->GetAlpha() : guiElement->GetCGUIElement()->GetEffectiveAlpha(); - lua_pushnumber(luaVM, fAlpha); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetVisible(lua_State* luaVM) -{ - // bool guiSetVisible ( element guiElement, bool state ) - CClientGUIElement* guiElement; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetVisible(*guiElement, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetEnabled(lua_State* luaVM) -{ - // bool guiSetEnabled ( element guiElement, bool enabled ) - CClientGUIElement* guiElement; - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetEnabled(*guiElement, enabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetProperty(lua_State* luaVM) -{ - // bool guiSetProperty ( element guiElement, string property, string value ) - CClientGUIElement* guiElement; - SString property; - SString value; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(property); - argStream.ReadString(value); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetProperty(*guiElement, property, value); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetVisible(lua_State* luaVM) -{ - // bool guiGetVisible ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - bool bResult = guiElement->GetCGUIElement()->IsVisible(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetEnabled(lua_State* luaVM) -{ - // bool guiGetEnabled ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - bool bResult = guiElement->GetCGUIElement()->IsEnabled(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetProperty(lua_State* luaVM) -{ - // string guiGetProperty ( element guiElement, string property ) - CClientGUIElement* guiElement; - SString property; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(property); - - if (!argStream.HasErrors()) - { - SString strValue = guiElement->GetCGUIElement()->GetProperty(property); - lua_pushstring(luaVM, strValue); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetProperties(lua_State* luaVM) -{ - // table guiGetProperties ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - // Create a new table - lua_newtable(luaVM); - - // Add all our properties to the table on top of the given lua main's stack - unsigned int uiIndex = 0; - CGUIPropertyIter iter = guiElement->GetCGUIElement()->GetPropertiesBegin(); - CGUIPropertyIter iterEnd = guiElement->GetCGUIElement()->GetPropertiesEnd(); - for (; iter != iterEnd; iter++) - { - const char* szKey = (*iter)->strKey; - const char* szValue = (*iter)->strValue; - - // Add it to the table - lua_pushstring(luaVM, szKey); - lua_pushstring(luaVM, szValue); - lua_settable(luaVM, -3); - } - - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetSize(lua_State* luaVM) -{ - // bool guiSetSize ( element guiElement, float width, float height, bool relative ) - CClientGUIElement* guiElement; - float width; - float height; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(width); - argStream.ReadNumber(height); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetSize(*guiElement, CVector2D(width, height), relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetPosition(lua_State* luaVM) -{ - // bool guiSetPosition ( element guiElement, float x, float y, bool relative ) - CClientGUIElement* guiElement; - float x; - float y; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(x); - argStream.ReadNumber(y); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetPosition(*guiElement, CVector2D(x, y), relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSortingEnabled(lua_State* luaVM) -{ - // bool guiGridListSetSortingEnabled ( element guiGridlist, bool enabled ) - CClientGUIElement* guiGridlist; - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSortingEnabled(*guiGridlist, enabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAddColumn(lua_State* luaVM) -{ - // int guiGridListAddColumn ( element gridList, string title, float width ) - CClientGUIElement* guiGridlist; - SString title; - float width; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadString(title); - argStream.ReadNumber(width); - - if (!argStream.HasErrors()) - { - uint id = CStaticFunctionDefinitions::GUIGridListAddColumn(*guiGridlist, title, width); - lua_pushnumber(luaVM, id); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListRemoveColumn(lua_State* luaVM) -{ - // bool guiGridListRemoveColumn ( element guiGridlist, int columnIndex ) - CClientGUIElement* guiGridlist; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListRemoveColumn(*guiGridlist, columnIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetColumnWidth(lua_State* luaVM) -{ - // bool guiGridListSetColumnWidth ( element gridList, int columnIndex, number width, bool relative ) - CClientGUIElement* guiGridlist; - int columnIndex; - float width; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - argStream.ReadNumber(width); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetColumnWidth(*guiGridlist, columnIndex, width, relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnWidth(lua_State* luaVM) -{ - // float guiGridListGetColumnWidth ( element gridList, int columnIndex, bool relative ) - CClientGUIElement* pGridList; - int columnIndex; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pGridList); - argStream.ReadNumber(columnIndex); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - float width; - if (static_cast(pGridList->GetCGUIElement())->GetColumnWidth(columnIndex, width, relative)) - { - lua_pushnumber(luaVM, width); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetColumnTitle(lua_State* luaVM) -{ - // bool guiGridListSetColumnTitle ( element guiGridlist, int columnIndex, string title ) - CClientGUIElement* guiGridlist; - int iColumnIndex; - SString sTitle; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(iColumnIndex); - argStream.ReadString(sTitle); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) - { - CStaticFunctionDefinitions::GUIGridListSetColumnTitle(*guiGridlist, iColumnIndex, sTitle); - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnTitle(lua_State* luaVM) -{ - // string guiGridListGetColumnTitle ( element guiGridlist, int columnIndex ) - CClientGUIElement* guiGridlist; - int iColumnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(iColumnIndex); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) - { - const char* szTitle = static_cast(guiGridlist->GetCGUIElement())->GetColumnTitle(iColumnIndex); - lua_pushstring(luaVM, szTitle); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAddRow(lua_State* luaVM) -{ - // int guiGridListAddRow ( element gridList ) - // int guiGridListAddRow ( element gridList, int/string itemText1, int/string itemText2 ... ) - CClientGUIElement* guiGridlist; - CLuaArguments Arguments; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadLuaArguments(Arguments); - - if (!argStream.HasErrors()) - { - int iRet = 0; - if (Arguments.Count() == 0) - iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true); - else - { - // Vector containing our string arguments. We add a bool to store whether it was originally a number. - std::vector > m_items; - std::vector::const_iterator it = Arguments.IterBegin(); - for (it; it != Arguments.IterEnd(); it++) - { - CLuaArgument* pArgument = *it; - SString strItemText; - bool bNumber = false; - - // Check the type of the argument and convert it to a string we can process - uint type = pArgument->GetType(); - if (type == LUA_TNUMBER) - { - // Grab the lua string and its size - const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); - size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); - - // Set our string - strItemText.assign(szLuaString, sizeLuaString); - bNumber = true; - } - else if (type == LUA_TSTRING) - strItemText = pArgument->GetString(); - else - continue; - - m_items.push_back(std::make_pair(strItemText, bNumber)); - } - iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true, &m_items); - } - - if (iRet >= 0) - { - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushnumber(luaVM, iRet); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListInsertRowAfter(lua_State* luaVM) -{ - // int guiGridListInsertRowAfter ( element gridList, int rowIndex ) - // int guiGridListInsertRowAfter ( element gridList, int rowIndex, int/string itemText1, int/string itemText2 ... ) - CClientGUIElement* guiGridlist; - int rowIndex; - CLuaArguments Arguments; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadLuaArguments(Arguments); - - if (!argStream.HasErrors()) - { - int iRet = 0; - if (Arguments.Count() == 0) - iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex); - else - { - // Vector containing our string arguments. We add a bool to store whether it was originally a number. - std::vector > m_items; - std::vector::const_iterator it = Arguments.IterBegin(); - for (it; it != Arguments.IterEnd(); it++) - { - CLuaArgument* pArgument = *it; - SString strItemText; - bool bNumber = false; - - // Check the type of the argument and convert it to a string we can process - uint type = pArgument->GetType(); - if (type == LUA_TNUMBER) - { - // Grab the lua string and its size - const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); - size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); - - // Set our string - strItemText.assign(szLuaString, sizeLuaString); - bNumber = true; - } - else if (type == LUA_TSTRING) - strItemText = pArgument->GetString(); - else - continue; - - m_items.push_back(std::make_pair(strItemText, bNumber)); - } - iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex, &m_items); - } - - if (iRet >= 0) - { - lua_pushnumber(luaVM, iRet); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAutoSizeColumn(lua_State* luaVM) -{ - // bool guiGridListAutoSizeColumn ( element gridList, int columnIndex ) - CClientGUIElement* guiGridlist; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListAutoSizeColumn(*guiGridlist, columnIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListClear(lua_State* luaVM) -{ - // bool guiGridListClear ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListClear(*guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSelectionMode(lua_State* luaVM) -{ - // bool guiGridListSetSelectionMode ( guiElement gridlist, int mode ) - CClientGUIElement* guiGridlist; - int mode; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(mode); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSelectionMode(*guiGridlist, mode); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedItem(lua_State* luaVM) -{ - // int, int guiGridListGetSelectedItem ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iRow = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemRow(); - int iColumn = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemColumn(); - lua_pushnumber(luaVM, iRow); - lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedItems(lua_State* luaVM) -{ - // table guiGridListGetSelectedItems ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - CGUIGridList* pList = static_cast(guiGridlist->GetCGUIElement()); - CGUIListItem* pItem = NULL; - - lua_newtable(luaVM); - - for (int i = 1; i <= pList->GetSelectedCount(); i++) - { - pItem = pList->GetNextSelectedItem(pItem); - if (!pItem) - break; - - lua_pushnumber(luaVM, i); - lua_newtable(luaVM); - - // column - lua_pushstring(luaVM, "column"); - lua_pushnumber(luaVM, pList->GetItemColumnIndex(pItem)); - lua_settable(luaVM, -3); - - // row - lua_pushstring(luaVM, "row"); - lua_pushnumber(luaVM, pList->GetItemRowIndex(pItem)); - lua_settable(luaVM, -3); - - // push to main table - lua_settable(luaVM, -3); - } - - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedCount(lua_State* luaVM) -{ - // int guiGridListGetSelectedCount ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iCount = static_cast(guiGridlist->GetCGUIElement())->GetSelectedCount(); - lua_pushnumber(luaVM, iCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSelectedItem(lua_State* luaVM) -{ - // bool guiGridListSetSelectedItem ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - bool bReset; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadBool(bReset, true); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSelectedItem(*guiGridlist, rowIndex, columnIndex, bReset); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListRemoveRow(lua_State* luaVM) -{ - // bool guiGridListRemoveRow ( element gridList, int rowIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListRemoveRow(*guiGridlist, rowIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemText(lua_State* luaVM) -{ - // string guiGridListGetItemText ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - const char* szText = static_cast(guiGridlist->GetCGUIElement())->GetItemText(rowIndex, columnIndex); - lua_pushstring(luaVM, szText); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemData(lua_State* luaVM) -{ - // string guiGridListGetItemData ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - void* pData = static_cast(guiGridlist->GetCGUIElement())->GetItemData(rowIndex, columnIndex); - CLuaArgument* pVariable = reinterpret_cast(pData); - if (pVariable) - pVariable->Push(luaVM); - else - lua_pushnil(luaVM); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemColor(lua_State* luaVM) -{ - // int int int int guiGridListGetItemColor ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255, ucAlpha = 255; - if (static_cast(guiGridlist->GetCGUIElement())->GetItemColor(rowIndex, columnIndex, ucRed, ucGreen, ucBlue, ucAlpha)) - { - lua_pushnumber(luaVM, ucRed); - lua_pushnumber(luaVM, ucGreen); - lua_pushnumber(luaVM, ucBlue); - lua_pushnumber(luaVM, ucAlpha); - return 4; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetHorizontalScrollPosition(lua_State* luaVM) -{ - // float guiGridListGetHorizontalScrollPosition ( element guiGridlist ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPosition); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiGridListGetVerticalScrollPosition ( element guiGridlist ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPosition); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemText(lua_State* luaVM) -{ - // bool guiGridListSetItemText ( element gridList, int rowIndex, int columnIndex, string text, bool section, bool number ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - SString text; - bool section; - bool number; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadString(text); - argStream.ReadBool(section); - argStream.ReadBool(number); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetItemText(*guiGridlist, rowIndex, columnIndex, text, section, number, true); - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemData(lua_State* luaVM) -{ - // bool guiGridListSetItemData ( element gridList, int rowIndex, int columnIndex, string data ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - CLuaArgument data; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadLuaArgument(data); - - if (!argStream.HasErrors()) - { - CLuaArgument* pData = new CLuaArgument(data); - CStaticFunctionDefinitions::GUIGridListSetItemData(*guiGridlist, rowIndex, columnIndex, pData); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemColor(lua_State* luaVM) -{ - // bool guiGridListSetItemColor ( element gridList, int rowIndex, int columnIndex, int red, int green, int blue[, int alpha = 255 ] ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - int red; - int green; - int blue; - int alpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadNumber(red); - argStream.ReadNumber(green); - argStream.ReadNumber(blue); - argStream.ReadNumber(alpha, 255); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetItemColor(*guiGridlist, rowIndex, columnIndex, red, green, blue, alpha); - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetScrollBars(lua_State* luaVM) -{ - // bool guiGridListSetScrollBars ( element guiGridlist, bool horizontalBar, bool verticalBar ) - CClientGUIElement* guiGridlist; - bool horizontalBar; - bool verticalBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadBool(horizontalBar); - argStream.ReadBool(verticalBar); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetScrollBars(*guiGridlist, horizontalBar, verticalBar); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetHorizontalScrollPosition(lua_State* luaVM) -{ - // bool guiGridListSetHorizontalScrollPosition ( element guiGridlist, float fPosition ) - CClientGUIElement* guiGridlist; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetHorizontalScrollPosition(*guiGridlist, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiGridListSetVerticalScrollPosition ( element guiGridlist, float fPosition ) - CClientGUIElement* guiGridlist; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetVerticalScrollPosition(*guiGridlist, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetScrollBars(lua_State* luaVM) -{ - // bool guiScrollPaneSetScrollBars ( element scrollPane, bool horizontal, bool vertical ) - CClientGUIElement* scrollPane; - bool horizontalBar; - bool verticalBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(scrollPane); - argStream.ReadBool(horizontalBar); - argStream.ReadBool(verticalBar); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetScrollBars(*scrollPane, horizontalBar, verticalBar); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetRowCount(lua_State* luaVM) -{ - // int guiGridListGetRowCount ( element theList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iRowCount = static_cast(guiGridlist->GetCGUIElement())->GetRowCount(); - lua_pushnumber(luaVM, iRowCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnCount(lua_State* luaVM) -{ - // int guiGridListGetColumnCount ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - lua_pushnumber(luaVM, iColumnCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) -{ - // bool guiEditSetReadOnly ( element editField, bool status ) - CClientGUIElement* editField; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetReadOnly(*editField, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) -{ - // bool guiEditIsReadOnly( element editField ) - CClientGUIElement* editField; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) -{ - // bool guiMemoSetReadOnly ( gui-memo theMemo, bool status ) - CClientGUIElement* theMemo; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetReadOnly(*theMemo, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) -{ - // bool guiMemoIsReadOnly( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) -{ - // bool guiEditSetMasked ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) -{ - // bool guiEditSetMaxLength ( element theElement, int length ) - CClientGUIElement* theElement; - int length; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(length); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetMaxLength(*theElement, length); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) -{ - // bool guiEditSetCaretIndex ( element theElement, int index ) - CClientGUIElement* theElement; - int index; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(index); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetCaretIndex(*theElement, index); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) -{ - // int guiEditGetCaretIndex ( element theElement ) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - lua_pushnumber(luaVM, static_cast(theElement->GetCGUIElement())->GetCaretIndex()); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) -{ - // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) - CClientGUIElement* theMemo; - int index; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(index); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetCaretIndex(*theMemo, index); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiMemoSetVerticalScrollPosition ( gui-memo theMemo, float fPosition ) - CClientGUIElement* theMemo; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) -{ - // bool guiMemoGetCaretIndex ( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - lua_pushnumber(luaVM, static_cast(theMemo->GetCGUIElement())->GetCaretIndex()); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiMemoGetVerticalScrollPosition ( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); - float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) -{ - // bool guiWindowSetMovable ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIWindowSetMovable(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) -{ - // bool guiWindowSetSizable ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIWindowSetSizable(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) -{ - // float guiLabelGetTextExtent ( element theLabel ) - CClientGUIElement* theLabel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - - if (!argStream.HasErrors()) - { - float fExtent = static_cast(theLabel->GetCGUIElement())->GetTextExtent(); - lua_pushnumber(luaVM, fExtent); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetFontHeight(lua_State* luaVM) -{ - // float guiLabelGetFontHeight ( element theLabel ) - CClientGUIElement* theLabel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - - if (!argStream.HasErrors()) - { - float fHeight = static_cast(theLabel->GetCGUIElement())->GetFontHeight(); - lua_pushnumber(luaVM, fHeight); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetColor(lua_State* luaVM) -{ - // bool guiLabelSetColor ( element theElement, int red, int green, int blue ) - CClientGUIElement* theElement; - int red; - int green; - int blue; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(red); - argStream.ReadNumber(green); - argStream.ReadNumber(blue); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUILabelSetColor(*theElement, red, green, blue); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetColor(lua_State* luaVM) -{ - // int r, int g, int b guiLabelGetColor ( element theElement ) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255; - static_cast(theElement->GetCGUIElement())->GetTextColor(ucRed, ucGreen, ucBlue); - lua_pushnumber(luaVM, ucRed); - lua_pushnumber(luaVM, ucGreen); - lua_pushnumber(luaVM, ucBlue); - return 3; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetVerticalAlign(lua_State* luaVM) -{ - // bool guiLabelSetVerticalAlign ( element theLabel, string align ) - CClientGUIElement* theLabel; - CGUIVerticalAlign align; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - argStream.ReadEnumString(align); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUILabelSetVerticalAlign(*theLabel, align); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetHorizontalAlign(lua_State* luaVM) -{ - // bool guiLabelSetHorizontalAlign ( element theLabel, string align, [ bool wordwrap = false ] ) - CClientGUIElement* theLabel; - CGUIHorizontalAlign align; - bool wordwrap; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - argStream.ReadEnumString(align); - argStream.ReadBool(wordwrap, false); - - if (!argStream.HasErrors()) - { - if (wordwrap) - align = (CGUIHorizontalAlign)(align + 4); - CStaticFunctionDefinitions::GUILabelSetHorizontalAlign(*theLabel, align); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) -{ - //* chat_font - Returns the chatbox font - //* chat_lines - Returns how many lines the chatbox has - //* chat_color - Returns the background color of the chatbox - //* chat_text_color - Returns the chatbox text color - //* chat_input_color - Returns the background color of the chatbox input - //* chat_input_prefix_color - Returns the color of the input prefix text - //* chat_input_text_color - Returns the color of the text in the chatbox input - //* chat_scale - Returns the scale of the text in the chatbox - //* chat_position_offset_x - Returns the position offset of the chatbox on the x axis - //* chat_position_offset_y - Returns the position offset of the chatbox on the y axis - //* chat_position_horizontal - Returns the horizontal position of the chatbox - //* chat_position_vertical - Returns the vertical position of the chatbox - //* chat_text_alignment - Returns the horizontal alignment of the chatbox text - //* chat_width - Returns the scale of the background width - //* chat_css_style_text - Returns whether text fades out over time - //* chat_css_style_background - Returns whether the background fades out over time - //* chat_line_life - Returns how long it takes for text to start fading out - //* chat_line_fade_out - Returns how long takes for text to fade out - //* chat_use_cegui - Returns whether CEGUI is used to render the chatbox - //* text_scale - Returns text scale - - CCVarsInterface* pCVars = g_pCore->GetCVars(); - int iNumber; - float fNumber; - pCVars->Get("chat_font", fNumber); - lua_newtable(luaVM); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_font"); - pCVars->Get("chat_lines", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_lines"); - pCVars->Get("chat_width", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_width"); - pCVars->Get("chat_position_offset_x", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_x"); - pCVars->Get("chat_position_offset_y", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_y"); - pCVars->Get("chat_position_horizontal", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_horizontal"); - pCVars->Get("chat_position_vertical", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_vertical"); - pCVars->Get("chat_text_alignment", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_text_alignment"); - pCVars->Get("chat_css_style_text", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_text"); - pCVars->Get("chat_css_style_background", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_background"); - pCVars->Get("chat_line_life", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_life"); - pCVars->Get("chat_line_fade_out", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_fade_out"); - pCVars->Get("text_scale", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "text_scale"); - pCVars->Get("chat_use_cegui", fNumber); - lua_pushboolean(luaVM, fNumber ? true : false); - lua_setfield(luaVM, -2, "chat_use_cegui"); - std::string strCVar; - std::stringstream ss; - int iR, iG, iB, iA; - pCVars->Get("chat_color", strCVar); - if (!strCVar.empty()) - { - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_color"); - } - pCVars->Get("chat_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_text_color"); - } - pCVars->Get("chat_input_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_color"); - } - pCVars->Get("chat_input_prefix_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_prefix_color"); - } - pCVars->Get("chat_input_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_text_color"); - } - pCVars->Get("chat_scale", strCVar); - if (!strCVar.empty()) - { - float fX, fY; - ss.clear(); - ss.str(strCVar); - ss >> fX >> fY; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, fX); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, fY); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_scale"); - } - - return 1; -} - -int CLuaGUIDefs::GUICreateComboBox(lua_State* luaVM) -{ - // element guiCreateComboBox ( float x, float y, float width, float height, string caption, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - SString caption; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(caption); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateComboBox(*pLuaMain, position, size, caption, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxAddItem(lua_State* luaVM) -{ - // int guiComboBoxAddItem( element comboBox, string value ) - CClientGUIElement* comboBox; - SString value; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadString(value); - - if (!argStream.HasErrors()) - { - int newId = CStaticFunctionDefinitions::GUIComboBoxAddItem(*comboBox, value); - lua_pushnumber(luaVM, newId); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxRemoveItem(lua_State* luaVM) -{ - // bool guiComboBoxRemoveItem( element comboBox, int itemId ) - CClientGUIElement* comboBox; - int itemId; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxRemoveItem(*comboBox, itemId); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxClear(lua_State* luaVM) -{ - // bool guiComboBoxClear ( element comboBox ) - CClientGUIElement* comboBox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxClear(*comboBox); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxGetSelected(lua_State* luaVM) -{ - // int guiComboBoxGetSelected ( element comboBox ) - CClientGUIElement* comboBox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - - if (!argStream.HasErrors()) - { - int selected = CStaticFunctionDefinitions::GUIComboBoxGetSelected(*comboBox); - lua_pushnumber(luaVM, selected); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxSetSelected(lua_State* luaVM) -{ - // bool guiComboBoxSetSelected ( element comboBox, int itemIndex ) - CClientGUIElement* comboBox; - int itemIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemIndex); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxSetSelected(*comboBox, itemIndex); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxGetItemText(lua_State* luaVM) -{ - // string guiComboBoxGetItemText ( element comboBox, int itemId ) - CClientGUIElement* comboBox; - int itemId; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - - if (!argStream.HasErrors()) - { - SString ret = CStaticFunctionDefinitions::GUIComboBoxGetItemText(*comboBox, itemId); - lua_pushstring(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxSetItemText(lua_State* luaVM) -{ - // bool guiComboBoxSetItemText ( element comboBox, int itemId, string text ) - CClientGUIElement* comboBox; - int itemId; - SString text; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - argStream.ReadString(text); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxSetItemText(*comboBox, itemId, text); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateFont(lua_State* luaVM) -{ - // element guiCreateFont( string filepath [, int size=9 ] ) - SString strFilePath; - int iSize; - - CScriptArgReader argStream(luaVM); - argStream.ReadString(strFilePath); - argStream.ReadNumber(iSize, 9); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CResource* pParentResource = pLuaMain->GetResource(); - CResource* pFileResource = pParentResource; - SString strPath, strMetaPath; - if (CResourceManager::ParseResourcePathInput(strFilePath, pFileResource, &strPath, &strMetaPath)) - { - if (FileExists(strPath)) - { - SString strUniqueName = SString("%s*%s*%s", pParentResource->GetName(), pFileResource->GetName(), strMetaPath.c_str()).Replace("\\", "/"); - CClientGuiFont* pGuiFont = g_pClientGame->GetManager()->GetRenderElementManager()->CreateGuiFont(strPath, strUniqueName, iSize); - if (pGuiFont) - { - // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's - // ElementGroup? ** - pGuiFont->SetParent(pParentResource->GetResourceDynamicEntity()); - lua_pushelement(luaVM, pGuiFont); - return 1; - } - argStream.SetCustomError(strFilePath, "Error creating font"); - } - else - argStream.SetCustomError(strFilePath, "File not found"); - } - else - argStream.SetCustomError(strFilePath, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) -{ - // string guiGetCursorType ( ) - auto eType = CStaticFunctionDefinitions::GUIGetCursorType(); - lua_pushstring(luaVM, EnumToString(eType)); - return 1; -} +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp + * PURPOSE: Lua definitions class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" + +void CLuaGUIDefs::LoadFunctions(void) +{ + CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); + CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); + CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); + CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); + + CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); + CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); + CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); + CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); + CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); + CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); + + CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); + CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); + CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); + + CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); + CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); + CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); + CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); + CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); + CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); + CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); + CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); + CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); + CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); + CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); + CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); + CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); + CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); + CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); + CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); + + CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); + CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); + CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); + CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); + CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); + + CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); + CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); + CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); + CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); + CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); + CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); + CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); + CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); + CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); + CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); + CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); + CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); + CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); + CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); + CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); + CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); + CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); + CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); + CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); + CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); + CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); + CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); + CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); + CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); + CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); + CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); + CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); + CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); + CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); + + CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); + CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); + CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); + CLuaCFunctions::AddFunction("guiSetText", GUISetText); + CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); + CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); + CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); + CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); + + CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); + CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); + + CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); + CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); + + CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); + CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); + CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); + CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); + CLuaCFunctions::AddFunction("guiGetText", GUIGetText); + CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); + CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); + CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); + CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); + CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); + + CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); + CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); + + CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); + CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); + + CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); + + CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); + CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); + CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); + CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); + CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); + CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); + + CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); + CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); + CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); + CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); + CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); + CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); + CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); + CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); + + CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); + CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); + + CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); + CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); + + CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); + + CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); + CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); + CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); + CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); + CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); + CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); + CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); +} + +void CLuaGUIDefs::AddClass(lua_State* luaVM) +{ + AddGuiElementClass(luaVM); + AddGuiFontClass(luaVM); + AddGuiWindowClass(luaVM); + AddGuiButtonClass(luaVM); + AddGuiEditClass(luaVM); + AddGuiLabelClass(luaVM); + AddGuiMemoClass(luaVM); + AddGuiImageClass(luaVM); + AddGuiComboBoxClass(luaVM); + AddGuiCheckBoxClass(luaVM); + AddGuiRadioButtonClass(luaVM); + AddGuiScrollPaneClass(luaVM); + AddGuiScrollBarClass(luaVM); + AddGuiProgressBarClass(luaVM); + AddGuiGridlistClass(luaVM); + AddGuiTabPanelClass(luaVM); + AddGuiTabClass(luaVM); +} + +// TODO: vector class +void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "bringToFront", "guiBringToFront"); + lua_classfunction(luaVM, "moveToBack", "guiMoveToBack"); + + lua_classfunction(luaVM, "isChatBoxInputActive", "isChatBoxInputActive"); + lua_classfunction(luaVM, "isConsoleActive", "isConsoleActive"); + lua_classfunction(luaVM, "isDebugViewActive", "isDebugViewActive"); + lua_classfunction(luaVM, "setDebugViewActive", "setDebugViewActive"); + lua_classfunction(luaVM, "isMainMenuActive", "isMainMenuActive"); + lua_classfunction(luaVM, "isMTAWindowActive", "isMTAWindowActive"); + lua_classfunction(luaVM, "isTransferBoxActive", "isTransferBoxActive"); + lua_classfunction(luaVM, "isInputEnabled", "guiGetInputEnabled"); + lua_classfunction(luaVM, "getInputMode", "guiGetInputMode"); + lua_classfunction(luaVM, "getCursorType", "guiGetCursorType"); + + lua_classfunction(luaVM, "getScreenSize", "guiGetScreenSize"); + lua_classfunction(luaVM, "getProperties", "guiGetProperties"); + lua_classfunction(luaVM, "getAlpha", "guiGetAlpha"); + lua_classfunction(luaVM, "getFont", "guiGetFont"); + lua_classfunction(luaVM, "getEnabled", "guiGetEnabled"); + lua_classfunction(luaVM, "getVisible", "guiGetVisible"); + lua_classfunction(luaVM, "getText", "guiGetText"); + lua_classfunction(luaVM, "getPosition", "guiGetPosition"); + lua_classfunction(luaVM, "getSize", "guiGetSize"); + lua_classfunction(luaVM, "getProperty", "guiGetProperty"); + + lua_classfunction(luaVM, "setInputEnabled", "guiSetInputEnabled"); + lua_classfunction(luaVM, "setAlpha", "guiSetAlpha"); + lua_classfunction(luaVM, "setEnabled", "guiSetEnabled"); + lua_classfunction(luaVM, "setFont", "guiSetFont"); + lua_classfunction(luaVM, "setVisible", "guiSetVisible"); + lua_classfunction(luaVM, "setText", "guiSetText"); + lua_classfunction(luaVM, "setInputMode", "guiSetInputMode"); + lua_classfunction(luaVM, "setProperty", "guiSetProperty"); + lua_classfunction(luaVM, "setPosition", "guiSetPosition"); + lua_classfunction(luaVM, "setSize", "guiSetSize"); + + lua_classvariable(luaVM, "chatBoxInputActive", NULL, "isChatBoxInputActive"); + lua_classvariable(luaVM, "consoleActive", NULL, "isConsoleActive"); + lua_classvariable(luaVM, "debugViewActive", "setDebugViewActive", "isDebugViewActive"); + lua_classvariable(luaVM, "mainMenuActive", NULL, "isMainMenuActive"); + lua_classvariable(luaVM, "mtaWindowActive", NULL, "isMTAWindowActive"); + lua_classvariable(luaVM, "transferBoxActive", NULL, "isTransferBoxActive"); + lua_classvariable(luaVM, "inputEnabled", "guiSetInputEnabled", "guiGetInputEnabled"); + lua_classvariable(luaVM, "inputMode", "guiGetInputMode", "guiSetInputMode"); + lua_classvariable(luaVM, "cursorAlpha", "setCursorAlpha", "getCursorAlpha"); + lua_classvariable(luaVM, "cursorType", NULL, "guiGetCursorType"); + lua_classvariable(luaVM, "font", "guiSetFont", "guiGetFont"); + lua_classvariable(luaVM, "visible", "guiSetVisible", "guiGetVisible"); + lua_classvariable(luaVM, "properties", NULL, "guiGetProperties"); + lua_classvariable(luaVM, "alpha", "guiSetAlpha", "guiGetAlpha"); + lua_classvariable(luaVM, "enabled", "guiSetEnabled", "guiGetEnabled"); + lua_classvariable(luaVM, "text", "guiSetText", "guiGetText"); + lua_classvariable(luaVM, "size", "guiSetSize", "guiGetSize"); + lua_classvariable(luaVM, "position", "guiSetPosition", "guiGetPosition"); + lua_classvariable(luaVM, "screenSize", NULL, "guiGetScreenSize"); + // lua_classvariable ( luaVM, "property" "guiSetProperty", "guiGetProperty" ); todo: .property[name] = value + + lua_registerclass(luaVM, "GuiElement", "Element"); +} + +void CLuaGUIDefs::AddGuiWindowClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateWindow"); + lua_classfunction(luaVM, "setMovable", "guiWindowSetMovable"); + lua_classfunction(luaVM, "setSizable", "guiWindowSetSizable"); + + lua_classvariable(luaVM, "movable", "guiWindowSetMovable", NULL); + lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", NULL); + + lua_registerclass(luaVM, "GuiWindow", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiButtonClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateButton"); + + lua_registerclass(luaVM, "GuiButton", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateEdit"); + lua_classfunction(luaVM, "getCaretIndex", "guiEditGetCaretIndex"); + lua_classfunction(luaVM, "setCaretIndex", "guiEditSetCaretIndex"); + lua_classfunction(luaVM, "setReadOnly", "guiEditSetReadOnly"); + lua_classfunction(luaVM, "setMasked", "guiEditSetMasked"); + lua_classfunction(luaVM, "setMaxLength", "guiEditSetMaxLength"); + + lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); + lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", "guiEditIsReadOnly"); + lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); + lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); + + lua_registerclass(luaVM, "GuiEdit", "GuiElement"); +} + +// TODO: specials +void CLuaGUIDefs::AddGuiLabelClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateLabel"); + + lua_classfunction(luaVM, "getFontHeight", "guiLabelGetFontHeight"); + lua_classfunction(luaVM, "getTextExtent", "guiLabelGetTextExtent"); + lua_classfunction(luaVM, "getColor", "guiLabelGetColor"); + + lua_classfunction(luaVM, "setColor", "guiLabelSetColor"); + lua_classfunction(luaVM, "setHorizontalAlign", "guiLabelSetHorizontalAlign"); + lua_classfunction(luaVM, "setVerticalAlign", "guiLabelSetVerticalAlign"); + + lua_classvariable(luaVM, "horizontalAlign", "guiLabelSetHorizontalAlign", NULL); + lua_classvariable(luaVM, "verticalAlign", "guiLabelSetVerticalAlign", NULL); + lua_classvariable(luaVM, "fontHeight", NULL, "guiLabelGetFontHeight"); + lua_classvariable(luaVM, "textExtent", NULL, "guiLabelGetTextExtent"); + // lua_classvariable ( luaVM, "color", "guiLabelGetColor", "guiLabelSetColor" ); + + lua_registerclass(luaVM, "GuiLabel", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiMemoClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateMemo"); + + lua_classfunction(luaVM, "getCaretIndex", "guiMemoGetCaretIndex"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); + + lua_classfunction(luaVM, "setCaretIndex", "guiMemoSetCaretIndex"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiMemoSetVerticalScrollPosition"); + lua_classfunction(luaVM, "setReadOnly", "guiMemoSetReadOnly"); + + lua_classvariable(luaVM, "caretIndex", "guiMemoSetCaretIndex", "guiMemoGetCaretIndex"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiMemoSetVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); + lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", "guiMemoIsReadOnly"); + + lua_registerclass(luaVM, "GuiMemo", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiImageClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateStaticImage"); + lua_classfunction(luaVM, "loadImage", "guiStaticImageLoadImage"); + + lua_classvariable(luaVM, "image", "guiStaticImageLoadImage", NULL); + + lua_registerclass(luaVM, "GuiStaticImage", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiComboBoxClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateComboBox"); + lua_classfunction(luaVM, "addItem", "guiComboBoxAddItem"); + lua_classfunction(luaVM, "clear", "guiComboBoxClear"); + lua_classfunction(luaVM, "removeItem", "guiComboBoxRemoveItem"); + + lua_classfunction(luaVM, "getSelected", "guiComboBoxGetSelected"); + lua_classfunction(luaVM, "getItemText", "guiComboBoxGetItemText"); + + lua_classfunction(luaVM, "setItemText", "guiComboBoxSetItemText"); + lua_classfunction(luaVM, "setSelected", "guiComboBoxSetSelected"); + + lua_classvariable(luaVM, "selected", "guiComboBoxSetSelected", "guiComboBoxGetSelected"); + + lua_registerclass(luaVM, "GuiComboBox", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiCheckBoxClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateCheckBox"); + + lua_classfunction(luaVM, "getSelected", "guiCheckBoxGetSelected"); + + lua_classfunction(luaVM, "setSelected", "guiCheckBoxSetSelected"); + + lua_classvariable(luaVM, "selected", "guiCheckBoxSetSelected", "guiCheckBoxGetSelected"); + + lua_registerclass(luaVM, "GuiCheckBox", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiRadioButtonClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateRadioButton"); + + lua_classfunction(luaVM, "getSelected", "guiRadioButtonGetSelected"); + + lua_classfunction(luaVM, "setSelected", "guiRadioButtonSetSelected"); + + lua_classvariable(luaVM, "selected", "guiRadioButtonSetSelected", "guiRadioButtonGetSelected"); + + lua_registerclass(luaVM, "GuiRadioButton", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiScrollPaneClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateScrollPane"); + + lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); + + lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition"); + lua_classfunction(luaVM, "setScrollBars", "guiScrollPaneSetScrollBars"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition"); + + lua_classvariable(luaVM, "horizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); + + lua_registerclass(luaVM, "GuiScrollPane", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiScrollBarClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateScrollBar"); + + lua_classfunction(luaVM, "getScrollPosition", "guiScrollBarGetScrollPosition"); + + lua_classfunction(luaVM, "setScrollPosition", "guiScrollBarSetScrollPosition"); + + lua_classvariable(luaVM, "scrollPosition", "guiScrollBarSetScrollPosition", "guiScrollBarGetScrollPosition"); + + lua_registerclass(luaVM, "GuiScrollBar", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiProgressBarClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateProgressBar"); + + lua_classfunction(luaVM, "getProgress", "guiProgressBarGetProgress"); + + lua_classfunction(luaVM, "setProgress", "guiProgressBarSetProgress"); + + lua_classvariable(luaVM, "progress", "guiProgressBarSetProgress", "guiProgressBarGetProgress"); + + lua_registerclass(luaVM, "GuiProgressBar", "GuiElement"); +} + +// TODO: special tables +void CLuaGUIDefs::AddGuiGridlistClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateGridList"); + lua_classfunction(luaVM, "addColumn", "guiGridListAddColumn"); + lua_classfunction(luaVM, "addRow", "guiGridListAddRow"); + lua_classfunction(luaVM, "autoSizeColumn", "guiGridListAutoSizeColumn"); + lua_classfunction(luaVM, "clear", "guiGridListClear"); + lua_classfunction(luaVM, "insertRowAfter", "guiGridListInsertRowAfter"); + lua_classfunction(luaVM, "removeColumn", "guiGridListRemoveColumn"); + lua_classfunction(luaVM, "removeRow", "guiGridListRemoveRow"); + + lua_classfunction(luaVM, "getItemData", "guiGridListGetItemData"); + lua_classfunction(luaVM, "getItemText", "guiGridListGetItemText"); + lua_classfunction(luaVM, "getRowCount", "guiGridListGetRowCount"); + lua_classfunction(luaVM, "getSelectedItem", "guiGridListGetSelectedItem"); + lua_classfunction(luaVM, "getItemColor", "guiGridListGetItemColor"); + lua_classfunction(luaVM, "getColumnTitle", "guiGridListGetColumnTitle"); + lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); + lua_classfunction(luaVM, "getSelectedCount", "guiGridListGetSelectedCount"); + lua_classfunction(luaVM, "getSelectedItems", "guiGridListGetSelectedItems"); + lua_classfunction(luaVM, "getColumnCount", "guiGridListGetColumnCount"); + + lua_classfunction(luaVM, "setItemData", "guiGridListSetItemData"); + lua_classfunction(luaVM, "setItemText", "guiGridListSetItemText"); + lua_classfunction(luaVM, "setScrollBars", "guiGridListSetScrollBars"); + lua_classfunction(luaVM, "setSelectedItem", "guiGridListSetSelectedItem"); + lua_classfunction(luaVM, "setSelectionMode", "guiGridListSetSelectionMode"); + lua_classfunction(luaVM, "setSortingEnabled", "guiGridListSetSortingEnabled"); + lua_classfunction(luaVM, "setColumnWidth", "guiGridListSetColumnWidth"); + lua_classfunction(luaVM, "setItemColor", "guiGridListSetItemColor"); + lua_classfunction(luaVM, "setColumnTitle", "guiGridListSetColumnTitle"); + lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiGridListSetHorizontalScrollPosition"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiGridListSetVerticalScrollPosition"); + + lua_classvariable(luaVM, "rowCount", NULL, "guiGridListGetRowCount"); + lua_classvariable(luaVM, "selectedCount", NULL, "guiGridListGetSelectedCount"); + lua_classvariable(luaVM, "selectedItems", NULL, "guiGridListGetSelectedItems"); + lua_classvariable(luaVM, "columnCount", NULL, "guiGridListGetColumnCount"); + lua_classvariable(luaVM, "selectionMode", "guiGridListSetSelectionMode", NULL); + lua_classvariable(luaVM, "sortingEnabled", "guiGridListSetSortingEnabled", NULL); + lua_classvariable(luaVM, "horizontalScrollPosition", "guiGridListSetHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiGridListGetVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); + // lua_classvariable ( luaVM, "selectedItem", NULL, "guiGridListGetSelectedItem" ); table + // lua_classvariable ( luaVM, "selectedItem", "guiGridListSetSelectedItem", NULL ); .selectedItem[column] = row (row in column) table + // lua_classvariable ( luaVM, "itemColor", "setItemColor", "getItemColor" ); table + // lua_classvariable ( luaVM, "columnTitle", "setColumnTitle", "getColumnTitle" ); table + + lua_registerclass(luaVM, "GuiGridList", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiTabPanelClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateTabPanel"); + + lua_classfunction(luaVM, "getSelectedTab", "guiGetSelectedTab"); + + lua_classfunction(luaVM, "setSelectedTab", "guiSetSelectedTab"); + + lua_classvariable(luaVM, "selectedTab", "guiSetSelectedTab", "guiGetSelectedTab"); + + lua_registerclass(luaVM, "GuiTabPanel", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiTabClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateTab"); + lua_classfunction(luaVM, "delete", "guiDeleteTab"); + + lua_registerclass(luaVM, "GuiTab", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiFontClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateFont"); + + lua_registerclass(luaVM, "GuiFont", "Element"); +} + +int CLuaGUIDefs::GUIGetInputEnabled(lua_State* luaVM) +{ + lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIGetInputEnabled()); + return 1; +} + +int CLuaGUIDefs::GUISetInputEnabled(lua_State* luaVM) +{ + // bool guiSetInputEnabled ( bool enabled ) + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetInputMode(enabled ? INPUTMODE_NO_BINDS : INPUTMODE_ALLOW_BINDS); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetInputMode(lua_State* luaVM) +{ + // bool guiSetInputMode ( string mode ) + eInputMode mode; + + CScriptArgReader argStream(luaVM); + argStream.ReadEnumString(mode); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetInputMode(mode); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetInputMode(lua_State* luaVM) +{ + eInputMode mode = CStaticFunctionDefinitions::GUIGetInputMode(); + lua_pushstring(luaVM, EnumToString(mode)); + return 1; +} + +int CLuaGUIDefs::GUIIsChatBoxInputActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsChatInputEnabled()); + return 1; +} + +int CLuaGUIDefs::GUIIsConsoleActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->GetConsole()->IsVisible()); + return 1; +} + +int CLuaGUIDefs::GUIIsDebugViewActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsDebugVisible()); + return 1; +} + +int CLuaGUIDefs::GUISetDebugViewActive(lua_State* luaVM) +{ + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + g_pCore->SetDebugVisible(enabled); + + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIIsMainMenuActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsMenuVisible()); + return 1; +} + +int CLuaGUIDefs::GUIIsMTAWindowActive(lua_State* luaVM) +{ + bool bActive = + (g_pCore->IsChatInputEnabled() || g_pCore->IsMenuVisible() || g_pCore->GetConsole()->IsVisible() || g_pClientGame->GetTransferBox()->IsVisible()); + + lua_pushboolean(luaVM, bActive); + return 1; +} + +int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); + return 1; +} + +int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) +{ + bool bEnabled; + CScriptArgReader argStream(luaVM); + argStream.ReadBool(bEnabled); + + if (!argStream.HasErrors()) + { + bool bAllowed = false; + g_pCore->GetCVars()->Get("allow_server_control_transfebox", bAllowed); + if (bAllowed) + { + g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + { + lua_pushboolean(luaVM, false); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + return 1; +} + +int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); + return 1; +} + +int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) +{ + // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) + CVector2D position; + CVector2D size; + SString titleBarText; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(titleBarText); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateWindow(*pLuaMain, position, size, titleBarText, relative); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateLabel(lua_State* luaVM) +{ + // element guiCreateLabel ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateLabel(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateStaticImage(lua_State* luaVM) +{ + // element guiCreateStaticImage ( float x, float y, float width, float height, string path, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString path; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(path); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CResource* pResource = pLuaMain->GetResource(); + SString strPath; + if (CResourceManager::ParseResourcePathInput(path, pResource, &strPath)) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateStaticImage(*pLuaMain, position, size, strPath, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + else + argStream.SetCustomError(path, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateButton(lua_State* luaVM) +{ + // element guiCreateButton ( float x, float y, float width, float height, string text, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateButton(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateProgressBar(lua_State* luaVM) +{ + // element guiCreateProgressBar ( float x, float y, float width, float height, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateProgressBar(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateCheckBox(lua_State* luaVM) +{ + // element guiCreateCheckBox ( float x, float y, float width, float height, string text, bool selected, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool selected; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(selected); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateCheckBox(*pLuaMain, position, size, text, selected, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateRadioButton(lua_State* luaVM) +{ + // element guiCreateRadioButton ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateRadioButton(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateEdit(lua_State* luaVM) +{ + // gui-edit guiCreateEdit ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateEdit(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateMemo(lua_State* luaVM) +{ + // gui-memo guiCreateMemo ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateMemo(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateGridList(lua_State* luaVM) +{ + // element guiCreateGridList ( float x, float y, float width, float height, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateGridList(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateScrollPane(lua_State* luaVM) +{ + // element guiCreateScrollPane( float x, float y, float width, float height, bool relative, [gui-element parent = nil]) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollPane(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateScrollBar(lua_State* luaVM) +{ + // gui-scrollbar guiCreateScrollBar ( float x, float y, float width, float height, bool horizontal, bool relative, [gui-element parent = nil]) + CVector2D position; + CVector2D size; + bool horizontal; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(horizontal); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollBar(*pLuaMain, position, size, horizontal, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateTabPanel(lua_State* luaVM) +{ + // element guiCreateTabPanel ( float x, float y, float width, float height, bool relative, [element parent = nil ] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTabPanel(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIStaticImageLoadImage(lua_State* luaVM) +{ + // bool guiStaticImageLoadImage ( element theElement, string filename ) + CClientGUIElement* theElement; + SString filename; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadString(filename); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CResource* pResource = pLuaMain->GetResource(); + SString strPath; + if (CResourceManager::ParseResourcePathInput(filename, pResource, &strPath)) + { + if (CStaticFunctionDefinitions::GUIStaticImageLoadImage(*theElement, strPath)) + { + lua_pushboolean(luaVM, true); + return 1; + } + else + argStream.SetCustomError(filename, "Error loading image"); + } + else + argStream.SetCustomError(filename, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIStaticImageGetNativeSize(lua_State* luaVM) +{ + // bool guiStaticImageGetNativeSize ( element theElement, string filename ) + CClientGUIElement* theElement; + CVector2D vecSize; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + if (CStaticFunctionDefinitions::GUIStaticImageGetNativeSize(*theElement, vecSize)) + { + lua_pushnumber(luaVM, vecSize.fX); + lua_pushnumber(luaVM, vecSize.fY); + return 2; + } + + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateTab(lua_State* luaVM) +{ + // element guiCreateTab ( string text, element parent ) + SString text; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadString(text); + argStream.ReadUserData(parent); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTab(*pLuaMain, text, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetSelectedTab(lua_State* luaVM) +{ + // element guiGetSelectedTab ( element tabPanel ) + CClientGUIElement* tabPanel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabPanel); + + if (!argStream.HasErrors()) + { + CClientGUIElement* pTab = CStaticFunctionDefinitions::GUIGetSelectedTab(*tabPanel); + lua_pushelement(luaVM, pTab); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetSelectedTab(lua_State* luaVM) +{ + // bool guiSetSelectedTab ( element tabPanel, element theTab ) + CClientGUIElement* tabPanel; + CClientGUIElement* theTab; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabPanel); + argStream.ReadUserData(theTab); + + if (!argStream.HasErrors()) + { + if (CStaticFunctionDefinitions::GUISetSelectedTab(*tabPanel, *theTab)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIDeleteTab(lua_State* luaVM) +{ + // bool guiDeleteTab ( element tabToDelete, element tabPanel ) + CClientGUIElement* tabToDelete; + CClientGUIElement* tabPanel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabToDelete); + argStream.ReadUserData(tabPanel); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + if (CStaticFunctionDefinitions::GUIDeleteTab(*pLuaMain, tabToDelete, tabPanel)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetText(lua_State* luaVM) +{ + // bool guiSetText ( element guiElement, string text ) + CClientGUIElement* guiElement; + SString text; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(text); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetText(*guiElement, text); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetFont(lua_State* luaVM) +{ + // bool guiSetFont ( element guiElement, mixed font ) + CClientGUIElement* guiElement; + SString strFontName; + CClientGuiFont* pGuiFontElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + MixedReadGuiFontString(argStream, strFontName, "default-normal", pGuiFontElement); + + if (!argStream.HasErrors()) + { + if (guiElement->SetFont(strFontName, pGuiFontElement)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIBringToFront(lua_State* luaVM) +{ + // bool guiBringToFront ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + if (CStaticFunctionDefinitions::GUIBringToFront(*guiElement)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMoveToBack(lua_State* luaVM) +{ + // bool guiMoveToBack( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMoveToBack(*guiElement); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIRadioButtonSetSelected(lua_State* luaVM) +{ + // bool guiRadioButtonSetSelected ( element guiRadioButton, bool state ) + CClientGUIElement* guiRadioButton; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiRadioButton); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIRadioButtonSetSelected(*guiRadioButton, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICheckBoxSetSelected(lua_State* luaVM) +{ + // bool guiCheckBoxSetSelected ( element theCheckbox, bool state ) + CClientGUIElement* theCheckbox; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theCheckbox); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUICheckBoxSetSelected(*theCheckbox, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIRadioButtonGetSelected(lua_State* luaVM) +{ + // bool guiRadioButtonGetSelected( element guiRadioButton ) + CClientGUIElement* guiRadioButton; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiRadioButton); + + if (!argStream.HasErrors()) + { + bool bResult = static_cast(guiRadioButton->GetCGUIElement())->GetSelected(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICheckBoxGetSelected(lua_State* luaVM) +{ + // bool guiCheckBoxGetSelected ( element theCheckbox ) + CClientGUIElement* theCheckbox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theCheckbox); + + if (!argStream.HasErrors()) + { + bool bResult = static_cast(theCheckbox->GetCGUIElement())->GetSelected(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIProgressBarSetProgress(lua_State* luaVM) +{ + // bool guiProgressBarSetProgress ( progressBar theProgressbar, float progress ) + CClientGUIElement* theProgressbar; + float progress; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theProgressbar); + argStream.ReadNumber(progress); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIProgressBarSetProgress(*theProgressbar, static_cast(progress)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollBarSetScrollPosition(lua_State* luaVM) +{ + // bool guiScrollBarSetScrollPosition ( gui-scrollBar theScrollBar, float amount ) + CClientGUIElement* theScrollBar; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollBar); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollBarSetScrollPosition(*theScrollBar, static_cast(amount)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetHorizontalScrollPosition(lua_State* luaVM) +{ + // bool guiScrollPaneSetHorizontalScrollPosition ( gui-scrollPane theScrollPane, float amount ) + CClientGUIElement* theScrollPane; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetHorizontalScrollPosition(*theScrollPane, amount); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiScrollPaneSetVerticalScrollPosition ( gui-scrollPane theScrollPane, float amount ) + CClientGUIElement* theScrollPane; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetVerticalScrollPosition(*theScrollPane, amount); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIProgressBarGetProgress(lua_State* luaVM) +{ + // float guiProgressBarGetProgress ( progressBar theProgressbar ); + CClientGUIElement* theProgressbar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theProgressbar); + + if (!argStream.HasErrors()) + { + int iProgress = (int)(static_cast(theProgressbar->GetCGUIElement())->GetProgress() * 100.0f + 0.5f); + lua_pushnumber(luaVM, iProgress); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneGetHorizontalScrollPosition(lua_State* luaVM) +{ + // float guiScrollPaneGetHorizontalScrollPosition ( gui-scrollPane theScrollPane ) + CClientGUIElement* theScrollPane; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + + if (!argStream.HasErrors()) + { + float fPos = static_cast(theScrollPane->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiScrollPaneGetVerticalScrollPosition ( gui-scrollPane theScrollPane ) + CClientGUIElement* theScrollPane; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + + if (!argStream.HasErrors()) + { + float fPos = static_cast(theScrollPane->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollBarGetScrollPosition(lua_State* luaVM) +{ + // float guiScrollBarGetScrollPosition ( gui-scrollBar theScrollBar ) + CClientGUIElement* theScrollBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollBar); + + if (!argStream.HasErrors()) + { + int iPos = (int)(static_cast(theScrollBar->GetCGUIElement())->GetScrollPosition() * 100.0f); + lua_pushnumber(luaVM, iPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetText(lua_State* luaVM) +{ + // string guiGetText ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + SString strText = guiElement->GetCGUIElement()->GetText(); + lua_pushstring(luaVM, strText); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetFont(lua_State* luaVM) +{ + // string,font guiGetFont ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + CClientGuiFont* pGuiFontElement; + SString strFontName = guiElement->GetFont(&pGuiFontElement); + + if (strFontName != "") + lua_pushstring(luaVM, strFontName); + else + lua_pushnil(luaVM); + lua_pushelement(luaVM, pGuiFontElement); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetSize(lua_State* luaVM) +{ + // float float guiGetSize ( element theElement, bool relative ) + CClientGUIElement* theElement; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CVector2D Size; + theElement->GetCGUIElement()->GetSize(Size, relative); + + lua_pushnumber(luaVM, Size.fX); + lua_pushnumber(luaVM, Size.fY); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetScreenSize(lua_State* luaVM) +{ + const CVector2D Size = CStaticFunctionDefinitions::GUIGetScreenSize(); + + lua_pushnumber(luaVM, Size.fX); + lua_pushnumber(luaVM, Size.fY); + return 2; +} + +int CLuaGUIDefs::GUIGetPosition(lua_State* luaVM) +{ + // float, float guiGetPosition ( element guiElement, bool relative ) + CClientGUIElement* guiElement; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CVector2D Pos; + guiElement->GetCGUIElement()->GetPosition(Pos, relative); + + lua_pushnumber(luaVM, Pos.fX); + lua_pushnumber(luaVM, Pos.fY); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetAlpha(lua_State* luaVM) +{ + // bool guiSetAlpha ( element guielement, float alpha ) + CClientGUIElement* guiElement; + float alpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(alpha); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetAlpha(*guiElement, Clamp(0.0f, alpha, 1.0f)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetAlpha(lua_State* luaVM) +{ + // int guiGetAlpha ( element guiElement [, bool effectiveAlpha = false] ) + CClientGUIElement* guiElement; + bool bEffectiveAlpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(bEffectiveAlpha, false); + + if (!argStream.HasErrors()) + { + float fAlpha = !bEffectiveAlpha ? guiElement->GetCGUIElement()->GetAlpha() : guiElement->GetCGUIElement()->GetEffectiveAlpha(); + lua_pushnumber(luaVM, fAlpha); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetVisible(lua_State* luaVM) +{ + // bool guiSetVisible ( element guiElement, bool state ) + CClientGUIElement* guiElement; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetVisible(*guiElement, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetEnabled(lua_State* luaVM) +{ + // bool guiSetEnabled ( element guiElement, bool enabled ) + CClientGUIElement* guiElement; + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetEnabled(*guiElement, enabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetProperty(lua_State* luaVM) +{ + // bool guiSetProperty ( element guiElement, string property, string value ) + CClientGUIElement* guiElement; + SString property; + SString value; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(property); + argStream.ReadString(value); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetProperty(*guiElement, property, value); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetVisible(lua_State* luaVM) +{ + // bool guiGetVisible ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + bool bResult = guiElement->GetCGUIElement()->IsVisible(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetEnabled(lua_State* luaVM) +{ + // bool guiGetEnabled ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + bool bResult = guiElement->GetCGUIElement()->IsEnabled(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetProperty(lua_State* luaVM) +{ + // string guiGetProperty ( element guiElement, string property ) + CClientGUIElement* guiElement; + SString property; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(property); + + if (!argStream.HasErrors()) + { + SString strValue = guiElement->GetCGUIElement()->GetProperty(property); + lua_pushstring(luaVM, strValue); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetProperties(lua_State* luaVM) +{ + // table guiGetProperties ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + // Create a new table + lua_newtable(luaVM); + + // Add all our properties to the table on top of the given lua main's stack + unsigned int uiIndex = 0; + CGUIPropertyIter iter = guiElement->GetCGUIElement()->GetPropertiesBegin(); + CGUIPropertyIter iterEnd = guiElement->GetCGUIElement()->GetPropertiesEnd(); + for (; iter != iterEnd; iter++) + { + const char* szKey = (*iter)->strKey; + const char* szValue = (*iter)->strValue; + + // Add it to the table + lua_pushstring(luaVM, szKey); + lua_pushstring(luaVM, szValue); + lua_settable(luaVM, -3); + } + + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetSize(lua_State* luaVM) +{ + // bool guiSetSize ( element guiElement, float width, float height, bool relative ) + CClientGUIElement* guiElement; + float width; + float height; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(width); + argStream.ReadNumber(height); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetSize(*guiElement, CVector2D(width, height), relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetPosition(lua_State* luaVM) +{ + // bool guiSetPosition ( element guiElement, float x, float y, bool relative ) + CClientGUIElement* guiElement; + float x; + float y; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(x); + argStream.ReadNumber(y); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetPosition(*guiElement, CVector2D(x, y), relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSortingEnabled(lua_State* luaVM) +{ + // bool guiGridListSetSortingEnabled ( element guiGridlist, bool enabled ) + CClientGUIElement* guiGridlist; + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSortingEnabled(*guiGridlist, enabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAddColumn(lua_State* luaVM) +{ + // int guiGridListAddColumn ( element gridList, string title, float width ) + CClientGUIElement* guiGridlist; + SString title; + float width; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadString(title); + argStream.ReadNumber(width); + + if (!argStream.HasErrors()) + { + uint id = CStaticFunctionDefinitions::GUIGridListAddColumn(*guiGridlist, title, width); + lua_pushnumber(luaVM, id); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListRemoveColumn(lua_State* luaVM) +{ + // bool guiGridListRemoveColumn ( element guiGridlist, int columnIndex ) + CClientGUIElement* guiGridlist; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListRemoveColumn(*guiGridlist, columnIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetColumnWidth(lua_State* luaVM) +{ + // bool guiGridListSetColumnWidth ( element gridList, int columnIndex, number width, bool relative ) + CClientGUIElement* guiGridlist; + int columnIndex; + float width; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + argStream.ReadNumber(width); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetColumnWidth(*guiGridlist, columnIndex, width, relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnWidth(lua_State* luaVM) +{ + // float guiGridListGetColumnWidth ( element gridList, int columnIndex, bool relative ) + CClientGUIElement* pGridList; + int columnIndex; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pGridList); + argStream.ReadNumber(columnIndex); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + float width; + if (static_cast(pGridList->GetCGUIElement())->GetColumnWidth(columnIndex, width, relative)) + { + lua_pushnumber(luaVM, width); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetColumnTitle(lua_State* luaVM) +{ + // bool guiGridListSetColumnTitle ( element guiGridlist, int columnIndex, string title ) + CClientGUIElement* guiGridlist; + int iColumnIndex; + SString sTitle; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(iColumnIndex); + argStream.ReadString(sTitle); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) + { + CStaticFunctionDefinitions::GUIGridListSetColumnTitle(*guiGridlist, iColumnIndex, sTitle); + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnTitle(lua_State* luaVM) +{ + // string guiGridListGetColumnTitle ( element guiGridlist, int columnIndex ) + CClientGUIElement* guiGridlist; + int iColumnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(iColumnIndex); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) + { + const char* szTitle = static_cast(guiGridlist->GetCGUIElement())->GetColumnTitle(iColumnIndex); + lua_pushstring(luaVM, szTitle); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAddRow(lua_State* luaVM) +{ + // int guiGridListAddRow ( element gridList ) + // int guiGridListAddRow ( element gridList, int/string itemText1, int/string itemText2 ... ) + CClientGUIElement* guiGridlist; + CLuaArguments Arguments; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadLuaArguments(Arguments); + + if (!argStream.HasErrors()) + { + int iRet = 0; + if (Arguments.Count() == 0) + iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true); + else + { + // Vector containing our string arguments. We add a bool to store whether it was originally a number. + std::vector > m_items; + std::vector::const_iterator it = Arguments.IterBegin(); + for (it; it != Arguments.IterEnd(); it++) + { + CLuaArgument* pArgument = *it; + SString strItemText; + bool bNumber = false; + + // Check the type of the argument and convert it to a string we can process + uint type = pArgument->GetType(); + if (type == LUA_TNUMBER) + { + // Grab the lua string and its size + const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); + size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); + + // Set our string + strItemText.assign(szLuaString, sizeLuaString); + bNumber = true; + } + else if (type == LUA_TSTRING) + strItemText = pArgument->GetString(); + else + continue; + + m_items.push_back(std::make_pair(strItemText, bNumber)); + } + iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true, &m_items); + } + + if (iRet >= 0) + { + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushnumber(luaVM, iRet); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListInsertRowAfter(lua_State* luaVM) +{ + // int guiGridListInsertRowAfter ( element gridList, int rowIndex ) + // int guiGridListInsertRowAfter ( element gridList, int rowIndex, int/string itemText1, int/string itemText2 ... ) + CClientGUIElement* guiGridlist; + int rowIndex; + CLuaArguments Arguments; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadLuaArguments(Arguments); + + if (!argStream.HasErrors()) + { + int iRet = 0; + if (Arguments.Count() == 0) + iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex); + else + { + // Vector containing our string arguments. We add a bool to store whether it was originally a number. + std::vector > m_items; + std::vector::const_iterator it = Arguments.IterBegin(); + for (it; it != Arguments.IterEnd(); it++) + { + CLuaArgument* pArgument = *it; + SString strItemText; + bool bNumber = false; + + // Check the type of the argument and convert it to a string we can process + uint type = pArgument->GetType(); + if (type == LUA_TNUMBER) + { + // Grab the lua string and its size + const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); + size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); + + // Set our string + strItemText.assign(szLuaString, sizeLuaString); + bNumber = true; + } + else if (type == LUA_TSTRING) + strItemText = pArgument->GetString(); + else + continue; + + m_items.push_back(std::make_pair(strItemText, bNumber)); + } + iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex, &m_items); + } + + if (iRet >= 0) + { + lua_pushnumber(luaVM, iRet); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAutoSizeColumn(lua_State* luaVM) +{ + // bool guiGridListAutoSizeColumn ( element gridList, int columnIndex ) + CClientGUIElement* guiGridlist; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListAutoSizeColumn(*guiGridlist, columnIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListClear(lua_State* luaVM) +{ + // bool guiGridListClear ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListClear(*guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSelectionMode(lua_State* luaVM) +{ + // bool guiGridListSetSelectionMode ( guiElement gridlist, int mode ) + CClientGUIElement* guiGridlist; + int mode; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(mode); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSelectionMode(*guiGridlist, mode); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedItem(lua_State* luaVM) +{ + // int, int guiGridListGetSelectedItem ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iRow = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemRow(); + int iColumn = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemColumn(); + lua_pushnumber(luaVM, iRow); + lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedItems(lua_State* luaVM) +{ + // table guiGridListGetSelectedItems ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + CGUIGridList* pList = static_cast(guiGridlist->GetCGUIElement()); + CGUIListItem* pItem = NULL; + + lua_newtable(luaVM); + + for (int i = 1; i <= pList->GetSelectedCount(); i++) + { + pItem = pList->GetNextSelectedItem(pItem); + if (!pItem) + break; + + lua_pushnumber(luaVM, i); + lua_newtable(luaVM); + + // column + lua_pushstring(luaVM, "column"); + lua_pushnumber(luaVM, pList->GetItemColumnIndex(pItem)); + lua_settable(luaVM, -3); + + // row + lua_pushstring(luaVM, "row"); + lua_pushnumber(luaVM, pList->GetItemRowIndex(pItem)); + lua_settable(luaVM, -3); + + // push to main table + lua_settable(luaVM, -3); + } + + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedCount(lua_State* luaVM) +{ + // int guiGridListGetSelectedCount ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iCount = static_cast(guiGridlist->GetCGUIElement())->GetSelectedCount(); + lua_pushnumber(luaVM, iCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSelectedItem(lua_State* luaVM) +{ + // bool guiGridListSetSelectedItem ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + bool bReset; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadBool(bReset, true); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSelectedItem(*guiGridlist, rowIndex, columnIndex, bReset); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListRemoveRow(lua_State* luaVM) +{ + // bool guiGridListRemoveRow ( element gridList, int rowIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListRemoveRow(*guiGridlist, rowIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemText(lua_State* luaVM) +{ + // string guiGridListGetItemText ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + const char* szText = static_cast(guiGridlist->GetCGUIElement())->GetItemText(rowIndex, columnIndex); + lua_pushstring(luaVM, szText); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemData(lua_State* luaVM) +{ + // string guiGridListGetItemData ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + void* pData = static_cast(guiGridlist->GetCGUIElement())->GetItemData(rowIndex, columnIndex); + CLuaArgument* pVariable = reinterpret_cast(pData); + if (pVariable) + pVariable->Push(luaVM); + else + lua_pushnil(luaVM); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemColor(lua_State* luaVM) +{ + // int int int int guiGridListGetItemColor ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255, ucAlpha = 255; + if (static_cast(guiGridlist->GetCGUIElement())->GetItemColor(rowIndex, columnIndex, ucRed, ucGreen, ucBlue, ucAlpha)) + { + lua_pushnumber(luaVM, ucRed); + lua_pushnumber(luaVM, ucGreen); + lua_pushnumber(luaVM, ucBlue); + lua_pushnumber(luaVM, ucAlpha); + return 4; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetHorizontalScrollPosition(lua_State* luaVM) +{ + // float guiGridListGetHorizontalScrollPosition ( element guiGridlist ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPosition); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiGridListGetVerticalScrollPosition ( element guiGridlist ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPosition); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemText(lua_State* luaVM) +{ + // bool guiGridListSetItemText ( element gridList, int rowIndex, int columnIndex, string text, bool section, bool number ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + SString text; + bool section; + bool number; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadString(text); + argStream.ReadBool(section); + argStream.ReadBool(number); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetItemText(*guiGridlist, rowIndex, columnIndex, text, section, number, true); + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemData(lua_State* luaVM) +{ + // bool guiGridListSetItemData ( element gridList, int rowIndex, int columnIndex, string data ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + CLuaArgument data; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadLuaArgument(data); + + if (!argStream.HasErrors()) + { + CLuaArgument* pData = new CLuaArgument(data); + CStaticFunctionDefinitions::GUIGridListSetItemData(*guiGridlist, rowIndex, columnIndex, pData); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemColor(lua_State* luaVM) +{ + // bool guiGridListSetItemColor ( element gridList, int rowIndex, int columnIndex, int red, int green, int blue[, int alpha = 255 ] ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + int red; + int green; + int blue; + int alpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadNumber(red); + argStream.ReadNumber(green); + argStream.ReadNumber(blue); + argStream.ReadNumber(alpha, 255); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetItemColor(*guiGridlist, rowIndex, columnIndex, red, green, blue, alpha); + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetScrollBars(lua_State* luaVM) +{ + // bool guiGridListSetScrollBars ( element guiGridlist, bool horizontalBar, bool verticalBar ) + CClientGUIElement* guiGridlist; + bool horizontalBar; + bool verticalBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadBool(horizontalBar); + argStream.ReadBool(verticalBar); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetScrollBars(*guiGridlist, horizontalBar, verticalBar); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetHorizontalScrollPosition(lua_State* luaVM) +{ + // bool guiGridListSetHorizontalScrollPosition ( element guiGridlist, float fPosition ) + CClientGUIElement* guiGridlist; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetHorizontalScrollPosition(*guiGridlist, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiGridListSetVerticalScrollPosition ( element guiGridlist, float fPosition ) + CClientGUIElement* guiGridlist; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetVerticalScrollPosition(*guiGridlist, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetScrollBars(lua_State* luaVM) +{ + // bool guiScrollPaneSetScrollBars ( element scrollPane, bool horizontal, bool vertical ) + CClientGUIElement* scrollPane; + bool horizontalBar; + bool verticalBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(scrollPane); + argStream.ReadBool(horizontalBar); + argStream.ReadBool(verticalBar); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetScrollBars(*scrollPane, horizontalBar, verticalBar); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetRowCount(lua_State* luaVM) +{ + // int guiGridListGetRowCount ( element theList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iRowCount = static_cast(guiGridlist->GetCGUIElement())->GetRowCount(); + lua_pushnumber(luaVM, iRowCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnCount(lua_State* luaVM) +{ + // int guiGridListGetColumnCount ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + lua_pushnumber(luaVM, iColumnCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) +{ + // bool guiEditSetReadOnly ( element editField, bool status ) + CClientGUIElement* editField; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(editField); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetReadOnly(*editField, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) +{ + // bool guiEditIsReadOnly( element editField ) + CClientGUIElement* editField; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(editField); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) +{ + // bool guiMemoSetReadOnly ( gui-memo theMemo, bool status ) + CClientGUIElement* theMemo; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetReadOnly(*theMemo, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) +{ + // bool guiMemoIsReadOnly( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) +{ + // bool guiEditSetMasked ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) +{ + // bool guiEditSetMaxLength ( element theElement, int length ) + CClientGUIElement* theElement; + int length; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(length); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetMaxLength(*theElement, length); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) +{ + // bool guiEditSetCaretIndex ( element theElement, int index ) + CClientGUIElement* theElement; + int index; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(index); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetCaretIndex(*theElement, index); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) +{ + // int guiEditGetCaretIndex ( element theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, static_cast(theElement->GetCGUIElement())->GetCaretIndex()); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) +{ + // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) + CClientGUIElement* theMemo; + int index; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadNumber(index); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetCaretIndex(*theMemo, index); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiMemoSetVerticalScrollPosition ( gui-memo theMemo, float fPosition ) + CClientGUIElement* theMemo; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) +{ + // bool guiMemoGetCaretIndex ( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, static_cast(theMemo->GetCGUIElement())->GetCaretIndex()); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiMemoGetVerticalScrollPosition ( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); + float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) +{ + // bool guiWindowSetMovable ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIWindowSetMovable(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) +{ + // bool guiWindowSetSizable ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIWindowSetSizable(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) +{ + // float guiLabelGetTextExtent ( element theLabel ) + CClientGUIElement* theLabel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + + if (!argStream.HasErrors()) + { + float fExtent = static_cast(theLabel->GetCGUIElement())->GetTextExtent(); + lua_pushnumber(luaVM, fExtent); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetFontHeight(lua_State* luaVM) +{ + // float guiLabelGetFontHeight ( element theLabel ) + CClientGUIElement* theLabel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + + if (!argStream.HasErrors()) + { + float fHeight = static_cast(theLabel->GetCGUIElement())->GetFontHeight(); + lua_pushnumber(luaVM, fHeight); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetColor(lua_State* luaVM) +{ + // bool guiLabelSetColor ( element theElement, int red, int green, int blue ) + CClientGUIElement* theElement; + int red; + int green; + int blue; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(red); + argStream.ReadNumber(green); + argStream.ReadNumber(blue); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUILabelSetColor(*theElement, red, green, blue); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetColor(lua_State* luaVM) +{ + // int r, int g, int b guiLabelGetColor ( element theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255; + static_cast(theElement->GetCGUIElement())->GetTextColor(ucRed, ucGreen, ucBlue); + lua_pushnumber(luaVM, ucRed); + lua_pushnumber(luaVM, ucGreen); + lua_pushnumber(luaVM, ucBlue); + return 3; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetVerticalAlign(lua_State* luaVM) +{ + // bool guiLabelSetVerticalAlign ( element theLabel, string align ) + CClientGUIElement* theLabel; + CGUIVerticalAlign align; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + argStream.ReadEnumString(align); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUILabelSetVerticalAlign(*theLabel, align); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetHorizontalAlign(lua_State* luaVM) +{ + // bool guiLabelSetHorizontalAlign ( element theLabel, string align, [ bool wordwrap = false ] ) + CClientGUIElement* theLabel; + CGUIHorizontalAlign align; + bool wordwrap; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + argStream.ReadEnumString(align); + argStream.ReadBool(wordwrap, false); + + if (!argStream.HasErrors()) + { + if (wordwrap) + align = (CGUIHorizontalAlign)(align + 4); + CStaticFunctionDefinitions::GUILabelSetHorizontalAlign(*theLabel, align); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) +{ + //* chat_font - Returns the chatbox font + //* chat_lines - Returns how many lines the chatbox has + //* chat_color - Returns the background color of the chatbox + //* chat_text_color - Returns the chatbox text color + //* chat_input_color - Returns the background color of the chatbox input + //* chat_input_prefix_color - Returns the color of the input prefix text + //* chat_input_text_color - Returns the color of the text in the chatbox input + //* chat_scale - Returns the scale of the text in the chatbox + //* chat_position_offset_x - Returns the position offset of the chatbox on the x axis + //* chat_position_offset_y - Returns the position offset of the chatbox on the y axis + //* chat_position_horizontal - Returns the horizontal position of the chatbox + //* chat_position_vertical - Returns the vertical position of the chatbox + //* chat_text_alignment - Returns the horizontal alignment of the chatbox text + //* chat_width - Returns the scale of the background width + //* chat_css_style_text - Returns whether text fades out over time + //* chat_css_style_background - Returns whether the background fades out over time + //* chat_line_life - Returns how long it takes for text to start fading out + //* chat_line_fade_out - Returns how long takes for text to fade out + //* chat_use_cegui - Returns whether CEGUI is used to render the chatbox + //* text_scale - Returns text scale + + CCVarsInterface* pCVars = g_pCore->GetCVars(); + int iNumber; + float fNumber; + pCVars->Get("chat_font", fNumber); + lua_newtable(luaVM); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_font"); + pCVars->Get("chat_lines", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_lines"); + pCVars->Get("chat_width", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_width"); + pCVars->Get("chat_position_offset_x", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_position_offset_x"); + pCVars->Get("chat_position_offset_y", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_position_offset_y"); + pCVars->Get("chat_position_horizontal", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_position_horizontal"); + pCVars->Get("chat_position_vertical", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_position_vertical"); + pCVars->Get("chat_text_alignment", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_text_alignment"); + pCVars->Get("chat_css_style_text", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_css_style_text"); + pCVars->Get("chat_css_style_background", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_css_style_background"); + pCVars->Get("chat_line_life", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_line_life"); + pCVars->Get("chat_line_fade_out", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_line_fade_out"); + pCVars->Get("text_scale", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "text_scale"); + pCVars->Get("chat_use_cegui", fNumber); + lua_pushboolean(luaVM, fNumber ? true : false); + lua_setfield(luaVM, -2, "chat_use_cegui"); + std::string strCVar; + std::stringstream ss; + int iR, iG, iB, iA; + pCVars->Get("chat_color", strCVar); + if (!strCVar.empty()) + { + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_color"); + } + pCVars->Get("chat_text_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_text_color"); + } + pCVars->Get("chat_input_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_color"); + } + pCVars->Get("chat_input_prefix_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_prefix_color"); + } + pCVars->Get("chat_input_text_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_text_color"); + } + pCVars->Get("chat_scale", strCVar); + if (!strCVar.empty()) + { + float fX, fY; + ss.clear(); + ss.str(strCVar); + ss >> fX >> fY; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, fX); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, fY); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_scale"); + } + + return 1; +} + +int CLuaGUIDefs::GUICreateComboBox(lua_State* luaVM) +{ + // element guiCreateComboBox ( float x, float y, float width, float height, string caption, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + SString caption; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(caption); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateComboBox(*pLuaMain, position, size, caption, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxAddItem(lua_State* luaVM) +{ + // int guiComboBoxAddItem( element comboBox, string value ) + CClientGUIElement* comboBox; + SString value; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadString(value); + + if (!argStream.HasErrors()) + { + int newId = CStaticFunctionDefinitions::GUIComboBoxAddItem(*comboBox, value); + lua_pushnumber(luaVM, newId); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxRemoveItem(lua_State* luaVM) +{ + // bool guiComboBoxRemoveItem( element comboBox, int itemId ) + CClientGUIElement* comboBox; + int itemId; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxRemoveItem(*comboBox, itemId); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxClear(lua_State* luaVM) +{ + // bool guiComboBoxClear ( element comboBox ) + CClientGUIElement* comboBox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxClear(*comboBox); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxGetSelected(lua_State* luaVM) +{ + // int guiComboBoxGetSelected ( element comboBox ) + CClientGUIElement* comboBox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + int selected = CStaticFunctionDefinitions::GUIComboBoxGetSelected(*comboBox); + lua_pushnumber(luaVM, selected); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxSetSelected(lua_State* luaVM) +{ + // bool guiComboBoxSetSelected ( element comboBox, int itemIndex ) + CClientGUIElement* comboBox; + int itemIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemIndex); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxSetSelected(*comboBox, itemIndex); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxGetItemText(lua_State* luaVM) +{ + // string guiComboBoxGetItemText ( element comboBox, int itemId ) + CClientGUIElement* comboBox; + int itemId; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + + if (!argStream.HasErrors()) + { + SString ret = CStaticFunctionDefinitions::GUIComboBoxGetItemText(*comboBox, itemId); + lua_pushstring(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxSetItemText(lua_State* luaVM) +{ + // bool guiComboBoxSetItemText ( element comboBox, int itemId, string text ) + CClientGUIElement* comboBox; + int itemId; + SString text; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + argStream.ReadString(text); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxSetItemText(*comboBox, itemId, text); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateFont(lua_State* luaVM) +{ + // element guiCreateFont( string filepath [, int size=9 ] ) + SString strFilePath; + int iSize; + + CScriptArgReader argStream(luaVM); + argStream.ReadString(strFilePath); + argStream.ReadNumber(iSize, 9); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CResource* pParentResource = pLuaMain->GetResource(); + CResource* pFileResource = pParentResource; + SString strPath, strMetaPath; + if (CResourceManager::ParseResourcePathInput(strFilePath, pFileResource, &strPath, &strMetaPath)) + { + if (FileExists(strPath)) + { + SString strUniqueName = SString("%s*%s*%s", pParentResource->GetName(), pFileResource->GetName(), strMetaPath.c_str()).Replace("\\", "/"); + CClientGuiFont* pGuiFont = g_pClientGame->GetManager()->GetRenderElementManager()->CreateGuiFont(strPath, strUniqueName, iSize); + if (pGuiFont) + { + // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's + // ElementGroup? ** + pGuiFont->SetParent(pParentResource->GetResourceDynamicEntity()); + lua_pushelement(luaVM, pGuiFont); + return 1; + } + argStream.SetCustomError(strFilePath, "Error creating font"); + } + else + argStream.SetCustomError(strFilePath, "File not found"); + } + else + argStream.SetCustomError(strFilePath, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) +{ + // string guiGetCursorType ( ) + auto eType = CStaticFunctionDefinitions::GUIGetCursorType(); + lua_pushstring(luaVM, EnumToString(eType)); + return 1; +} From df074aeb286fab6423654dcb5f052cdab7604224 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 17:36:38 +0200 Subject: [PATCH 10/27] Revert "added option to allow server control transfer box" This reverts commit cd8ac81fd3ba8210a702adf1c45d2f082a06f447. --- Client/core/CClientVariables.cpp | 1 - Client/core/CSettings.cpp | 21 +- Client/core/CSettings.h | 4 - Client/mods/deathmatch/logic/CClientGame.cpp | 13748 ++++++++-------- .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 7764 +++++---- 5 files changed, 10752 insertions(+), 10786 deletions(-) diff --git a/Client/core/CClientVariables.cpp b/Client/core/CClientVariables.cpp index e8b9a2245ee..4516a4813b6 100644 --- a/Client/core/CClientVariables.cpp +++ b/Client/core/CClientVariables.cpp @@ -330,7 +330,6 @@ void CClientVariables::LoadDefaults(void) DEFAULT("high_detail_vehicles", 0); // Disable rendering high detail vehicles all the time DEFAULT("fast_clothes_loading", 1); // 0-off 1-auto 2-on DEFAULT("allow_screen_upload", 1); // 0-off 1-on - DEFAULT("allow_server_control_transfebox", 1); // 0-off 1-on DEFAULT("max_clientscript_log_kb", 5000); // Max size in KB (0-No limit) DEFAULT("display_fullscreen_style", 0); // 0-standard 1-borderless 2-borderless keep res 3-borderless stretch DEFAULT("display_windowed", 0); // 0-off 1-on diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 5dab8377fa5..13ce2ee374b 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -376,11 +376,6 @@ void CSettings::CreateGUI(void) m_pCheckBoxAllowScreenUpload->GetPosition(vecTemp, false); m_pCheckBoxAllowScreenUpload->AutoSize(NULL, 20.0f); - m_pCheckBoxAllowControlTransferBox = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Allow server to control transfer box"), true)); - m_pCheckBoxAllowControlTransferBox->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); - m_pCheckBoxAllowControlTransferBox->GetPosition(vecTemp, false); - m_pCheckBoxAllowControlTransferBox->AutoSize(NULL, 20.0f); - m_pCheckBoxCustomizedSAFiles = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Use customized GTA:SA files"), true)); m_pCheckBoxCustomizedSAFiles->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); m_pCheckBoxCustomizedSAFiles->GetPosition(vecTemp, false); @@ -1493,11 +1488,6 @@ void CSettings::UpdateVideoTab(void) CVARS_GET("allow_screen_upload", bAllowScreenUploadEnabled); m_pCheckBoxAllowScreenUpload->SetSelected(bAllowScreenUploadEnabled); - // Allow screen upload - bool bAllowServerTransferBoxControl; - CVARS_GET("allow_server_control_transfebox", bAllowServerTransferBoxControl); - m_pCheckBoxAllowControlTransferBox->SetSelected(bAllowServerTransferBoxControl); - // Customized sa files m_pCheckBoxCustomizedSAFiles->SetSelected(GetApplicationSettingInt("customized-sa-files-request") != 0); m_pCheckBoxCustomizedSAFiles->SetVisible(GetApplicationSettingInt("customized-sa-files-show") != 0); @@ -3304,13 +3294,9 @@ void CSettings::SaveData(void) CVARS_SET("show_unsafe_resolutions", bShowUnsafeResolutions); // Allow screen upload - bAllowScreenUploadEnabled = m_pCheckBoxAllowScreenUpload->GetSelected(); + bool bAllowScreenUploadEnabled = m_pCheckBoxAllowScreenUpload->GetSelected(); CVARS_SET("allow_screen_upload", bAllowScreenUploadEnabled); - // Allow screen upload - bool m_pCheckBoxAllowScreenUpload = m_pCheckBoxAllowControlTransferBox->GetSelected(); - CVARS_SET("allow_server_control_transfebox", m_pCheckBoxAllowScreenUpload); - // Grass bool bGrassEnabled = m_pCheckBoxGrass->GetSelected(); CVARS_SET("grass", bGrassEnabled); @@ -4548,8 +4534,3 @@ bool CSettings::IsActive(void) { return m_pWindow->IsActive(); } - -bool CSettings::IsTransferBoxControlEnabled(void) -{ - return bAllowScreenUploadEnabled; -} diff --git a/Client/core/CSettings.h b/Client/core/CSettings.h index b46dec45061..0fb9c252a20 100644 --- a/Client/core/CSettings.h +++ b/Client/core/CSettings.h @@ -117,7 +117,6 @@ class CSettings void TabSkip(bool bBackwards); bool IsActive(void); - bool IsTransferBoxControlEnabled(void); void SetSelectedIndex(unsigned int uiIndex); @@ -152,7 +151,6 @@ class CSettings CGUICheckBox* m_pCheckBoxDeviceSelectionDialog; CGUICheckBox* m_pCheckBoxShowUnsafeResolutions; CGUICheckBox* m_pCheckBoxAllowScreenUpload; - CGUICheckBox* m_pCheckBoxAllowControlTransferBox; CGUICheckBox* m_pCheckBoxCustomizedSAFiles; CGUICheckBox* m_pCheckBoxGrass; CGUICheckBox* m_pCheckBoxHeatHaze; @@ -445,6 +443,4 @@ class CSettings int m_iMaxAnisotropic; std::list m_pKeyBindSections; - - bool bAllowScreenUploadEnabled; }; diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 80cb359d464..cef5af3a459 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -1,6874 +1,6874 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto v1.0 - * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/CClientGame.cpp - * PURPOSE: Client game manager - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#include "StdInc.h" -#include -#include "game/CAnimBlendAssocGroup.h" -#include "game/CAnimBlendAssociation.h" -#include "game/CAnimBlendHierarchy.h" - -SString StringZeroPadout(const SString& strInput, uint uiPadoutSize) -{ - SString strResult = strInput; - while (strResult.length() < uiPadoutSize) - strResult += '\0'; - return strResult; -} - -using SharedUtil::CalcMTASAPath; -using std::list; -using std::vector; - -// Hide the "conversion from 'unsigned long' to 'DWORD*' of greater size" warning -#pragma warning(disable:4312) - -// Used within this file by the packet handler to grab the this pointer of CClientGame -extern CClientGame* g_pClientGame; -extern int g_iDamageEventLimit; -float g_fApplyDamageLastAmount; -uchar g_ucApplyDamageLastHitZone; -CClientPed* g_pApplyDamageLastDamagedPed; -bool g_bBulletFireVectorsValid; -CVector g_vecBulletFireStartPosition; -CVector g_vecBulletFireEndPosition; - -#define DEFAULT_GRAVITY 0.008f -#define DEFAULT_GAME_SPEED 1.0f -#define DEFAULT_BLUR_LEVEL 36 -#define DEFAULT_JETPACK_MAXHEIGHT 100 -#define DEFAULT_AIRCRAFT_MAXHEIGHT 800 -#define DEFAULT_AIRCRAFT_MAXVELOCITY 1.5f -#define DEFAULT_MINUTE_DURATION 1000 -#define DOUBLECLICK_TIMEOUT 330 -#define DOUBLECLICK_MOVE_THRESHOLD 10.0f - -CClientGame::CClientGame(bool bLocalPlay) -{ - // Init the global var with ourself - g_pClientGame = this; - - // Packet handler - m_pPacketHandler = new CPacketHandler(); - - // Init - m_bLocalPlay = bLocalPlay; - m_bErrorStartingLocal = false; - m_iLocalConnectAttempts = 0; - m_Status = CClientGame::STATUS_CONNECTING; - m_ulVerifyTimeStart = 0; - m_ulLastClickTick = 0; - m_pLocalPlayer = NULL; - m_LocalID = INVALID_ELEMENT_ID; - m_bShowNametags = true; - m_bWaitingForLocalConnect = false; - m_bShowRadar = false; - m_bGameLoaded = false; - m_bTriggeredIngameAndConnected = false; - m_bGracefulDisconnect = false; - m_ulLastVehicleInOutTime = 0; - m_bIsGettingOutOfVehicle = false; - m_bIsGettingIntoVehicle = false; - m_bIsGettingJacked = false; - m_bIsJackingVehicle = false; - m_VehicleInOutID = INVALID_ELEMENT_ID; - m_pGettingJackedBy = NULL; - m_ucVehicleInOutSeat = 0xFF; - m_pTargetedEntity = NULL; - m_TargetedPlayerID = INVALID_ELEMENT_ID; - m_pDamageEntity = NULL; - m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageBodyPiece = 0xFF; - m_ucDamageWeapon = 0xFF; - m_ulDamageTime = 0; - m_bDamageSent = true; - m_bShowNetstat = false; - m_bShowFPS = false; - m_bHudAreaNameDisabled = false; - m_fGameSpeed = 1.0f; - m_lMoney = 0; - m_dwWanted = 0; - m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) - ResetAmmoInClip(); - - m_bNoNewVehicleTask = false; - m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; - - m_bCursorEventsEnabled = false; - m_bInitiallyFadedOut = true; - - m_bIsPlayingBack = false; - m_bFirstPlaybackFrame = false; - - // Setup game glitch defaults ( false = disabled ). Remember to update these serverside if you alter them! - m_Glitches[GLITCH_QUICKRELOAD] = false; - g_pMultiplayer->DisableQuickReload(true); - m_Glitches[GLITCH_FASTFIRE] = false; - m_Glitches[GLITCH_FASTMOVE] = false; - m_Glitches[GLITCH_CROUCHBUG] = false; - m_Glitches[GLITCH_CLOSEDAMAGE] = false; - g_pMultiplayer->DisableCloseRangeDamage(true); - m_Glitches[GLITCH_HITANIM] = false; - m_Glitches[GLITCH_FASTSPRINT] = false; - m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; - m_Glitches[GLITCH_QUICKSTAND] = false; - g_pMultiplayer->DisableBadDrivebyHitboxes(true); - - // Remove Night & Thermal vision view (if enabled). - g_pMultiplayer->SetNightVisionEnabled(false); - g_pMultiplayer->SetThermalVisionEnabled(false); - - m_bCloudsEnabled = true; - - m_bBirdsEnabled = true; - - m_bWasMinimized = false; - - // Grab the mod path - m_strModRoot = g_pCore->GetModInstallRoot("deathmatch"); - - // Figure out which directory to use for the client resource file cache - SetFileCacheRoot(); - - // Override CGUI's global events - g_pCore->GetGUI()->SetKeyDownHandler(INPUT_MOD, GUI_CALLBACK_KEY(&CClientGame::OnKeyDown, this)); - g_pCore->GetGUI()->SetMouseClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseClick, this)); - g_pCore->GetGUI()->SetMouseDoubleClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseDoubleClick, this)); - g_pCore->GetGUI()->SetMouseButtonDownHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonDown, this)); - g_pCore->GetGUI()->SetMouseButtonUpHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonUp, this)); - g_pCore->GetGUI()->SetMouseMoveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseMove, this)); - g_pCore->GetGUI()->SetMouseEnterHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseEnter, this)); - g_pCore->GetGUI()->SetMouseLeaveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseLeave, this)); - g_pCore->GetGUI()->SetMouseWheelHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseWheel, this)); - g_pCore->GetGUI()->SetMovedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnMove, this)); - g_pCore->GetGUI()->SetSizedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnSize, this)); - g_pCore->GetGUI()->SetFocusGainedHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusGain, this)); - g_pCore->GetGUI()->SetFocusLostHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusLoss, this)); - g_pCore->GetGUI()->SelectInputHandlers(INPUT_MOD); - - // Startup "entities from root" optimization for getElementsByType - CClientEntity::StartupEntitiesFromRoot(); - - // Startup game entity tracking manager - m_pGameEntityXRefManager = NewGameEntityXRefManager(); - m_pModelCacheManager = NewClientModelCacheManager(); - - // Initialize our root entity with an invalid id, we dont know the true id until map-start - m_pRootEntity = new CClientDummy(NULL, INVALID_ELEMENT_ID, "root"); - m_pRootEntity->MakeSystemEntity(); - - m_pDebugHookManager = new CDebugHookManager(); - - // Movings objects manager - m_pMovingObjectsManager = new CMovingObjectsManager(); - - // Create the manager and grab the most important pointers - m_pManager = new CClientManager; - m_pCamera = m_pManager->GetCamera(); - m_pMarkerManager = m_pManager->GetMarkerManager(); - m_pObjectManager = m_pManager->GetObjectManager(); - m_pPickupManager = m_pManager->GetPickupManager(); - m_pPlayerManager = m_pManager->GetPlayerManager(); - m_pRadarAreaManager = m_pManager->GetRadarAreaManager(); - m_pDisplayManager = m_pManager->GetDisplayManager(); - m_pVehicleManager = m_pManager->GetVehicleManager(); - m_pRadarMarkerManager = m_pManager->GetRadarMarkerManager(); - m_pPathManager = m_pManager->GetPathManager(); - m_pTeamManager = m_pManager->GetTeamManager(); - m_pPedManager = m_pManager->GetPedManager(); - m_pGUIManager = m_pManager->GetGUIManager(); - m_pResourceManager = m_pManager->GetResourceManager(); - m_pProjectileManager = m_pManager->GetProjectileManager(); - m_pLocalServer = NULL; - - m_pLatentTransferManager = new CLatentTransferManager(); - m_pZoneNames = new CZoneNames; - m_pScriptKeyBinds = new CScriptKeyBinds; - m_pRemoteCalls = new CRemoteCalls(); - m_pResourceFileDownloadManager = new CResourceFileDownloadManager(); - - // Create our net API - m_pNetAPI = new CNetAPI(m_pManager); - m_pNetworkStats = new CNetworkStats(m_pDisplayManager); - m_pSyncDebug = new CSyncDebug(m_pManager); - - // Create our blended weather class - m_pBlendedWeather = new CBlendedWeather; - - // Create our RPC class - m_pRPCFunctions = new CRPCFunctions(this); - - // Our management classes - m_pUnoccupiedVehicleSync = new CUnoccupiedVehicleSync(m_pVehicleManager); - m_pPedSync = new CPedSync(m_pPedManager); -#ifdef WITH_OBJECT_SYNC - m_pObjectSync = new CObjectSync(m_pObjectManager); -#endif - m_pNametags = new CNametags(m_pManager); - m_pRadarMap = new CRadarMap(m_pManager); - - // Set the screenshot path - /* This is now done in CCore, to maintain a global screenshot path - SString strScreenShotPath = SString::Printf ( "%s\\screenshots", m_szModRoot ); - g_pCore->SetScreenShotPath ( strScreenShotPath ); - */ - - // Create the transfer boxes (GUI) - m_pTransferBox = new CTransferBox(); - m_pBigPacketTransferBox = new CTransferBox(); - - // Store the time we started on - if (bLocalPlay) - m_ulTimeStart = 0; - else - m_ulTimeStart = CClientTime::GetTime(); - - // MTA Voice - m_pVoiceRecorder = new CVoiceRecorder(); - - // Singular file download manager - m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); - - // Register the message and the net packet handler - g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); - g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); - g_pMultiplayer->SetBulletImpactHandler(CClientGame::BulletImpact); - g_pMultiplayer->SetBulletFireHandler(CClientGame::BulletFire); - g_pMultiplayer->SetExplosionHandler(CClientExplosionManager::Hook_StaticExplosionCreation); - g_pMultiplayer->SetBreakTowLinkHandler(CClientGame::StaticBreakTowLinkHandler); - g_pMultiplayer->SetDrawRadarAreasHandler(CClientGame::StaticDrawRadarAreasHandler); - g_pMultiplayer->SetDamageHandler(CClientGame::StaticDamageHandler); - g_pMultiplayer->SetDeathHandler(CClientGame::StaticDeathHandler); - g_pMultiplayer->SetFireHandler(CClientGame::StaticFireHandler); - g_pMultiplayer->SetProjectileStopHandler(CClientProjectileManager::Hook_StaticProjectileAllow); - g_pMultiplayer->SetProjectileHandler(CClientProjectileManager::Hook_StaticProjectileCreation); - g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); - g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); - g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); - g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); - g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); - g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); - g_pMultiplayer->SetPreFxRenderHandler(CClientGame::StaticPreFxRenderHandler); - g_pMultiplayer->SetPreHudRenderHandler(CClientGame::StaticPreHudRenderHandler); - g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(CClientGame::StaticCAnimBlendAssocDestructorHandler); - g_pMultiplayer->SetAddAnimationHandler(CClientGame::StaticAddAnimationHandler); - g_pMultiplayer->SetAddAnimationAndSyncHandler(CClientGame::StaticAddAnimationAndSyncHandler); - g_pMultiplayer->SetAssocGroupCopyAnimationHandler(CClientGame::StaticAssocGroupCopyAnimationHandler); - g_pMultiplayer->SetBlendAnimationHierarchyHandler(CClientGame::StaticBlendAnimationHierarchyHandler); - g_pMultiplayer->SetProcessCollisionHandler(CClientGame::StaticProcessCollisionHandler); - g_pMultiplayer->SetVehicleCollisionHandler(CClientGame::StaticVehicleCollisionHandler); - g_pMultiplayer->SetVehicleDamageHandler(CClientGame::StaticVehicleDamageHandler); - g_pMultiplayer->SetHeliKillHandler(CClientGame::StaticHeliKillHandler); - g_pMultiplayer->SetObjectDamageHandler(CClientGame::StaticObjectDamageHandler); - g_pMultiplayer->SetObjectBreakHandler(CClientGame::StaticObjectBreakHandler); - g_pMultiplayer->SetWaterCannonHitHandler(CClientGame::StaticWaterCannonHandler); - g_pMultiplayer->SetVehicleFellThroughMapHandler(CClientGame::StaticVehicleFellThroughMapHandler); - g_pMultiplayer->SetGameObjectDestructHandler(CClientGame::StaticGameObjectDestructHandler); - g_pMultiplayer->SetGameVehicleDestructHandler(CClientGame::StaticGameVehicleDestructHandler); - g_pMultiplayer->SetGamePlayerDestructHandler(CClientGame::StaticGamePlayerDestructHandler); - g_pMultiplayer->SetGameProjectileDestructHandler(CClientGame::StaticGameProjectileDestructHandler); - g_pMultiplayer->SetGameModelRemoveHandler(CClientGame::StaticGameModelRemoveHandler); - g_pMultiplayer->SetGameEntityRenderHandler(CClientGame::StaticGameEntityRenderHandler); - g_pMultiplayer->SetFxSystemDestructionHandler(CClientGame::StaticFxSystemDestructionHandler); - g_pMultiplayer->SetDrivebyAnimationHandler(CClientGame::StaticDrivebyAnimationHandler); - g_pGame->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); - g_pGame->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); - g_pGame->SetTaskSimpleBeHitHandler(CClientGame::StaticTaskSimpleBeHitHandler); - g_pCore->SetMessageProcessor(CClientGame::StaticProcessMessage); - g_pCore->GetKeyBinds()->SetKeyStrokeHandler(CClientGame::StaticKeyStrokeHandler); - g_pCore->GetKeyBinds()->SetCharacterKeyHandler(CClientGame::StaticCharacterKeyHandler); - g_pNet->RegisterPacketHandler(CClientGame::StaticProcessPacket); - - m_pLuaManager = new CLuaManager(this); - m_pScriptDebugging = new CScriptDebugging(m_pLuaManager); - m_pScriptDebugging->SetLogfile(CalcMTASAPath("mta\\logs\\clientscript.log"), 3); - - CStaticFunctionDefinitions(m_pLuaManager, &m_Events, g_pCore, g_pGame, this, m_pManager); - CLuaFunctionDefs::Initialize(m_pLuaManager, m_pScriptDebugging, this); - CLuaDefs::Initialize(this, m_pLuaManager, m_pScriptDebugging); - - // Start async task scheduler - m_pAsyncTaskScheduler = new SharedUtil::CAsyncTaskScheduler(2); - - // Disable the enter/exit vehicle key button (we want to handle this button ourselves) - g_pMultiplayer->DisableEnterExitVehicleKey(true); - - // Disable GTA's pickup processing as we want to confirm the hits with the server - m_pPickupManager->SetPickupProcessingDisabled(true); - - // Key-bind for fire-key (for handling satchels and stealth-kills) - g_pCore->GetKeyBinds()->AddControlFunction("fire", CClientGame::StaticUpdateFireKey, true); - - // Init big packet progress vars - m_bReceivingBigPacket = false; - m_ulBigPacketSize = 0; - m_ulBigPacketBytesReceivedBase = 0; - - m_bBeingDeleted = false; - - #if defined (MTA_DEBUG) || defined (MTA_BETA) - m_bShowSyncingInfo = false; - #endif - - #ifdef MTA_DEBUG - m_pShowPlayer = m_pShowPlayerTasks = NULL; - m_bMimicLag = false; - m_ulLastMimicLag = 0; - m_bDoPaintballs = false; - m_bShowInterpolation = false; - #endif - - // Add our lua events - AddBuiltInEvents(); - - // Init debugger class - m_Foo.Init(this); - - // Load some stuff from the core config - float fScale; - g_pCore->GetCVars()->Get("text_scale", fScale); - CClientTextDisplay::SetGlobalScale(fScale); - - // Reset async loading script settings to default - g_pGame->SetAsyncLoadingFromScript(true, false); - - // Reset test mode script settings to default - g_pCore->GetGraphics()->GetRenderItemManager()->SetTestMode(DX_TEST_MODE_NONE); -} - -CClientGame::~CClientGame(void) -{ - m_bBeingDeleted = true; - // Stop all explosions. Unfortunately this doesn't fix the crash - // if a vehicle is destroyed while it explodes. - g_pGame->GetExplosionManager()->RemoveAllExplosions(); - - // Reset camera shaking - g_pGame->GetCamera()->SetShakeForce(0.0f); - - // Stop playing the continious sounds - // if the game was loaded. This is done by - // playing these special IDS. - if (m_bGameLoaded) - { - g_pGame->GetAudio()->PlayFrontEndSound(35); - g_pGame->GetAudio()->PlayFrontEndSound(48); - } - - // Reset the GUI input mode - g_pCore->GetGUI()->SetGUIInputMode(INPUTMODE_NO_BINDS_ON_EDIT); - - // Reset CGUI's global events - g_pCore->GetGUI()->ClearInputHandlers(INPUT_MOD); - - // Destroy mimics - #ifdef MTA_DEBUG - list::const_iterator iterMimics = m_Mimics.begin(); - for (; iterMimics != m_Mimics.end(); iterMimics++) - { - CClientPlayer* pPlayer = *iterMimics; - CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); - if (pVehicle) - delete pVehicle; - - delete pPlayer; - } - #endif - - // Hide the transfer box incase it is showing - m_pTransferBox->Hide(); - m_pBigPacketTransferBox->Hide(); - - // Stop async task scheduler - SAFE_DELETE(m_pAsyncTaskScheduler); - - SAFE_DELETE(m_pVoiceRecorder); - - // Singular file download manager - SAFE_DELETE(m_pSingularFileDownloadManager); - - // NULL the message/net stuff - g_pMultiplayer->SetPreContextSwitchHandler(NULL); - g_pMultiplayer->SetPostContextSwitchHandler(NULL); - g_pMultiplayer->SetPreWeaponFireHandler(NULL); - g_pMultiplayer->SetPostWeaponFireHandler(NULL); - g_pMultiplayer->SetBulletImpactHandler(NULL); - g_pMultiplayer->SetBulletFireHandler(NULL); - g_pMultiplayer->SetExplosionHandler(NULL); - g_pMultiplayer->SetBreakTowLinkHandler(NULL); - g_pMultiplayer->SetDrawRadarAreasHandler(NULL); - g_pMultiplayer->SetDamageHandler(NULL); - g_pMultiplayer->SetFireHandler(NULL); - g_pMultiplayer->SetProjectileStopHandler(NULL); - g_pMultiplayer->SetProjectileHandler(NULL); - g_pMultiplayer->SetProcessCamHandler(nullptr); - g_pMultiplayer->SetRender3DStuffHandler(NULL); - g_pMultiplayer->SetPreRenderSkyHandler(NULL); - g_pMultiplayer->SetRenderHeliLightHandler(nullptr); - g_pMultiplayer->SetChokingHandler(NULL); - g_pMultiplayer->SetPreWorldProcessHandler(NULL); - g_pMultiplayer->SetPostWorldProcessHandler(NULL); - g_pMultiplayer->SetPreFxRenderHandler(NULL); - g_pMultiplayer->SetPreHudRenderHandler(NULL); - g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(NULL); - g_pMultiplayer->SetAddAnimationHandler(NULL); - g_pMultiplayer->SetAddAnimationAndSyncHandler(NULL); - g_pMultiplayer->SetAssocGroupCopyAnimationHandler(NULL); - g_pMultiplayer->SetBlendAnimationHierarchyHandler(NULL); - g_pMultiplayer->SetProcessCollisionHandler(NULL); - g_pMultiplayer->SetVehicleCollisionHandler(NULL); - g_pMultiplayer->SetVehicleDamageHandler(NULL); - g_pMultiplayer->SetHeliKillHandler(NULL); - g_pMultiplayer->SetObjectDamageHandler(NULL); - g_pMultiplayer->SetObjectBreakHandler(NULL); - g_pMultiplayer->SetWaterCannonHitHandler(NULL); - g_pMultiplayer->SetGameObjectDestructHandler(NULL); - g_pMultiplayer->SetGameVehicleDestructHandler(NULL); - g_pMultiplayer->SetGamePlayerDestructHandler(NULL); - g_pMultiplayer->SetGameProjectileDestructHandler(NULL); - g_pMultiplayer->SetGameModelRemoveHandler(NULL); - g_pMultiplayer->SetGameEntityRenderHandler(NULL); - g_pMultiplayer->SetDrivebyAnimationHandler(nullptr); - g_pGame->SetPreWeaponFireHandler(NULL); - g_pGame->SetPostWeaponFireHandler(NULL); - g_pGame->SetTaskSimpleBeHitHandler(NULL); - g_pGame->GetAudio()->SetWorldSoundHandler(NULL); - g_pCore->SetMessageProcessor(NULL); - g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); - g_pCore->GetKeyBinds()->SetCharacterKeyHandler(NULL); - g_pNet->StopNetwork(); - g_pNet->RegisterPacketHandler(NULL); - CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); - pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessClientKeyBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessClientControlBind); - pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessServerKeyBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessServerControlBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticUpdateFireKey); - pKeyBinds->SetAllControlsEnabled(true, true, true); - g_pCore->ForceCursorVisible(false); - SetCursorEventsEnabled(false); - - // Destroy our stuff - SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop - SAFE_DELETE(m_pNametags); - SAFE_DELETE(m_pSyncDebug); - SAFE_DELETE(m_pNetworkStats); - SAFE_DELETE(m_pNetAPI); - SAFE_DELETE(m_pRPCFunctions); - SAFE_DELETE(m_pUnoccupiedVehicleSync); - SAFE_DELETE(m_pPedSync); -#ifdef WITH_OBJECT_SYNC - SAFE_DELETE(m_pObjectSync); -#endif - SAFE_DELETE(m_pBlendedWeather); - SAFE_DELETE(m_pMovingObjectsManager); - SAFE_DELETE(m_pRadarMap); - SAFE_DELETE(m_pRemoteCalls); - SAFE_DELETE(m_pLuaManager); - SAFE_DELETE(m_pLatentTransferManager); - SAFE_DELETE(m_pResourceFileDownloadManager); - - SAFE_DELETE(m_pRootEntity); - - SAFE_DELETE(m_pModelCacheManager); - SAFE_DELETE(m_pGameEntityXRefManager); - SAFE_DELETE(m_pZoneNames); - SAFE_DELETE(m_pScriptKeyBinds); - - // Delete the scriptdebugger - SAFE_DELETE(m_pScriptDebugging); - - // Delete the transfer boxes - SAFE_DELETE(m_pTransferBox); - SAFE_DELETE(m_pBigPacketTransferBox); - - SAFE_DELETE(m_pLocalServer); - SAFE_DELETE(m_pDebugHookManager); - - // Packet handler - SAFE_DELETE(m_pPacketHandler); - - // Delete PerfStatManager - delete CClientPerfStatManager::GetSingleton(); - - // NULL the global CClientGame var - g_pClientGame = NULL; - m_bBeingDeleted = false; -} - -/* -bool CClientGame::StartGame ( void ) // for an offline game (e.g. editor) -{ - m_Status = STATUS_OFFLINE; - g_pCore->SetOfflineMod ( true ); // hide chatbox etc - g_pCore->SetConnected ( true ); // not sure, but its required :) - g_pCore->HideMainMenu (); // duh - - // If the game isn't started, start it - if ( g_pGame->GetSystemState () == 7 ) - { - g_pGame->StartGame (); - } - return true; -} -*/ - -#include -//#define _CRTDBG_CHECK_EVERY_16_DF 0x00100000 /* check heap every 16 heap ops */ -//#define _CRTDBG_CHECK_EVERY_128_DF 0x00800000 /* check heap every 128 heap ops */ -//#define _CRTDBG_CHECK_EVERY_1024_DF 0x04000000 /* check heap every 1024 heap ops */ - -void CClientGame::EnablePacketRecorder(const char* szFilename) -{ - m_pManager->GetPacketRecorder()->StartRecord(szFilename, true); -} - -void CClientGame::StartPlayback(void) -{ - // strcpy ( m_szNick, "Playback" ); - - m_bIsPlayingBack = true; - m_bFirstPlaybackFrame = true; - m_pManager->GetPacketRecorder()->SetPacketHandler(CClientGame::StaticProcessPacket); - - if (!m_pManager->IsGameLoaded()) - { - g_pGame->StartGame(); - } -} - -bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerType Type) -{ - m_ServerType = Type; - // int dbg = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ); - // dbg |= _CRTDBG_ALLOC_MEM_DF; - // dbg |= _CRTDBG_CHECK_ALWAYS_DF; - // dbg |= _CRTDBG_DELAY_FREE_MEM_DF; - // dbg |= _CRTDBG_LEAK_CHECK_DF; - //_CrtSetDbgFlag(dbg); - - // Verify that the nickname is valid - if (!IsNickValid(szNick)) - { - g_pCore->ShowMessageBox(_("Error") + _E("CD01"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - // Store our nickname - m_strLocalNick.AssignLeft(szNick, MAX_PLAYER_NICK_LENGTH); - - // Are we connected? - if (g_pNet->IsConnected() || m_bIsPlayingBack) - { - // Hide the console when connecting.. - if (g_pCore->GetConsole()->IsVisible()) - g_pCore->GetConsole()->SetVisible(false); - - // Display the status box - g_pCore->ShowMessageBox(_("CONNECTING"), _("Entering the game ..."), MB_ICON_INFO); - - // Send the initial data to the server - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Hash the password if neccessary - MD5 Password; - memset(Password.data, 0, sizeof(MD5)); - if (szPassword) - { - // Is it long enough? - size_t sizePassword = strlen(szPassword); - if (sizePassword > 0) - { - // Hash the password and put it in the struct - CMD5Hasher Hasher; - Hasher.Calculate(szPassword, sizePassword, Password); - } - } - - // Append version information - pBitStream->Write(static_cast(MTA_DM_NETCODE_VERSION)); - pBitStream->Write(static_cast(MTA_DM_VERSION)); - pBitStream->Write(static_cast(MTA_DM_BITSTREAM_VERSION)); - - SString strPlayerVersion("%d.%d.%d-%d.%05d.%d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, - MTASA_VERSION_BUILD, g_pNet->GetNetRev()); - pBitStream->WriteString(strPlayerVersion); - - pBitStream->WriteBit(g_pCore->IsOptionalUpdateInfoRequired(g_pNet->GetConnectedServer(true))); - - pBitStream->Write(static_cast(g_pGame->GetGameVersion())); - - // Append user details - SString strTemp = StringZeroPadout(m_strLocalNick, MAX_PLAYER_NICK_LENGTH); - pBitStream->Write(strTemp.c_str(), MAX_PLAYER_NICK_LENGTH); - pBitStream->Write(reinterpret_cast(Password.data), sizeof(MD5)); - - // Append community information (Removed) - std::string strUser; - pBitStream->Write(strUser.c_str(), MAX_SERIAL_LENGTH); - - // Send the packet as joindata - g_pNet->SendPacket(PACKET_ID_PLAYER_JOINDATA, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - return true; - } - } - else - { - g_pCore->ShowMessageBox(_("Error") + _E("CD02"), _("Not connected; please use Quick Connect or the 'connect' command to connect to a server."), - MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - } - - return false; -} - -void CClientGame::SetupLocalGame(eServerType Type) -{ - SString strConfig = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; - m_bWaitingForLocalConnect = true; - if (!m_pLocalServer) - m_pLocalServer = new CLocalServer(strConfig); -} - -bool CClientGame::StartLocalGame(eServerType Type, const char* szPassword) -{ - // Verify that the nickname is valid - std::string strNick; - g_pCore->GetCVars()->Get("nick", strNick); - - if (!IsNickValid(strNick.c_str())) - { - g_pCore->ShowMessageBox(_("Error") + _E("CD03"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - m_bWaitingForLocalConnect = false; - m_ServerType = Type; - SString strTemp = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; - - SAFE_DELETE(m_pLocalServer); - - // Store our nickname - m_strLocalNick.AssignLeft(strNick.c_str(), MAX_PLAYER_NICK_LENGTH); - - // Got a server? - if (m_bLocalPlay) - { - // Start the server locally - if (!m_Server.Start(strTemp)) - { - m_bWaitingForLocalConnect = true; - m_bErrorStartingLocal = true; - g_pCore->ShowMessageBox(_("Error") + _E("CD04"), _("The server is not installed"), MB_ICON_ERROR | MB_BUTTON_OK); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - if (szPassword) - m_Server.SetPassword(szPassword); - - // Display the status box<<<<< - m_OnCancelLocalGameClick = GUI_CALLBACK(&CClientGame::OnCancelLocalGameClick, this); - g_pCore->ShowMessageBox(_("Local Server"), _("Starting local server ..."), MB_BUTTON_CANCEL | MB_ICON_INFO, &m_OnCancelLocalGameClick); - } - else - { - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - // We're waiting for connection - m_bWaitingForLocalConnect = true; - return true; -} - -bool CClientGame::OnCancelLocalGameClick(CGUIElement* pElement) -{ - if (m_bLocalPlay && m_bWaitingForLocalConnect) - { - g_pCore->RemoveMessageBox(); - g_pCore->GetModManager()->RequestUnload(); - return true; - } - return false; -} - -void CClientGame::DoPulsePreFrame(void) -{ - if (m_Status == CClientGame::STATUS_JOINED) - { - if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) - { - m_pVoiceRecorder->DoPulse(); - } - } -} - -void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRenderTargets) -{ - // Allow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); - - // If appropriate, call onClientRestore - if (bDidUnminimize) - { - CLuaArguments Arguments; - Arguments.PushBoolean(bDidRecreateRenderTargets); - m_pRootEntity->CallEvent("onClientRestore", Arguments, false); - m_bWasMinimized = false; - - // Reverse any mute on minimize effects - g_pGame->GetAudio()->SetEffectsMasterVolume(g_pGame->GetSettings()->GetSFXVolume()); - g_pGame->GetAudio()->SetMusicMasterVolume(g_pGame->GetSettings()->GetRadioVolume()); - m_pManager->GetSoundManager()->SetMinimizeMuted(false); - } - - // Call onClientHUDRender LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientHUDRender", Arguments, false); - - // Disallow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); - - // Restore in case script forgets - g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); - - DebugElementRender(); -} - -void CClientGame::DoPulsePostFrame(void) -{ - TIMING_CHECKPOINT("+CClientGame::DoPulsePostFrame"); - #ifdef DEBUG_KEYSTATES - // Get the controller state - CControllerState cs; - g_pGame->GetPad()->GetCurrentControllerState(&cs); - - SString strBuffer; - strBuffer = SString::Printf( - "LeftShoulder1: %u\n" - "LeftShoulder2: %u\n" - "RightShoulder1: %u\n" - "RightShoulder2: %u\n" - "DPadUp: %u\n" - "DPadDown: %u\n" - "DPadLeft: %u\n" - "DPadRight: %u\n" - "Start: %u\n" - "Select: %u\n" - "ButtonSquare: %u\n" - "ButtonTriangle: %u\n" - "ButtonCross: %u\n" - "ButtonCircle: %u\n" - "ShockButtonL: %u\n" - "ShockButtonR: %u\n" - "PedWalk: %u\n", - cs.LeftShoulder1, cs.LeftShoulder2, cs.RightShoulder1, cs.RightShoulder2, cs.DPadUp, cs.DPadDown, cs.DPadLeft, cs.DPadRight, cs.Start, cs.Select, - cs.ButtonSquare, cs.ButtonTriangle, cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.ShockButtonR, cs.m_bPedWalk); - - g_pCore->GetGraphics()->DrawTextTTF(300, 10, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); - - strBuffer = SString::Printf( - "VehicleMouseLook: %u\n" - "LeftStickX: %u\n" - "LeftStickY: %u\n" - "RightStickX: %u\n" - "RightStickY: %u", - cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, cs.RightStickX, cs.RightStickY); - - g_pCore->GetGraphics()->DrawTextTTF(300, 320, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); - #endif - - UpdateModuleTickCount64(); - - if (m_pManager->IsGameLoaded()) - { - // Pulse the nametags before anything that changes player positions, we'll be 1 frame behind, but so is the camera - // If nametags are enabled, pulse the nametag manager - if (m_bShowNametags) - { - m_pNametags->DoPulse(); - } - - // Sync debug - m_pSyncDebug->OnPulse(); - - // Also eventually draw FPS - if (m_bShowFPS) - { - DrawFPS(); - } - - CGraphicsInterface* pGraphics = g_pCore->GetGraphics(); - unsigned int uiHeight = pGraphics->GetViewportHeight(); - unsigned int uiWidth = pGraphics->GetViewportWidth(); - - // Draw a little star in the corner if async is on - if (g_pGame->IsASyncLoadingEnabled(true)) - { - unsigned int uiPosY = g_pGame->IsASyncLoadingEnabled() ? uiHeight - 7 : uiHeight - 12; - pGraphics->DrawString(uiWidth - 5, uiPosY, 0x80ffffff, 1, "*"); - } - - // Draw notice text if dx test mode is enabled - if (g_pCore->GetGraphics()->GetRenderItemManager()->GetTestMode()) - { - unsigned int uiPosY = uiHeight - 30; - pGraphics->DrawString(uiWidth - 155, uiPosY, 0x40ffffff, 1, "dx test mode enabled"); - } - - // Draw notice text if diagnostic mode enabled - EDiagnosticDebugType diagnosticDebug = g_pCore->GetDiagnosticDebug(); - if (diagnosticDebug == EDiagnosticDebug::LOG_TIMING_0000) - { - unsigned int uiPosY = uiHeight - 30; - pGraphics->DrawString(uiWidth - 185, uiPosY, 0xffffff00, 1, "Debug setting: #0000 Log timing"); - } - - // Draw network trouble message if required - if (m_pNetAPI->IsNetworkTrouble()) - { - int iPosX = uiWidth / 2; // Half way across - int iPosY = uiHeight * 45 / 100; // 45/100 down - g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, - DT_NOCLIP | DT_CENTER); - } - - // Adjust the streaming memory limit. - unsigned int uiStreamingMemoryPrev; - g_pCore->GetCVars()->Get("streaming_memory", uiStreamingMemoryPrev); - uint uiStreamingMemory = SharedUtil::Clamp(g_pCore->GetMinStreamingMemory(), uiStreamingMemoryPrev, g_pCore->GetMaxStreamingMemory()); - if (uiStreamingMemory != uiStreamingMemoryPrev) - g_pCore->GetCVars()->Set("streaming_memory", uiStreamingMemory); - - int iStreamingMemoryBytes = static_cast(uiStreamingMemory) * 1024 * 1024; - if (g_pMultiplayer->GetLimits()->GetStreamingMemory() != iStreamingMemoryBytes) - g_pMultiplayer->GetLimits()->SetStreamingMemory(iStreamingMemoryBytes); - - // If we're in debug mode and are supposed to show task data, do it - #ifdef MTA_DEBUG - if (m_pShowPlayerTasks) - { - DrawTasks(m_pShowPlayerTasks); - } - - if (m_pShowPlayer) - { - DrawPlayerDetails(m_pShowPlayer); - } - - std::vector::const_iterator iter = m_pPlayerManager->IterBegin(); - for (; iter != m_pPlayerManager->IterEnd(); ++iter) - { - CClientPlayer* pPlayer = *iter; - if (pPlayer->IsStreamedIn() && pPlayer->IsShowingWepdata()) - DrawWeaponsyncData(pPlayer); - } - #endif - - #if defined (MTA_DEBUG) || defined (MTA_BETA) - if (m_bShowSyncingInfo) - { - // Draw the header boxz - CVector vecPosition = CVector(0.05f, 0.32f, 0); - m_pDisplayManager->DrawText2D("Syncing vehicles:", vecPosition, 1.0f, 0xFFFFFFFF); - - // Print each vehicle we're syncing - CDeathmatchVehicle* pVehicle; - list::const_iterator iter = m_pUnoccupiedVehicleSync->IterBegin(); - for (; iter != m_pUnoccupiedVehicleSync->IterEnd(); iter++) - { - vecPosition.fY += 0.03f; - pVehicle = *iter; - - SString strBuffer("ID: %u (%s)", pVehicle->GetID(), pVehicle->GetNamePointer()); - - m_pDisplayManager->DrawText2D(strBuffer, vecPosition, 1.0f, 0xFFFFFFFF); - } - } - #endif - // Heli Clear time - if (m_LastClearTime.Get() > HeliKill_List_Clear_Rate) - { - // Clear our list now - m_HeliCollisionsMap.clear(); - m_LastClearTime.Reset(); - } - - CClientPerfStatManager::GetSingleton()->DoPulse(); - } - - m_pRadarMap->DoRender(); - m_pManager->DoRender(); - DoPulses(); - - // If we're supposed to show netstat, draw them infront of everything else - if (m_bShowNetstat) - { - m_pNetworkStats->Draw(); - } -} - -void CClientGame::DoPulses(void) -{ - TIMING_CHECKPOINT("-CClientGame::DoPulsePostFrame"); - - g_pCore->ApplyFrameRateLimit(); - - TIMING_CHECKPOINT("+CClientGame::DoPulses"); - - m_BuiltCollisionMapThisFrame = false; - - if (m_bIsPlayingBack && m_bFirstPlaybackFrame && m_pManager->IsGameLoaded()) - { - g_pCore->GetConsole()->Printf("First playback frame, starting"); - m_pManager->GetPacketRecorder()->StartPlayback("log.rec", false); - m_bFirstPlaybackFrame = false; - } - - // Call debug code if debug mode - m_Foo.DoPulse(); - - // Output stuff from our internal server eventually - m_Server.DoPulse(); - - if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED && GetTickCount64_() - m_llLastTransgressionTime > 60000) - { - uint uiLevel = 0; - uint uiInform = 0; - SString strMessage; - - // Is the player a cheater? - if (!m_pManager->GetAntiCheat().PerformChecks()) - { - uiLevel = 1; - uiInform = 2; - } - else - { - strMessage = g_pNet->GetNextBuffer(); - if (strMessage.length()) - { - uiLevel = atoi(strMessage.SplitLeft(":", &strMessage)); - uiInform = atoi(strMessage.SplitLeft(":", &strMessage)); - } - } - - // Send message to the server - if (uiLevel) - { - SString strPrefix = (uiInform == 2) ? "AC" : (uiInform == 1) ? "VF" : "SD"; - SString strMessageCombo = SString("%s #%d %s", *strPrefix, uiLevel, strMessage.c_str()).TrimEnd(" "); - m_llLastTransgressionTime = GetTickCount64_(); - AddReportLog(3100, strMessageCombo + SString(" (%d)", uiInform)); - - if (uiInform > 0) - { - // The server will use the whole message as supplied here - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write(uiLevel); - pBitStream->WriteString(strMessageCombo); - g_pNet->SendPacket(PACKET_ID_PLAYER_TRANSGRESSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - else - { - // Otherwise, disconnect here - AddReportLog(7105, SString("Core - Kicked (%s)", *strMessageCombo)); - g_pCore->ShowMessageBox(_("Error") + _E("CD05"), SString(_("You were kicked from the game ( %s )"), *strMessageCombo), - MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - } - - // Send diagnostic info - if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED) - { - // Retrieve data - SString strMessage = g_pNet->GetDiagnosticStatus(); - - // Send to the server if changed - if (strMessage != m_strLastDiagnosticStatus) - { - m_strLastDiagnosticStatus = strMessage; - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->WriteString(strMessage); - g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } - - // Pulse the network interface - - // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) - DoPulses2(false); - - m_pUnoccupiedVehicleSync->DoPulse(); - m_pPedSync->DoPulse(); -#ifdef WITH_OBJECT_SYNC - m_pObjectSync->DoPulse(); -#endif - m_pLatentTransferManager->DoPulse(); - m_pLuaManager->DoPulse(); - m_pScriptDebugging->UpdateLogOutput(); - - GetModelCacheManager()->DoPulse(); - - #ifdef MTA_DEBUG - UpdateMimics(); - #endif - - // Grab the current time - unsigned long ulCurrentTime = CClientTime::GetTime(); - - // Waiting for a connect? - if (m_bWaitingForLocalConnect) - { - // Connected? - if (g_pNet->IsConnected()) - { - // No longer waiting for connect - m_bWaitingForLocalConnect = false; - - // Assume local server has the same bitstream version - g_pNet->SetServerBitStreamVersion(MTA_DM_BITSTREAM_VERSION); - - // Run the game normally. - StartGame(m_strLocalNick, m_Server.GetPassword().c_str(), m_ServerType); - } - else - { - // Going to try connecting? Do this when the internal server has booted - // and we haven't started the connecting. - if (m_Server.IsReady() && m_iLocalConnectAttempts == 0) - { - g_pCore->ShowMessageBox(_("Local Server"), _("Connecting to local server..."), MB_ICON_INFO); - - // Connect - if (g_pNet->StartNetwork("localhost", 22010)) - { - // We're waiting for connection - m_iLocalConnectAttempts = 1; - m_ulTimeStart = CClientTime::GetTime(); - } - else - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD06"), _("Error connecting to server.")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - - // Timeout? - if (m_ulTimeStart != 0 && CClientTime::GetTime() >= m_ulTimeStart + 5000) - { - // Show timeout message and disconnect - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD07"), _("Connecting to local server timed out. See console for details.")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - } - - // If the game is loaded ... - if (m_pManager->IsGameLoaded()) - { - // Pulse the blended weather manager - m_pBlendedWeather->DoPulse(); - - // If we weren't ingame last frame; call the on ingame event - if (!m_bGameLoaded) - { - // Fix for gta not being focused sometimes - SetActiveWindow(g_pCore->GetHookedWindow()); - SetFocus(g_pCore->GetHookedWindow()); - - m_bGameLoaded = true; - Event_OnIngame(); - } - - // Check if the player is hitting the enter vehicle button - DoVehicleInKeyCheck(); - - // Pulse some stuff - m_pMovingObjectsManager->DoPulse(); - - // Get rid of our deleted elements - m_ElementDeleter.DoDeleteAll(); - m_pLuaManager->ProcessPendingDeleteList(); - - // Get rid of deleted GUI elements - g_pCore->GetGUI()->CleanDeadPool(); - - // Allow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); - - // Call onClientRender LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientRender", Arguments, false); - - // Disallow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); - - // Restore in case script forgets - g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); - - // Ensure replaced/restored textures for models in the GTA map are correct - g_pGame->FlushPendingRestreamIPL(); - - // Respawn objects in respawn pool - m_ObjectRespawner.DoRespawnAll(); - } - - // Are we connecting? - if (m_Status == CClientGame::STATUS_CONNECTING) - { - if (m_bErrorStartingLocal) - { - g_pCore->GetModManager()->RequestUnload(); - return; - } - - // Timed out? - if (!m_bWaitingForLocalConnect && ulCurrentTime >= m_ulTimeStart + NET_CONNECT_TIMEOUT) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD08"), _("Connection timed out"), "connect-timed-out", true); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - else if (m_Status == CClientGame::STATUS_JOINED) - { - // Pulse DownloadFiles if we're transferring stuff - GetResourceFileDownloadManager()->DoPulse(); - DownloadSingularResourceFiles(); - GetRemoteCalls()->ProcessQueuedFiles(); - } - - // Not waiting for local connect? - if (!m_bWaitingForLocalConnect) - { - // Trigger the ingame and connected event - if (!m_bTriggeredIngameAndConnected && m_pManager->IsGameLoaded() && g_pCore->IsConnected()) - { - m_bTriggeredIngameAndConnected = true; - Event_OnIngameAndConnected(); - - // Initialize the game - g_pCore->GetGame()->Initialize(); - } - - unsigned char ucError = g_pNet->GetConnectionError(); - - // Lost connection? - if (!g_pNet->IsConnected() && !m_bGracefulDisconnect && !m_bIsPlayingBack) - { - // See if we can figure out what specifically it was - if (ucError == 0) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD09"), _("Connection with the server was lost")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - else - { - SString strError; - SString strErrorCode; - switch (ucError) - { - case RID_RSA_PUBLIC_KEY_MISMATCH: - strError = _("Disconnected: unknown protocol error"); - strErrorCode = _E("CD10"); // encryption key mismatch - break; - case RID_REMOTE_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected remotely"); - strErrorCode = _E("CD11"); - break; - case RID_REMOTE_CONNECTION_LOST: - strError = _("Disconnected: connection lost remotely"); - strErrorCode = _E("CD12"); - break; - case RID_CONNECTION_BANNED: - strError = _("Disconnected: you are banned from this server"); - strErrorCode = _E("CD13"); - break; - case RID_NO_FREE_INCOMING_CONNECTIONS: - strError = _("Disconnected: the server is currently full"); - strErrorCode = _E("CD14"); - break; - case RID_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected from the server"); - strErrorCode = _E("CD15"); - break; - case RID_CONNECTION_LOST: - strError = _("Disconnected: connection to the server was lost"); - strErrorCode = _E("CD16"); - break; - case RID_INVALID_PASSWORD: - strError = _("Disconnected: invalid password specified"); - strErrorCode = _E("CD17"); - break; - default: - strError = _("Disconnected: connection was refused"); - strErrorCode = _E("CD18"); - break; - } - - // Display an error, reset the error status and exit - g_pCore->ShowNetErrorMessageBox(_("Error") + strErrorCode, strError); - g_pNet->SetConnectionError(0); - g_pCore->GetModManager()->RequestUnload(); - } - } - - // If we're in the verificating status - if (m_Status == CClientGame::STATUS_JOINING) - { - // Time out the verification if it takes too long - if (m_ulVerifyTimeStart != 0 && ulCurrentTime >= m_ulVerifyTimeStart + CLIENT_VERIFICATION_TIMEOUT) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD19"), _("MTA Client verification failed!")); - g_pCore->GetModManager()->RequestUnload(); - } - } - } - - // Check for radar input - m_pRadarMap->DoPulse(); - g_pCore->GetGraphics()->SetAspectRatioAdjustmentSuspended(m_pRadarMap->IsRadarShowing()); - - // Got a local player? - if (m_pLocalPlayer) - { - // Network updates - UpdateVehicleInOut(); - UpdatePlayerTarget(); - UpdatePlayerWeapons(); - // UpdateTrailers (); // Test: Does it always work without this check? - UpdateStunts(); - // Clear last damager if more than 2 seconds old - if (CClientTime::GetTime() - m_ulDamageTime > 2000) - { - m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageWeapon = 0xFF; - m_ucDamageBodyPiece = 0xFF; - } - DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); - } - - // Game hacks, restore certain variables - // game-speed changes after spawning - g_pGame->SetGameSpeed(m_fGameSpeed); - // money changes on death/getting into taxis - g_pGame->GetPlayerInfo()->SetPlayerMoney(m_lMoney); - // wanted to stop it changing on skin change etc - if (m_pLocalPlayer) - { - if (m_dwWanted != g_pGame->GetPlayerInfo()->GetWanted()->GetWantedLevel()) - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevelNoFlash(m_dwWanted); - } - // stop players dying from starvation - g_pGame->GetPlayerInfo()->SetLastTimeEaten(0); - // reset weapon logs (for preventing quickreload) - - // Update streaming - m_pManager->UpdateStreamers(); - - // Send screen shot data - ProcessDelayedSendList(); - - // Collect async task scheduler results - m_pAsyncTaskScheduler->CollectResults(); - - TIMING_CHECKPOINT("-CClientGame::DoPulses"); -} - -// Extrapolation test -void CClientGame::DoPulses2(bool bCalledFromIdle) -{ - bool bIsUsingAlternatePulseOrder = IsUsingAlternatePulseOrder(!bCalledFromIdle); - - // Figure out which pulses to do - bool bDoStandardPulses; - bool bDoVehicleManagerPulse; - - if (!bIsUsingAlternatePulseOrder) - { - // With std pulse order, do pulses when not called from idle - bDoStandardPulses = !bCalledFromIdle; - bDoVehicleManagerPulse = !bCalledFromIdle; - } - else - { - // With alt pulse order, do pulses when called from idle - bDoStandardPulses = bCalledFromIdle; - bDoVehicleManagerPulse = bCalledFromIdle; - - // Except when watching a remote synced vehicle - if (CClientVehicle* pTargetVehicle = DynamicCast(m_pCamera->GetTargetEntity())) - if (pTargetVehicle->GetControllingPlayer() != m_pPlayerManager->GetLocalPlayer()) - bDoVehicleManagerPulse = !bDoVehicleManagerPulse; - } - - if (bDoStandardPulses) - { - // Change to high precision so arguments in element data and events can - // be rounded to look more like what is expected - ChangeFloatPrecision(true); - - // Pulse the network interface - TIMING_CHECKPOINT("+NetPulse"); - g_pNet->DoPulse(); - TIMING_CHECKPOINT("-NetPulse"); - - // Change precision back, and check we are in low precision mode 4 sure - ChangeFloatPrecision(false); - assert(!IsHighFloatPrecision()); - } - - m_pManager->DoPulse(bDoStandardPulses, bDoVehicleManagerPulse); - - if (bDoStandardPulses) - { - m_pNetAPI->DoPulse(); - } -} - -void CClientGame::HandleException(CExceptionInformation* pExceptionInformation) -{ -} - -void CClientGame::HandleRadioNext(CControlFunctionBind*) -{ - if (g_pClientGame) - { - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); - if (pPlayer) - { - pPlayer->NextRadioChannel(); - } - } -} - -void CClientGame::HandleRadioPrevious(CControlFunctionBind*) -{ - if (g_pClientGame) - { - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); - if (pPlayer) - { - pPlayer->PreviousRadioChannel(); - } - } -} -bool CClientGame::IsNametagValid(const char* szNick) -{ - // Grab the size of the nametag. Check that it's not to long or short - size_t sizeNick = MbUTF8ToUTF16(szNick).size(); - if (sizeNick < MIN_PLAYER_NAMETAG_LENGTH || sizeNick > MAX_PLAYER_NAMETAG_LENGTH) - { - return false; - } - - // Check that each character is valid (Anything above 32) - unsigned char ucTemp; - for (size_t i = 0; i < sizeNick; i++) - { - ucTemp = szNick[i]; - if (ucTemp < 32) - { - return false; - } - } - - // nametag is valid, return true - return true; -} - -bool CClientGame::IsNickValid(const char* szNick) -{ - // Grab the size of the nick. Check that it's within the player - size_t sizeNick = strlen(szNick); - if (sizeNick < MIN_PLAYER_NICK_LENGTH || sizeNick > MAX_PLAYER_NICK_LENGTH) - { - return false; - } - - // Check that each character is valid (visible characters exluding space) - unsigned char ucTemp; - for (size_t i = 0; i < sizeNick; i++) - { - ucTemp = szNick[i]; - if (ucTemp < 33 || ucTemp > 126) - { - return false; - } - } - - // Nickname is valid, return true - return true; -} - -void CClientGame::ShowNetstat(int iCmd) -{ - bool bShow = (iCmd == 1) ? true : (iCmd == 0) ? false : !m_bShowNetstat; - - if (bShow && !m_bShowNetstat) - { - m_pNetworkStats->Reset(); - } - m_bShowNetstat = bShow; -} - -void CClientGame::ShowEaeg(bool) -{ - if (m_pLocalPlayer) - m_pLocalPlayer->SetStat(0x2329, 1.0f); -} - -#ifdef MTA_WEPSYNCDBG -void CClientGame::ShowWepdata(const char* szNick) -{ - CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); - if (pPlayer) - { - pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); - } -} -#endif - -#ifdef MTA_DEBUG - -void CClientGame::ShowWepdata(const char* szNick) -{ - CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); - if (pPlayer) - { - pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); - } -} - -void CClientGame::ShowPlayer(const char* szNick) -{ - m_pShowPlayer = m_pPlayerManager->Get(szNick); -} - -void CClientGame::ShowTasks(const char* szNick) -{ - m_pShowPlayerTasks = m_pPlayerManager->Get(szNick); -} - -void CClientGame::SetMimic(unsigned int uiMimicCount) -{ - // Check if we're within the max mimics boundary - if (uiMimicCount > MAX_MIMICS) - return; - - // Create neccessary players - while (m_Mimics.size() < uiMimicCount) - { - CClientPlayer* pPlayer = new CClientPlayer(m_pManager, static_cast(MAX_NET_PLAYERS_REAL + (int)m_Mimics.size())); - pPlayer->SetNick("Mimic"); - m_Mimics.push_back(pPlayer); - } - - // Destroy neccessary players - while (m_Mimics.size() > uiMimicCount) - { - CClientPlayer* pPlayer = m_Mimics.back(); - CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); - if (pVehicle) - delete pVehicle; - - delete pPlayer; - m_Mimics.pop_back(); - } -} - -#endif - -void CClientGame::DoVehicleInKeyCheck(void) -{ - // Grab the controller state - CControllerState cs; - g_pGame->GetPad()->GetCurrentControllerState(&cs); - static bool bButtonTriangleWasDown = false; - if (cs.ButtonTriangle) - { - if (!bButtonTriangleWasDown) - { - bButtonTriangleWasDown = true; - - // Process the hit - ProcessVehicleInOutKey(false); - } - } - else - { - bButtonTriangleWasDown = false; - } -} - -void CClientGame::UpdateVehicleInOut(void) -{ - // We got told by the server to animate into a certain vehicle? - if (m_VehicleInOutID != INVALID_ELEMENT_ID) - { - // Grab the vehicle we're getting in/out of - CDeathmatchVehicle* pInOutVehicle = static_cast(m_pVehicleManager->Get(m_VehicleInOutID)); - - // In or out? - if (m_bIsGettingOutOfVehicle) - { - // If we aren't working on leaving the car (he's eiter finished or cancelled/failed leaving) - if (!m_pLocalPlayer->IsLeavingVehicle()) - { - // Are we outside the car? - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - if (!pVehicle) - { - // Tell the server that we successfully left the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction = VEHICLE_NOTIFY_OUT; - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself out (so we're sure the records are correct) - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it, and damagable if we're syncing it - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - }*/ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - - // Reset the vehicle in out stuff so we're ready for another car entry/leave. - // Don't allow a new entry/leave until we've gotten the notify return packet - ElementID ReasonVehicleID = m_VehicleInOutID; - g_pClientGame->ResetVehicleInOut(); - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = ReasonVehicleID; - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_out"); -#endif - } - // Are we still inside the car? - else - { - // Warp us out now to keep in sync with the server - m_pLocalPlayer->RemoveFromVehicle(); - } - } - } - - // Are we getting into a vehicle? - else if (m_bIsGettingIntoVehicle) - { - // If we aren't working on entering the car (he's either finished or cancelled) - if (!m_pLocalPlayer->IsEnteringVehicle()) - { - // Is he in a vehicle now? - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - if (pVehicle) - { - // Tell the server that we successfully entered the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction; - - if (m_bIsJackingVehicle) - { - ucAction = static_cast(VEHICLE_NOTIFY_JACK); -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack"); -#endif - } - else - { - ucAction = static_cast(VEHICLE_NOTIFY_IN); -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in"); -#endif - } - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself in (so we're sure the records are correct) - pVehicle->AllowDoorRatioSetting(m_pLocalPlayer->m_ucEnteringDoor, true); - m_pLocalPlayer->WarpIntoVehicle(pVehicle, m_ucVehicleInOutSeat); - - /* - // Make it damagable - if ( pInOutVehicle ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - */ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - } - else - { - // Tell the server that we aborted entered the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction; - if (m_bIsJackingVehicle) - { - ucAction = static_cast(VEHICLE_NOTIFY_JACK_ABORT); - pBitStream->WriteBits(&ucAction, 4); - - // Did we start jacking them? - bool bAlreadyStartedJacking = false; - CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); - if (pVehicle) - { - CClientPed* pJackedPlayer = pVehicle->GetOccupant(); - if (pJackedPlayer) - { - // Jax: have we already started to jack the other player? - if (pJackedPlayer->IsGettingJacked()) - { - bAlreadyStartedJacking = true; - } - } - unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; - pBitStream->WriteBits(&ucDoor, 3); - SDoorOpenRatioSync door; - door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); - pBitStream->Write(&door); - } - pBitStream->WriteBit(bAlreadyStartedJacking); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack_abort"); -#endif - } - else - { - ucAction = static_cast(VEHICLE_NOTIFY_IN_ABORT); - pBitStream->WriteBits(&ucAction, 4); - CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); - if (pVehicle) - { - unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; - pBitStream->WriteBits(&ucDoor, 3); - SDoorOpenRatioSync door; - door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); - pBitStream->Write(&door); - } - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in_abort"); -#endif - } - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself out again (so we're sure the records are correct) - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it, and damagable if we're syncing it - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - } - */ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - } - - // Reset - // Don't allow a new entry/leave until we've gotten the notify return packet - ElementID ReasonID = m_VehicleInOutID; - ResetVehicleInOut(); - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = ReasonID; - } - } - } - else - { - // If we aren't getting jacked - if (!m_bIsGettingJacked) - { - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - - // Jax: this was commented, re-comment if it was there for a reason (..and give the reason!) - // Are we in a vehicle we aren't supposed to be in? - if (pVehicle && !pOccupiedVehicle) - { - g_pCore->GetConsole()->Print("You shouldn't be in this vehicle"); - m_pLocalPlayer->RemoveFromVehicle(); - } - - // Are we supposed to be in a vehicle? But aren't? - if (pOccupiedVehicle && !pVehicle) - { - // Jax: this happens when we try to warp into a streamed out vehicle, including when we use CClientVehicle::StreamInNow - // ..maybe we need a different way to detect bike falls? - - // Tell the server - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Vehicle id - pBitStream->Write(pOccupiedVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_NOTIFY_FELL_OFF); - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're not allowed to enter any vehicle before we get a confirm - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = pOccupiedVehicle->GetID(); - - // Remove him from the vehicle - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it - CDeathmatchVehicle* pInOutVehicle = static_cast < CDeathmatchVehicle* > ( pOccupiedVehicle ); - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - } - */ - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_fell_off"); -#endif - } - } - } - } -} - -void CClientGame::UpdatePlayerTarget(void) -{ - CControllerState ControllerState; - m_pLocalPlayer->GetControllerState(ControllerState); - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - - // Ignore the local player so we don't get hit - m_pLocalPlayer->WorldIgnore(true); - - // Run a process line of sight and look for an entity we target - CEntity* pColEntity = NULL; - CColPoint* pColPoint = NULL; - g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pColEntity); - - // Unignore the local player again - m_pLocalPlayer->WorldIgnore(false); - - // Kill the colpoint or we get a severe memoryleak - if (pColPoint) - pColPoint->Destroy(); - - if (pColEntity != m_pTargetedGameEntity) - { - m_pTargetedGameEntity = pColEntity; - - if (pColEntity) - { - m_pTargetedEntity = m_pManager->FindEntity(pColEntity); - } - else - m_pTargetedEntity = NULL; - - // Store the last targeted player's id - if (m_pTargetedEntity && m_pTargetedEntity->GetType() == CCLIENTPLAYER) - { - m_TargetedPlayerID = m_pTargetedEntity->GetID(); - } - else - m_TargetedPlayerID = INVALID_ELEMENT_ID; - - // Send the target - ElementID TargetID = INVALID_ELEMENT_ID; - if (m_pTargetedEntity && !m_pTargetedEntity->IsLocalEntity()) - { - TargetID = m_pTargetedEntity->GetID(); - } - - CBitStream bitStream; - bitStream.pBitStream->Write(TargetID); - m_pNetAPI->RPC(PLAYER_TARGET, bitStream.pBitStream); - - // Call our onClientPlayerTarget event - CLuaArguments Arguments; - if (m_pTargetedEntity) - Arguments.PushElement(m_pTargetedEntity); - else - Arguments.PushBoolean(false); - m_pLocalPlayer->CallEvent("onClientPlayerTarget", Arguments, true); - } -} - -void CClientGame::UpdatePlayerWeapons(void) -{ - // Check whether we changed weapon slots - eWeaponSlot currentSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - if (currentSlot != m_lastWeaponSlot) - { - CLuaArguments Arguments; - Arguments.PushNumber(m_lastWeaponSlot); - Arguments.PushNumber(currentSlot); - bool bCancelled = !m_pLocalPlayer->CallEvent("onClientPlayerWeaponSwitch", Arguments, true); - - if (bCancelled) - { - // Save the current ammo in clip - unsigned short usAmmoInClip = 0; - CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); - if (pWeapon) - usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); - - // Force it back to the old slot - m_pLocalPlayer->SetCurrentWeaponSlot(m_lastWeaponSlot); - - // Restore the ammo in clip that there was in that slot - if (usAmmoInClip > 0) - m_pLocalPlayer->GetWeapon()->SetAmmoInClip(usAmmoInClip); - } - else - { - CBitStream bitStream; - CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(); - NetBitStreamInterface& BitStream = *(bitStream.pBitStream); - SWeaponSlotSync slot; - - // Always send bit in case server is not in sync - if ((BitStream.Version() >= 0x44 && m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN) || BitStream.Version() >= 0x4D) - { - CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); - if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && - (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || - (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) - BitStream.WriteBit(true); - else - BitStream.WriteBit(false); - } - - if (pWeapon) - { - /* Send a packet to the server with info about the new weapon, - so the server stays in sync reliably */ - unsigned int uiSlot = static_cast(pWeapon->GetSlot()); - slot.data.uiSlot = uiSlot; - BitStream.Write(&slot); - - if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) - { - SWeaponAmmoSync ammo(pWeapon->GetType(), true, true); - ammo.data.usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); - ammo.data.usTotalAmmo = static_cast(pWeapon->GetAmmoTotal()); - BitStream.Write(&ammo); - } - } - else - { - slot.data.uiSlot = 0; - BitStream.Write(&slot); - } - - m_pNetAPI->RPC(PLAYER_WEAPON, bitStream.pBitStream); - m_lastWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - } - } -} - -void CClientGame::UpdateTrailers(void) -{ - // This function is here to re-attach trailers if they fall off - - unsigned long ulCurrentTime = GetTickCount32(); - - CClientVehicle * pVehicle = NULL, *pTrailer = NULL; - CVehicle * pGameVehicle = NULL, *pGameTrailer = NULL; - unsigned long ulIllegalTowBreakTime; - vector::const_iterator iterVehicles = m_pVehicleManager->StreamedBegin(); - for (; iterVehicles != m_pVehicleManager->StreamedEnd(); iterVehicles++) - { - pVehicle = *iterVehicles; - ulIllegalTowBreakTime = pVehicle->GetIllegalTowBreakTime(); - - // Do we have an illegal break? - if (ulIllegalTowBreakTime != 0) - { - // Has it been atleast 1 second since the break - if (ulCurrentTime > (ulIllegalTowBreakTime + 1000)) - { - // Try to re-attach them - CClientVehicle* pTowedBy = pVehicle->GetTowedByVehicle(); - if (pTowedBy) - { - // Little hack to keep illegaly detached trailers close to their tower - CVector vecPosition; - pVehicle->GetPosition(vecPosition); - pVehicle->SetPosition(vecPosition); - - pGameVehicle = pTowedBy->GetGameVehicle(); - pGameTrailer = pVehicle->GetGameVehicle(); - if (pGameVehicle && pGameTrailer) - { - // pGameTrailer->SetTowLink ( pGameVehicle ); - CVector vecRotation; - pTowedBy->GetRotationRadians(vecRotation); - pVehicle->SetRotationRadians(vecRotation); - pTowedBy->InternalSetTowLink(pVehicle); - } - } - - // Reset the break time, even if we couldnt re-attach it - pVehicle->SetIllegalTowBreakTime(0); - } - } - } -} - -void CClientGame::UpdateFireKey(void) -{ - if (m_pLocalPlayer) - { - SBindableGTAControl* pControl = g_pCore->GetKeyBinds()->GetBindableFromControl("fire"); - - // Is our 'fire' control enabled? - if (pControl->bEnabled) - { - // ** Satchel charge detonation ** - { - // Do we have a detonator in our hand? - if (m_pLocalPlayer->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_DETONATOR) - { - // Planted any satchels? - if (m_pLocalPlayer->CountProjectiles(WEAPONTYPE_REMOTE_SATCHEL_CHARGE) > 0) - { - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - - // Tell the server we want to detonate our satchels - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - g_pNet->SendPacket(PACKET_ID_DETONATE_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } - // Remove the detonator if we dont have any satchels planted - else - { - m_pLocalPlayer->RemoveWeapon(WEAPONTYPE_DETONATOR); - } - } - } - - // Has our control state been cut short? - if (!pControl->bState) - return; - - // ** Stealth kill ** - { - if (m_pLocalPlayer->IsStealthAiming()) - { - // Do we have a target ped? - CClientPed* pTargetPed = m_pLocalPlayer->GetTargetedPed(); - if (pTargetPed) - { - // Do we have a target player? - if (IS_PLAYER(pTargetPed)) - { - CClientPlayer* pTargetPlayer = static_cast(pTargetPed); - - // Is the targetted player on a team - CClientTeam* pTeam = pTargetPlayer->GetTeam(); - if (pTeam) - { - // Is this friendly-fire? - if (pTargetPlayer->IsOnMyTeam(m_pLocalPlayer) && !pTeam->GetFriendlyFire()) - { - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - return; - } - } - } - CPlayerPed* pGameTarget = static_cast(pTargetPed)->GetGamePlayer(); - if (pGameTarget) - { - // Would GTA let us stealth kill now? - if (m_pLocalPlayer->GetGamePlayer()->GetPedIntelligence()->TestForStealthKill(pGameTarget, false)) - { - // Grab our local position - CVector vecLocalPosition; - m_pLocalPlayer->GetPosition(vecLocalPosition); - - // Grab the target's position - CVector vecTargetPosition; - pTargetPed->GetPosition(vecTargetPosition); - - // Work out an angle between the players, and set this as we initiate our knife kill - float fAngle = AngleBetweenPoints2D(vecLocalPosition, vecTargetPosition); - m_pLocalPlayer->SetCurrentRotation(fAngle); - - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - CLuaArguments Arguments; - Arguments.PushElement(pTargetPed); - if (m_pLocalPlayer->CallEvent("onClientPlayerStealthKill", Arguments, false)) - { - if (pTargetPed->IsLocalEntity()) - { - CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, 4 /*WEAPONTYPE_KNIFE*/, 9 /*BODYPART_HEAD*/, true); - return; - } - - // Lets request a stealth kill - CBitStream bitStream; - bitStream.pBitStream->Write(pTargetPed->GetID()); - m_pNetAPI->RPC(REQUEST_STEALTH_KILL, bitStream.pBitStream); - } - else - { - return; - } - } - } - } - } - } - } - } -} - -void CClientGame::UpdateStunts(void) -{ - // * Two wheeler * - static unsigned long ulLastCarTwoWheelCounter = 0; - static float fLastCarTwoWheelDist = 0.0f; - unsigned long ulTemp = g_pGame->GetPlayerInfo()->GetCarTwoWheelCounter(); - // Did we start a stunt? - if (ulLastCarTwoWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("2wheeler"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastCarTwoWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("2wheeler"); - Arguments.PushNumber(ulLastCarTwoWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastCarTwoWheelCounter = ulTemp; - fLastCarTwoWheelDist = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); - - // * Wheelie * - static unsigned long ulLastBikeRearWheelCounter = 0; - static float fLastBikeRearWheelDist = 0.0f; - ulTemp = g_pGame->GetPlayerInfo()->GetBikeRearWheelCounter(); - // Did we start a stunt? - if (ulLastBikeRearWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("wheelie"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastBikeRearWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("wheelie"); - Arguments.PushNumber(ulLastBikeRearWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastBikeRearWheelCounter = ulTemp; - fLastBikeRearWheelDist = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); - - // * Stoppie * - static unsigned long ulLastBikeFrontWheelCounter = 0; - static float fLastBikeFrontWheelDist = 0.0f; - ulTemp = g_pGame->GetPlayerInfo()->GetBikeFrontWheelCounter(); - // Did we start a stunt? - if (ulLastBikeFrontWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("stoppie"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastBikeFrontWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("stoppie"); - Arguments.PushNumber(ulLastBikeFrontWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastBikeFrontWheelCounter = ulTemp; - fLastBikeFrontWheelDist = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); -} - -void CClientGame::StaticUpdateFireKey(CControlFunctionBind* pBind) -{ - g_pClientGame->UpdateFireKey(); -} - -void CClientGame::ChangeVehicleWeapon(bool bNext) -{ - if (m_pLocalPlayer && m_pLocalPlayer->GetRealOccupiedVehicle()) - { - eWeaponSlot currentWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - eWeaponSlot weaponSlot = currentWeaponSlot; - CWeapon* pWeapon = NULL; - while (!pWeapon || pWeapon->GetType() == WEAPONTYPE_UNARMED) - { - if (bNext) - { - if (weaponSlot == WEAPONSLOT_TYPE_DETONATOR) - { - weaponSlot = WEAPONSLOT_TYPE_UNARMED; - break; - } - - weaponSlot = (eWeaponSlot)(weaponSlot + 1); - - if (weaponSlot == currentWeaponSlot) - break; - - pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); - } - else - { - if (weaponSlot == WEAPONSLOT_TYPE_UNARMED) - { - if (weaponSlot != currentWeaponSlot) - break; - weaponSlot = WEAPONSLOT_TYPE_DETONATOR; - } - - weaponSlot = (eWeaponSlot)(weaponSlot - 1); - - if (weaponSlot == currentWeaponSlot) - break; - - pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); - } - } - if (pWeapon || weaponSlot == WEAPONSLOT_TYPE_UNARMED) - { - m_pLocalPlayer->SetCurrentWeaponSlot(weaponSlot); - } - } -} - -void CClientGame::ResetVehicleInOut(void) -{ - m_ulLastVehicleInOutTime = 0; - m_bIsGettingOutOfVehicle = false; - m_bIsGettingIntoVehicle = false; - m_bIsJackingVehicle = false; - m_bIsGettingJacked = false; - m_VehicleInOutID = INVALID_ELEMENT_ID; - m_ucVehicleInOutSeat = 0xFF; - m_bNoNewVehicleTask = false; - m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; - m_pGettingJackedBy = NULL; -} - -void CClientGame::SetAllDimensions(unsigned short usDimension) -{ - m_pManager->GetMarkerStreamer()->SetDimension(usDimension); - m_pManager->GetObjectStreamer()->SetDimension(usDimension); - m_pManager->GetObjectLodStreamer()->SetDimension(usDimension); - m_pManager->GetPickupStreamer()->SetDimension(usDimension); - m_pManager->GetPlayerStreamer()->SetDimension(usDimension); - m_pManager->GetRadarAreaManager()->SetDimension(usDimension); - m_pManager->GetVehicleStreamer()->SetDimension(usDimension); - m_pManager->GetRadarMarkerManager()->SetDimension(usDimension); - m_pManager->GetSoundManager()->SetDimension(usDimension); - m_pManager->GetPointLightsManager()->SetDimension(usDimension); - m_pManager->GetWaterManager()->SetDimension(usDimension); - m_pNametags->SetDimension(usDimension); - m_pCamera->SetDimension(usDimension); -} - -bool CClientGame::StaticKeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) -{ - return g_pClientGame->KeyStrokeHandler(strKey, bState, bIsConsoleInputKey); -} - -bool CClientGame::KeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) -{ - // Do we have a root yet? - if (m_pRootEntity) - { - // Ignore keydown/up pair if main menu is displayed, or console input will use the character - bool bIgnore = false; - if (bState) - { - auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; - bool isMouseKey = strKey.substr(0, 5) == "mouse"; - - if (g_pCore->IsMenuVisible() || (g_pCore->GetConsole()->IsInputActive() && bIsConsoleInputKey) || - (pFocusedBrowser && !pFocusedBrowser->IsLocal() && !isMouseKey)) - - bIgnore = true; // Ignore this keydown and the matching keyup - else - MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup - } - else - { - if (!MapContains(m_AllowKeyUpMap, strKey)) - bIgnore = true; // Ignore this keyup - else - MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup - } - - if (!bIgnore) - { - bool bAllow = true; - // Call our key-stroke event - CLuaArguments Arguments; - Arguments.PushString(strKey); - Arguments.PushBoolean(bState); - bAllow = m_pRootEntity->CallEvent("onClientKey", Arguments, false); - if (bState == true) - { - if (bAllow == false && strKey == "escape") - { - if (m_bLastKeyWasEscapeCancelled) - { - // Escape cannot be skipped twice - bAllow = true; - m_bLastKeyWasEscapeCancelled = false; - } - else - m_bLastKeyWasEscapeCancelled = true; - } - else - m_bLastKeyWasEscapeCancelled = false; - } - return bAllow; - } - } - m_bLastKeyWasEscapeCancelled = false; - return true; -} - -bool CClientGame::StaticCharacterKeyHandler(WPARAM wChar) -{ - return g_pClientGame->CharacterKeyHandler(wChar); -} - -bool CClientGame::CharacterKeyHandler(WPARAM wChar) -{ - // Do we have a root yet? - if (m_pRootEntity && g_pCore->IsMenuVisible() == false && g_pCore->GetConsole()->IsInputActive() == false) - { - // Cancel event if remote browser is focused - auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; - if (pFocusedBrowser && !pFocusedBrowser->IsLocal()) - return false; - - // Safe character? - if (wChar >= 32) - { - // Generate a null-terminating string for our character - wchar_t wUNICODE[2] = {wChar, '\0'}; - - // Convert our UTF character into an ANSI string - SString strANSI = UTF16ToMbUTF8(wUNICODE); - - // Call our character event - CLuaArguments Arguments; - Arguments.PushString(strANSI); - m_pRootEntity->CallEvent("onClientCharacter", Arguments, false); - } - } - - return false; -} - -void CClientGame::StaticProcessClientKeyBind(CKeyFunctionBind* pBind) -{ - g_pClientGame->ProcessClientKeyBind(pBind); -} - -void CClientGame::ProcessClientKeyBind(CKeyFunctionBind* pBind) -{ - m_pScriptKeyBinds->ProcessKey(pBind->boundKey->szKey, pBind->bHitState, SCRIPT_KEY_BIND_FUNCTION); -} - -void CClientGame::StaticProcessClientControlBind(CControlFunctionBind* pBind) -{ - g_pClientGame->ProcessClientControlBind(pBind); -} - -void CClientGame::ProcessClientControlBind(CControlFunctionBind* pBind) -{ - m_pScriptKeyBinds->ProcessKey(pBind->control->szControl, pBind->bHitState, SCRIPT_KEY_BIND_CONTROL_FUNCTION); -} - -void CClientGame::StaticProcessServerKeyBind(CKeyFunctionBind* pBind) -{ - g_pClientGame->ProcessServerKeyBind(pBind); -} - -void CClientGame::ProcessServerKeyBind(CKeyFunctionBind* pBind) -{ - const char* szName = pBind->boundKey->szKey; - unsigned char ucNameLength = (unsigned char)strlen(szName); - CBitStream bitStream; - bitStream.pBitStream->WriteBit(false); - bitStream.pBitStream->WriteBit(pBind->bHitState); - bitStream.pBitStream->Write(szName, ucNameLength); - m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); -} - -void CClientGame::StaticProcessServerControlBind(CControlFunctionBind* pBind) -{ - g_pClientGame->ProcessServerControlBind(pBind); -} - -void CClientGame::ProcessServerControlBind(CControlFunctionBind* pBind) -{ - const char* szName = pBind->control->szControl; - unsigned char ucNameLength = (unsigned char)strlen(szName); - CBitStream bitStream; - bitStream.pBitStream->WriteBit(true); - bitStream.pBitStream->WriteBit(pBind->bHitState); - bitStream.pBitStream->Write(szName, ucNameLength); - m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); -} - -bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - bool bCursorForcedVisible = g_pCore->IsCursorForcedVisible(); - bool bMenuVisible = g_pCore->IsMenuVisible(); - bool bConsoleVisible = g_pCore->GetConsole()->IsVisible(); - - if (bCursorForcedVisible) - { - if (!bMenuVisible && !bConsoleVisible) - { - if (m_bCursorEventsEnabled) - { - unsigned char ucButtonHit = 0xFF; - switch (uMsg) - { - case WM_LBUTTONDOWN: - ucButtonHit = 0; - break; - case WM_LBUTTONUP: - ucButtonHit = 1; - break; - case WM_MBUTTONDOWN: - ucButtonHit = 2; - break; - case WM_MBUTTONUP: - ucButtonHit = 3; - break; - case WM_RBUTTONDOWN: - ucButtonHit = 4; - break; - case WM_RBUTTONUP: - ucButtonHit = 5; - break; - } - if (ucButtonHit != 0xFF) - { - int iX = LOWORD(lParam); - int iY = HIWORD(lParam); - - CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); - - /* - // (IJs) why are these relative? it doesn't make sense - CVector2D vecCursorPosition ( ( ( float ) iX ) / vecResolution.fX, - ( ( float ) iY ) / vecResolution.fY ); - */ - - CVector2D vecCursorPosition((float)iX, (float)iY); - - CVector vecOrigin, vecTarget, vecScreen((float)iX, (float)iY, 300.0f); - g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); - - // Grab the camera position - CCamera* pCamera = g_pGame->GetCamera(); - CCam* pCam = pCamera->GetCam(pCamera->GetActiveCam()); - CMatrix matCamera; - pCamera->GetMatrix(&matCamera); - vecOrigin = matCamera.vPos; - - CColPoint* pColPoint = NULL; - CEntity* pGameEntity = NULL; - - // Grab the collision point/entity - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pGameEntity); - - CVector vecCollision; - ElementID CollisionEntityID = INVALID_ELEMENT_ID; - CClientEntity* pCollisionEntity = NULL; - if (bCollision && pColPoint) - { - vecCollision = pColPoint->GetPosition(); - if (pGameEntity) - { - CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity); - if (pEntity) - { - pCollisionEntity = pEntity; - if (!pEntity->IsLocalEntity()) - CollisionEntityID = pEntity->GetID(); - } - } - } - else - { - vecCollision = vecTarget; - } - - // Destroy the colpoint so we don't get a leak - if (pColPoint) - { - pColPoint->Destroy(); - } - - const char* szButton = NULL; - const char* szState = NULL; - switch (ucButtonHit) - { - case 0: - szButton = "left"; - szState = "down"; - break; - case 1: - szButton = "left"; - szState = "up"; - break; - case 2: - szButton = "middle"; - szState = "down"; - break; - case 3: - szButton = "middle"; - szState = "up"; - break; - case 4: - szButton = "right"; - szState = "down"; - break; - case 5: - szButton = "right"; - szState = "up"; - break; - } - if (szButton && szState) - { - if (std::isnan(vecCollision.fX)) - vecCollision.fX = 0; - if (std::isnan(vecCollision.fY)) - vecCollision.fY = 0; - if (std::isnan(vecCollision.fZ)) - vecCollision.fZ = 0; - - // Call the event for the client - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(vecCursorPosition.fX); - Arguments.PushNumber(vecCursorPosition.fY); - Arguments.PushNumber(vecCollision.fX); - Arguments.PushNumber(vecCollision.fY); - Arguments.PushNumber(vecCollision.fZ); - if (pCollisionEntity) - Arguments.PushElement(pCollisionEntity); - else - Arguments.PushBoolean(false); - m_pRootEntity->CallEvent("onClientClick", Arguments, false); - - // Send the button, cursor position, 3d position and the entity collided with - CBitStream bitStream; - - SMouseButtonSync button; - button.data.ucButton = ucButtonHit; - bitStream.pBitStream->Write(&button); - - bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fX)); - bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fY)); - - SPositionSync position(false); - position.data.vecPosition = vecCollision; - bitStream.pBitStream->Write(&position); - - if (CollisionEntityID != INVALID_ELEMENT_ID) - { - bitStream.pBitStream->WriteBit(true); - bitStream.pBitStream->Write(CollisionEntityID); - } - else - bitStream.pBitStream->WriteBit(false); - - m_pNetAPI->RPC(CURSOR_EVENT, bitStream.pBitStream); - - if (strcmp(szState, "down") == 0) - { - CVector2D vecDelta = m_vecLastCursorPosition - vecCursorPosition; - - if ((GetTickCount32() - m_ulLastClickTick) < DOUBLECLICK_TIMEOUT && vecDelta.Length() <= DOUBLECLICK_MOVE_THRESHOLD) - { - // Call the event for the client - CLuaArguments DoubleClickArguments; - DoubleClickArguments.PushString(szButton); - DoubleClickArguments.PushNumber(vecCursorPosition.fX); - DoubleClickArguments.PushNumber(vecCursorPosition.fY); - DoubleClickArguments.PushNumber(vecCollision.fX); - DoubleClickArguments.PushNumber(vecCollision.fY); - DoubleClickArguments.PushNumber(vecCollision.fZ); - if (pCollisionEntity) - DoubleClickArguments.PushElement(pCollisionEntity); - else - DoubleClickArguments.PushBoolean(false); - m_pRootEntity->CallEvent("onClientDoubleClick", DoubleClickArguments, false); - } - - m_ulLastClickTick = GetTickCount32(); - m_vecLastCursorPosition = vecCursorPosition; - } - - return true; - } - } - } - } - } - switch (uMsg) - { - case WM_MOUSEMOVE: - { - int iX = LOWORD(lParam), iY = HIWORD(lParam); - static int iPreviousX = 0, iPreviousY = 0; - if (iX != iPreviousX || iY != iPreviousY) - { - iPreviousX = iX, iPreviousY = iY; - - CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); - CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); - - CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); - g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); - - // Call the onClientCursorMove event - CLuaArguments Arguments; - Arguments.PushNumber((double)vecCursorPosition.fX); - Arguments.PushNumber((double)vecCursorPosition.fY); - Arguments.PushNumber((double)iX); - Arguments.PushNumber((double)iY); - Arguments.PushNumber((double)vecTarget.fX); - Arguments.PushNumber((double)vecTarget.fY); - Arguments.PushNumber((double)vecTarget.fZ); - m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); - } - break; - } - } - return false; -} - -CClientPlayer* CClientGame::GetClosestRemotePlayer(const CVector& vecPosition, float fMaxDistance) -{ - CClientPlayer* pClosest = NULL; - float fDistance = 0.0f, fTemp; - CVector vecTemp; - CClientPlayer* pPlayer; - vector::const_iterator iter = m_pPlayerManager->IterBegin(); - for (; iter != m_pPlayerManager->IterEnd(); ++iter) - { - pPlayer = *iter; - if (!pPlayer->IsLocalPlayer() && !pPlayer->IsDeadOnNetwork() && pPlayer->GetHealth() > 0) - { - // Ensure remote player is alive and sending position updates - ulong ulTimeSinceLastPuresync = CClientTime::GetTime() - pPlayer->GetLastPuresyncTime(); - if (ulTimeSinceLastPuresync < static_cast(g_TickRateSettings.iPureSync) * 2) - { - pPlayer->GetPosition(vecTemp); - fTemp = DistanceBetweenPoints3D(vecPosition, vecTemp); - if (fTemp < fMaxDistance) - { - if (!pClosest || fTemp < fDistance) - { - pClosest = pPlayer; - fDistance = fTemp; - } - } - } - } - } - return pClosest; -} - -void CClientGame::SetGameSpeed(float fSpeed) -{ - g_pGame->SetGameSpeed(fSpeed); - m_fGameSpeed = fSpeed; -} - -void CClientGame::SetMinuteDuration(unsigned long ulDelay) -{ - g_pGame->SetMinuteDuration(ulDelay); - m_ulMinuteDuration = ulDelay; -} - -void CClientGame::SetMoney(long lMoney, bool bInstant) -{ - g_pGame->GetPlayerInfo()->SetPlayerMoney(lMoney, bInstant); - m_lMoney = lMoney; -} - -void CClientGame::SetWanted(DWORD dwWanted) -{ - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(dwWanted); - m_dwWanted = dwWanted; -} - -void CClientGame::AddBuiltInEvents(void) -{ - // Resource events - m_Events.AddEvent("onClientResourceStart", "resource", NULL, false); - m_Events.AddEvent("onClientResourceStop", "resource", NULL, false); - - // Element events - m_Events.AddEvent("onClientElementDataChange", "name", NULL, false); - m_Events.AddEvent("onClientElementStreamIn", "", NULL, false); - m_Events.AddEvent("onClientElementStreamOut", "", NULL, false); - m_Events.AddEvent("onClientElementDestroy", "", NULL, false); - - // Player events - m_Events.AddEvent("onClientPlayerJoin", "", NULL, false); - m_Events.AddEvent("onClientPlayerQuit", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerTarget", "target", NULL, false); - m_Events.AddEvent("onClientPlayerSpawn", "team", NULL, false); - m_Events.AddEvent("onClientPlayerChangeNick", "oldNick", NULL, false); - m_Events.AddEvent("onClientPlayerVehicleEnter", "vehicle, seat", NULL, false); - m_Events.AddEvent("onClientPlayerVehicleExit", "vehicle, seat", NULL, false); - m_Events.AddEvent("onClientPlayerTask", "priority, slot, name", NULL, false); - m_Events.AddEvent("onClientPlayerWeaponSwitch", "previous, current", NULL, false); - m_Events.AddEvent("onClientPlayerStuntStart", "type", NULL, false); - m_Events.AddEvent("onClientPlayerStuntFinish", "type, time, distance", NULL, false); - m_Events.AddEvent("onClientPlayerRadioSwitch", "", NULL, false); - m_Events.AddEvent("onClientPlayerDamage", "attacker, weapon, bodypart", NULL, false); - m_Events.AddEvent("onClientPlayerWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); - m_Events.AddEvent("onClientPlayerWasted", "", NULL, false); - m_Events.AddEvent("onClientPlayerChoke", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceStart", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceStop", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoicePause", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceResumed", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerStealthKill", "target", NULL, false); - m_Events.AddEvent("onClientPlayerHitByWaterCannon", "vehicle", NULL, false); - m_Events.AddEvent("onClientPlayerHeliKilled", "heli", NULL, false); - m_Events.AddEvent("onClientPlayerPickupHit", "pickup, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPlayerPickupLeave", "pickup, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPlayerNetworkStatus", "type, ticks", NULL, false); - - // Ped events - m_Events.AddEvent("onClientPedDamage", "attacker, weapon, bodypart", NULL, false); - m_Events.AddEvent("onClientPedWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); - m_Events.AddEvent("onClientPedWasted", "", NULL, false); - m_Events.AddEvent("onClientPedChoke", "", NULL, false); - m_Events.AddEvent("onClientPedHeliKilled", "heli", NULL, false); - m_Events.AddEvent("onClientPedHitByWaterCannon", "vehicle", NULL, false); - - // Vehicle events - m_Events.AddEvent("onClientVehicleRespawn", "", NULL, false); - m_Events.AddEvent("onClientVehicleEnter", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleExit", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleStartEnter", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleStartExit", "player, seat", NULL, false); - m_Events.AddEvent("onClientTrailerAttach", "towedBy", NULL, false); - m_Events.AddEvent("onClientTrailerDetach", "towedBy", NULL, false); - m_Events.AddEvent("onClientVehicleExplode", "", NULL, false); - m_Events.AddEvent("onClientVehicleCollision", "collidedelement, damageImpulseMag, bodypart, x, y, z, velX, velY, velZ", NULL, false); - m_Events.AddEvent("onClientVehicleDamage", "attacker, weapon, loss, x, y, z, tyre", NULL, false); - m_Events.AddEvent("onClientVehicleNitroStateChange", "activated", NULL, false); - - // GUI events - m_Events.AddEvent("onClientGUIClick", "button, state, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIDoubleClick", "button, state, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIMouseDown", "button, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIMouseUp", "button, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIScroll", "element", NULL, false); - m_Events.AddEvent("onClientGUIChanged", "element", NULL, false); - m_Events.AddEvent("onClientGUIAccepted", "element", NULL, false); - // m_Events.AddEvent ( "onClientGUIClose", "element", NULL, false ); - // m_Events.AddEvent ( "onClientGUIKeyDown", "element", NULL, false ); - m_Events.AddEvent("onClientGUITabSwitched", "element", NULL, false); - m_Events.AddEvent("onClientGUIComboBoxAccepted", "element", NULL, false); - - // Input events - m_Events.AddEvent("onClientDoubleClick", "button, screenX, screenY, worldX, worldY, worldZ, element", NULL, false); - m_Events.AddEvent("onClientMouseMove", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseEnter", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseLeave", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseWheel", "", NULL, false); - m_Events.AddEvent("onClientGUIMove", "", NULL, false); - m_Events.AddEvent("onClientGUISize", "", NULL, false); - m_Events.AddEvent("onClientGUIFocus", "", NULL, false); - m_Events.AddEvent("onClientGUIBlur", "", NULL, false); - m_Events.AddEvent("onClientKey", "key, state", NULL, false); - m_Events.AddEvent("onClientCharacter", "character", NULL, false); - - // Console events - m_Events.AddEvent("onClientConsole", "text", NULL, false); - - // Chat events - m_Events.AddEvent("onClientChatMessage", "test, r, g, b", NULL, false); - - // Debug events - m_Events.AddEvent("onClientDebugMessage", "message, level, file, line", NULL, false); - - // Game events - m_Events.AddEvent("onClientPreRender", "", NULL, false); - m_Events.AddEvent("onClientHUDRender", "", NULL, false); - m_Events.AddEvent("onClientRender", "", NULL, false); - m_Events.AddEvent("onClientMinimize", "", NULL, false); - m_Events.AddEvent("onClientRestore", "", NULL, false); - - // Cursor events - m_Events.AddEvent("onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false); - m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); - - // Transfer box event - m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); - - // Marker events - m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); - - // Marker events - m_Events.AddEvent("onClientPickupHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPickupLeave", "entity, matchingDimension", NULL, false); - - // Col-shape events - m_Events.AddEvent("onClientColShapeHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientColShapeLeave", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientElementColShapeHit", "colShape, matchingDimension", NULL, false); - m_Events.AddEvent("onClientElementColShapeLeave", "colShape, matchingDimension", NULL, false); - - // Explosion events - m_Events.AddEvent("onClientExplosion", "x, y, z, type", NULL, false); - - // Projectile events - m_Events.AddEvent("onClientProjectileCreation", "creator", NULL, false); - - // Sound events - m_Events.AddEvent("onClientSoundStream", "success, length, streamName, error", NULL, false); - m_Events.AddEvent("onClientSoundFinishedDownload", "length", NULL, false); - m_Events.AddEvent("onClientSoundChangedMeta", "streamTitle", NULL, false); - m_Events.AddEvent("onClientSoundStarted", "reason", NULL, false); - m_Events.AddEvent("onClientSoundStopped", "reason", NULL, false); - m_Events.AddEvent("onClientSoundBeat", "time", NULL, false); - - // Object events - m_Events.AddEvent("onClientObjectDamage", "loss, attacker", NULL, false); - m_Events.AddEvent("onClientObjectBreak", "attacker", NULL, false); - - // Web events - m_Events.AddEvent("onClientBrowserWhitelistChange", "newPages", NULL, false); - m_Events.AddEvent("onClientBrowserCreated", "", NULL, false); - m_Events.AddEvent("onClientBrowserLoadingStart", "url, mainframe", NULL, false); - m_Events.AddEvent("onClientBrowserDocumentReady", "url", NULL, false); - m_Events.AddEvent("onClientBrowserLoadingFailed", "url, errorcode, errordescription", NULL, false); - m_Events.AddEvent("onClientBrowserNavigate", "url, isblocked", NULL, false); - m_Events.AddEvent("onClientBrowserPopup", "targeturl, openerurl, ispopup", NULL, false); - m_Events.AddEvent("onClientBrowserCursorChange", "cursor", NULL, false); - m_Events.AddEvent("onClientBrowserTooltip", "text", NULL, false); - m_Events.AddEvent("onClientBrowserInputFocusChanged", "gainedfocus", NULL, false); - m_Events.AddEvent("onClientBrowserResourceBlocked", "url, domain, reason", NULL, false); - - // Misc events - m_Events.AddEvent("onClientFileDownloadComplete", "fileName, success", NULL, false); - - m_Events.AddEvent("onClientWeaponFire", "ped, x, y, z", NULL, false); -} - -void CClientGame::DrawFPS(void) -{ - // Draw the background - float fResWidth = static_cast(g_pCore->GetGraphics()->GetViewportWidth()); - float fResHeight = static_cast(g_pCore->GetGraphics()->GetViewportHeight()); - g_pCore->GetGraphics()->DrawRectangle(0.75f * fResWidth, 0.22f * fResHeight, 0.25f * fResWidth, 0.04f * fResHeight, 0x78000000); - - static char x = 0; - static float fDisp = 0.0f; - if (x == 20) - { - x = 0; - fDisp = g_pGame->GetFPS(); - } - else - x++; - SString strBuffer("FrameRate: %4.2f\n", fDisp); - - // Print it - m_pDisplayManager->DrawText2D(strBuffer, CVector(0.76f, 0.23f, 0), 1.0f, 0xFFFFFFFF); -} - -#ifdef MTA_DEBUG - -void CClientGame::DrawTasks(CClientPlayer* pPlayer) -{ - CTask* pTask = NULL; - CTask* pSubTask = NULL; - - // Got a local player model - if (pPlayer) - { - CTaskManager* man = pPlayer->GetTaskManager(); - if (man == NULL) - return; - if ((unsigned long)man == 0xDDDDDDDD) - { - m_pDisplayManager->DrawText2D("HELP! MANAGER FUCKED", CVector(0.05f, 0.5f, 0), 1.0f); - return; - } - - // Grab the current task - SString strOutput; - SString strSubOutput; - - pTask = man->GetTask(TASK_PRIORITY_PHYSICAL_RESPONSE); - strOutput += SString("Physical Response: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_TEMP); - strOutput += SString("Event Response Temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_NONTEMP); - strOutput += SString("Event Response Non-temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_PRIMARY); - strOutput += SString("Primary: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_DEFAULT); - strOutput += SString("Default: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_ATTACK); - strOutput += SString("Secondary Attack: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_DUCK); - strOutput += SString("Secondary Duck: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_SAY); - strOutput += SString("Secondary Say: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX); - strOutput += SString("Secondary Facial Complex: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM); - strOutput += SString("Secondary Partial Anim: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_IK); - strOutput += SString("Secondary IK: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - m_pDisplayManager->DrawText2D(strOutput, CVector(0.05f, 0.5f, 0), 1.0f); - m_pDisplayManager->DrawText2D(strSubOutput, CVector(0.5f, 0.5f, 0), 1.0f); - } -} - -int iPlayerTask = 0; -void CClientGame::DrawPlayerDetails(CClientPlayer* pPlayer) -{ - // Get the info - CControllerState cs; - - pPlayer->GetControllerState(cs); - - CVector vecPosition; - pPlayer->GetPosition(vecPosition); - - float fRotation = pPlayer->GetCurrentRotation(); - float fCameraRotation = pPlayer->GetCameraRotation(); - float fHealth = pPlayer->GetHealth(); - bool bIsDucked = pPlayer->IsDucked(); - bool bWearingGoggles = pPlayer->IsWearingGoggles(); - bool bInVehicle = pPlayer->GetOccupiedVehicle() != NULL; - float fWeaponRange = 0.0f; - - unsigned char ucWeapon = 0; - unsigned char ucWeaponState = 0; - unsigned short usWeaponAmmo = 0; - CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); - if (pWeapon) - { - ucWeapon = static_cast(pWeapon->GetType()); - ucWeaponState = static_cast(pWeapon->GetState()); - usWeaponAmmo = static_cast(pWeapon->GetAmmoInClip()); - float fSkill = pPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(pWeapon->GetType())); - CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(pWeapon->GetType(), fSkill); - fWeaponRange = pWeaponInfo->GetWeaponRange(); - } - - float fAimX, fAimY; - pPlayer->GetAim(fAimX, fAimY); - const CVector& vecAimSource = pPlayer->GetAimSource(); - const CVector& vecAimTarget = pPlayer->GetAimTarget(); - unsigned char ucDrivebyAim = pPlayer->GetVehicleAimAnim(); - - g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x10DE1212, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x90DE1212, false); - - CTask* pPrimaryTask = pPlayer->GetCurrentPrimaryTask(); - int iPrimaryTask = pPrimaryTask ? pPrimaryTask->GetTaskType() : -1; - - // Copy the stuff - SString strBuffer( - "Orient:\n" - "Position: %f %f %f\n" - "Rotation/camera: %f %f\n" - "Health: %f\n" - "\n" - "Keys:\n" - "LeftShoulder1: %hi\n" - "RightShoulder1: %hi\n" - "ButtonSquare: %hi\n" - "ButtonCross: %hi\n" - "ButtonCircle: %hi\n" - "ShockButtonL: %hi\n" - "PedWalk: %hi\n" - "VehicleMouseLook: %hi\n" - "LeftStickX: %hi\n" - "LeftStickY: %hi\n" - "\n" - "Misc:\n" - "Primary task: %d\n" - "Ducked: %u\n" - "Goggles: %u\n" - "In vehicle: %u\n" - "Weapon: %u\n" - "Weapon state: %u\n" - "Weapon ammo: %u\n" - "Weapon range: %f\n" - "Aim: %f %f\n" - "Aim source: %f %f %f\n" - "Aim target: %f %f %f\n" - "Driveby aim: %u\n" - "Frozen: %u\n", - vecPosition.fX, vecPosition.fY, vecPosition.fZ, fRotation, fCameraRotation, fHealth, cs.LeftShoulder1, cs.RightShoulder1, cs.ButtonSquare, - cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.m_bPedWalk, cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, iPrimaryTask, bIsDucked, - bWearingGoggles, bInVehicle, ucWeapon, ucWeaponState, usWeaponAmmo, fWeaponRange, fAimX, fAimY, vecAimSource.fX, vecAimSource.fY, vecAimSource.fZ, - vecAimTarget.fX, vecAimTarget.fY, vecAimTarget.fZ, ucDrivebyAim, pPlayer->IsFrozen()); - - // Draw it - m_pDisplayManager->DrawText2D(strBuffer, CVector(0.45f, 0.05f, 0), 1.0f, 0xFFFFFFFF); -} - -void CClientGame::DrawWeaponsyncData(CClientPlayer* pPlayer) -{ - CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); - - if (pWeapon) - { - CVector vecSource; - CVector vecTarget; - - // red line: Draw their synced aim line - pPlayer->GetShotData(&vecSource, &vecTarget); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x10DE1212, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x90DE1212, false); - - // green line: Set muzzle as origin and perform a collision test for the target - CColPoint* pCollision; - CVector vecTemp; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecSource, &vecTarget, &pCollision, NULL); - if (pCollision) - { - if (bCollision) - { - CVector vecBullet = pCollision->GetPosition() - vecSource; - vecBullet.Normalize(); - CVector vecTarget = vecSource + (vecBullet * 200); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x1012DE12, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x9012DE12, false); - } - pCollision->Destroy(); - } - - if (m_pLocalPlayer != pPlayer) - { - // Draw information about their weapon state, total ammo and ammo in clip - CVector vecScreenPosition; - CVector vecPosition; - - pPlayer->GetPosition(vecPosition); - - vecPosition.fZ += 1.0f; - g_pCore->GetGraphics()->CalcScreenCoors(&vecPosition, &vecScreenPosition); - - SString strTemp; - int yoffset; - - yoffset = 0; - strTemp.Format("Ammo in clip: %d", pWeapon->GetAmmoInClip()); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); - - yoffset = 15; - strTemp.Format("State: %d", pWeapon->GetState()); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); - } - } -} - -void CClientGame::UpdateMimics(void) -{ - // Got a local player? - if (m_pLocalPlayer) - { - unsigned char ucWeaponType = 0; - unsigned char ucWeaponState = 0; - unsigned long ulWeaponAmmoInClip = 0; - eWeaponSlot weaponSlot = WEAPONSLOT_TYPE_UNARMED; - - CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(m_pLocalPlayer->GetCurrentWeaponSlot()); - if (pPlayerWeapon) - { - ucWeaponType = static_cast(pPlayerWeapon->GetType()); - ucWeaponState = static_cast(pPlayerWeapon->GetState()); - weaponSlot = pPlayerWeapon->GetSlot(); - ulWeaponAmmoInClip = pPlayerWeapon->GetAmmoInClip(); - } - - // Simulate lag (or not) - if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) - { - m_ulLastMimicLag = CClientTime::GetTime(); - - // Grab the local data - CControllerState Controller; - m_pLocalPlayer->GetControllerState(Controller); - CVector vecPosition; - m_pLocalPlayer->GetPosition(vecPosition); - float fRotation = m_pLocalPlayer->GetCurrentRotation(); - CVector vecMoveSpeed; - m_pLocalPlayer->GetMoveSpeed(vecMoveSpeed); - float fHealth = m_pLocalPlayer->GetHealth(); - float fArmor = m_pLocalPlayer->GetArmor(); - float fCameraRotation = g_pGame->GetCamera()->GetCameraRotation(); - bool bDucked = m_pLocalPlayer->IsDucked(); - bool bWearingGoggles = m_pLocalPlayer->IsWearingGoggles(true); - bool bHasJetpack = m_pLocalPlayer->HasJetPack(); - bool bChoking = m_pLocalPlayer->IsChoking(); - bool bSunbathing = m_pLocalPlayer->IsSunbathing(); - bool bDoingDriveby = m_pLocalPlayer->IsDoingGangDriveby(); - bool bStealthAiming = m_pLocalPlayer->IsStealthAiming(); - - // Is the current weapon goggles (44 or 45) or a camera (43), or a detonator (40), don't apply the fire key - if (weaponSlot == 11 || weaponSlot == 12 || ucWeaponType == 43) - Controller.ButtonCircle = 0; - - CClientVehicle* pVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - unsigned int uiSeat = m_pLocalPlayer->GetOccupiedVehicleSeat(); - - CShotSyncData* pShotSync = g_pMultiplayer->GetLocalShotSyncData(); - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - float fAimX = pShotSync->m_fArmDirectionX; - float fAimY = pShotSync->m_fArmDirectionY; - char cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; - bool bAkimboUp = g_pMultiplayer->GetAkimboTargetUp(); - - /* - static CClientMarker *pOriginCorona = NULL, *pTargetCorona = NULL; - if ( pOriginCorona == NULL ) - { - pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); - pOriginCorona->SetColor ( 0, 255, 0, 255 ); - pOriginCorona->SetSize ( 0.5f ); - } - else - pOriginCorona->SetPosition ( vecOrigin ); - - if ( pTargetCorona == NULL ) - { - pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); - pTargetCorona->SetColor ( 255, 0, 0, 255 ); - pTargetCorona->SetSize ( 0.5f ); - } - else - pTargetCorona->SetPosition ( vecTarget );*/ - - // Apply this to each of our mimic players - unsigned int uiMimicIndex = 0; - list::const_iterator iterMimics = m_Mimics.begin(); - for (; iterMimics != m_Mimics.end(); ++iterMimics, ++uiMimicIndex) - { - vecPosition.fX += 4.0f; - vecOrigin.fX += 4.0f; - vecTarget.fX += 4.0f; - - CClientPlayer* pMimic = *iterMimics; - - pMimic->SetHealth(fHealth); - pMimic->LockHealth(fHealth); - pMimic->SetArmor(fArmor); - pMimic->LockArmor(fArmor); - pMimic->SetWearingGoggles(bWearingGoggles); - pMimic->SetHasJetPack(bHasJetpack); - pMimic->SetChoking(bChoking); - pMimic->SetSunbathing(bSunbathing); - pMimic->SetDoingGangDriveby(bDoingDriveby); - pMimic->SetStealthAiming(bStealthAiming); - - Controller.ShockButtonL = 0; - - if (m_bMimicLag) - { - pMimic->SetTargetPosition(vecPosition, TICK_RATE); - pMimic->SetMoveSpeed(vecMoveSpeed); - pMimic->SetControllerState(Controller); - pMimic->SetTargetRotation(fRotation); - pMimic->SetCameraRotation(fCameraRotation); - pMimic->Duck(bDucked); - } - else - { - pMimic->SetPosition(vecPosition); - pMimic->SetMoveSpeed(vecMoveSpeed); - pMimic->SetTargetRotation(fRotation); - pMimic->SetCameraRotation(fCameraRotation); - pMimic->SetControllerState(Controller); - pMimic->Duck(bDucked); - } - - if (ucWeaponType != 0) - { - if (ucWeaponType == 44 || ucWeaponType == 45) - { - Controller.ButtonCircle = 0; - } - - if (m_bMimicLag) - { - pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); - pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); - - pMimic->AddChangeWeapon(TICK_RATE, weaponSlot, (unsigned char)ulWeaponAmmoInClip); - } - else - { - CWeapon* pPlayerWeapon = pMimic->GetWeapon(); - eWeaponType eCurrentWeapon = static_cast(ucWeaponType); - if ((pPlayerWeapon && pPlayerWeapon->GetType() != eCurrentWeapon) || !pPlayerWeapon) - { - pPlayerWeapon = pMimic->GiveWeapon(eCurrentWeapon, ulWeaponAmmoInClip); - if (pPlayerWeapon) - { - pPlayerWeapon->SetAsCurrentWeapon(); - } - } - - if (pPlayerWeapon) - { - pPlayerWeapon->SetAmmoTotal(9999); - pPlayerWeapon->SetAmmoInClip(ulWeaponAmmoInClip); - pPlayerWeapon->SetState(static_cast(ucWeaponState)); - } - pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); - pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); - } - } - else - { - pMimic->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); - } - - CClientVehicle* pMimicVehicle = pMimic->GetOccupiedVehicle(); - if (pVehicle) - { - unsigned int uiModel; - CVector vecPosition, vecRotationDegrees; - CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; - float fHealth; - - uiModel = pVehicle->GetModel(); - pVehicle->GetPosition(vecPosition); - pVehicle->GetRotationDegrees(vecRotationDegrees); - pVehicle->GetMoveSpeed(vecMoveSpeed); - pVehicle->GetTurnSpeed(vecTurnSpeed); - fHealth = pVehicle->GetHealth(); - - if (pMimicVehicle && pMimicVehicle->GetModel() != uiModel) - { - delete pMimicVehicle; - pMimicVehicle = NULL; - } - - vecPosition.fX += ((float)(uiMimicIndex + 1) * 10.0f); - - if (pMimicVehicle == NULL) - { - pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, uiModel, 0, 0); - pMimicVehicle->SetPosition(vecPosition); - - const SSlotStates& usUpgrades = pVehicle->GetUpgrades()->GetSlotStates(); - for (unsigned char uc = 0; uc < VEHICLE_UPGRADE_SLOTS; uc++) - { - if (usUpgrades[uc]) - { - pMimicVehicle->GetUpgrades()->AddUpgrade(usUpgrades[uc], true); - } - } - - m_vecLastMimicPos = vecPosition; - } - - if (m_bMimicLag) - { - pMimicVehicle->SetTargetPosition(vecPosition, TICK_RATE); - pMimicVehicle->SetTargetRotation(vecRotationDegrees, TICK_RATE); - pMimicVehicle->SetMoveSpeed(vecMoveSpeed); - pMimicVehicle->SetTurnSpeed(vecTurnSpeed); - } - else - { - pMimicVehicle->SetPosition(vecPosition); - pMimicVehicle->SetRotationDegrees(vecRotationDegrees); - pMimicVehicle->SetMoveSpeed(vecMoveSpeed); - pMimicVehicle->SetTurnSpeed(vecTurnSpeed); - } - pMimicVehicle->SetHealth(fHealth); - if (pMimic->GetOccupiedVehicle() != pMimicVehicle) - pMimic->WarpIntoVehicle(pMimicVehicle, uiSeat); - - unsigned int uiTrailerLoop = 0; - CClientVehicle* pTrailer = pVehicle->GetTowedVehicle(); - CClientVehicle* pMimicTrailer = NULL; - while (pTrailer) - { - uiModel = pTrailer->GetModel(); - pTrailer->GetPosition(vecPosition); - pTrailer->GetRotationDegrees(vecRotationDegrees); - pTrailer->GetMoveSpeed(vecMoveSpeed); - pTrailer->GetTurnSpeed(vecTurnSpeed); - fHealth = pTrailer->GetHealth(); - - pMimicTrailer = DynamicCast(CElementIDs::GetElement(static_cast(450 + uiMimicIndex + uiTrailerLoop))); - - if (pMimicTrailer && pMimicTrailer->GetModel() != uiModel) - { - delete pMimicTrailer; - pMimicTrailer = NULL; - } - - if (!pMimicTrailer) - { - pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, - static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); - pMimicVehicle->SetTowedVehicle(pMimicTrailer); - } - - pTrailer = pTrailer->GetTowedVehicle(); - pMimicTrailer = pMimicTrailer->GetTowedVehicle(); - uiTrailerLoop++; - } - if (pMimicTrailer) - { - if (pMimicTrailer->GetTowedByVehicle()) - { - pMimicTrailer->GetTowedByVehicle()->SetTowedVehicle(NULL); - } - } - } - else if (pMimicVehicle) - { - pMimic->RemoveFromVehicle(); - delete pMimicVehicle; - } - } - } - } -} - -void CClientGame::DoPaintballs(void) -{ - if (m_pLocalPlayer) - { - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - - CColPoint* pCollision = NULL; - CEntity* pCollisionEntity = NULL; - m_pLocalPlayer->WorldIgnore(true); - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionEntity); - m_pLocalPlayer->WorldIgnore(false); - - static list paintBalls; - if (paintBalls.size() >= 5) - { - CClientMarker* pCorona = paintBalls.back(); - delete pCorona; - paintBalls.pop_back(); - } - - CClientMarker* pCorona = new CClientMarker(m_pManager, INVALID_ELEMENT_ID, CClientMarker::MARKER_CORONA); - paintBalls.push_front(pCorona); - pCorona->SetSize(0.2f); - if (bCollision && pCollision) - { - pCorona->SetPosition(pCollision->GetPosition()); - pCorona->SetColor(SColorRGBA(255, 0, 0, 255)); - } - else - { - pCorona->SetPosition(vecTarget); - pCorona->SetColor(SColorRGBA(255, 255, 0, 255)); - } - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - } -} - -#endif - -void CClientGame::QuitPlayer(CClientPlayer* pPlayer, eQuitReason Reason) -{ - // Get the nick pointer and echo the quit message to the chat - const char* szNick = pPlayer->GetNick(); - const char* szReason = "Unknown"; - switch (Reason) - { - case QUIT_QUIT: - szReason = "Quit"; - break; - case QUIT_KICK: - szReason = "Kicked"; - break; - case QUIT_BAN: - szReason = "Banned"; - break; - case QUIT_CONNECTION_DESYNC: - szReason = "Bad Connection"; - break; - case QUIT_TIMEOUT: - szReason = "Timed Out"; - break; - } - - // In debug, make sure we don't look at this player's details -#ifdef MTA_DEBUG - if (m_pShowPlayer == pPlayer) - { - m_pShowPlayer = NULL; - } -#endif - - // Call our onClientPlayerQuit event - CLuaArguments Arguments; - Arguments.PushString(szReason); - pPlayer->CallEvent("onClientPlayerQuit", Arguments, true); - - // Detach the camera from this player if we're watching them - m_pManager->GetCamera()->UnreferencePlayer(pPlayer); - - // Was this player jacking us? - if (m_bIsGettingJacked && m_pGettingJackedBy == pPlayer) - { - ResetVehicleInOut(); - m_pLocalPlayer->RemoveFromVehicle(false); - m_pLocalPlayer->SetVehicleInOutState(VEHICLE_INOUT_NONE); - } - - // Delete the player - delete pPlayer; -} - -void CClientGame::Event_OnIngame(void) -{ - // Unpause the game - g_pGame->Pause(false); - - // Disable parts of the Hud - CHud* pHud = g_pGame->GetHud(); - pHud->SetComponentVisible(HUD_HELP_TEXT, false); - pHud->SetComponentVisible(HUD_VITAL_STATS, false); - pHud->SetComponentVisible(HUD_AREA_NAME, false); - - g_pMultiplayer->DeleteAndDisableGangTags(); - - // Switch off peds and traffic - SFixedArray vecs = {CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), - CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0)}; - g_pGame->GetPathFind()->SwitchRoadsOffInArea(&vecs[0], &vecs[1]); - g_pGame->GetPathFind()->SwitchPedRoadsOffInArea(&vecs[2], &vecs[3]); - g_pGame->GetPathFind()->SetPedDensity(0.0f); - g_pGame->GetPathFind()->SetVehicleDensity(0.0f); - - g_pGame->GetWorld()->ClearRemovedBuildingLists(); - g_pGame->GetWorld()->SetOcclusionsEnabled(true); - - g_pGame->ResetModelLodDistances(); - g_pGame->ResetAlphaTransparencies(); - - // Make sure we can access all areas - g_pGame->GetStats()->ModifyStat(CITIES_PASSED, 2.0); - - // This is to prevent the 'white arrows in checkpoints' bug (#274) - g_pGame->Get3DMarkers()->CreateMarker(87654, (e3DMarkerType)5, &vecs[4], 1, 0.2f, 0, 0, 0, 0); - - // Stop us getting 4 stars if we visit the SF or LV - // g_pGame->GetPlayerInfo()->GetWanted()->SetMaximumWantedLevel ( 0 ); - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(0); - - // Reset anything from last game - ResetMapInfo(); - g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level - g_pGame->GetWaterManager()->SetWaterDrawnLast(true); - m_pCamera->SetCameraClip(true, true); - - // Create a local player for us - m_pLocalPlayer = new CClientPlayer(m_pManager, m_LocalID, true); - if (m_pLocalPlayer) - { - // Set our parent the root entity - m_pLocalPlayer->SetParent(m_pRootEntity); - - // Give the local player our nickname - m_pLocalPlayer->SetNick(m_strLocalNick); - - // Freeze the player at some location we won't see - m_pLocalPlayer->SetHealth(100); - m_pLocalPlayer->SetPosition(CVector(0, 0, 0)); - m_pLocalPlayer->SetFrozen(true); - m_pLocalPlayer->ResetInterpolation(); - - // Reset him - m_pLocalPlayer->ResetStats(); - } - else - { - RaiseFatalError(2); - } - - // Make sure we never get tired - g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true); - - // Tell doggy we got the game running - WatchDogCompletedSection("L1"); -} - -void CClientGame::Event_OnIngameAndConnected(void) -{ - m_ulVerifyTimeStart = CClientTime::GetTime(); - - // Keep criminal records of how many times they've connected to servers - SetApplicationSettingInt("times-connected", GetApplicationSettingInt("times-connected") + 1); - if (m_ServerType == SERVER_TYPE_EDITOR) - SetApplicationSettingInt("times-connected-editor", GetApplicationSettingInt("times-connected-editor") + 1); - - // Notify the server telling we're ingame - m_pNetAPI->RPC(PLAYER_INGAME_NOTICE); -} - -bool CClientGame::StaticBreakTowLinkHandler(CVehicle* pTowingVehicle) -{ - return g_pClientGame->BreakTowLinkHandler(pTowingVehicle); -} - -void CClientGame::StaticDrawRadarAreasHandler(void) -{ - g_pClientGame->DrawRadarAreasHandler(); -} - -bool CClientGame::StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent) -{ - return g_pClientGame->DamageHandler(pDamagePed, pEvent); -} - -void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart) -{ - g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart); -} - -void CClientGame::StaticFireHandler(CFire* pFire) -{ - g_pClientGame->FireHandler(pFire); -} - -void CClientGame::StaticRender3DStuffHandler(void) -{ - g_pClientGame->Render3DStuffHandler(); -} - -void CClientGame::StaticPreRenderSkyHandler(void) -{ - g_pClientGame->PreRenderSkyHandler(); -} - -void CClientGame::StaticRenderHeliLightHandler() -{ - g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); -} - -bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) -{ - return g_pClientGame->ChokingHandler(ucWeaponType); -} - -void CClientGame::StaticCAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) -{ - g_pClientGame->CAnimBlendAssocDestructorHandler(pThis); -} - -CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) -{ - return g_pClientGame->AddAnimationHandler(pClump, animGroup, animID); -} - -CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) -{ - return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); -} - -bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) -{ - return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); -} - -bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, - int* pFlags, RpClump* pClump) -{ - return g_pClientGame->BlendAnimationHierarchyHandler(pAnimAssoc, pOutAnimHierarchy, pFlags, pClump); -} - -void CClientGame::StaticPreWorldProcessHandler(void) -{ - g_pClientGame->PreWorldProcessHandler(); -} - -void CClientGame::StaticPostWorldProcessHandler(void) -{ - g_pClientGame->PostWorldProcessHandler(); -} - -void CClientGame::StaticPreFxRenderHandler(void) -{ - g_pCore->OnPreFxRender(); -} - -void CClientGame::StaticPreHudRenderHandler(void) -{ - g_pCore->OnPreHUDRender(); -} - -bool CClientGame::StaticProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) -{ - return g_pClientGame->ProcessCollisionHandler(pThisInterface, pOtherInterface); -} - -bool CClientGame::StaticVehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, - float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, - CVector vecCollisionVelocity) -{ - return g_pClientGame->VehicleCollisionHandler(pCollidingVehicle, pCollidedVehicle, iModelIndex, fDamageImpulseMag, fCollidingDamageImpulseMag, usPieceType, - vecCollisionPos, vecCollisionVelocity); -} - -bool CClientGame::StaticVehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) -{ - return g_pClientGame->VehicleDamageHandler(pVehicleInterface, fLoss, pAttackerInterface, weaponType, vecDamagePos, ucTyre); -} - -bool CClientGame::StaticHeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) -{ - return g_pClientGame->HeliKillHandler(pHeliInterface, pHitInterface); -} - -bool CClientGame::StaticObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) -{ - return g_pClientGame->ObjectDamageHandler(pObjectInterface, fLoss, pAttackerInterface); -} - -bool CClientGame::StaticObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) -{ - return g_pClientGame->ObjectBreakHandler(pObjectInterface, pAttackerInterface); -} - -bool CClientGame::StaticWaterCannonHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) -{ - return g_pClientGame->WaterCannonHitHandler(pCannonVehicle, pHitPed); -} - -bool CClientGame::StaticVehicleFellThroughMapHandler(CVehicleSAInterface* pVehicle) -{ - return g_pClientGame->VehicleFellThroughMapHandler(pVehicle); -} - -void CClientGame::StaticGameObjectDestructHandler(CEntitySAInterface* pObject) -{ - g_pClientGame->GameObjectDestructHandler(pObject); -} - -void CClientGame::StaticGameVehicleDestructHandler(CEntitySAInterface* pVehicle) -{ - g_pClientGame->GameVehicleDestructHandler(pVehicle); -} - -void CClientGame::StaticGamePlayerDestructHandler(CEntitySAInterface* pPlayer) -{ - g_pClientGame->GamePlayerDestructHandler(pPlayer); -} - -void CClientGame::StaticGameProjectileDestructHandler(CEntitySAInterface* pProjectile) -{ - g_pClientGame->GameProjectileDestructHandler(pProjectile); -} - -void CClientGame::StaticGameModelRemoveHandler(ushort usModelId) -{ - g_pClientGame->GameModelRemoveHandler(usModelId); -} - -void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) -{ - if (pGameEntity) - { - // Map to client entity and pass to the texture replacer - CClientEntity* pClientEntity = g_pClientGame->GetGameEntityXRefManager()->FindClientEntity(pGameEntity); - if (pClientEntity) - { - int iTypeMask; - ushort usModelId = 0xFFFF; - switch (pClientEntity->GetType()) - { - case CCLIENTPED: - case CCLIENTPLAYER: - iTypeMask = TYPE_MASK_PED; - usModelId = (ushort) static_cast(pClientEntity)->GetModel(); - break; - case CCLIENTVEHICLE: - iTypeMask = TYPE_MASK_VEHICLE; - break; - case CCLIENTOBJECT: - iTypeMask = TYPE_MASK_OBJECT; - break; - default: - iTypeMask = TYPE_MASK_OTHER; - break; - } - g_pGame->GetRenderWare()->SetRenderingClientEntity(pClientEntity, usModelId, iTypeMask); - return; - } - } - - g_pGame->GetRenderWare()->SetRenderingClientEntity(NULL, 0xFFFF, TYPE_MASK_WORLD); -} - -void CClientGame::StaticTaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) -{ - g_pClientGame->TaskSimpleBeHitHandler(pPedAttacker, hitBodyPart, hitBodySide, weaponId); -} - -void CClientGame::StaticFxSystemDestructionHandler(void* pFxSAInterface) -{ - g_pClientGame->GetManager()->GetEffectManager()->SAEffectDestroyed(pFxSAInterface); -} - -AnimationId CClientGame::StaticDrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId) -{ - return g_pClientGame->DrivebyAnimationHandler(animGroup, animId); -} - -void CClientGame::DrawRadarAreasHandler(void) -{ - m_pRadarAreaManager->DoPulse(); -} - -bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle) -{ - CClientVehicle* pVehicle = m_pVehicleManager->Get(pTowedVehicle, false); - if (pVehicle) - { - // Check if this is a legal break - bool bLegal = ((pVehicle->GetControllingPlayer() == m_pLocalPlayer) || (m_pUnoccupiedVehicleSync->Exists(static_cast(pVehicle)))); - - // Not a legal break? - if (!bLegal) - { - // Save the time it broke (used in UpdateTrailers) - pVehicle->SetIllegalTowBreakTime(GetTickCount32()); - } - } - - // Allow it to break - return true; -} - -void CClientGame::FireHandler(CFire* pFire) -{ - // Disable spreading fires - pFire->SetNumGenerationsAllowed(0); -} - -void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) -{ - if (pProjectile->IsLocal()) - { - // Did the local player create this projectile? - if (m_pLocalPlayer && pProjectile->GetCreator() == m_pLocalPlayer) - { - // Physics says our projectile should start off at our velocity - CVector vecVelocity, vecPlayerVelocity; - pProjectile->GetVelocity(vecVelocity); - m_pLocalPlayer->GetMoveSpeed(vecPlayerVelocity); - vecVelocity += vecPlayerVelocity; - pProjectile->SetVelocity(vecVelocity); - } - - SendProjectileSync(pProjectile); - } - - // Renew the interior and dimension - if (pProjectile->GetCreator()) - { - pProjectile->SetInterior(pProjectile->GetCreator()->GetInterior()); - pProjectile->SetDimension(pProjectile->GetCreator()->GetDimension()); - } - - // Validate the projectile for our element tree - pProjectile->SetParent(m_pRootEntity); - - // Call our creation event - CLuaArguments Arguments; - Arguments.PushElement(pProjectile->GetCreator()); - pProjectile->CallEvent("onClientProjectileCreation", Arguments, true); -} - -void CClientGame::Render3DStuffHandler(void) -{ -} - -void CClientGame::PreRenderSkyHandler(void) -{ - g_pCore->GetGraphics()->GetRenderItemManager()->PreDrawWorld(); -} - -void CClientGame::PreWorldProcessHandler(void) -{ -} - -void CClientGame::PostWorldProcessHandler(void) -{ - m_pManager->GetMarkerManager()->DoPulse(); - m_pManager->GetPointLightsManager()->DoPulse(); - m_pManager->GetObjectManager()->DoPulse(); - - // Update frame time slice - uint uiCurrentTick = GetTickCount32(); - if (m_uiLastFrameTick) - { - m_uiFrameTimeSlice = uiCurrentTick - m_uiLastFrameTick; - m_uiFrameCount++; - - // Call onClientPreRender LUA event - CLuaArguments Arguments; - Arguments.PushNumber(m_uiFrameTimeSlice); - m_pRootEntity->CallEvent("onClientPreRender", Arguments, false); - } - m_uiLastFrameTick = uiCurrentTick; -} - -void CClientGame::IdleHandler(void) -{ - // If we are minimized we do the pulsing here - if (g_pCore->IsWindowMinimized()) - { - if (!m_bWasMinimized) - { - m_bWasMinimized = true; - // Call onClientMinimize LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); - - bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); - - // Apply mute on minimize options - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) - g_pGame->GetAudio()->SetMusicMasterVolume(0); - - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) - g_pGame->GetAudio()->SetEffectsMasterVolume(0); - - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) - m_pManager->GetSoundManager()->SetMinimizeMuted(true); - } - } - - // Ensure dummy progress graphic will be displayed when using alt pulse order - g_pCore->SetDummyProgressUpdateAlways(true); - - // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) - DoPulses2(true); - - g_pCore->SetDummyProgressUpdateAlways(false); -} - -bool CClientGame::ChokingHandler(unsigned char ucWeaponType) -{ - if (!m_pLocalPlayer) - return true; - CLuaArguments Arguments; - Arguments.PushNumber(ucWeaponType); - return m_pLocalPlayer->CallEvent("onClientPlayerChoke", Arguments, true); -} - -void CClientGame::CAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) -{ - // printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID); - RemoveAnimationAssociationFromMap(pThis); -} - -CAnimBlendAssociationSAInterface* CClientGame::AddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) -{ - // printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); - return nullptr; -} - -CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) -{ - // printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); - return nullptr; -} - -bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) -{ - bool isCustomAnimationToPlay = false; - CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); - auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); - auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); - auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); - auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); - - CClientPed* pClientPed = GetClientPedByClump(*pClump); - if (pClientPed != nullptr) - { - auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); - if (pReplacedAnimation != nullptr) - { - std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); - - // Play our custom animation instead of default - auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); - pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); - pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); - pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); - isCustomAnimationToPlay = true; - } - } - - if (!isCustomAnimationToPlay) - { - auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); - - // Play default internal animation - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); - } - return isCustomAnimationToPlay; -} - -bool CClientGame::BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags, - RpClump* pClump) -{ - bool isCustomAnimationToPlay = false; - CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); - CClientPed* pClientPed = GetClientPedByClump(*pClump); - if (pClientPed != nullptr) - { - if (pClientPed->IsNextAnimationCustom()) - { - std::shared_ptr pIFP = pClientPed->GetCustomAnimationIFP(); - if (pIFP) - { - const SString& strAnimationName = pClientPed->GetNextAnimationCustomName(); - auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy(strAnimationName); - if (pCustomAnimBlendHierarchy != nullptr) - { - std::shared_ptr pIFPAnimations = pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); - - pClientPed->SetCurrentAnimationCustom(true); - pClientPed->SetNextAnimationNormal(); - - if (pIFP->IsUnloading()) - { - pClientPed->DereferenceCustomAnimationBlock(); - } - *pOutAnimHierarchy = pCustomAnimBlendHierarchy; - isCustomAnimationToPlay = true; - return isCustomAnimationToPlay; - } - } - } - - pClientPed->SetCurrentAnimationCustom(false); - pClientPed->SetNextAnimationNormal(); - } - return isCustomAnimationToPlay; -} - -bool CClientGame::ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) -{ - if (pThisInterface == pOtherInterface) - return true; - - if (!m_BuiltCollisionMapThisFrame) - { - // Build a map of CPhysicalSAInterface*/CClientEntity*'s that have collision disabled - m_BuiltCollisionMapThisFrame = true; - m_CachedCollisionMap.clear(); - - std::map::iterator iter = m_AllDisabledCollisions.begin(); - for (; iter != m_AllDisabledCollisions.end(); ++iter) - { - CClientEntity* pEntity = iter->first; - CEntity* pGameEntity = pEntity->GetGameEntity(); - CEntitySAInterface* pInterface = pGameEntity ? pGameEntity->GetInterface() : NULL; - - if (pInterface) - m_CachedCollisionMap[pInterface] = pEntity; - } - } - - // Check both elements appear in the cached map before doing extra processing - std::map::iterator iter1 = m_CachedCollisionMap.find((CEntitySAInterface*)pThisInterface); - if (iter1 != m_CachedCollisionMap.end()) - { - std::map::iterator iter2 = m_CachedCollisionMap.find((CEntitySAInterface*)pOtherInterface); - if (iter2 != m_CachedCollisionMap.end()) - { - // Re-get the entity pointers using a safer method - CEntity* pGameEntity = g_pGame->GetPools()->GetEntity((DWORD*)pThisInterface); - CEntity* pGameColEntity = g_pGame->GetPools()->GetEntity((DWORD*)pOtherInterface); - - if (pGameEntity && pGameColEntity) - { - CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity, true); - CClientEntity* pColEntity = m_pManager->FindEntity(pGameColEntity, true); - - if (pEntity && pColEntity) - { - #if MTA_DEBUG - CClientEntity* ppThisEntity2 = iter1->second; - CClientEntity* ppOtherEntity2 = iter2->second; - // These should match, but its not essential. - assert(ppThisEntity2 == pEntity); - assert(ppOtherEntity2 == pColEntity); - #endif - if (!pEntity->IsCollidableWith(pColEntity)) - return false; - } - } - } - } - - return true; -} - -// -// On demand files -// -void CClientGame::DownloadSingularResourceFiles(void) -{ - if (!IsTransferringSingularFiles()) - return; - - if (!g_pNet->IsConnected()) - return; - - CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES); - if (!pHTTP->ProcessQueuedFiles()) - { - // Downloading - } - else - { - // Can't clear list until all files have been processed - if (m_pSingularFileDownloadManager->AllComplete()) - { - SetTransferringSingularFiles(false); - m_pSingularFileDownloadManager->ClearList(); - } - } -} - -// Get relevant death anim for animation purposes during death situation -void GetDeathAnim(CClientPed* pDamagedPed, CEventDamage* pEvent, AssocGroupId& outAnimGroup, AnimationId& outAnimID) -{ - if (pEvent) - { - pEvent->ComputeDeathAnim(pDamagedPed->GetGamePlayer(), false); - outAnimGroup = pEvent->GetAnimGroup(); - outAnimID = pEvent->GetAnimId(); - } - else - { - // Using same numbers as CClientGame::DoWastedCheck defaults - outAnimGroup = 0; - outAnimID = 15; - } -} - -// -// DamageHandler seems to be called 3 times for each bit of damage: -// -// pass 1 - preApplyDamage -// is pass 1 if: fDamage == zero && fCurrentHealth == fPreviousHealth -// returning false stops any damage being inflicted -// returning true applies damage and allows pass 2 -// pass 2 - postApplyDamage/preApplyAnim -// is pass 2 if: fDamage > zero && fCurrentHealth != fPreviousHealth -// returning false stops damage anim -// returning true allows damage anim and allows pass 3 -// pass 3 - postApplyAnim -// is pass 3 if: fDamage > zero && fCurrentHealth == fPreviousHealth -// returning false ?? -// returning true ?? -// -bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) -{ - // CEventDamage::AffectsPed: This is/can be called more than once for each bit of damage (and may not actually take any more health (even if we return - // true)) - - // Grab some data from the event - CEntity* pInflictor = pEvent->GetInflictingEntity(); - eWeaponType weaponUsed = pEvent->GetWeaponUsed(); - ePedPieceTypes hitZone = pEvent->GetPedPieceType(); - CWeaponInfo* pWeaponInfo = g_pGame->GetWeaponInfo(weaponUsed); - float fDamage = pEvent->GetDamageApplied(); - EDamageReasonType damageReason = pEvent->GetDamageReason(); - - /* Causes too much desync right now - // Is this shotgun damage? - if ( weaponUsed == WEAPONTYPE_SHOTGUN || weaponUsed == WEAPONTYPE_SPAS12_SHOTGUN ) - { - // Make the ped fall down - pEvent->MakePedFallDown (); - } */ - - // Grab the damaged ped - CClientPed* pDamagedPed = NULL; - if (pDamagePed) - pDamagedPed = m_pPedManager->Get(dynamic_cast(pDamagePed), true, true); - - // Grab the inflictor - CClientEntity* pInflictingEntity = NULL; - if (pInflictor) - pInflictingEntity = m_pManager->FindEntity(pInflictor, true); - - // If the damage was caused by an explosion - if (weaponUsed == WEAPONTYPE_EXPLOSION) - { - CClientEntity* pLastExplosionCreator = m_pManager->GetExplosionManager()->m_pLastCreator; - - // If we don't have an inflictor, look for the last explosion creator - if (!pInflictor && pLastExplosionCreator) - pInflictingEntity = pLastExplosionCreator; - - // Change the weapon used to whatever created the explosion - weaponUsed = m_pManager->GetExplosionManager()->m_LastWeaponType; - } - - // Do we have a damaged ped? - if (pDamagedPed) - { - /////////////////////////////////////////////////////////////////////////// - // - // Pass 1 stuff - // - // return false to stop any damage being inflicted - // - /////////////////////////////////////////////////////////////////////////// - - // Pass 1 checks for double shots - if (fDamage == 0.0f && damageReason != EDamageReason::PISTOL_WHIP) - { - // Only check for remote players - CClientPlayer* pInflictingPlayer = DynamicCast(pInflictingEntity); - if (pInflictingPlayer && !pInflictingPlayer->IsLocalPlayer()) - { - bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon - bool bBulletSyncWeapon = GetWeaponTypeUsesBulletSync(weaponUsed); - - if (bBulletSyncShot) - { - if (g_iDamageEventLimit == 0) - { - AddReportLog(5501, SString("2nd pass 1 for BulletSyncShot damage. weaponUsed:%d", weaponUsed)); - return false; - } - g_iDamageEventLimit--; - if (!bBulletSyncWeapon) - { - AddReportLog(5502, SString("BulletSyncShot but not bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); - return false; - } - } - else - { - if (bBulletSyncWeapon) - { - AddReportLog(5503, SString("not BulletSyncShot but bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); - return false; - } - } - } - } - - // Is the damaged ped a player? - if (IS_PLAYER(pDamagedPed)) - { - CClientPlayer* pDamagedPlayer = static_cast(pDamagedPed); - - // Do we have an inflicting entity? - if (pInflictingEntity) - { - // Grab the inflicting player - CClientPlayer* pInflictingPlayer = NULL; - - switch (pInflictingEntity->GetType()) - { - case CCLIENTPLAYER: - { - pInflictingPlayer = static_cast(pInflictingEntity); - break; - } - case CCLIENTVEHICLE: - { - CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); - if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) - { - CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); - if (pPed && pPed->GetType() == CCLIENTPLAYER) - pInflictingPlayer = static_cast(pPed); - } - break; - } - default: - break; - } - if (pInflictingPlayer) - { - // Is the damaged player on a team - CClientTeam* pTeam = pDamagedPlayer->GetTeam(); - if (pTeam) - { - // Is this friendly-fire from a team-mate? - if (pDamagedPlayer->IsOnMyTeam(pInflictingPlayer) && !pTeam->GetFriendlyFire() && pDamagedPlayer != pInflictingPlayer) - return false; - } - } - } - } - /////////////////////////////////////////////////////////////////////////// - // Pass 1 end - /////////////////////////////////////////////////////////////////////////// - - return ApplyPedDamageFromGame(weaponUsed, fDamage, hitZone, pDamagedPed, pInflictingEntity, pEvent); - } - - // No damage anim for fire - if (weaponUsed == WEAPONTYPE_FLAMETHROWER) - return false; - - // Allow the damage processing to continue - return true; -} - -// -// Check GTA stored health with our stored health and do stuff -// -bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, uchar hitZone, CClientPed* pDamagedPed, CClientEntity* pInflictingEntity, - CEventDamage* pEvent) -{ - float fPreviousHealth = pDamagedPed->m_fHealth; - float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); - float fPreviousArmor = pDamagedPed->m_fArmor; - float fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); - - // Have we taken any damage here? - if ((fPreviousHealth != fCurrentHealth || fPreviousArmor != fCurrentArmor) && fDamage != 0.0f) - { - /////////////////////////////////////////////////////////////////////////// - /// - // Pass 2 stuff - (GTA has applied the damage) - // - // return false to stop damage anim (incl. death task) - // - /////////////////////////////////////////////////////////////////////////// - - g_fApplyDamageLastAmount = fDamage; - g_ucApplyDamageLastHitZone = hitZone; - g_pApplyDamageLastDamagedPed = pDamagedPed; - - CLuaArguments Arguments; - if (pInflictingEntity) - Arguments.PushElement(pInflictingEntity); - else - Arguments.PushBoolean(false); - Arguments.PushNumber(static_cast(weaponUsed)); - Arguments.PushNumber(static_cast(hitZone)); - Arguments.PushNumber(fDamage); - - // Call our event - if ((IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPlayerDamage", Arguments, true)) || - (!IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPedDamage", Arguments, true))) - { - // Stop here if they cancelEvent it - if (pDamagedPed->IsLocalPlayer()) - { - // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) - fPreviousHealth = pDamagedPed->m_fHealth; - fPreviousArmor = pDamagedPed->m_fArmor; - } - pDamagedPed->GetGamePlayer()->SetHealth(fPreviousHealth); - pDamagedPed->GetGamePlayer()->SetArmor(fPreviousArmor); - return false; - } - - if (pDamagedPed->IsLocalPlayer()) - { - // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) - fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); - fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); - } - - bool bIsBeingShotWhilstAiming = (weaponUsed >= WEAPONTYPE_PISTOL && weaponUsed <= WEAPONTYPE_MINIGUN && pDamagedPed->IsUsingGun()); - bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); - - bool bAllowChoke = true; - // Is this is a remote player? - if (!pDamagedPed->IsLocalPlayer()) - { - // Don't allow GTA to start the choking task - if (weaponUsed == WEAPONTYPE_TEARGAS || weaponUsed == WEAPONTYPE_SPRAYCAN || weaponUsed == WEAPONTYPE_EXTINGUISHER) - bAllowChoke = false; - } - - // Check if their health or armor is locked, and if so prevent applying the damage locally - if (pDamagedPed->IsHealthLocked() || pDamagedPed->IsArmorLocked()) - { - // Restore health+armor - pDamagedPed->GetGamePlayer()->SetHealth(pDamagedPed->GetHealth()); - pDamagedPed->GetGamePlayer()->SetArmor(pDamagedPed->GetArmor()); - - if (bOldBehaviour) - { - // Don't play the animation if it's going to be a death one, or if it's going to interrupt aiming - if (fCurrentHealth == 0.0f || bIsBeingShotWhilstAiming) - return false; - - // Allow animation for remote players (if currently we don't need block choke) - return bAllowChoke; - } - - // No hit animation for remote players - return false; - } - - // Update our stored health/armor - pDamagedPed->m_fHealth = fCurrentHealth; - pDamagedPed->m_fArmor = fCurrentArmor; - - ElementID damagerID = INVALID_ELEMENT_ID; - if (pInflictingEntity && !pInflictingEntity->IsLocalEntity()) - damagerID = pInflictingEntity->GetID(); - - // Is it the local player? - if (pDamagedPed->IsLocalPlayer()) - { - // Update our stored damage stuff - m_ucDamageWeapon = static_cast(weaponUsed); - m_ucDamageBodyPiece = static_cast(hitZone); - m_pDamageEntity = pInflictingEntity; - m_ulDamageTime = CClientTime::GetTime(); - m_DamagerID = damagerID; - m_bDamageSent = false; - } - // Does this damage kill the player? - if (fCurrentHealth == 0.0f) - { - if (pDamagedPed->GetType() == CCLIENTPLAYER) - { - // Is the local player dying? - if (pDamagedPed->IsLocalPlayer() && fPreviousHealth > 0.0f) - { - // Grab our death animation - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - - // Check if we're dead - DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); - } - - // Allow GTA to kill us if we've fell to our death - if (pDamagedPed->IsLocalPlayer() && weaponUsed == WEAPONTYPE_FALL) - return true; - - // Don't let GTA start the death task - return false; - } - else - { - if (pDamagedPed->IsLocalEntity() && fPreviousHealth > 0.0f) - { - // Client-side ped - pDamagedPed->CallEvent("onClientPedWasted", Arguments, true); - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - pDamagedPed->Kill(weaponUsed, hitZone, false, false, animGroup, animID); - return true; - } - if (fPreviousHealth > 0.0f) - { - // Grab our death animation - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - - SendPedWastedPacket(pDamagedPed, damagerID, weaponUsed, hitZone, animGroup, animID); - } - } - } - - // Disallow choke task if it's necessary - if (!bAllowChoke) - return false; - - // Inhibit hit-by-gun animation for local player if required - if (bOldBehaviour) - if (pDamagedPed->IsLocalPlayer() && bIsBeingShotWhilstAiming) - return false; - - /////////////////////////////////////////////////////////////////////////// - // Pass 2 end - /////////////////////////////////////////////////////////////////////////// - } - - // No damage anim for fire - if (weaponUsed == WEAPONTYPE_FLAMETHROWER) - return false; - - // Allow the damage processing to continue - return true; -} - -void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, unsigned char ucBodyPart) -{ - CClientPed* pKilledPed = m_pPedManager->Get(dynamic_cast(pKilledPedSA), true, true); - - if (!pKilledPed) - return; - - // Not required for remote players. Local player is handled in DoPulses->DoWastedCheck - if (IS_PLAYER(pKilledPed)) - return; - - // Set the health to zero (this is safe as GTA will do it anyway in a few ticks) - pKilledPed->SetHealth(0.0f); - - // Call Lua - CLuaArguments Arguments; - Arguments.PushBoolean(false); - Arguments.PushNumber(ucDeathReason); - Arguments.PushNumber(ucBodyPart); - - pKilledPed->CallEvent("onClientPedWasted", Arguments, true); - - // Notify the server - SendPedWastedPacket(pKilledPed, INVALID_ELEMENT_ID, ucDeathReason, ucBodyPart); -} - -bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, - float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) -{ - if (pCollidingVehicle && pCollidedWith) - { - CVehicle* pColliderVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidingVehicle); - CClientEntity* pVehicleClientEntity = m_pManager->FindEntity(pColliderVehicle, true); - if (pVehicleClientEntity) - { - CClientVehicle* pClientVehicle = static_cast(pVehicleClientEntity); - - CEntity* pCollidedWithEntity = g_pGame->GetPools()->GetEntity((DWORD*)pCollidedWith); - CClientEntity* pCollidedWithClientEntity = NULL; - if (pCollidedWithEntity) - { - if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pCollidedWithVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithVehicle, true); - } - else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_OBJECT) - { - CObject* pCollidedWithObject = g_pGame->GetPools()->GetObject((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithObject, true); - } - else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pCollidedWithPed = g_pGame->GetPools()->GetPed((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithPed, true); - } - } - CLuaArguments Arguments; - if (pCollidedWithClientEntity) - { - Arguments.PushElement(pCollidedWithClientEntity); - } - else - { - Arguments.PushNil(); - } - Arguments.PushNumber(fDamageImpulseMag); - Arguments.PushNumber(usPieceType); - Arguments.PushNumber(vecCollisionPos.fX); - Arguments.PushNumber(vecCollisionPos.fY); - Arguments.PushNumber(vecCollisionPos.fZ); - Arguments.PushNumber(vecCollisionVelocity.fX); - Arguments.PushNumber(vecCollisionVelocity.fY); - Arguments.PushNumber(vecCollisionVelocity.fZ); - Arguments.PushNumber(fCollidingDamageImpulseMag); - Arguments.PushNumber(iModelIndex); - - pVehicleClientEntity->CallEvent("onClientVehicleCollision", Arguments, true); - // Alocate a BitStream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - // Make sure it created - if (pBitStream) - { - if (pBitStream->Version() >= 0x028) - { - // Sync Stuff - // if it's not a local vehicle + it collided with the local player - if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) - { - // is it below the anti spam threshold? - if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) - { - // if there is no controlling player - if (!pClientVehicle->GetControllingPlayer()) - { - CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); - // if We aren't already syncing the vehicle - if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) - { - // Write the vehicle ID - pBitStream->Write(pVehicleClientEntity->GetID()); - // Send! - g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, - PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); - // Reset our push time - pClientVehicle->ResetLastPushTime(); - } - } - } - } - } - g_pNet->DeallocateNetBitStream(pBitStream); - } - return true; - } - } - return false; -} - -bool CClientGame::HeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) -{ - if (pHeliInterface && pHitInterface) - { - // Get our heli and client heli - CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); - CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); - if (pHeli && pClientHeli && pClientHeli->AreHeliBladeCollisionsEnabled()) - { - // Get our ped and client ped - CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitInterface); - CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); - // Was our client ped valid - if (pClientPed) - { - // Get our heli and client heli - CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); - CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); - - // Iterate our "stored" cancel state and find the heli in question - std::pair::iterator, std::multimap::iterator> iterators = - m_HeliCollisionsMap.equal_range(pClientHeli); - std::multimap::const_iterator iter = iterators.first; - for (; iter != iterators.second; ++iter) - { - // If the Heli and ped collided within the clear rate return false - if ((*iter).first == pClientHeli && (*iter).second == pClientPed) - return false; - } - - CLuaArguments Arguments; - if (pClientHeli) - { - // Push our heli - Arguments.PushElement(pClientHeli); - } - else - { - Arguments.PushNil(); - } - - // Trigger our event - bool bContinue; - if (IS_PLAYER(pClientPed)) - bContinue = pClientPed->CallEvent("onClientPlayerHeliKilled", Arguments, true); - else - bContinue = pClientPed->CallEvent("onClientPedHeliKilled", Arguments, true); - - // Was our event cancelled - if (!bContinue) - { - // Add our heli and ped pair to the list - std::pair pair = std::pair(pClientHeli, pClientPed); - m_HeliCollisionsMap.insert(pair); - } - // Return if it was cancelled - return bContinue; - } - } - else - { - return false; - } - } - return true; -} - -bool CClientGame::VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) -{ - bool bAllowDamage = true; - CClientVehicle* pClientVehicle = GetGameEntityXRefManager()->FindClientVehicle(pVehicleInterface); - if (pClientVehicle) - { - CClientEntity* pClientAttacker = GetGameEntityXRefManager()->FindClientEntity(pAttackerInterface); - - // Compose arguments - // attacker, weapon, loss, damagepos, tyreIdx - CLuaArguments Arguments; - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - if (weaponType != WEAPONTYPE_INVALID) - Arguments.PushNumber(weaponType); - else - Arguments.PushNil(); - Arguments.PushNumber(fLoss); - Arguments.PushNumber(vecDamagePos.fX); - Arguments.PushNumber(vecDamagePos.fY); - Arguments.PushNumber(vecDamagePos.fZ); - if (ucTyre != UCHAR_INVALID_INDEX) - Arguments.PushNumber(ucTyre); - else - Arguments.PushNil(); - - if (!pClientVehicle->CallEvent("onClientVehicleDamage", Arguments, true)) - { - bAllowDamage = false; - } - } - - return bAllowDamage; -} - -bool CClientGame::ObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) -{ - if (pObjectInterface) - { - // Get our object and client object - CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); - CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); - - // Is our client vehicle valid? - if (pClientObject) - { - CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); - CClientEntity* pClientAttacker = NULL; - if (pAttacker) - { - if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); - } - else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerPed); - } - } - - CLuaArguments Arguments; - Arguments.PushNumber(fLoss); - - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - - return pClientObject->CallEvent("onClientObjectDamage", Arguments, true); - } - } - return true; -} - -bool CClientGame::ObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) -{ - if (pObjectInterface) - { - // Get our object and client object - CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); - CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); - - // Is our client vehicle valid? - if (pClientObject) - { - if (!pClientObject->IsBreakable(false)) - return false; - - // Apply to MTA's "internal storage", too - pClientObject->SetHealth(0.0f); - - CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); - CClientEntity* pClientAttacker = NULL; - if (pAttacker) - { - if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); - } - else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerPed); - } - } - - CLuaArguments Arguments; - - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - - return pClientObject->CallEvent("onClientObjectBreak", Arguments, true); - } - } - return true; -} - -bool CClientGame::WaterCannonHitHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) -{ - if (pCannonVehicle && pHitPed) - { - // Get our vehicle and client vehicle - CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCannonVehicle); - CClientVehicle* pCannonClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); - // Was our client vehicle valid - if (pCannonClientVehicle) - { - // Get our ped and client ped - CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitPed); - CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); - - CLuaArguments Arguments; - if (pClientPed) - { - // Push our ped - Arguments.PushElement(pClientPed); - } - else - { - Arguments.PushNil(); - } - - // Trigger our event - bool bContinue = true; - if (!IS_PLAYER(pClientPed)) - bContinue = pCannonClientVehicle->CallEvent("onClientPedHitByWaterCannon", Arguments, true); - else - bContinue = pCannonClientVehicle->CallEvent("onClientPlayerHitByWaterCannon", Arguments, true); - - // Return if it was cancelled - return bContinue; - } - } - return false; -} - -bool CClientGame::VehicleFellThroughMapHandler(CVehicleSAInterface* pVehicleInterface) -{ - if (pVehicleInterface) - { - // Get our vehicle and client vehicle - CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pVehicleInterface); - CClientVehicle* pClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); - if (pClientVehicle) - { - // handle or don't - return pClientVehicle->OnVehicleFallThroughMap(); - } - } - // unhandled - return false; -} - -// Validate known objects -void CClientGame::GameObjectDestructHandler(CEntitySAInterface* pObject) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pObject); -} - -void CClientGame::GameVehicleDestructHandler(CEntitySAInterface* pVehicle) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pVehicle); -} - -void CClientGame::GamePlayerDestructHandler(CEntitySAInterface* pPlayer) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pPlayer); -} - -void CClientGame::GameProjectileDestructHandler(CEntitySAInterface* pProjectile) -{ - CClientProjectile* pClientProjectile = m_pManager->GetProjectileManager()->Get(pProjectile); - // Happens when destroyElement is called rather than letting the projectile expire - // Normal code path is destruction from CProjectileSAInterface -> CProjectileSA -> CClientProjectile - // destroyElement is CClientProjectile -> CProjectileSA -> CProjectileSAInterface - // which means the CClientProjectile element is deleted when we get here - if (pClientProjectile) - CStaticFunctionDefinitions::DestroyElement(*pClientProjectile); -} - -void CClientGame::GameModelRemoveHandler(ushort usModelId) -{ - m_pGameEntityXRefManager->OnGameModelRemove(usModelId); -} - -void CClientGame::TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) -{ - bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); - if (bOldBehaviour) - return; - - CClientPed* pClientPedAttacker = DynamicCast(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedAttacker)); - - // Make sure cause was networked ped - if (pClientPedAttacker && !pClientPedAttacker->IsLocalEntity()) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write((ushort)TASK_SIMPLE_BE_HIT); - pBitStream->Write(pClientPedAttacker->GetID()); - pBitStream->Write((uchar)hitBodyPart); - pBitStream->Write((uchar)hitBodySide); - pBitStream->Write((uchar)weaponId); - g_pNet->SendPacket(PACKET_ID_PED_TASK, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -bool CClientGame::StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (g_pClientGame) - { - return g_pClientGame->ProcessMessage(hwnd, uMsg, wParam, lParam); - } - - return false; -} - -bool CClientGame::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (ProcessMessageForCursorEvents(hwnd, uMsg, wParam, lParam)) - { - return true; - } - - return false; -} - -void CClientGame::ProcessVehicleInOutKey(bool bPassenger) -{ - // Are we already sending an in/out request or not allowed to create a new in/out? - if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? - || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) - || m_bIsGettingJacked // Make sure we're not currently getting carjacked && - || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... - || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... - || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon - ) - { - return; - } - - // Reset the "is jacking" bit - m_bIsJackingVehicle = false; - - // Got a local player model? - if (!m_pLocalPlayer) - { - // No local player. Stop. - return; - } - - // If the player is in a vehicle we need to leave the vehicle. - CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - if (pOccupiedVehicle) - { - // Only let us leave the vehicle if: - // - we press F (as driver) - // - we press either F or G as a passenger - if (bPassenger && m_pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - // Driver pressed G, so stop. - return; - } - - // We're about to exit a vehicle - // Send an in request - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!pBitStream) - { - return; - } - - // Write the vehicle id to it and that we're requesting to get out of it - pBitStream->Write(pOccupiedVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_REQUEST_OUT); - pBitStream->WriteBits(&ucAction, 4); - - unsigned char ucDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pLocalPlayer->GetGamePlayer(), pOccupiedVehicle->GetGameVehicle()); - if (ucDoor >= 2 && ucDoor <= 5) - { - ucDoor -= 2; - pBitStream->WriteBits(&ucDoor, 2); - } - - // Send and destroy it - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're now exiting a vehicle - m_bIsGettingOutOfVehicle = true; - m_ulLastVehicleInOutTime = CClientTime::GetTime(); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_out"); -#endif - return; - } - - // - // We're going to enter a vehicle - // - - // If the Jump task is playing and we are in water - I know right - // Kill the task. - // - CTask* pTask = m_pLocalPlayer->GetCurrentPrimaryTask(); - if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter - { - CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, nullptr, nullptr, 20.0f); - if (pVehicle && - (pVehicle->IsInWater() || - m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) - { - m_pLocalPlayer->KillTask(3, true); // Kill jump task if we are about to warp in - } - } - - // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle' - // task will replace it and fuck it up! - // - if (m_pLocalPlayer->GetCurrentPrimaryTask()) - { - // We already have a primary task, so stop. - return; - } - - // Are we holding the aim_weapon key? - SBindableGTAControl* pBind = g_pCore->GetKeyBinds()->GetBindableFromControl("aim_weapon"); - if (pBind && pBind->bState) - { - // Stop because the player is probably using rshift + f/g - return; - } - - if (m_pLocalPlayer->IsClimbing() // Make sure we're not currently climbing - || m_pLocalPlayer->HasJetPack() // Make sure we don't have a jetpack - || m_pLocalPlayer->IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway - || m_pLocalPlayer->IsRunningAnimation() // Make sure we aren't running an animation - ) - { - return; - } - - // Grab the closest vehicle - unsigned int uiDoor = 0; - CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, &uiDoor, nullptr, 20.0f); - unsigned int uiSeat = uiDoor; - - if (bPassenger && uiDoor == 0) - { - // We're trying to enter as a passenger, yet our closest door - // is the driver's door. Force an enter for the passenger seat. - uiSeat = 1; - } - else if (!bPassenger) - { - // We want to drive. Force our seat to the driver's seat. - uiSeat = 0; - } - - if (!pVehicle || !pVehicle->IsEnterable()) - { - // Stop if there isn't a vehicle, or the vehicle is not enterable - return; - } - - // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly) - if (pVehicle->GetVehicleType() == CLIENTVEHICLE_BOAT && m_pLocalPlayer->GetContactEntity() != pVehicle) - { - return; - } - - // Call the onClientVehicleStartEnter event for remote players - // Local player triggered before sending packet in CClientGame - CLuaArguments Arguments; - Arguments.PushElement(m_pLocalPlayer); // player - Arguments.PushNumber(uiSeat); // seat - Arguments.PushNumber(uiDoor); // Door - - if (!pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true)) - { - // Event has been cancelled - return; - } - - // Send an in request - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!pBitStream) - { - return; - } - - // Write the vehicle id to it and that we're requesting to get into it - pBitStream->Write(pVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_REQUEST_IN); - unsigned char ucSeat = static_cast(uiSeat); - bool bIsOnWater = pVehicle->IsOnWater(); - unsigned char ucDoor = static_cast(uiDoor); - pBitStream->WriteBits(&ucAction, 4); - pBitStream->WriteBits(&ucSeat, 4); - pBitStream->WriteBit(bIsOnWater); - pBitStream->WriteBits(&ucDoor, 3); - - // Send and destroy it - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're now entering a vehicle - m_bIsGettingIntoVehicle = true; - m_ulLastVehicleInOutTime = CClientTime::GetTime(); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_in"); -#endif -} - -// Shot compensation (Jax): -// Positions the local player where he should of been on the shooting player's screen when he -// fired remotely. (the position we !reported! around the time he shot) -bool bShotCompensation = true; - -// Temporary pointers for pre- and post-functions -CVector vecWeaponFirePosition, vecRemoteWeaponFirePosition; -CPlayerPed* pWeaponFirePed = NULL; - -bool CClientGame::PreWeaponFire(CPlayerPed* pPlayerPed, bool bStopIfUsingBulletSync) -{ - pWeaponFirePed = pPlayerPed; - - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pWeaponFirePed) - { - CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); - - // Get the CClientNetPlayer class with the specified player ped - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(pWeaponFirePed, true); - - // Move both players to where they should be for shot compensation - if (pPlayer && !pPlayer->IsLocalPlayer()) - { - if (bStopIfUsingBulletSync && pPlayer->IsCurrentWeaponUsingBulletSync()) - return false; // Don't apply shot compensation & tell caller to not do bullet trace - - if (bShotCompensation) - { - if (!pVehicle || pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - // Warp back in time to where we were when this player shot (their latency) - - // We don't account for interpolation here, +250ms seems to work better - // ** Changed ajustment to +125ms as the position of this clients player on the firers screen - // has been changed. See CClientPed::UpdateTargetPosition() ** - CVector vecPosition; - unsigned short usLatency = (pPlayer->GetLatency() + 125); - g_pClientGame->m_pNetAPI->GetInterpolation(vecPosition, usLatency); - - // Move the entity back - if (pVehicle) - { - pVehicle->GetPosition(vecWeaponFirePosition); - pVehicle->SetPosition(vecPosition, false, false); - } - else - { - pLocalPlayer->GetPosition(vecWeaponFirePosition); - pLocalPlayer->SetPosition(vecPosition, false, false); - } - } - } - } - } - return true; -} - -void CClientGame::PostWeaponFire(void) -{ - // Send bullet sync with local damage info - if (g_bBulletFireVectorsValid) - { - g_bBulletFireVectorsValid = false; - CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer) - { - eWeaponType weaponType = pLocalPlayer->GetCurrentWeaponType(); - if (g_pClientGame->GetWeaponTypeUsesBulletSync(weaponType)) - { - g_pClientGame->GetNetAPI()->SendBulletSyncFire(weaponType, g_vecBulletFireStartPosition, g_vecBulletFireEndPosition, g_fApplyDamageLastAmount, - g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); - } - } - } - - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pWeaponFirePed) - { - CClientPed* pPed = g_pClientGame->GetPedManager()->Get(pWeaponFirePed, true, true); - if (pPed) - { - if (pPed->GetType() == CCLIENTPLAYER) - { - if (bShotCompensation) - { - // Restore compensated positions - if (!pPed->IsLocalPlayer()) - { - CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); - if (!pVehicle) - { - pLocalPlayer->SetPosition(vecWeaponFirePosition, false, false); - } - else if (pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - pVehicle->SetPosition(vecWeaponFirePosition, false, false); - } - } - } - } - - // Call some events - CWeapon* pWeapon = pPed->GetWeapon(); - if (pWeapon) - { - CVector vecCollision; - CClientEntity* pCollisionEntity = NULL; - - if (pPed->GetBulletImpactData(&pCollisionEntity, &vecCollision) == false) - { - CShotSyncData* pShotsyncData = pPed->m_shotSyncData; - CVector vecOrigin, vecTarget; - pPed->GetShotData(&vecOrigin, &vecTarget); - - CColPoint* pCollision = NULL; - CEntity* pCollisionGameEntity = NULL; - vecCollision = vecTarget; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionGameEntity); - if (bCollision && pCollision) - vecCollision = pCollision->GetPosition(); - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - - if (pCollisionGameEntity) - pCollisionEntity = g_pClientGame->m_pManager->FindEntity(pCollisionGameEntity); - } - else - { - pPed->ClearBulletImpactData(); - } - - // Call our lua event - CLuaArguments Arguments; - Arguments.PushNumber((double)pWeapon->GetType()); - Arguments.PushNumber((double)pWeapon->GetAmmoTotal()); - Arguments.PushNumber((double)pWeapon->GetAmmoInClip()); - Arguments.PushNumber((double)vecCollision.fX); - Arguments.PushNumber((double)vecCollision.fY); - Arguments.PushNumber((double)vecCollision.fZ); - if (pCollisionEntity) - Arguments.PushElement(pCollisionEntity); - else - Arguments.PushNil(); - - if (IS_PLAYER(pPed)) - { - CVector vecOrigin; - pPed->GetShotData(&vecOrigin); - Arguments.PushNumber((double)vecOrigin.fX); - Arguments.PushNumber((double)vecOrigin.fY); - Arguments.PushNumber((double)vecOrigin.fZ); - pPed->CallEvent("onClientPlayerWeaponFire", Arguments, true); - } - else - pPed->CallEvent("onClientPedWeaponFire", Arguments, true); - } - pPed->PostWeaponFire(); -#ifdef MTA_DEBUG - if (pPed->IsLocalPlayer() && g_pClientGame->m_bDoPaintballs) - { - g_pClientGame->DoPaintballs(); - } -#endif - } - } - pWeaponFirePed = NULL; -} - -void CClientGame::BulletImpact(CPed* pInitiator, CEntity* pVictim, const CVector* pStartPosition, const CVector* pEndPosition) -{ - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pInitiator) - { - // Find the client ped that initiated the bullet impact - CClientPed* pInitiatorPed = g_pClientGame->GetPedManager()->Get(dynamic_cast(pInitiator), true, true); - - if (pInitiatorPed) - { - // Calculate the collision of the bullet - CVector vecCollision; - CColPoint* pCollision = NULL; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(pStartPosition, pEndPosition, &pCollision, NULL); - if (bCollision && pCollision) - { - vecCollision = pCollision->GetPosition(); - } - else - { - // If we don't have a collision, use the end of the ray that the bullet is tracing. - vecCollision = *pEndPosition; - } - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - - // Find the client entity for the victim. - CClientEntity* pClientVictim = NULL; - if (pVictim) - { - pClientVictim = g_pClientGame->m_pManager->FindEntity(pVictim); - } - - // Store the data in the bullet fire initiator. - pInitiatorPed->SetBulletImpactData(pClientVictim, vecCollision); - } - } -} - -void CClientGame::BulletFire(CPed* pInitiator, const CVector* pStartPosition, const CVector* pEndPosition) -{ - g_bBulletFireVectorsValid = false; - g_fApplyDamageLastAmount = 0; - g_ucApplyDamageLastHitZone = 0; - g_pApplyDamageLastDamagedPed = NULL; - - // Got a local player model? - CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pLocalPlayer->GetGamePlayer() == pInitiator) - { - g_bBulletFireVectorsValid = true; - g_vecBulletFireStartPosition = *pStartPosition; - g_vecBulletFireEndPosition = *pEndPosition; - } -} - -bool CClientGame::StaticProcessPacket(unsigned char ucPacketID, NetBitStreamInterface& bitStream) -{ - if (g_pClientGame) - { - g_pCore->UpdateDummyProgress(); - g_pClientGame->GetManager()->GetPacketRecorder()->RecordPacket(ucPacketID, bitStream); - return g_pClientGame->m_pPacketHandler->ProcessPacket(ucPacketID, bitStream); - } - - return false; -} - -void CClientGame::SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin) -{ - SPositionSync position(false); - position.data.vecPosition = vecPosition; - - // Create the bitstream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write our origin id - if (pOrigin) - { - pBitStream->WriteBit(true); - pBitStream->Write(pOrigin->GetID()); - - // Convert position - CVector vecTemp; - pOrigin->GetPosition(vecTemp); - position.data.vecPosition -= vecTemp; - } - else - pBitStream->WriteBit(false); - - // Write the position and the type - pBitStream->Write(&position); - - SExplosionTypeSync explosionType; - explosionType.data.uiType = Type; - pBitStream->Write(&explosionType); - - // Destroy it - g_pNet->SendPacket(PACKET_ID_EXPLOSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -void CClientGame::SendFireSync(CFire* pFire) -{ -#ifdef MTA_DEBUG - CVector* vecPos = pFire->GetPosition(); - if (vecPos) - g_pCore->GetConsole()->Printf("we're sending fire: %f %f %f %f", pFire->GetStrength(), vecPos->fX, vecPos->fY, vecPos->fZ); - else - g_pCore->GetConsole()->Printf("we're sending a fire!"); -#endif -} - -void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) -{ - // Create the bitstream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - SPositionSync origin(false); - CClientEntity* pOriginSource = NULL; - eWeaponType weaponType = pProjectile->GetWeaponType(); - CClientEntity* pTarget = pProjectile->GetTargetEntity(); - origin.data.vecPosition = *pProjectile->GetOrigin(); - - // Is this a heatseaking missile with a target? sync it relative to the target - if (weaponType == WEAPONTYPE_ROCKET_HS && pTarget && !pTarget->IsLocalEntity()) - pOriginSource = pTarget; - - // Write the source of the projectile, if it has - if (pOriginSource) - { - CVector vecTemp; - pOriginSource->GetPosition(vecTemp); - origin.data.vecPosition -= vecTemp; - - pBitStream->WriteBit(true); - pBitStream->Write(pOriginSource->GetID()); - } - else - pBitStream->WriteBit(false); - - // Write the origin position - pBitStream->Write(&origin); - - // Write the creator weapon type - SWeaponTypeSync weaponTypeSync; - weaponTypeSync.data.ucWeaponType = static_cast(weaponType); - pBitStream->Write(&weaponTypeSync); - - // Write the projectile's model - if (pBitStream->Version() >= 0x4F) - if (pBitStream->Version() >= 0x52 || pOriginSource) // Fix possible error for 0x51 server - pBitStream->Write(pProjectile->GetModel()); - - switch (weaponType) - { - case WEAPONTYPE_GRENADE: - case WEAPONTYPE_TEARGAS: - case WEAPONTYPE_MOLOTOV: - case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: - { - SFloatSync<7, 17> projectileForce; - projectileForce.data.fValue = pProjectile->GetForce(); - pBitStream->Write(&projectileForce); - - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); - - break; - } - case WEAPONTYPE_ROCKET: - case WEAPONTYPE_ROCKET_HS: - { - if (pTarget) - { - pBitStream->WriteBit(true); - pBitStream->Write(pTarget->GetID()); - } - else - pBitStream->WriteBit(false); - - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); - - SRotationRadiansSync rotation(true); - pProjectile->GetRotationRadians(rotation.data.vecRotation); - pBitStream->Write(&rotation); - - break; - } - case WEAPONTYPE_FLARE: - case WEAPONTYPE_FREEFALL_BOMB: - break; - } - g_pNet->SendPacket(PACKET_ID_PROJECTILE, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - - // Destroy it - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -void CClientGame::ResetAmmoInClip(void) -{ - memset(&m_wasWeaponAmmoInClip[0], 0, sizeof(m_wasWeaponAmmoInClip)); -} - -void CClientGame::ResetMapInfo(void) -{ - // Restore some game stuff - // Keybinds - g_pCore->GetKeyBinds()->SetAllControlsEnabled(true, true, true); - - // Radarmap - m_pRadarMap->SetForcedState(false); - - // Camera - m_pCamera->FadeOut(0.0f, 0, 0, 0); - g_pGame->GetWorld()->SetCurrentArea(0); - m_pCamera->SetFocusToLocalPlayer(); - g_pGame->GetSettings()->ResetFieldOfViewFromScript(); - - // Dimension - SetAllDimensions(0); - - // Hud - g_pGame->GetHud()->SetComponentVisible(HUD_ALL, true); - // Disable area names as they are on load until camera unfades - g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); - g_pGame->GetHud()->SetComponentVisible(HUD_VITAL_STATS, false); - - m_bHudAreaNameDisabled = false; - - // Gravity - g_pMultiplayer->SetLocalPlayerGravity(DEFAULT_GRAVITY); - g_pMultiplayer->SetGlobalGravity(DEFAULT_GRAVITY); - g_pGame->SetGravity(DEFAULT_GRAVITY); - - // Gamespeed - SetGameSpeed(DEFAULT_GAME_SPEED); - - // Game minute duration - SetMinuteDuration(DEFAULT_MINUTE_DURATION); - - // Wanted-level - SetWanted(0); - - // Money - SetMoney(0, true); - - // Weather - m_pBlendedWeather->SetWeather(0); - - // Rain - g_pGame->GetWeather()->ResetAmountOfRain(); - - // Wind - g_pMultiplayer->RestoreWindVelocity(); - - // Far clip distance - g_pMultiplayer->RestoreFarClipDistance(); - - // Near clip distance - g_pMultiplayer->RestoreNearClipDistance(); - - // Fog distance - g_pMultiplayer->RestoreFogDistance(); - - // Vehicles LOD distance - g_pGame->GetSettings()->ResetVehiclesLODDistance(); - - // Peds LOD distance - g_pGame->GetSettings()->ResetPedsLODDistance(); - - // Sun color - g_pMultiplayer->ResetSunColor(); - - // Sun size - g_pMultiplayer->ResetSunSize(); - - // Sky-gradient - g_pMultiplayer->ResetSky(); - - // Heat haze - g_pMultiplayer->ResetHeatHaze(); - - // Water-colour - g_pMultiplayer->ResetWater(); - - // Water - GetManager()->GetWaterManager()->ResetWorldWaterLevel(); - - // Re-enable interior sounds and furniture - g_pMultiplayer->SetInteriorSoundsEnabled(true); - for (int i = 0; i <= 4; ++i) - g_pMultiplayer->SetInteriorFurnitureEnabled(i, true); - - // Clouds - g_pMultiplayer->SetCloudsEnabled(true); - g_pClientGame->SetCloudsEnabled(true); - - // Birds - g_pMultiplayer->DisableBirds(false); - g_pClientGame->SetBirdsEnabled(true); - - // Ambient sounds - g_pGame->GetAudio()->ResetAmbientSounds(); - - // World sounds - g_pGame->GetAudio()->ResetWorldSounds(); - - // Cheats - g_pGame->ResetCheats(); - - // Players - m_pPlayerManager->ResetAll(); - - // Jetpack max height - g_pGame->GetWorld()->SetJetpackMaxHeight(DEFAULT_JETPACK_MAXHEIGHT); - - // Aircraft max height - g_pGame->GetWorld()->SetAircraftMaxHeight(DEFAULT_AIRCRAFT_MAXHEIGHT); - - // Aircraft max velocity - g_pGame->GetWorld()->SetAircraftMaxVelocity(DEFAULT_AIRCRAFT_MAXVELOCITY); - - // Moon size - g_pMultiplayer->ResetMoonSize(); - - // Disable the change of any player stats - g_pMultiplayer->SetLocalStatsStatic(true); - - // Restore blur -#ifdef MTA_DEBUG - g_pGame->SetBlurLevel(0); -#else - g_pGame->SetBlurLevel(DEFAULT_BLUR_LEVEL); -#endif - - // Close all garages - CGarage* pGarage = NULL; - CGarages* pGarages = g_pCore->GetGame()->GetGarages(); - - for (unsigned char i = 0; (pGarage = pGarages->GetGarage(i)) != NULL; i++) - { - pGarage->SetOpen(false); - } - - // Player specific stuff - if (m_pLocalPlayer) - { - // Interior - m_pLocalPlayer->SetInterior(0); - - // Headless state - m_pLocalPlayer->SetHeadless(false); - - // Frozen state - m_pLocalPlayer->SetFrozen(false); - - // Voice - short sVoiceType, sVoiceID; - m_pLocalPlayer->GetModelInfo()->GetVoice(&sVoiceType, &sVoiceID); - m_pLocalPlayer->SetVoice(sVoiceType, sVoiceID); - - m_pLocalPlayer->DestroySatchelCharges(false, true); - // Tell the server we want to destroy our satchels - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - g_pNet->SendPacket(PACKET_ID_DESTROY_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, - AnimationId animID) -{ - if (Ped && Ped->GetHealth() == 0.0f) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write some death info - pBitStream->WriteCompressed(animGroup); - pBitStream->WriteCompressed(animID); - - pBitStream->Write(damagerID); - - SWeaponTypeSync weapon; - weapon.data.ucWeaponType = ucWeapon; - pBitStream->Write(&weapon); - - SBodypartSync bodyPart; - bodyPart.data.uiBodypart = ucBodyPiece; - pBitStream->Write(&bodyPart); - - // Write the position we died in - SPositionSync pos(false); - Ped->GetPosition(pos.data.vecPosition); - pBitStream->Write(&pos); - - pBitStream->Write(Ped->GetID()); - - // The ammo in our weapon and write the ammo total - CWeapon* pPlayerWeapon = Ped->GetWeapon(); - SWeaponAmmoSync ammo(ucWeapon, true, false); - ammo.data.usTotalAmmo = 0; - if (pPlayerWeapon) - ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); - pBitStream->Write(&ammo); - - // Send the packet - g_pNet->SendPacket(PACKET_ID_PED_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, AnimationId animID) -{ - // Are we not already marked as dead? and have we run out of health? - if (!m_pLocalPlayer->IsDeadOnNetwork() && m_pLocalPlayer->GetHealth() == 0.0f) - { - // Send the "i am dead" packet - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - m_pLocalPlayer->SetDeadOnNetwork(true); - - // Call the onClientPlayerWasted event - CClientEntity* pKiller = (damagerID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(damagerID) : NULL; - CLuaArguments Arguments; - if (pKiller) - Arguments.PushElement(pKiller); - else - Arguments.PushBoolean(false); - if (ucWeapon != 0xFF) - Arguments.PushNumber(ucWeapon); - else - Arguments.PushBoolean(false); - if (ucBodyPiece != 0xFF) - Arguments.PushNumber(ucBodyPiece); - else - Arguments.PushBoolean(false); - Arguments.PushBoolean(false); - m_pLocalPlayer->CallEvent("onClientPlayerWasted", Arguments, true); - - // Write some death info - pBitStream->WriteCompressed(animGroup); - pBitStream->WriteCompressed(animID); - - pBitStream->Write(damagerID); - - SWeaponTypeSync weapon; - weapon.data.ucWeaponType = ucWeapon; - pBitStream->Write(&weapon); - - SBodypartSync bodyPart; - bodyPart.data.uiBodypart = ucBodyPiece; - pBitStream->Write(&bodyPart); - - // Write the position we died in - SPositionSync pos(false); - m_pLocalPlayer->GetPosition(pos.data.vecPosition); - pBitStream->Write(&pos); - - // The ammo in our weapon and write the ammo total - CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(); - SWeaponAmmoSync ammo(ucWeapon, true, false); - ammo.data.usTotalAmmo = 0; - if (pPlayerWeapon) - ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); - pBitStream->Write(&ammo); - - // Send the packet - g_pNet->SendPacket(PACKET_ID_PLAYER_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -bool CClientGame::OnKeyDown(CGUIKeyEventArgs Args) -{ - return true; -} - -bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - const char* szState = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIClick", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseDoubleClick(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - const char* szState = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIDoubleClick", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIMouseDown", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseButtonUp(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIMouseUp", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseMove(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseMove", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseEnter(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - if (Args.pSwitchedWindow) - { - CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); - if (GetGUIManager()->Exists(pGUISwitchedElement)) - Arguments.PushElement(pGUISwitchedElement); - } - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseEnter", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseLeave(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - if (Args.pSwitchedWindow) - { - CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); - if (GetGUIManager()->Exists(pGUISwitchedElement)) - Arguments.PushElement(pGUISwitchedElement); - } - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseLeave", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseWheel(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.wheelChange); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseWheel", Arguments, true); - - return true; -} - -bool CClientGame::OnMove(CGUIElement* pElement) -{ - if (!pElement) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); - if (pGUIElement && GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientGUIMove", Arguments, true); - - return true; -} - -bool CClientGame::OnSize(CGUIElement* pElement) -{ - if (!pElement) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientGUISize", Arguments, true); - - return true; -} - -bool CClientGame::OnFocusGain(CGUIFocusEventArgs Args) -{ - if (!Args.pActivatedWindow) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pActivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pActivatedWindow); - - if (Args.pDeactivatedWindow) - { - CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); - if (GetGUIManager()->Exists(pDeactivatedGUIElement)) - pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); - } - - if (GetGUIManager()->Exists(pActivatedGUIElement)) - pActivatedGUIElement->CallEvent("onClientGUIFocus", Arguments, true); - - return true; -} - -bool CClientGame::OnFocusLoss(CGUIFocusEventArgs Args) -{ - if (!Args.pDeactivatedWindow) - return false; - - CLuaArguments Arguments; - - if (Args.pActivatedWindow) - { - // pDeactivatedWindow looses focus but an other window is now gaining it so we let CClientGame::OnFocusGain trigger both events in the right order - return true; - } - - CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); - if (GetGUIManager()->Exists(pDeactivatedGUIElement)) - pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); - - return true; -} - -// -// Display a progress dialog if a big packet is coming in -// -void CClientGame::NotifyBigPacketProgress(unsigned long ulBytesReceived, unsigned long ulTotalSize) -{ - // Should display progress box? - if (ulBytesReceived >= ulTotalSize || ulTotalSize < 50000) - { - if (m_bReceivingBigPacket) - { - // Switch off progress box - m_bReceivingBigPacket = false; - m_pBigPacketTransferBox->Hide(); - } - return; - } - - // Update progress box - if (!m_bReceivingBigPacket || m_ulBigPacketSize != ulTotalSize) - { - m_bReceivingBigPacket = true; - m_ulBigPacketSize = ulTotalSize; - m_pBigPacketTransferBox->Hide(); - m_pBigPacketTransferBox->AddToTotalSize(ulTotalSize); - m_pBigPacketTransferBox->Show(); - } - - m_pBigPacketTransferBox->DoPulse(); - m_pBigPacketTransferBox->SetInfo(std::min(ulTotalSize, ulBytesReceived), CTransferBox::PACKET); -} - -bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled) -{ - if (ucGlitch < NUM_GLITCHES && bEnabled != m_Glitches[ucGlitch]) - { - m_Glitches[ucGlitch] = bEnabled; - if (ucGlitch == GLITCH_QUICKRELOAD) - g_pMultiplayer->DisableQuickReload(!bEnabled); - if (ucGlitch == GLITCH_CLOSEDAMAGE) - g_pMultiplayer->DisableCloseRangeDamage(!bEnabled); - return true; - } - return false; -} - -bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) -{ - return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; -} - -bool CClientGame::SetCloudsEnabled(bool bEnabled) -{ - m_bCloudsEnabled = bEnabled; - return true; -} -bool CClientGame::GetCloudsEnabled(void) -{ - return m_bCloudsEnabled; -} - -bool CClientGame::SetBirdsEnabled(bool bEnabled) -{ - m_bBirdsEnabled = bEnabled; - return true; -} -bool CClientGame::GetBirdsEnabled(void) -{ - return m_bBirdsEnabled; -} - -#pragma code_seg(".text") -bool CClientGame::VerifySADataFiles(int iEnableClientChecks) -{ - int& iCheckStatus = g_pGame->GetCheckStatus(); - - if (!g_pGame->VerifySADataFileNames()) - iCheckStatus |= (1 << 11); - - __declspec(allocate(".text")) static char szVerifyData[][32] = {"data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", - "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", - "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", - "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", - "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", - "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", - "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", - "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", - "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", - "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", - "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", - "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74"}; - - CMD5Hasher hasher; - for (int i = 0; i < NUMELMS(szVerifyData); i += 2) - { - MD5 md5; - if (!hasher.Calculate(szVerifyData[i], md5) || memcmp(md5.data, szVerifyData[i + 1], 0x10)) - { - iCheckStatus |= (1 << i); - } - } - - if (iCheckStatus & iEnableClientChecks) - { - g_pCore->InitiateDataFilesFix(); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - return true; -} - -void CClientGame::InitVoice(bool bEnabled, unsigned int uiServerSampleRate, unsigned char ucQuality, unsigned int uiBitrate) -{ - if (m_pVoiceRecorder) - { - m_pVoiceRecorder->Init(bEnabled, uiServerSampleRate, ucQuality, uiBitrate); - } -} - -// -// If debug render mode is on, allow each element in range to draw some stuff -// -void CClientGame::DebugElementRender(void) -{ - if (!GetDevelopmentMode() || !GetShowCollision()) - return; - - CVector vecCameraPos; - m_pCamera->GetPosition(vecCameraPos); - float fDrawRadius = 200.f; - - // Get all entities within range - CClientEntityResult result; - GetClientSpatialDatabase()->SphereQuery(result, CSphere(vecCameraPos, fDrawRadius)); - - // For each entity found - for (CClientEntityResult::const_iterator it = result.begin(); it != result.end(); ++it) - { - CClientEntity* pEntity = *it; - if (pEntity->GetParent()) - pEntity->DebugRender(vecCameraPos, fDrawRadius); - } -} - -////////////////////////////////////////////////////////////////// -// Click -// -void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString& strTag, uint uiQuality, uint uiMaxBandwidth, uint uiMaxPacketSize, - CResource* pResource, uint uiServerSentTime) -{ - if (!pResource) - return; - - bool bAllowScreenUploadEnabled = 1; - g_pCore->GetCVars()->Get("allow_screen_upload", bAllowScreenUploadEnabled); - bool bWindowMinimized = g_pCore->IsWindowMinimized(); - - if (bWindowMinimized || !bAllowScreenUploadEnabled) - { - // If alt-tabbed or opt-out - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!bAllowScreenUploadEnabled) - pBitStream->Write((uchar)EPlayerScreenShotResult::DISABLED); - else - pBitStream->Write((uchar)EPlayerScreenShotResult::MINIMIZED); - pBitStream->Write(uiServerSentTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); - g_pNet->DeallocateNetBitStream(pBitStream); - } - else - { - // Do grab and send - SScreenShotArgs screenShotArgs; - screenShotArgs.uiMaxBandwidth = uiMaxBandwidth; - screenShotArgs.uiMaxPacketSize = uiMaxPacketSize; - screenShotArgs.usResourceNetId = pResource->GetNetID(); - screenShotArgs.strTag = strTag; - screenShotArgs.uiServerSentTime = uiServerSentTime; - m_ScreenShotArgList.push_back(screenShotArgs); - g_pCore->GetGraphics()->GetScreenGrabber()->QueueScreenShot(uiSizeX, uiSizeY, uiQuality, &CClientGame::StaticGottenPlayerScreenShot); - } -} - -////////////////////////////////////////////////////////////////// -// Callback from TakePlayerScreendsShot -// -void CClientGame::StaticGottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strError) -{ - if (g_pClientGame) - g_pClientGame->GottenPlayerScreenShot(pBuffer, uiTimeSpentInQueue, strError); -} - -////////////////////////////////////////////////////////////////// -// Break data into packets and put into delayed send list -// -void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strInError) -{ - SString strError = strInError; - - // Pop saved args - if (m_ScreenShotArgList.empty()) - return; - - SScreenShotArgs screenShotArgs = m_ScreenShotArgList.front(); - m_ScreenShotArgList.pop_front(); - const uint uiMaxBandwidth = Clamp(100, screenShotArgs.uiMaxBandwidth, 1000000); - const uint uiMaxPacketSize = Clamp(100, screenShotArgs.uiMaxPacketSize, 100000); - const ushort usResourceNetId = screenShotArgs.usResourceNetId; - const SString strTag = screenShotArgs.strTag; - const uint uiServerGrabTime = screenShotArgs.uiServerSentTime + uiTimeSpentInQueue; - - // Silently ignore if resource has been stopped - CResource* pResource = GetResourceManager()->GetResourceFromNetID(usResourceNetId); - if (!pResource) - return; - - // Validate buffer - if (strError.empty()) - { - if (!pBuffer || pBuffer->GetSize() == 0) - strError = "Buffer empty"; - } - - // Handle error - if (!strError.empty()) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write((uchar)EPlayerScreenShotResult::ERROR_); - pBitStream->Write(uiServerGrabTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - if (pBitStream->Version() >= 0x053) - pBitStream->WriteString(strError); - g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); - g_pNet->DeallocateNetBitStream(pBitStream); - return; - } - - // Calc constants stuff - const uint uiSendRate = Clamp(5, uiMaxBandwidth / uiMaxPacketSize, 20); - const long long llPacketInterval = 1000 / uiSendRate; - const uint uiTotalByteSize = pBuffer->GetSize(); - const char* pData = pBuffer->GetData(); - const uint uiBytesPerPart = std::min(std::min(std::max(100U, uiMaxBandwidth / uiSendRate), uiTotalByteSize), 30000U); - const uint uiNumParts = std::max(1U, (uiTotalByteSize + uiBytesPerPart - 1) / uiBytesPerPart); - - // Calc variables stuff - CTickCount tickCount = CTickCount::Now() + CTickCount(llPacketInterval); - uint uiBytesRemaining = uiTotalByteSize; - m_usNextScreenShotId++; - - // Make each packet - for (uint i = 0; i < uiNumParts; i++) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - - ushort usPartNumber = i; - ushort usBytesThisPart = std::min(uiBytesRemaining, uiBytesPerPart); - assert(usBytesThisPart != 0); - - pBitStream->Write((uchar)EPlayerScreenShotResult::SUCCESS); - pBitStream->Write(m_usNextScreenShotId); - pBitStream->Write(usPartNumber); - pBitStream->Write(usBytesThisPart); - pBitStream->Write(pData, usBytesThisPart); - - // Write more info if first part - if (usPartNumber == 0) - { - pBitStream->Write(uiServerGrabTime); - pBitStream->Write(uiTotalByteSize); - pBitStream->Write((ushort)uiNumParts); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - } - - // Add to delay send list - SDelayedPacketInfo delayedPacketInfo; - delayedPacketInfo.useTickCount = tickCount; - delayedPacketInfo.ucPacketID = PACKET_ID_PLAYER_SCREENSHOT; - delayedPacketInfo.pBitStream = pBitStream; - delayedPacketInfo.packetPriority = PACKET_PRIORITY_LOW; - delayedPacketInfo.packetReliability = PACKET_RELIABILITY_RELIABLE_ORDERED; - delayedPacketInfo.packetOrdering = PACKET_ORDERING_DATA_TRANSFER; - m_DelayedSendList.push_back(delayedPacketInfo); - - // Increment stuff - pData += usBytesThisPart; - uiBytesRemaining -= usBytesThisPart; - tickCount += CTickCount(llPacketInterval); - } - - assert(uiBytesRemaining == 0); -} - -////////////////////////////////////////////////////////////////// -// Process delay send list -// -void CClientGame::ProcessDelayedSendList(void) -{ - CTickCount tickCount = CTickCount::Now(); - - while (!m_DelayedSendList.empty()) - { - SDelayedPacketInfo& info = m_DelayedSendList.front(); - if (info.useTickCount > tickCount) - break; - - g_pNet->SendPacket(info.ucPacketID, info.pBitStream, info.packetPriority, info.packetReliability, info.packetOrdering); - g_pNet->DeallocateNetBitStream(info.pBitStream); - m_DelayedSendList.pop_front(); - } -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetWeaponTypesUsingBulletSync -// -// Set whether the local player will send bulletsync messages for the supplied weapon type -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetWeaponTypesUsingBulletSync(const std::set& weaponTypesUsingBulletSync) -{ - m_weaponTypesUsingBulletSync = weaponTypesUsingBulletSync; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::GetWeaponTypeUsesBulletSync -// -// Get whether the local player should send bulletsync messages for the supplied weapon type -// -////////////////////////////////////////////////////////////////// -bool CClientGame::GetWeaponTypeUsesBulletSync(eWeaponType weaponType) -{ - return MapContains(m_weaponTypesUsingBulletSync, weaponType); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetDevelopmentMode -// -// Special mode which enables commands such as showcol and showsound -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetDevelopmentMode(bool bEnable, bool bEnableWeb) -{ - m_bDevelopmentMode = bEnable; - - if (m_bDevelopmentMode) - g_pGame->GetAudio()->SetWorldSoundHandler(CClientGame::StaticWorldSoundHandler); - else - g_pGame->GetAudio()->SetWorldSoundHandler(NULL); - - if (g_pCore->IsWebCoreLoaded()) - g_pCore->GetWebCore()->SetTestModeEnabled(bEnableWeb); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::StaticWorldSoundHandler -// -// Handle callback from CAudioSA when a world sound is played -// -////////////////////////////////////////////////////////////////// -void CClientGame::StaticWorldSoundHandler(uint uiGroup, uint uiIndex) -{ - g_pClientGame->WorldSoundHandler(uiGroup, uiIndex); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::WorldSoundHandler -// -// Handle callback from CAudioSA when a world sound is played -// -////////////////////////////////////////////////////////////////// -void CClientGame::WorldSoundHandler(uint uiGroup, uint uiIndex) -{ - if (m_bShowSound) - m_pScriptDebugging->LogInformation(NULL, "%s - World sound group:%d index:%d", *GetLocalTimeString(false, true), uiGroup, uiIndex); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::IsUsingAlternatePulseOrder -// -// Returns true if should be using alternate pulse order -// -////////////////////////////////////////////////////////////////// -bool CClientGame::IsUsingAlternatePulseOrder(bool bAdvanceDelayCounter) -{ - if (m_MiscGameSettings.bUseAltPulseOrder) - { - // Only actually start using alternate pulse order after 100 frames - if (m_uiAltPulseOrderCounter >= 100) - return true; - else if (bAdvanceDelayCounter) - m_uiAltPulseOrderCounter++; - } - - return false; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::OutputServerInfo -// -// Output info about the connected server for player -// -////////////////////////////////////////////////////////////////// -void CClientGame::OutputServerInfo(void) -{ - SString strTotalOutput; - strTotalOutput += SString("Server info for %s", g_pNet->GetConnectedServer(true)); - strTotalOutput += "\n"; - strTotalOutput += SString("Ver: %s\n", *GetServerVersionSortable()); - strTotalOutput += SString("AC: %s\n", *m_strACInfo); - - { - SString strVoice; - if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) - strVoice += SString("Enabled - Sample rate:%d Quality:%d", m_pVoiceRecorder->GetSampleRate(), m_pVoiceRecorder->GetSampleQuality()); - else - strVoice += "Disabled"; - - strTotalOutput += SString("Voice: %s\n", *strVoice); - } - - { - SString strEnabledGlitches; - const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", - "Bad driveby hitboxes", "Quick stand"}; - for (uint i = 0; i < NUM_GLITCHES; i++) - { - if (IsGlitchEnabled(i)) - { - if (!strEnabledGlitches.empty()) - strEnabledGlitches += ", "; - if (i < NUMELMS(szGlitchNames)) - strEnabledGlitches += szGlitchNames[i]; - else - strEnabledGlitches += SString("Unknown(#%d)", i + 1); - } - } - if (strEnabledGlitches.empty()) - strEnabledGlitches = "None"; - strTotalOutput += SString("Glitches: %s\n", *strEnabledGlitches); - } - - { - SString strEnabledBulletSync; - for (std::set::iterator iter = m_weaponTypesUsingBulletSync.begin(); iter != m_weaponTypesUsingBulletSync.end(); ++iter) - { - eWeaponType weaponType = *iter; - if (!strEnabledBulletSync.empty()) - strEnabledBulletSync += ","; - strEnabledBulletSync += SString("%d", weaponType); - } - if (strEnabledBulletSync.empty()) - strEnabledBulletSync = "None"; - strTotalOutput += SString("Bullet sync weapons: %s\n", *strEnabledBulletSync); - } - - { - SString strVehExtrapolate; - if (m_VehExtrapolateSettings.bEnabled) - strVehExtrapolate += SString("Amount:%d%% (LimitMs:%d)", m_VehExtrapolateSettings.iScalePercent, m_VehExtrapolateSettings.iMaxMs); - else - strVehExtrapolate += "Disabled"; - - strTotalOutput += SString("Vehicle extrapolation: %s\n", *strVehExtrapolate); - } - - { - SString strTickRates; - strTickRates += SString("Plr:%d Cam:%d Ped:%d UnocVeh:%d KeyRot:%d KeyJoy:%d", g_TickRateSettings.iPureSync, g_TickRateSettings.iCamSync, - g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, - g_TickRateSettings.iKeySyncAnalogMove); - - strTotalOutput += SString("Tick rates: %s\n", *strTickRates); - } - - { - SString strSyncerDists; - strSyncerDists += SString("Ped:%d UnoccupiedVehicle:%d ", g_TickRateSettings.iPedSyncerDistance, g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); - - strTotalOutput += SString("Syncer distances: %s\n", *strSyncerDists); - } - - g_pCore->GetConsole()->Print(strTotalOutput); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::TellServerSomethingImportant -// -// Report misc important warnings/errors to the current server -// -////////////////////////////////////////////////////////////////// -void CClientGame::TellServerSomethingImportant(uint uiId, const SString& strMessage, uint uiSendLimitForThisId) -{ - g_pCore->GetConsole()->Print(strMessage); - AddReportLog(3400 + uiId, strMessage + g_pNet->GetConnectedServer(true), 10); - - if (uiSendLimitForThisId) - { - uint& uiCount = MapGet(m_SentMessageIds, uiId); - if (uiCount++ >= uiSendLimitForThisId) - return; - } - - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->WriteString(SString("%d,%s", uiId, *strMessage)); - g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE); - g_pNet->DeallocateNetBitStream(pBitStream); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::ChangeFloatPrecision -// -// Manage the change to high floating point precision -// -////////////////////////////////////////////////////////////////// -void CClientGame::ChangeFloatPrecision(bool bHigh) -{ - if (bHigh) - { - // Switch to 53 bit floating point precision on the first call - if (m_uiPrecisionCallDepth++ == 0) - _controlfp(_PC_53, MCW_PC); - } - else - { - // Even though is should never happen, m_uiPrecisionCallDepth is sometimes zero here - dassert(m_uiPrecisionCallDepth != 0); - if (m_uiPrecisionCallDepth != 0) - m_uiPrecisionCallDepth--; - // Switch back to 24 bit floating point precision on the last call - if (m_uiPrecisionCallDepth == 0) - _controlfp(_PC_24, MCW_PC); - } -} - -bool CClientGame::IsHighFloatPrecision(void) const -{ - return m_uiPrecisionCallDepth != 0; -} - -AnimationId CClientGame::DrivebyAnimationHandler(AnimationId animId, AssocGroupId animGroupId) -{ - // Only apply if all clients support the fix - if (!GetMiscGameSettings().bAllowBadDrivebyHitboxFix) - return animId; - - // If the glitch is enabled, don't apply the fix - if (IsGlitchEnabled(GLITCH_BADDRIVEBYHITBOX)) - return animId; - - // Bad animations are 232 and 236 of assoc group 72 - if (animGroupId != 72) - return animId; - - if (animId == 232) - return 235; - else if (animId == 236) - return 231; - - return animId; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetFileCacheRoot -// -// Figure out which directory to use for the client resource file cache -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetFileCacheRoot(void) -{ - if (g_pCore->GetCVars()->GetValue("share_file_cache") == false) - { - // Not sharing, so use current mod directory - m_strFileCacheRoot = GetModRoot(); - AddReportLog(7410, SString("CClientGame::SetFileCacheRoot - Not shared '%s'", *m_strFileCacheRoot)); - } - else - { - // Get shared directory - SString strFileCachePath = GetCommonRegistryValue("", "File Cache Path"); - // Check exists - if (!strFileCachePath.empty() && DirectoryExists(strFileCachePath)) - { - // Check writable - SString strTestFileName = PathJoin(strFileCachePath, "resources", "_test.tmp"); - if (FileSave(strTestFileName, "x")) - { - FileDelete(strTestFileName); - strTestFileName = PathJoin(strFileCachePath, "priv", "_test.tmp"); - if (FileSave(strTestFileName, "x")) - { - FileDelete(strTestFileName); - // Use shared directory - m_strFileCacheRoot = strFileCachePath; - AddReportLog(7411, SString("CClientGame::SetFileCacheRoot - Is shared '%s'", *m_strFileCacheRoot)); - return; - } - } - } - - // Otherwise set this install mod directory as shared - m_strFileCacheRoot = GetModRoot(); - SetCommonRegistryValue("", "File Cache Path", m_strFileCacheRoot); - - if (strFileCachePath.empty()) - AddReportLog(7412, SString("CClientGame::SetFileCacheRoot - Initial setting '%s'", *m_strFileCacheRoot)); - else - AddReportLog(7413, SString("CClientGame::SetFileCacheRoot - Change shared from '%s' to '%s'", *strFileCachePath, *m_strFileCacheRoot)); - } -} - -bool CClientGame::TriggerBrowserRequestResultEvent(const std::unordered_set& newPages) -{ - CLuaArguments Arguments; - CLuaArguments LuaTable; - int i = 0; - - for (auto& domain : newPages) - { - LuaTable.PushNumber(++i); - LuaTable.PushString(domain); - } - Arguments.PushTable(&LuaTable); - - return GetRootEntity()->CallEvent("onClientBrowserWhitelistChange", Arguments, false); -} - -void CClientGame::RestreamModel(unsigned short usModel) -{ - // Is this a vehicle ID? - if (CClientVehicleManager::IsValidModel(usModel)) - { - // Stream the vehicles of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetVehicleManager()->RestreamVehicles(usModel); - } - - // Is this an object ID? - else if (CClientObjectManager::IsValidModel(usModel)) - { - if (CClientPedManager::IsValidWeaponModel(usModel)) - { - // Stream the weapon of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamWeapon(usModel); - m_pManager->GetPickupManager()->RestreamPickups(usModel); - } - // Stream the objects of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetObjectManager()->RestreamObjects(usModel); - g_pGame->GetModelInfo(usModel)->RestreamIPL(); - } - // Is this an ped ID? - else if (CClientPlayerManager::IsValidModel(usModel)) - { - // Stream the ped of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamPeds(usModel); - } - else - - // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect - if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) - m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); -} - -void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) -{ - m_mapOfIfpPointers[u32BlockNameHash] = pIFP; -} - -std::shared_ptr CClientGame::GetIFPPointerFromMap(const unsigned int u32BlockNameHash) -{ - auto it = m_mapOfIfpPointers.find(u32BlockNameHash); - if (it != m_mapOfIfpPointers.end()) - { - return it->second; - } - return nullptr; -} - -void CClientGame::RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash) -{ - m_mapOfIfpPointers.erase(u32BlockNameHash); -} - -void CClientGame::InsertPedPointerToSet(CClientPed* pPed) -{ - m_setOfPedPointers.insert(pPed); -} - -void CClientGame::RemovePedPointerFromSet(CClientPed* pPed) -{ - m_setOfPedPointers.erase(pPed); -} - -CClientPed* CClientGame::GetClientPedByClump(const RpClump& Clump) -{ - for (auto& pPed : m_setOfPedPointers) - { - CEntity* pEntity = pPed->GetGameEntity(); - if (pEntity != nullptr) - { - if (pEntity->GetRpClump() != nullptr) - { - const RpClump& entityClump = *pEntity->GetRpClump(); - if (std::addressof(entityClump) == std::addressof(Clump)) - { - return pPed; - } - } - } - } - return nullptr; -} - -void CClientGame::OnClientIFPUnload(const std::shared_ptr& IFP) -{ - IFP->MarkAsUnloading(); - for (auto& pPed : m_setOfPedPointers) - { - // Remove IFP animations from replaced animations of peds/players - pPed->RestoreAnimations(IFP); - - // Make sure that streamed in pulses or changing model does not accidently - // play our custom animation. We can do that by making the custom animation - // untriggerable - if (pPed->GetCustomAnimationBlockNameHash() == IFP->GetBlockNameHash()) - { - if (pPed->IsCustomAnimationPlaying()) - { - pPed->SetCustomAnimationUntriggerable(); - } - - // Important! As we are using a shared_ptr, we need to decrement the reference counter - // by setting the shared_ptr to nullptr, this will avoid memory leak - if (!pPed->IsNextAnimationCustom() && pPed->IsCurrentAnimationCustom()) - { - pPed->DereferenceCustomAnimationBlock(); - } - } - } -} - -void CClientGame::InsertAnimationAssociationToMap(CAnimBlendAssociationSAInterface* pAnimAssociation, const std::shared_ptr& pIFPAnimations) -{ - m_mapOfCustomAnimationAssociations[pAnimAssociation] = pIFPAnimations; -} - -void CClientGame::RemoveAnimationAssociationFromMap(CAnimBlendAssociationSAInterface* pAnimAssociation) -{ - m_mapOfCustomAnimationAssociations.erase(pAnimAssociation); -} +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CClientGame.cpp + * PURPOSE: Client game manager + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include +#include "game/CAnimBlendAssocGroup.h" +#include "game/CAnimBlendAssociation.h" +#include "game/CAnimBlendHierarchy.h" + +SString StringZeroPadout(const SString& strInput, uint uiPadoutSize) +{ + SString strResult = strInput; + while (strResult.length() < uiPadoutSize) + strResult += '\0'; + return strResult; +} + +using SharedUtil::CalcMTASAPath; +using std::list; +using std::vector; + +// Hide the "conversion from 'unsigned long' to 'DWORD*' of greater size" warning +#pragma warning(disable:4312) + +// Used within this file by the packet handler to grab the this pointer of CClientGame +extern CClientGame* g_pClientGame; +extern int g_iDamageEventLimit; +float g_fApplyDamageLastAmount; +uchar g_ucApplyDamageLastHitZone; +CClientPed* g_pApplyDamageLastDamagedPed; +bool g_bBulletFireVectorsValid; +CVector g_vecBulletFireStartPosition; +CVector g_vecBulletFireEndPosition; + +#define DEFAULT_GRAVITY 0.008f +#define DEFAULT_GAME_SPEED 1.0f +#define DEFAULT_BLUR_LEVEL 36 +#define DEFAULT_JETPACK_MAXHEIGHT 100 +#define DEFAULT_AIRCRAFT_MAXHEIGHT 800 +#define DEFAULT_AIRCRAFT_MAXVELOCITY 1.5f +#define DEFAULT_MINUTE_DURATION 1000 +#define DOUBLECLICK_TIMEOUT 330 +#define DOUBLECLICK_MOVE_THRESHOLD 10.0f + +CClientGame::CClientGame(bool bLocalPlay) +{ + // Init the global var with ourself + g_pClientGame = this; + + // Packet handler + m_pPacketHandler = new CPacketHandler(); + + // Init + m_bLocalPlay = bLocalPlay; + m_bErrorStartingLocal = false; + m_iLocalConnectAttempts = 0; + m_Status = CClientGame::STATUS_CONNECTING; + m_ulVerifyTimeStart = 0; + m_ulLastClickTick = 0; + m_pLocalPlayer = NULL; + m_LocalID = INVALID_ELEMENT_ID; + m_bShowNametags = true; + m_bWaitingForLocalConnect = false; + m_bShowRadar = false; + m_bGameLoaded = false; + m_bTriggeredIngameAndConnected = false; + m_bGracefulDisconnect = false; + m_ulLastVehicleInOutTime = 0; + m_bIsGettingOutOfVehicle = false; + m_bIsGettingIntoVehicle = false; + m_bIsGettingJacked = false; + m_bIsJackingVehicle = false; + m_VehicleInOutID = INVALID_ELEMENT_ID; + m_pGettingJackedBy = NULL; + m_ucVehicleInOutSeat = 0xFF; + m_pTargetedEntity = NULL; + m_TargetedPlayerID = INVALID_ELEMENT_ID; + m_pDamageEntity = NULL; + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageBodyPiece = 0xFF; + m_ucDamageWeapon = 0xFF; + m_ulDamageTime = 0; + m_bDamageSent = true; + m_bShowNetstat = false; + m_bShowFPS = false; + m_bHudAreaNameDisabled = false; + m_fGameSpeed = 1.0f; + m_lMoney = 0; + m_dwWanted = 0; + m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) + ResetAmmoInClip(); + + m_bNoNewVehicleTask = false; + m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; + + m_bCursorEventsEnabled = false; + m_bInitiallyFadedOut = true; + + m_bIsPlayingBack = false; + m_bFirstPlaybackFrame = false; + + // Setup game glitch defaults ( false = disabled ). Remember to update these serverside if you alter them! + m_Glitches[GLITCH_QUICKRELOAD] = false; + g_pMultiplayer->DisableQuickReload(true); + m_Glitches[GLITCH_FASTFIRE] = false; + m_Glitches[GLITCH_FASTMOVE] = false; + m_Glitches[GLITCH_CROUCHBUG] = false; + m_Glitches[GLITCH_CLOSEDAMAGE] = false; + g_pMultiplayer->DisableCloseRangeDamage(true); + m_Glitches[GLITCH_HITANIM] = false; + m_Glitches[GLITCH_FASTSPRINT] = false; + m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; + m_Glitches[GLITCH_QUICKSTAND] = false; + g_pMultiplayer->DisableBadDrivebyHitboxes(true); + + // Remove Night & Thermal vision view (if enabled). + g_pMultiplayer->SetNightVisionEnabled(false); + g_pMultiplayer->SetThermalVisionEnabled(false); + + m_bCloudsEnabled = true; + + m_bBirdsEnabled = true; + + m_bWasMinimized = false; + + // Grab the mod path + m_strModRoot = g_pCore->GetModInstallRoot("deathmatch"); + + // Figure out which directory to use for the client resource file cache + SetFileCacheRoot(); + + // Override CGUI's global events + g_pCore->GetGUI()->SetKeyDownHandler(INPUT_MOD, GUI_CALLBACK_KEY(&CClientGame::OnKeyDown, this)); + g_pCore->GetGUI()->SetMouseClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseClick, this)); + g_pCore->GetGUI()->SetMouseDoubleClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseDoubleClick, this)); + g_pCore->GetGUI()->SetMouseButtonDownHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonDown, this)); + g_pCore->GetGUI()->SetMouseButtonUpHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonUp, this)); + g_pCore->GetGUI()->SetMouseMoveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseMove, this)); + g_pCore->GetGUI()->SetMouseEnterHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseEnter, this)); + g_pCore->GetGUI()->SetMouseLeaveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseLeave, this)); + g_pCore->GetGUI()->SetMouseWheelHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseWheel, this)); + g_pCore->GetGUI()->SetMovedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnMove, this)); + g_pCore->GetGUI()->SetSizedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnSize, this)); + g_pCore->GetGUI()->SetFocusGainedHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusGain, this)); + g_pCore->GetGUI()->SetFocusLostHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusLoss, this)); + g_pCore->GetGUI()->SelectInputHandlers(INPUT_MOD); + + // Startup "entities from root" optimization for getElementsByType + CClientEntity::StartupEntitiesFromRoot(); + + // Startup game entity tracking manager + m_pGameEntityXRefManager = NewGameEntityXRefManager(); + m_pModelCacheManager = NewClientModelCacheManager(); + + // Initialize our root entity with an invalid id, we dont know the true id until map-start + m_pRootEntity = new CClientDummy(NULL, INVALID_ELEMENT_ID, "root"); + m_pRootEntity->MakeSystemEntity(); + + m_pDebugHookManager = new CDebugHookManager(); + + // Movings objects manager + m_pMovingObjectsManager = new CMovingObjectsManager(); + + // Create the manager and grab the most important pointers + m_pManager = new CClientManager; + m_pCamera = m_pManager->GetCamera(); + m_pMarkerManager = m_pManager->GetMarkerManager(); + m_pObjectManager = m_pManager->GetObjectManager(); + m_pPickupManager = m_pManager->GetPickupManager(); + m_pPlayerManager = m_pManager->GetPlayerManager(); + m_pRadarAreaManager = m_pManager->GetRadarAreaManager(); + m_pDisplayManager = m_pManager->GetDisplayManager(); + m_pVehicleManager = m_pManager->GetVehicleManager(); + m_pRadarMarkerManager = m_pManager->GetRadarMarkerManager(); + m_pPathManager = m_pManager->GetPathManager(); + m_pTeamManager = m_pManager->GetTeamManager(); + m_pPedManager = m_pManager->GetPedManager(); + m_pGUIManager = m_pManager->GetGUIManager(); + m_pResourceManager = m_pManager->GetResourceManager(); + m_pProjectileManager = m_pManager->GetProjectileManager(); + m_pLocalServer = NULL; + + m_pLatentTransferManager = new CLatentTransferManager(); + m_pZoneNames = new CZoneNames; + m_pScriptKeyBinds = new CScriptKeyBinds; + m_pRemoteCalls = new CRemoteCalls(); + m_pResourceFileDownloadManager = new CResourceFileDownloadManager(); + + // Create our net API + m_pNetAPI = new CNetAPI(m_pManager); + m_pNetworkStats = new CNetworkStats(m_pDisplayManager); + m_pSyncDebug = new CSyncDebug(m_pManager); + + // Create our blended weather class + m_pBlendedWeather = new CBlendedWeather; + + // Create our RPC class + m_pRPCFunctions = new CRPCFunctions(this); + + // Our management classes + m_pUnoccupiedVehicleSync = new CUnoccupiedVehicleSync(m_pVehicleManager); + m_pPedSync = new CPedSync(m_pPedManager); +#ifdef WITH_OBJECT_SYNC + m_pObjectSync = new CObjectSync(m_pObjectManager); +#endif + m_pNametags = new CNametags(m_pManager); + m_pRadarMap = new CRadarMap(m_pManager); + + // Set the screenshot path + /* This is now done in CCore, to maintain a global screenshot path + SString strScreenShotPath = SString::Printf ( "%s\\screenshots", m_szModRoot ); + g_pCore->SetScreenShotPath ( strScreenShotPath ); + */ + + // Create the transfer boxes (GUI) + m_pTransferBox = new CTransferBox(); + m_pBigPacketTransferBox = new CTransferBox(); + + // Store the time we started on + if (bLocalPlay) + m_ulTimeStart = 0; + else + m_ulTimeStart = CClientTime::GetTime(); + + // MTA Voice + m_pVoiceRecorder = new CVoiceRecorder(); + + // Singular file download manager + m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); + + // Register the message and the net packet handler + g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); + g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); + g_pMultiplayer->SetBulletImpactHandler(CClientGame::BulletImpact); + g_pMultiplayer->SetBulletFireHandler(CClientGame::BulletFire); + g_pMultiplayer->SetExplosionHandler(CClientExplosionManager::Hook_StaticExplosionCreation); + g_pMultiplayer->SetBreakTowLinkHandler(CClientGame::StaticBreakTowLinkHandler); + g_pMultiplayer->SetDrawRadarAreasHandler(CClientGame::StaticDrawRadarAreasHandler); + g_pMultiplayer->SetDamageHandler(CClientGame::StaticDamageHandler); + g_pMultiplayer->SetDeathHandler(CClientGame::StaticDeathHandler); + g_pMultiplayer->SetFireHandler(CClientGame::StaticFireHandler); + g_pMultiplayer->SetProjectileStopHandler(CClientProjectileManager::Hook_StaticProjectileAllow); + g_pMultiplayer->SetProjectileHandler(CClientProjectileManager::Hook_StaticProjectileCreation); + g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); + g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); + g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); + g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); + g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); + g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); + g_pMultiplayer->SetPreFxRenderHandler(CClientGame::StaticPreFxRenderHandler); + g_pMultiplayer->SetPreHudRenderHandler(CClientGame::StaticPreHudRenderHandler); + g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(CClientGame::StaticCAnimBlendAssocDestructorHandler); + g_pMultiplayer->SetAddAnimationHandler(CClientGame::StaticAddAnimationHandler); + g_pMultiplayer->SetAddAnimationAndSyncHandler(CClientGame::StaticAddAnimationAndSyncHandler); + g_pMultiplayer->SetAssocGroupCopyAnimationHandler(CClientGame::StaticAssocGroupCopyAnimationHandler); + g_pMultiplayer->SetBlendAnimationHierarchyHandler(CClientGame::StaticBlendAnimationHierarchyHandler); + g_pMultiplayer->SetProcessCollisionHandler(CClientGame::StaticProcessCollisionHandler); + g_pMultiplayer->SetVehicleCollisionHandler(CClientGame::StaticVehicleCollisionHandler); + g_pMultiplayer->SetVehicleDamageHandler(CClientGame::StaticVehicleDamageHandler); + g_pMultiplayer->SetHeliKillHandler(CClientGame::StaticHeliKillHandler); + g_pMultiplayer->SetObjectDamageHandler(CClientGame::StaticObjectDamageHandler); + g_pMultiplayer->SetObjectBreakHandler(CClientGame::StaticObjectBreakHandler); + g_pMultiplayer->SetWaterCannonHitHandler(CClientGame::StaticWaterCannonHandler); + g_pMultiplayer->SetVehicleFellThroughMapHandler(CClientGame::StaticVehicleFellThroughMapHandler); + g_pMultiplayer->SetGameObjectDestructHandler(CClientGame::StaticGameObjectDestructHandler); + g_pMultiplayer->SetGameVehicleDestructHandler(CClientGame::StaticGameVehicleDestructHandler); + g_pMultiplayer->SetGamePlayerDestructHandler(CClientGame::StaticGamePlayerDestructHandler); + g_pMultiplayer->SetGameProjectileDestructHandler(CClientGame::StaticGameProjectileDestructHandler); + g_pMultiplayer->SetGameModelRemoveHandler(CClientGame::StaticGameModelRemoveHandler); + g_pMultiplayer->SetGameEntityRenderHandler(CClientGame::StaticGameEntityRenderHandler); + g_pMultiplayer->SetFxSystemDestructionHandler(CClientGame::StaticFxSystemDestructionHandler); + g_pMultiplayer->SetDrivebyAnimationHandler(CClientGame::StaticDrivebyAnimationHandler); + g_pGame->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); + g_pGame->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); + g_pGame->SetTaskSimpleBeHitHandler(CClientGame::StaticTaskSimpleBeHitHandler); + g_pCore->SetMessageProcessor(CClientGame::StaticProcessMessage); + g_pCore->GetKeyBinds()->SetKeyStrokeHandler(CClientGame::StaticKeyStrokeHandler); + g_pCore->GetKeyBinds()->SetCharacterKeyHandler(CClientGame::StaticCharacterKeyHandler); + g_pNet->RegisterPacketHandler(CClientGame::StaticProcessPacket); + + m_pLuaManager = new CLuaManager(this); + m_pScriptDebugging = new CScriptDebugging(m_pLuaManager); + m_pScriptDebugging->SetLogfile(CalcMTASAPath("mta\\logs\\clientscript.log"), 3); + + CStaticFunctionDefinitions(m_pLuaManager, &m_Events, g_pCore, g_pGame, this, m_pManager); + CLuaFunctionDefs::Initialize(m_pLuaManager, m_pScriptDebugging, this); + CLuaDefs::Initialize(this, m_pLuaManager, m_pScriptDebugging); + + // Start async task scheduler + m_pAsyncTaskScheduler = new SharedUtil::CAsyncTaskScheduler(2); + + // Disable the enter/exit vehicle key button (we want to handle this button ourselves) + g_pMultiplayer->DisableEnterExitVehicleKey(true); + + // Disable GTA's pickup processing as we want to confirm the hits with the server + m_pPickupManager->SetPickupProcessingDisabled(true); + + // Key-bind for fire-key (for handling satchels and stealth-kills) + g_pCore->GetKeyBinds()->AddControlFunction("fire", CClientGame::StaticUpdateFireKey, true); + + // Init big packet progress vars + m_bReceivingBigPacket = false; + m_ulBigPacketSize = 0; + m_ulBigPacketBytesReceivedBase = 0; + + m_bBeingDeleted = false; + + #if defined (MTA_DEBUG) || defined (MTA_BETA) + m_bShowSyncingInfo = false; + #endif + + #ifdef MTA_DEBUG + m_pShowPlayer = m_pShowPlayerTasks = NULL; + m_bMimicLag = false; + m_ulLastMimicLag = 0; + m_bDoPaintballs = false; + m_bShowInterpolation = false; + #endif + + // Add our lua events + AddBuiltInEvents(); + + // Init debugger class + m_Foo.Init(this); + + // Load some stuff from the core config + float fScale; + g_pCore->GetCVars()->Get("text_scale", fScale); + CClientTextDisplay::SetGlobalScale(fScale); + + // Reset async loading script settings to default + g_pGame->SetAsyncLoadingFromScript(true, false); + + // Reset test mode script settings to default + g_pCore->GetGraphics()->GetRenderItemManager()->SetTestMode(DX_TEST_MODE_NONE); +} + +CClientGame::~CClientGame(void) +{ + m_bBeingDeleted = true; + // Stop all explosions. Unfortunately this doesn't fix the crash + // if a vehicle is destroyed while it explodes. + g_pGame->GetExplosionManager()->RemoveAllExplosions(); + + // Reset camera shaking + g_pGame->GetCamera()->SetShakeForce(0.0f); + + // Stop playing the continious sounds + // if the game was loaded. This is done by + // playing these special IDS. + if (m_bGameLoaded) + { + g_pGame->GetAudio()->PlayFrontEndSound(35); + g_pGame->GetAudio()->PlayFrontEndSound(48); + } + + // Reset the GUI input mode + g_pCore->GetGUI()->SetGUIInputMode(INPUTMODE_NO_BINDS_ON_EDIT); + + // Reset CGUI's global events + g_pCore->GetGUI()->ClearInputHandlers(INPUT_MOD); + + // Destroy mimics + #ifdef MTA_DEBUG + list::const_iterator iterMimics = m_Mimics.begin(); + for (; iterMimics != m_Mimics.end(); iterMimics++) + { + CClientPlayer* pPlayer = *iterMimics; + CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); + if (pVehicle) + delete pVehicle; + + delete pPlayer; + } + #endif + + // Hide the transfer box incase it is showing + m_pTransferBox->Hide(); + m_pBigPacketTransferBox->Hide(); + + // Stop async task scheduler + SAFE_DELETE(m_pAsyncTaskScheduler); + + SAFE_DELETE(m_pVoiceRecorder); + + // Singular file download manager + SAFE_DELETE(m_pSingularFileDownloadManager); + + // NULL the message/net stuff + g_pMultiplayer->SetPreContextSwitchHandler(NULL); + g_pMultiplayer->SetPostContextSwitchHandler(NULL); + g_pMultiplayer->SetPreWeaponFireHandler(NULL); + g_pMultiplayer->SetPostWeaponFireHandler(NULL); + g_pMultiplayer->SetBulletImpactHandler(NULL); + g_pMultiplayer->SetBulletFireHandler(NULL); + g_pMultiplayer->SetExplosionHandler(NULL); + g_pMultiplayer->SetBreakTowLinkHandler(NULL); + g_pMultiplayer->SetDrawRadarAreasHandler(NULL); + g_pMultiplayer->SetDamageHandler(NULL); + g_pMultiplayer->SetFireHandler(NULL); + g_pMultiplayer->SetProjectileStopHandler(NULL); + g_pMultiplayer->SetProjectileHandler(NULL); + g_pMultiplayer->SetProcessCamHandler(nullptr); + g_pMultiplayer->SetRender3DStuffHandler(NULL); + g_pMultiplayer->SetPreRenderSkyHandler(NULL); + g_pMultiplayer->SetRenderHeliLightHandler(nullptr); + g_pMultiplayer->SetChokingHandler(NULL); + g_pMultiplayer->SetPreWorldProcessHandler(NULL); + g_pMultiplayer->SetPostWorldProcessHandler(NULL); + g_pMultiplayer->SetPreFxRenderHandler(NULL); + g_pMultiplayer->SetPreHudRenderHandler(NULL); + g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(NULL); + g_pMultiplayer->SetAddAnimationHandler(NULL); + g_pMultiplayer->SetAddAnimationAndSyncHandler(NULL); + g_pMultiplayer->SetAssocGroupCopyAnimationHandler(NULL); + g_pMultiplayer->SetBlendAnimationHierarchyHandler(NULL); + g_pMultiplayer->SetProcessCollisionHandler(NULL); + g_pMultiplayer->SetVehicleCollisionHandler(NULL); + g_pMultiplayer->SetVehicleDamageHandler(NULL); + g_pMultiplayer->SetHeliKillHandler(NULL); + g_pMultiplayer->SetObjectDamageHandler(NULL); + g_pMultiplayer->SetObjectBreakHandler(NULL); + g_pMultiplayer->SetWaterCannonHitHandler(NULL); + g_pMultiplayer->SetGameObjectDestructHandler(NULL); + g_pMultiplayer->SetGameVehicleDestructHandler(NULL); + g_pMultiplayer->SetGamePlayerDestructHandler(NULL); + g_pMultiplayer->SetGameProjectileDestructHandler(NULL); + g_pMultiplayer->SetGameModelRemoveHandler(NULL); + g_pMultiplayer->SetGameEntityRenderHandler(NULL); + g_pMultiplayer->SetDrivebyAnimationHandler(nullptr); + g_pGame->SetPreWeaponFireHandler(NULL); + g_pGame->SetPostWeaponFireHandler(NULL); + g_pGame->SetTaskSimpleBeHitHandler(NULL); + g_pGame->GetAudio()->SetWorldSoundHandler(NULL); + g_pCore->SetMessageProcessor(NULL); + g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); + g_pCore->GetKeyBinds()->SetCharacterKeyHandler(NULL); + g_pNet->StopNetwork(); + g_pNet->RegisterPacketHandler(NULL); + CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); + pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessClientKeyBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessClientControlBind); + pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessServerKeyBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessServerControlBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticUpdateFireKey); + pKeyBinds->SetAllControlsEnabled(true, true, true); + g_pCore->ForceCursorVisible(false); + SetCursorEventsEnabled(false); + + // Destroy our stuff + SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop + SAFE_DELETE(m_pNametags); + SAFE_DELETE(m_pSyncDebug); + SAFE_DELETE(m_pNetworkStats); + SAFE_DELETE(m_pNetAPI); + SAFE_DELETE(m_pRPCFunctions); + SAFE_DELETE(m_pUnoccupiedVehicleSync); + SAFE_DELETE(m_pPedSync); +#ifdef WITH_OBJECT_SYNC + SAFE_DELETE(m_pObjectSync); +#endif + SAFE_DELETE(m_pBlendedWeather); + SAFE_DELETE(m_pMovingObjectsManager); + SAFE_DELETE(m_pRadarMap); + SAFE_DELETE(m_pRemoteCalls); + SAFE_DELETE(m_pLuaManager); + SAFE_DELETE(m_pLatentTransferManager); + SAFE_DELETE(m_pResourceFileDownloadManager); + + SAFE_DELETE(m_pRootEntity); + + SAFE_DELETE(m_pModelCacheManager); + SAFE_DELETE(m_pGameEntityXRefManager); + SAFE_DELETE(m_pZoneNames); + SAFE_DELETE(m_pScriptKeyBinds); + + // Delete the scriptdebugger + SAFE_DELETE(m_pScriptDebugging); + + // Delete the transfer boxes + SAFE_DELETE(m_pTransferBox); + SAFE_DELETE(m_pBigPacketTransferBox); + + SAFE_DELETE(m_pLocalServer); + SAFE_DELETE(m_pDebugHookManager); + + // Packet handler + SAFE_DELETE(m_pPacketHandler); + + // Delete PerfStatManager + delete CClientPerfStatManager::GetSingleton(); + + // NULL the global CClientGame var + g_pClientGame = NULL; + m_bBeingDeleted = false; +} + +/* +bool CClientGame::StartGame ( void ) // for an offline game (e.g. editor) +{ + m_Status = STATUS_OFFLINE; + g_pCore->SetOfflineMod ( true ); // hide chatbox etc + g_pCore->SetConnected ( true ); // not sure, but its required :) + g_pCore->HideMainMenu (); // duh + + // If the game isn't started, start it + if ( g_pGame->GetSystemState () == 7 ) + { + g_pGame->StartGame (); + } + return true; +} +*/ + +#include +//#define _CRTDBG_CHECK_EVERY_16_DF 0x00100000 /* check heap every 16 heap ops */ +//#define _CRTDBG_CHECK_EVERY_128_DF 0x00800000 /* check heap every 128 heap ops */ +//#define _CRTDBG_CHECK_EVERY_1024_DF 0x04000000 /* check heap every 1024 heap ops */ + +void CClientGame::EnablePacketRecorder(const char* szFilename) +{ + m_pManager->GetPacketRecorder()->StartRecord(szFilename, true); +} + +void CClientGame::StartPlayback(void) +{ + // strcpy ( m_szNick, "Playback" ); + + m_bIsPlayingBack = true; + m_bFirstPlaybackFrame = true; + m_pManager->GetPacketRecorder()->SetPacketHandler(CClientGame::StaticProcessPacket); + + if (!m_pManager->IsGameLoaded()) + { + g_pGame->StartGame(); + } +} + +bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerType Type) +{ + m_ServerType = Type; + // int dbg = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ); + // dbg |= _CRTDBG_ALLOC_MEM_DF; + // dbg |= _CRTDBG_CHECK_ALWAYS_DF; + // dbg |= _CRTDBG_DELAY_FREE_MEM_DF; + // dbg |= _CRTDBG_LEAK_CHECK_DF; + //_CrtSetDbgFlag(dbg); + + // Verify that the nickname is valid + if (!IsNickValid(szNick)) + { + g_pCore->ShowMessageBox(_("Error") + _E("CD01"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + // Store our nickname + m_strLocalNick.AssignLeft(szNick, MAX_PLAYER_NICK_LENGTH); + + // Are we connected? + if (g_pNet->IsConnected() || m_bIsPlayingBack) + { + // Hide the console when connecting.. + if (g_pCore->GetConsole()->IsVisible()) + g_pCore->GetConsole()->SetVisible(false); + + // Display the status box + g_pCore->ShowMessageBox(_("CONNECTING"), _("Entering the game ..."), MB_ICON_INFO); + + // Send the initial data to the server + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Hash the password if neccessary + MD5 Password; + memset(Password.data, 0, sizeof(MD5)); + if (szPassword) + { + // Is it long enough? + size_t sizePassword = strlen(szPassword); + if (sizePassword > 0) + { + // Hash the password and put it in the struct + CMD5Hasher Hasher; + Hasher.Calculate(szPassword, sizePassword, Password); + } + } + + // Append version information + pBitStream->Write(static_cast(MTA_DM_NETCODE_VERSION)); + pBitStream->Write(static_cast(MTA_DM_VERSION)); + pBitStream->Write(static_cast(MTA_DM_BITSTREAM_VERSION)); + + SString strPlayerVersion("%d.%d.%d-%d.%05d.%d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, + MTASA_VERSION_BUILD, g_pNet->GetNetRev()); + pBitStream->WriteString(strPlayerVersion); + + pBitStream->WriteBit(g_pCore->IsOptionalUpdateInfoRequired(g_pNet->GetConnectedServer(true))); + + pBitStream->Write(static_cast(g_pGame->GetGameVersion())); + + // Append user details + SString strTemp = StringZeroPadout(m_strLocalNick, MAX_PLAYER_NICK_LENGTH); + pBitStream->Write(strTemp.c_str(), MAX_PLAYER_NICK_LENGTH); + pBitStream->Write(reinterpret_cast(Password.data), sizeof(MD5)); + + // Append community information (Removed) + std::string strUser; + pBitStream->Write(strUser.c_str(), MAX_SERIAL_LENGTH); + + // Send the packet as joindata + g_pNet->SendPacket(PACKET_ID_PLAYER_JOINDATA, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + return true; + } + } + else + { + g_pCore->ShowMessageBox(_("Error") + _E("CD02"), _("Not connected; please use Quick Connect or the 'connect' command to connect to a server."), + MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + } + + return false; +} + +void CClientGame::SetupLocalGame(eServerType Type) +{ + SString strConfig = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; + m_bWaitingForLocalConnect = true; + if (!m_pLocalServer) + m_pLocalServer = new CLocalServer(strConfig); +} + +bool CClientGame::StartLocalGame(eServerType Type, const char* szPassword) +{ + // Verify that the nickname is valid + std::string strNick; + g_pCore->GetCVars()->Get("nick", strNick); + + if (!IsNickValid(strNick.c_str())) + { + g_pCore->ShowMessageBox(_("Error") + _E("CD03"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + m_bWaitingForLocalConnect = false; + m_ServerType = Type; + SString strTemp = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; + + SAFE_DELETE(m_pLocalServer); + + // Store our nickname + m_strLocalNick.AssignLeft(strNick.c_str(), MAX_PLAYER_NICK_LENGTH); + + // Got a server? + if (m_bLocalPlay) + { + // Start the server locally + if (!m_Server.Start(strTemp)) + { + m_bWaitingForLocalConnect = true; + m_bErrorStartingLocal = true; + g_pCore->ShowMessageBox(_("Error") + _E("CD04"), _("The server is not installed"), MB_ICON_ERROR | MB_BUTTON_OK); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + if (szPassword) + m_Server.SetPassword(szPassword); + + // Display the status box<<<<< + m_OnCancelLocalGameClick = GUI_CALLBACK(&CClientGame::OnCancelLocalGameClick, this); + g_pCore->ShowMessageBox(_("Local Server"), _("Starting local server ..."), MB_BUTTON_CANCEL | MB_ICON_INFO, &m_OnCancelLocalGameClick); + } + else + { + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + // We're waiting for connection + m_bWaitingForLocalConnect = true; + return true; +} + +bool CClientGame::OnCancelLocalGameClick(CGUIElement* pElement) +{ + if (m_bLocalPlay && m_bWaitingForLocalConnect) + { + g_pCore->RemoveMessageBox(); + g_pCore->GetModManager()->RequestUnload(); + return true; + } + return false; +} + +void CClientGame::DoPulsePreFrame(void) +{ + if (m_Status == CClientGame::STATUS_JOINED) + { + if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) + { + m_pVoiceRecorder->DoPulse(); + } + } +} + +void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRenderTargets) +{ + // Allow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); + + // If appropriate, call onClientRestore + if (bDidUnminimize) + { + CLuaArguments Arguments; + Arguments.PushBoolean(bDidRecreateRenderTargets); + m_pRootEntity->CallEvent("onClientRestore", Arguments, false); + m_bWasMinimized = false; + + // Reverse any mute on minimize effects + g_pGame->GetAudio()->SetEffectsMasterVolume(g_pGame->GetSettings()->GetSFXVolume()); + g_pGame->GetAudio()->SetMusicMasterVolume(g_pGame->GetSettings()->GetRadioVolume()); + m_pManager->GetSoundManager()->SetMinimizeMuted(false); + } + + // Call onClientHUDRender LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientHUDRender", Arguments, false); + + // Disallow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); + + // Restore in case script forgets + g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); + + DebugElementRender(); +} + +void CClientGame::DoPulsePostFrame(void) +{ + TIMING_CHECKPOINT("+CClientGame::DoPulsePostFrame"); + #ifdef DEBUG_KEYSTATES + // Get the controller state + CControllerState cs; + g_pGame->GetPad()->GetCurrentControllerState(&cs); + + SString strBuffer; + strBuffer = SString::Printf( + "LeftShoulder1: %u\n" + "LeftShoulder2: %u\n" + "RightShoulder1: %u\n" + "RightShoulder2: %u\n" + "DPadUp: %u\n" + "DPadDown: %u\n" + "DPadLeft: %u\n" + "DPadRight: %u\n" + "Start: %u\n" + "Select: %u\n" + "ButtonSquare: %u\n" + "ButtonTriangle: %u\n" + "ButtonCross: %u\n" + "ButtonCircle: %u\n" + "ShockButtonL: %u\n" + "ShockButtonR: %u\n" + "PedWalk: %u\n", + cs.LeftShoulder1, cs.LeftShoulder2, cs.RightShoulder1, cs.RightShoulder2, cs.DPadUp, cs.DPadDown, cs.DPadLeft, cs.DPadRight, cs.Start, cs.Select, + cs.ButtonSquare, cs.ButtonTriangle, cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.ShockButtonR, cs.m_bPedWalk); + + g_pCore->GetGraphics()->DrawTextTTF(300, 10, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); + + strBuffer = SString::Printf( + "VehicleMouseLook: %u\n" + "LeftStickX: %u\n" + "LeftStickY: %u\n" + "RightStickX: %u\n" + "RightStickY: %u", + cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, cs.RightStickX, cs.RightStickY); + + g_pCore->GetGraphics()->DrawTextTTF(300, 320, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); + #endif + + UpdateModuleTickCount64(); + + if (m_pManager->IsGameLoaded()) + { + // Pulse the nametags before anything that changes player positions, we'll be 1 frame behind, but so is the camera + // If nametags are enabled, pulse the nametag manager + if (m_bShowNametags) + { + m_pNametags->DoPulse(); + } + + // Sync debug + m_pSyncDebug->OnPulse(); + + // Also eventually draw FPS + if (m_bShowFPS) + { + DrawFPS(); + } + + CGraphicsInterface* pGraphics = g_pCore->GetGraphics(); + unsigned int uiHeight = pGraphics->GetViewportHeight(); + unsigned int uiWidth = pGraphics->GetViewportWidth(); + + // Draw a little star in the corner if async is on + if (g_pGame->IsASyncLoadingEnabled(true)) + { + unsigned int uiPosY = g_pGame->IsASyncLoadingEnabled() ? uiHeight - 7 : uiHeight - 12; + pGraphics->DrawString(uiWidth - 5, uiPosY, 0x80ffffff, 1, "*"); + } + + // Draw notice text if dx test mode is enabled + if (g_pCore->GetGraphics()->GetRenderItemManager()->GetTestMode()) + { + unsigned int uiPosY = uiHeight - 30; + pGraphics->DrawString(uiWidth - 155, uiPosY, 0x40ffffff, 1, "dx test mode enabled"); + } + + // Draw notice text if diagnostic mode enabled + EDiagnosticDebugType diagnosticDebug = g_pCore->GetDiagnosticDebug(); + if (diagnosticDebug == EDiagnosticDebug::LOG_TIMING_0000) + { + unsigned int uiPosY = uiHeight - 30; + pGraphics->DrawString(uiWidth - 185, uiPosY, 0xffffff00, 1, "Debug setting: #0000 Log timing"); + } + + // Draw network trouble message if required + if (m_pNetAPI->IsNetworkTrouble()) + { + int iPosX = uiWidth / 2; // Half way across + int iPosY = uiHeight * 45 / 100; // 45/100 down + g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, + DT_NOCLIP | DT_CENTER); + } + + // Adjust the streaming memory limit. + unsigned int uiStreamingMemoryPrev; + g_pCore->GetCVars()->Get("streaming_memory", uiStreamingMemoryPrev); + uint uiStreamingMemory = SharedUtil::Clamp(g_pCore->GetMinStreamingMemory(), uiStreamingMemoryPrev, g_pCore->GetMaxStreamingMemory()); + if (uiStreamingMemory != uiStreamingMemoryPrev) + g_pCore->GetCVars()->Set("streaming_memory", uiStreamingMemory); + + int iStreamingMemoryBytes = static_cast(uiStreamingMemory) * 1024 * 1024; + if (g_pMultiplayer->GetLimits()->GetStreamingMemory() != iStreamingMemoryBytes) + g_pMultiplayer->GetLimits()->SetStreamingMemory(iStreamingMemoryBytes); + + // If we're in debug mode and are supposed to show task data, do it + #ifdef MTA_DEBUG + if (m_pShowPlayerTasks) + { + DrawTasks(m_pShowPlayerTasks); + } + + if (m_pShowPlayer) + { + DrawPlayerDetails(m_pShowPlayer); + } + + std::vector::const_iterator iter = m_pPlayerManager->IterBegin(); + for (; iter != m_pPlayerManager->IterEnd(); ++iter) + { + CClientPlayer* pPlayer = *iter; + if (pPlayer->IsStreamedIn() && pPlayer->IsShowingWepdata()) + DrawWeaponsyncData(pPlayer); + } + #endif + + #if defined (MTA_DEBUG) || defined (MTA_BETA) + if (m_bShowSyncingInfo) + { + // Draw the header boxz + CVector vecPosition = CVector(0.05f, 0.32f, 0); + m_pDisplayManager->DrawText2D("Syncing vehicles:", vecPosition, 1.0f, 0xFFFFFFFF); + + // Print each vehicle we're syncing + CDeathmatchVehicle* pVehicle; + list::const_iterator iter = m_pUnoccupiedVehicleSync->IterBegin(); + for (; iter != m_pUnoccupiedVehicleSync->IterEnd(); iter++) + { + vecPosition.fY += 0.03f; + pVehicle = *iter; + + SString strBuffer("ID: %u (%s)", pVehicle->GetID(), pVehicle->GetNamePointer()); + + m_pDisplayManager->DrawText2D(strBuffer, vecPosition, 1.0f, 0xFFFFFFFF); + } + } + #endif + // Heli Clear time + if (m_LastClearTime.Get() > HeliKill_List_Clear_Rate) + { + // Clear our list now + m_HeliCollisionsMap.clear(); + m_LastClearTime.Reset(); + } + + CClientPerfStatManager::GetSingleton()->DoPulse(); + } + + m_pRadarMap->DoRender(); + m_pManager->DoRender(); + DoPulses(); + + // If we're supposed to show netstat, draw them infront of everything else + if (m_bShowNetstat) + { + m_pNetworkStats->Draw(); + } +} + +void CClientGame::DoPulses(void) +{ + TIMING_CHECKPOINT("-CClientGame::DoPulsePostFrame"); + + g_pCore->ApplyFrameRateLimit(); + + TIMING_CHECKPOINT("+CClientGame::DoPulses"); + + m_BuiltCollisionMapThisFrame = false; + + if (m_bIsPlayingBack && m_bFirstPlaybackFrame && m_pManager->IsGameLoaded()) + { + g_pCore->GetConsole()->Printf("First playback frame, starting"); + m_pManager->GetPacketRecorder()->StartPlayback("log.rec", false); + m_bFirstPlaybackFrame = false; + } + + // Call debug code if debug mode + m_Foo.DoPulse(); + + // Output stuff from our internal server eventually + m_Server.DoPulse(); + + if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED && GetTickCount64_() - m_llLastTransgressionTime > 60000) + { + uint uiLevel = 0; + uint uiInform = 0; + SString strMessage; + + // Is the player a cheater? + if (!m_pManager->GetAntiCheat().PerformChecks()) + { + uiLevel = 1; + uiInform = 2; + } + else + { + strMessage = g_pNet->GetNextBuffer(); + if (strMessage.length()) + { + uiLevel = atoi(strMessage.SplitLeft(":", &strMessage)); + uiInform = atoi(strMessage.SplitLeft(":", &strMessage)); + } + } + + // Send message to the server + if (uiLevel) + { + SString strPrefix = (uiInform == 2) ? "AC" : (uiInform == 1) ? "VF" : "SD"; + SString strMessageCombo = SString("%s #%d %s", *strPrefix, uiLevel, strMessage.c_str()).TrimEnd(" "); + m_llLastTransgressionTime = GetTickCount64_(); + AddReportLog(3100, strMessageCombo + SString(" (%d)", uiInform)); + + if (uiInform > 0) + { + // The server will use the whole message as supplied here + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write(uiLevel); + pBitStream->WriteString(strMessageCombo); + g_pNet->SendPacket(PACKET_ID_PLAYER_TRANSGRESSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + else + { + // Otherwise, disconnect here + AddReportLog(7105, SString("Core - Kicked (%s)", *strMessageCombo)); + g_pCore->ShowMessageBox(_("Error") + _E("CD05"), SString(_("You were kicked from the game ( %s )"), *strMessageCombo), + MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + } + + // Send diagnostic info + if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED) + { + // Retrieve data + SString strMessage = g_pNet->GetDiagnosticStatus(); + + // Send to the server if changed + if (strMessage != m_strLastDiagnosticStatus) + { + m_strLastDiagnosticStatus = strMessage; + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->WriteString(strMessage); + g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } + + // Pulse the network interface + + // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) + DoPulses2(false); + + m_pUnoccupiedVehicleSync->DoPulse(); + m_pPedSync->DoPulse(); +#ifdef WITH_OBJECT_SYNC + m_pObjectSync->DoPulse(); +#endif + m_pLatentTransferManager->DoPulse(); + m_pLuaManager->DoPulse(); + m_pScriptDebugging->UpdateLogOutput(); + + GetModelCacheManager()->DoPulse(); + + #ifdef MTA_DEBUG + UpdateMimics(); + #endif + + // Grab the current time + unsigned long ulCurrentTime = CClientTime::GetTime(); + + // Waiting for a connect? + if (m_bWaitingForLocalConnect) + { + // Connected? + if (g_pNet->IsConnected()) + { + // No longer waiting for connect + m_bWaitingForLocalConnect = false; + + // Assume local server has the same bitstream version + g_pNet->SetServerBitStreamVersion(MTA_DM_BITSTREAM_VERSION); + + // Run the game normally. + StartGame(m_strLocalNick, m_Server.GetPassword().c_str(), m_ServerType); + } + else + { + // Going to try connecting? Do this when the internal server has booted + // and we haven't started the connecting. + if (m_Server.IsReady() && m_iLocalConnectAttempts == 0) + { + g_pCore->ShowMessageBox(_("Local Server"), _("Connecting to local server..."), MB_ICON_INFO); + + // Connect + if (g_pNet->StartNetwork("localhost", 22010)) + { + // We're waiting for connection + m_iLocalConnectAttempts = 1; + m_ulTimeStart = CClientTime::GetTime(); + } + else + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD06"), _("Error connecting to server.")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + + // Timeout? + if (m_ulTimeStart != 0 && CClientTime::GetTime() >= m_ulTimeStart + 5000) + { + // Show timeout message and disconnect + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD07"), _("Connecting to local server timed out. See console for details.")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + } + + // If the game is loaded ... + if (m_pManager->IsGameLoaded()) + { + // Pulse the blended weather manager + m_pBlendedWeather->DoPulse(); + + // If we weren't ingame last frame; call the on ingame event + if (!m_bGameLoaded) + { + // Fix for gta not being focused sometimes + SetActiveWindow(g_pCore->GetHookedWindow()); + SetFocus(g_pCore->GetHookedWindow()); + + m_bGameLoaded = true; + Event_OnIngame(); + } + + // Check if the player is hitting the enter vehicle button + DoVehicleInKeyCheck(); + + // Pulse some stuff + m_pMovingObjectsManager->DoPulse(); + + // Get rid of our deleted elements + m_ElementDeleter.DoDeleteAll(); + m_pLuaManager->ProcessPendingDeleteList(); + + // Get rid of deleted GUI elements + g_pCore->GetGUI()->CleanDeadPool(); + + // Allow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); + + // Call onClientRender LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientRender", Arguments, false); + + // Disallow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); + + // Restore in case script forgets + g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); + + // Ensure replaced/restored textures for models in the GTA map are correct + g_pGame->FlushPendingRestreamIPL(); + + // Respawn objects in respawn pool + m_ObjectRespawner.DoRespawnAll(); + } + + // Are we connecting? + if (m_Status == CClientGame::STATUS_CONNECTING) + { + if (m_bErrorStartingLocal) + { + g_pCore->GetModManager()->RequestUnload(); + return; + } + + // Timed out? + if (!m_bWaitingForLocalConnect && ulCurrentTime >= m_ulTimeStart + NET_CONNECT_TIMEOUT) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD08"), _("Connection timed out"), "connect-timed-out", true); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + else if (m_Status == CClientGame::STATUS_JOINED) + { + // Pulse DownloadFiles if we're transferring stuff + GetResourceFileDownloadManager()->DoPulse(); + DownloadSingularResourceFiles(); + GetRemoteCalls()->ProcessQueuedFiles(); + } + + // Not waiting for local connect? + if (!m_bWaitingForLocalConnect) + { + // Trigger the ingame and connected event + if (!m_bTriggeredIngameAndConnected && m_pManager->IsGameLoaded() && g_pCore->IsConnected()) + { + m_bTriggeredIngameAndConnected = true; + Event_OnIngameAndConnected(); + + // Initialize the game + g_pCore->GetGame()->Initialize(); + } + + unsigned char ucError = g_pNet->GetConnectionError(); + + // Lost connection? + if (!g_pNet->IsConnected() && !m_bGracefulDisconnect && !m_bIsPlayingBack) + { + // See if we can figure out what specifically it was + if (ucError == 0) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD09"), _("Connection with the server was lost")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + else + { + SString strError; + SString strErrorCode; + switch (ucError) + { + case RID_RSA_PUBLIC_KEY_MISMATCH: + strError = _("Disconnected: unknown protocol error"); + strErrorCode = _E("CD10"); // encryption key mismatch + break; + case RID_REMOTE_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected remotely"); + strErrorCode = _E("CD11"); + break; + case RID_REMOTE_CONNECTION_LOST: + strError = _("Disconnected: connection lost remotely"); + strErrorCode = _E("CD12"); + break; + case RID_CONNECTION_BANNED: + strError = _("Disconnected: you are banned from this server"); + strErrorCode = _E("CD13"); + break; + case RID_NO_FREE_INCOMING_CONNECTIONS: + strError = _("Disconnected: the server is currently full"); + strErrorCode = _E("CD14"); + break; + case RID_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected from the server"); + strErrorCode = _E("CD15"); + break; + case RID_CONNECTION_LOST: + strError = _("Disconnected: connection to the server was lost"); + strErrorCode = _E("CD16"); + break; + case RID_INVALID_PASSWORD: + strError = _("Disconnected: invalid password specified"); + strErrorCode = _E("CD17"); + break; + default: + strError = _("Disconnected: connection was refused"); + strErrorCode = _E("CD18"); + break; + } + + // Display an error, reset the error status and exit + g_pCore->ShowNetErrorMessageBox(_("Error") + strErrorCode, strError); + g_pNet->SetConnectionError(0); + g_pCore->GetModManager()->RequestUnload(); + } + } + + // If we're in the verificating status + if (m_Status == CClientGame::STATUS_JOINING) + { + // Time out the verification if it takes too long + if (m_ulVerifyTimeStart != 0 && ulCurrentTime >= m_ulVerifyTimeStart + CLIENT_VERIFICATION_TIMEOUT) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD19"), _("MTA Client verification failed!")); + g_pCore->GetModManager()->RequestUnload(); + } + } + } + + // Check for radar input + m_pRadarMap->DoPulse(); + g_pCore->GetGraphics()->SetAspectRatioAdjustmentSuspended(m_pRadarMap->IsRadarShowing()); + + // Got a local player? + if (m_pLocalPlayer) + { + // Network updates + UpdateVehicleInOut(); + UpdatePlayerTarget(); + UpdatePlayerWeapons(); + // UpdateTrailers (); // Test: Does it always work without this check? + UpdateStunts(); + // Clear last damager if more than 2 seconds old + if (CClientTime::GetTime() - m_ulDamageTime > 2000) + { + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageWeapon = 0xFF; + m_ucDamageBodyPiece = 0xFF; + } + DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); + } + + // Game hacks, restore certain variables + // game-speed changes after spawning + g_pGame->SetGameSpeed(m_fGameSpeed); + // money changes on death/getting into taxis + g_pGame->GetPlayerInfo()->SetPlayerMoney(m_lMoney); + // wanted to stop it changing on skin change etc + if (m_pLocalPlayer) + { + if (m_dwWanted != g_pGame->GetPlayerInfo()->GetWanted()->GetWantedLevel()) + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevelNoFlash(m_dwWanted); + } + // stop players dying from starvation + g_pGame->GetPlayerInfo()->SetLastTimeEaten(0); + // reset weapon logs (for preventing quickreload) + + // Update streaming + m_pManager->UpdateStreamers(); + + // Send screen shot data + ProcessDelayedSendList(); + + // Collect async task scheduler results + m_pAsyncTaskScheduler->CollectResults(); + + TIMING_CHECKPOINT("-CClientGame::DoPulses"); +} + +// Extrapolation test +void CClientGame::DoPulses2(bool bCalledFromIdle) +{ + bool bIsUsingAlternatePulseOrder = IsUsingAlternatePulseOrder(!bCalledFromIdle); + + // Figure out which pulses to do + bool bDoStandardPulses; + bool bDoVehicleManagerPulse; + + if (!bIsUsingAlternatePulseOrder) + { + // With std pulse order, do pulses when not called from idle + bDoStandardPulses = !bCalledFromIdle; + bDoVehicleManagerPulse = !bCalledFromIdle; + } + else + { + // With alt pulse order, do pulses when called from idle + bDoStandardPulses = bCalledFromIdle; + bDoVehicleManagerPulse = bCalledFromIdle; + + // Except when watching a remote synced vehicle + if (CClientVehicle* pTargetVehicle = DynamicCast(m_pCamera->GetTargetEntity())) + if (pTargetVehicle->GetControllingPlayer() != m_pPlayerManager->GetLocalPlayer()) + bDoVehicleManagerPulse = !bDoVehicleManagerPulse; + } + + if (bDoStandardPulses) + { + // Change to high precision so arguments in element data and events can + // be rounded to look more like what is expected + ChangeFloatPrecision(true); + + // Pulse the network interface + TIMING_CHECKPOINT("+NetPulse"); + g_pNet->DoPulse(); + TIMING_CHECKPOINT("-NetPulse"); + + // Change precision back, and check we are in low precision mode 4 sure + ChangeFloatPrecision(false); + assert(!IsHighFloatPrecision()); + } + + m_pManager->DoPulse(bDoStandardPulses, bDoVehicleManagerPulse); + + if (bDoStandardPulses) + { + m_pNetAPI->DoPulse(); + } +} + +void CClientGame::HandleException(CExceptionInformation* pExceptionInformation) +{ +} + +void CClientGame::HandleRadioNext(CControlFunctionBind*) +{ + if (g_pClientGame) + { + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); + if (pPlayer) + { + pPlayer->NextRadioChannel(); + } + } +} + +void CClientGame::HandleRadioPrevious(CControlFunctionBind*) +{ + if (g_pClientGame) + { + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); + if (pPlayer) + { + pPlayer->PreviousRadioChannel(); + } + } +} +bool CClientGame::IsNametagValid(const char* szNick) +{ + // Grab the size of the nametag. Check that it's not to long or short + size_t sizeNick = MbUTF8ToUTF16(szNick).size(); + if (sizeNick < MIN_PLAYER_NAMETAG_LENGTH || sizeNick > MAX_PLAYER_NAMETAG_LENGTH) + { + return false; + } + + // Check that each character is valid (Anything above 32) + unsigned char ucTemp; + for (size_t i = 0; i < sizeNick; i++) + { + ucTemp = szNick[i]; + if (ucTemp < 32) + { + return false; + } + } + + // nametag is valid, return true + return true; +} + +bool CClientGame::IsNickValid(const char* szNick) +{ + // Grab the size of the nick. Check that it's within the player + size_t sizeNick = strlen(szNick); + if (sizeNick < MIN_PLAYER_NICK_LENGTH || sizeNick > MAX_PLAYER_NICK_LENGTH) + { + return false; + } + + // Check that each character is valid (visible characters exluding space) + unsigned char ucTemp; + for (size_t i = 0; i < sizeNick; i++) + { + ucTemp = szNick[i]; + if (ucTemp < 33 || ucTemp > 126) + { + return false; + } + } + + // Nickname is valid, return true + return true; +} + +void CClientGame::ShowNetstat(int iCmd) +{ + bool bShow = (iCmd == 1) ? true : (iCmd == 0) ? false : !m_bShowNetstat; + + if (bShow && !m_bShowNetstat) + { + m_pNetworkStats->Reset(); + } + m_bShowNetstat = bShow; +} + +void CClientGame::ShowEaeg(bool) +{ + if (m_pLocalPlayer) + m_pLocalPlayer->SetStat(0x2329, 1.0f); +} + +#ifdef MTA_WEPSYNCDBG +void CClientGame::ShowWepdata(const char* szNick) +{ + CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); + if (pPlayer) + { + pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); + } +} +#endif + +#ifdef MTA_DEBUG + +void CClientGame::ShowWepdata(const char* szNick) +{ + CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); + if (pPlayer) + { + pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); + } +} + +void CClientGame::ShowPlayer(const char* szNick) +{ + m_pShowPlayer = m_pPlayerManager->Get(szNick); +} + +void CClientGame::ShowTasks(const char* szNick) +{ + m_pShowPlayerTasks = m_pPlayerManager->Get(szNick); +} + +void CClientGame::SetMimic(unsigned int uiMimicCount) +{ + // Check if we're within the max mimics boundary + if (uiMimicCount > MAX_MIMICS) + return; + + // Create neccessary players + while (m_Mimics.size() < uiMimicCount) + { + CClientPlayer* pPlayer = new CClientPlayer(m_pManager, static_cast(MAX_NET_PLAYERS_REAL + (int)m_Mimics.size())); + pPlayer->SetNick("Mimic"); + m_Mimics.push_back(pPlayer); + } + + // Destroy neccessary players + while (m_Mimics.size() > uiMimicCount) + { + CClientPlayer* pPlayer = m_Mimics.back(); + CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); + if (pVehicle) + delete pVehicle; + + delete pPlayer; + m_Mimics.pop_back(); + } +} + +#endif + +void CClientGame::DoVehicleInKeyCheck(void) +{ + // Grab the controller state + CControllerState cs; + g_pGame->GetPad()->GetCurrentControllerState(&cs); + static bool bButtonTriangleWasDown = false; + if (cs.ButtonTriangle) + { + if (!bButtonTriangleWasDown) + { + bButtonTriangleWasDown = true; + + // Process the hit + ProcessVehicleInOutKey(false); + } + } + else + { + bButtonTriangleWasDown = false; + } +} + +void CClientGame::UpdateVehicleInOut(void) +{ + // We got told by the server to animate into a certain vehicle? + if (m_VehicleInOutID != INVALID_ELEMENT_ID) + { + // Grab the vehicle we're getting in/out of + CDeathmatchVehicle* pInOutVehicle = static_cast(m_pVehicleManager->Get(m_VehicleInOutID)); + + // In or out? + if (m_bIsGettingOutOfVehicle) + { + // If we aren't working on leaving the car (he's eiter finished or cancelled/failed leaving) + if (!m_pLocalPlayer->IsLeavingVehicle()) + { + // Are we outside the car? + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + if (!pVehicle) + { + // Tell the server that we successfully left the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction = VEHICLE_NOTIFY_OUT; + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself out (so we're sure the records are correct) + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it, and damagable if we're syncing it + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + }*/ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + + // Reset the vehicle in out stuff so we're ready for another car entry/leave. + // Don't allow a new entry/leave until we've gotten the notify return packet + ElementID ReasonVehicleID = m_VehicleInOutID; + g_pClientGame->ResetVehicleInOut(); + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = ReasonVehicleID; + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_out"); +#endif + } + // Are we still inside the car? + else + { + // Warp us out now to keep in sync with the server + m_pLocalPlayer->RemoveFromVehicle(); + } + } + } + + // Are we getting into a vehicle? + else if (m_bIsGettingIntoVehicle) + { + // If we aren't working on entering the car (he's either finished or cancelled) + if (!m_pLocalPlayer->IsEnteringVehicle()) + { + // Is he in a vehicle now? + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + if (pVehicle) + { + // Tell the server that we successfully entered the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction; + + if (m_bIsJackingVehicle) + { + ucAction = static_cast(VEHICLE_NOTIFY_JACK); +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack"); +#endif + } + else + { + ucAction = static_cast(VEHICLE_NOTIFY_IN); +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in"); +#endif + } + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself in (so we're sure the records are correct) + pVehicle->AllowDoorRatioSetting(m_pLocalPlayer->m_ucEnteringDoor, true); + m_pLocalPlayer->WarpIntoVehicle(pVehicle, m_ucVehicleInOutSeat); + + /* + // Make it damagable + if ( pInOutVehicle ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + */ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + } + else + { + // Tell the server that we aborted entered the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction; + if (m_bIsJackingVehicle) + { + ucAction = static_cast(VEHICLE_NOTIFY_JACK_ABORT); + pBitStream->WriteBits(&ucAction, 4); + + // Did we start jacking them? + bool bAlreadyStartedJacking = false; + CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); + if (pVehicle) + { + CClientPed* pJackedPlayer = pVehicle->GetOccupant(); + if (pJackedPlayer) + { + // Jax: have we already started to jack the other player? + if (pJackedPlayer->IsGettingJacked()) + { + bAlreadyStartedJacking = true; + } + } + unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; + pBitStream->WriteBits(&ucDoor, 3); + SDoorOpenRatioSync door; + door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); + pBitStream->Write(&door); + } + pBitStream->WriteBit(bAlreadyStartedJacking); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack_abort"); +#endif + } + else + { + ucAction = static_cast(VEHICLE_NOTIFY_IN_ABORT); + pBitStream->WriteBits(&ucAction, 4); + CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); + if (pVehicle) + { + unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; + pBitStream->WriteBits(&ucDoor, 3); + SDoorOpenRatioSync door; + door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); + pBitStream->Write(&door); + } + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in_abort"); +#endif + } + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself out again (so we're sure the records are correct) + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it, and damagable if we're syncing it + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + } + */ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + } + + // Reset + // Don't allow a new entry/leave until we've gotten the notify return packet + ElementID ReasonID = m_VehicleInOutID; + ResetVehicleInOut(); + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = ReasonID; + } + } + } + else + { + // If we aren't getting jacked + if (!m_bIsGettingJacked) + { + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + + // Jax: this was commented, re-comment if it was there for a reason (..and give the reason!) + // Are we in a vehicle we aren't supposed to be in? + if (pVehicle && !pOccupiedVehicle) + { + g_pCore->GetConsole()->Print("You shouldn't be in this vehicle"); + m_pLocalPlayer->RemoveFromVehicle(); + } + + // Are we supposed to be in a vehicle? But aren't? + if (pOccupiedVehicle && !pVehicle) + { + // Jax: this happens when we try to warp into a streamed out vehicle, including when we use CClientVehicle::StreamInNow + // ..maybe we need a different way to detect bike falls? + + // Tell the server + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Vehicle id + pBitStream->Write(pOccupiedVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_NOTIFY_FELL_OFF); + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're not allowed to enter any vehicle before we get a confirm + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = pOccupiedVehicle->GetID(); + + // Remove him from the vehicle + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it + CDeathmatchVehicle* pInOutVehicle = static_cast < CDeathmatchVehicle* > ( pOccupiedVehicle ); + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + } + */ + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_fell_off"); +#endif + } + } + } + } +} + +void CClientGame::UpdatePlayerTarget(void) +{ + CControllerState ControllerState; + m_pLocalPlayer->GetControllerState(ControllerState); + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + + // Ignore the local player so we don't get hit + m_pLocalPlayer->WorldIgnore(true); + + // Run a process line of sight and look for an entity we target + CEntity* pColEntity = NULL; + CColPoint* pColPoint = NULL; + g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pColEntity); + + // Unignore the local player again + m_pLocalPlayer->WorldIgnore(false); + + // Kill the colpoint or we get a severe memoryleak + if (pColPoint) + pColPoint->Destroy(); + + if (pColEntity != m_pTargetedGameEntity) + { + m_pTargetedGameEntity = pColEntity; + + if (pColEntity) + { + m_pTargetedEntity = m_pManager->FindEntity(pColEntity); + } + else + m_pTargetedEntity = NULL; + + // Store the last targeted player's id + if (m_pTargetedEntity && m_pTargetedEntity->GetType() == CCLIENTPLAYER) + { + m_TargetedPlayerID = m_pTargetedEntity->GetID(); + } + else + m_TargetedPlayerID = INVALID_ELEMENT_ID; + + // Send the target + ElementID TargetID = INVALID_ELEMENT_ID; + if (m_pTargetedEntity && !m_pTargetedEntity->IsLocalEntity()) + { + TargetID = m_pTargetedEntity->GetID(); + } + + CBitStream bitStream; + bitStream.pBitStream->Write(TargetID); + m_pNetAPI->RPC(PLAYER_TARGET, bitStream.pBitStream); + + // Call our onClientPlayerTarget event + CLuaArguments Arguments; + if (m_pTargetedEntity) + Arguments.PushElement(m_pTargetedEntity); + else + Arguments.PushBoolean(false); + m_pLocalPlayer->CallEvent("onClientPlayerTarget", Arguments, true); + } +} + +void CClientGame::UpdatePlayerWeapons(void) +{ + // Check whether we changed weapon slots + eWeaponSlot currentSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + if (currentSlot != m_lastWeaponSlot) + { + CLuaArguments Arguments; + Arguments.PushNumber(m_lastWeaponSlot); + Arguments.PushNumber(currentSlot); + bool bCancelled = !m_pLocalPlayer->CallEvent("onClientPlayerWeaponSwitch", Arguments, true); + + if (bCancelled) + { + // Save the current ammo in clip + unsigned short usAmmoInClip = 0; + CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); + if (pWeapon) + usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); + + // Force it back to the old slot + m_pLocalPlayer->SetCurrentWeaponSlot(m_lastWeaponSlot); + + // Restore the ammo in clip that there was in that slot + if (usAmmoInClip > 0) + m_pLocalPlayer->GetWeapon()->SetAmmoInClip(usAmmoInClip); + } + else + { + CBitStream bitStream; + CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(); + NetBitStreamInterface& BitStream = *(bitStream.pBitStream); + SWeaponSlotSync slot; + + // Always send bit in case server is not in sync + if ((BitStream.Version() >= 0x44 && m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN) || BitStream.Version() >= 0x4D) + { + CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); + if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && + (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || + (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) + BitStream.WriteBit(true); + else + BitStream.WriteBit(false); + } + + if (pWeapon) + { + /* Send a packet to the server with info about the new weapon, + so the server stays in sync reliably */ + unsigned int uiSlot = static_cast(pWeapon->GetSlot()); + slot.data.uiSlot = uiSlot; + BitStream.Write(&slot); + + if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) + { + SWeaponAmmoSync ammo(pWeapon->GetType(), true, true); + ammo.data.usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); + ammo.data.usTotalAmmo = static_cast(pWeapon->GetAmmoTotal()); + BitStream.Write(&ammo); + } + } + else + { + slot.data.uiSlot = 0; + BitStream.Write(&slot); + } + + m_pNetAPI->RPC(PLAYER_WEAPON, bitStream.pBitStream); + m_lastWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + } + } +} + +void CClientGame::UpdateTrailers(void) +{ + // This function is here to re-attach trailers if they fall off + + unsigned long ulCurrentTime = GetTickCount32(); + + CClientVehicle * pVehicle = NULL, *pTrailer = NULL; + CVehicle * pGameVehicle = NULL, *pGameTrailer = NULL; + unsigned long ulIllegalTowBreakTime; + vector::const_iterator iterVehicles = m_pVehicleManager->StreamedBegin(); + for (; iterVehicles != m_pVehicleManager->StreamedEnd(); iterVehicles++) + { + pVehicle = *iterVehicles; + ulIllegalTowBreakTime = pVehicle->GetIllegalTowBreakTime(); + + // Do we have an illegal break? + if (ulIllegalTowBreakTime != 0) + { + // Has it been atleast 1 second since the break + if (ulCurrentTime > (ulIllegalTowBreakTime + 1000)) + { + // Try to re-attach them + CClientVehicle* pTowedBy = pVehicle->GetTowedByVehicle(); + if (pTowedBy) + { + // Little hack to keep illegaly detached trailers close to their tower + CVector vecPosition; + pVehicle->GetPosition(vecPosition); + pVehicle->SetPosition(vecPosition); + + pGameVehicle = pTowedBy->GetGameVehicle(); + pGameTrailer = pVehicle->GetGameVehicle(); + if (pGameVehicle && pGameTrailer) + { + // pGameTrailer->SetTowLink ( pGameVehicle ); + CVector vecRotation; + pTowedBy->GetRotationRadians(vecRotation); + pVehicle->SetRotationRadians(vecRotation); + pTowedBy->InternalSetTowLink(pVehicle); + } + } + + // Reset the break time, even if we couldnt re-attach it + pVehicle->SetIllegalTowBreakTime(0); + } + } + } +} + +void CClientGame::UpdateFireKey(void) +{ + if (m_pLocalPlayer) + { + SBindableGTAControl* pControl = g_pCore->GetKeyBinds()->GetBindableFromControl("fire"); + + // Is our 'fire' control enabled? + if (pControl->bEnabled) + { + // ** Satchel charge detonation ** + { + // Do we have a detonator in our hand? + if (m_pLocalPlayer->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_DETONATOR) + { + // Planted any satchels? + if (m_pLocalPlayer->CountProjectiles(WEAPONTYPE_REMOTE_SATCHEL_CHARGE) > 0) + { + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + + // Tell the server we want to detonate our satchels + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + g_pNet->SendPacket(PACKET_ID_DETONATE_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } + // Remove the detonator if we dont have any satchels planted + else + { + m_pLocalPlayer->RemoveWeapon(WEAPONTYPE_DETONATOR); + } + } + } + + // Has our control state been cut short? + if (!pControl->bState) + return; + + // ** Stealth kill ** + { + if (m_pLocalPlayer->IsStealthAiming()) + { + // Do we have a target ped? + CClientPed* pTargetPed = m_pLocalPlayer->GetTargetedPed(); + if (pTargetPed) + { + // Do we have a target player? + if (IS_PLAYER(pTargetPed)) + { + CClientPlayer* pTargetPlayer = static_cast(pTargetPed); + + // Is the targetted player on a team + CClientTeam* pTeam = pTargetPlayer->GetTeam(); + if (pTeam) + { + // Is this friendly-fire? + if (pTargetPlayer->IsOnMyTeam(m_pLocalPlayer) && !pTeam->GetFriendlyFire()) + { + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + return; + } + } + } + CPlayerPed* pGameTarget = static_cast(pTargetPed)->GetGamePlayer(); + if (pGameTarget) + { + // Would GTA let us stealth kill now? + if (m_pLocalPlayer->GetGamePlayer()->GetPedIntelligence()->TestForStealthKill(pGameTarget, false)) + { + // Grab our local position + CVector vecLocalPosition; + m_pLocalPlayer->GetPosition(vecLocalPosition); + + // Grab the target's position + CVector vecTargetPosition; + pTargetPed->GetPosition(vecTargetPosition); + + // Work out an angle between the players, and set this as we initiate our knife kill + float fAngle = AngleBetweenPoints2D(vecLocalPosition, vecTargetPosition); + m_pLocalPlayer->SetCurrentRotation(fAngle); + + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + CLuaArguments Arguments; + Arguments.PushElement(pTargetPed); + if (m_pLocalPlayer->CallEvent("onClientPlayerStealthKill", Arguments, false)) + { + if (pTargetPed->IsLocalEntity()) + { + CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, 4 /*WEAPONTYPE_KNIFE*/, 9 /*BODYPART_HEAD*/, true); + return; + } + + // Lets request a stealth kill + CBitStream bitStream; + bitStream.pBitStream->Write(pTargetPed->GetID()); + m_pNetAPI->RPC(REQUEST_STEALTH_KILL, bitStream.pBitStream); + } + else + { + return; + } + } + } + } + } + } + } + } +} + +void CClientGame::UpdateStunts(void) +{ + // * Two wheeler * + static unsigned long ulLastCarTwoWheelCounter = 0; + static float fLastCarTwoWheelDist = 0.0f; + unsigned long ulTemp = g_pGame->GetPlayerInfo()->GetCarTwoWheelCounter(); + // Did we start a stunt? + if (ulLastCarTwoWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("2wheeler"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastCarTwoWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("2wheeler"); + Arguments.PushNumber(ulLastCarTwoWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastCarTwoWheelCounter = ulTemp; + fLastCarTwoWheelDist = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); + + // * Wheelie * + static unsigned long ulLastBikeRearWheelCounter = 0; + static float fLastBikeRearWheelDist = 0.0f; + ulTemp = g_pGame->GetPlayerInfo()->GetBikeRearWheelCounter(); + // Did we start a stunt? + if (ulLastBikeRearWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("wheelie"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastBikeRearWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("wheelie"); + Arguments.PushNumber(ulLastBikeRearWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastBikeRearWheelCounter = ulTemp; + fLastBikeRearWheelDist = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); + + // * Stoppie * + static unsigned long ulLastBikeFrontWheelCounter = 0; + static float fLastBikeFrontWheelDist = 0.0f; + ulTemp = g_pGame->GetPlayerInfo()->GetBikeFrontWheelCounter(); + // Did we start a stunt? + if (ulLastBikeFrontWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("stoppie"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastBikeFrontWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("stoppie"); + Arguments.PushNumber(ulLastBikeFrontWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastBikeFrontWheelCounter = ulTemp; + fLastBikeFrontWheelDist = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); +} + +void CClientGame::StaticUpdateFireKey(CControlFunctionBind* pBind) +{ + g_pClientGame->UpdateFireKey(); +} + +void CClientGame::ChangeVehicleWeapon(bool bNext) +{ + if (m_pLocalPlayer && m_pLocalPlayer->GetRealOccupiedVehicle()) + { + eWeaponSlot currentWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + eWeaponSlot weaponSlot = currentWeaponSlot; + CWeapon* pWeapon = NULL; + while (!pWeapon || pWeapon->GetType() == WEAPONTYPE_UNARMED) + { + if (bNext) + { + if (weaponSlot == WEAPONSLOT_TYPE_DETONATOR) + { + weaponSlot = WEAPONSLOT_TYPE_UNARMED; + break; + } + + weaponSlot = (eWeaponSlot)(weaponSlot + 1); + + if (weaponSlot == currentWeaponSlot) + break; + + pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); + } + else + { + if (weaponSlot == WEAPONSLOT_TYPE_UNARMED) + { + if (weaponSlot != currentWeaponSlot) + break; + weaponSlot = WEAPONSLOT_TYPE_DETONATOR; + } + + weaponSlot = (eWeaponSlot)(weaponSlot - 1); + + if (weaponSlot == currentWeaponSlot) + break; + + pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); + } + } + if (pWeapon || weaponSlot == WEAPONSLOT_TYPE_UNARMED) + { + m_pLocalPlayer->SetCurrentWeaponSlot(weaponSlot); + } + } +} + +void CClientGame::ResetVehicleInOut(void) +{ + m_ulLastVehicleInOutTime = 0; + m_bIsGettingOutOfVehicle = false; + m_bIsGettingIntoVehicle = false; + m_bIsJackingVehicle = false; + m_bIsGettingJacked = false; + m_VehicleInOutID = INVALID_ELEMENT_ID; + m_ucVehicleInOutSeat = 0xFF; + m_bNoNewVehicleTask = false; + m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; + m_pGettingJackedBy = NULL; +} + +void CClientGame::SetAllDimensions(unsigned short usDimension) +{ + m_pManager->GetMarkerStreamer()->SetDimension(usDimension); + m_pManager->GetObjectStreamer()->SetDimension(usDimension); + m_pManager->GetObjectLodStreamer()->SetDimension(usDimension); + m_pManager->GetPickupStreamer()->SetDimension(usDimension); + m_pManager->GetPlayerStreamer()->SetDimension(usDimension); + m_pManager->GetRadarAreaManager()->SetDimension(usDimension); + m_pManager->GetVehicleStreamer()->SetDimension(usDimension); + m_pManager->GetRadarMarkerManager()->SetDimension(usDimension); + m_pManager->GetSoundManager()->SetDimension(usDimension); + m_pManager->GetPointLightsManager()->SetDimension(usDimension); + m_pManager->GetWaterManager()->SetDimension(usDimension); + m_pNametags->SetDimension(usDimension); + m_pCamera->SetDimension(usDimension); +} + +bool CClientGame::StaticKeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) +{ + return g_pClientGame->KeyStrokeHandler(strKey, bState, bIsConsoleInputKey); +} + +bool CClientGame::KeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) +{ + // Do we have a root yet? + if (m_pRootEntity) + { + // Ignore keydown/up pair if main menu is displayed, or console input will use the character + bool bIgnore = false; + if (bState) + { + auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; + bool isMouseKey = strKey.substr(0, 5) == "mouse"; + + if (g_pCore->IsMenuVisible() || (g_pCore->GetConsole()->IsInputActive() && bIsConsoleInputKey) || + (pFocusedBrowser && !pFocusedBrowser->IsLocal() && !isMouseKey)) + + bIgnore = true; // Ignore this keydown and the matching keyup + else + MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup + } + else + { + if (!MapContains(m_AllowKeyUpMap, strKey)) + bIgnore = true; // Ignore this keyup + else + MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup + } + + if (!bIgnore) + { + bool bAllow = true; + // Call our key-stroke event + CLuaArguments Arguments; + Arguments.PushString(strKey); + Arguments.PushBoolean(bState); + bAllow = m_pRootEntity->CallEvent("onClientKey", Arguments, false); + if (bState == true) + { + if (bAllow == false && strKey == "escape") + { + if (m_bLastKeyWasEscapeCancelled) + { + // Escape cannot be skipped twice + bAllow = true; + m_bLastKeyWasEscapeCancelled = false; + } + else + m_bLastKeyWasEscapeCancelled = true; + } + else + m_bLastKeyWasEscapeCancelled = false; + } + return bAllow; + } + } + m_bLastKeyWasEscapeCancelled = false; + return true; +} + +bool CClientGame::StaticCharacterKeyHandler(WPARAM wChar) +{ + return g_pClientGame->CharacterKeyHandler(wChar); +} + +bool CClientGame::CharacterKeyHandler(WPARAM wChar) +{ + // Do we have a root yet? + if (m_pRootEntity && g_pCore->IsMenuVisible() == false && g_pCore->GetConsole()->IsInputActive() == false) + { + // Cancel event if remote browser is focused + auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; + if (pFocusedBrowser && !pFocusedBrowser->IsLocal()) + return false; + + // Safe character? + if (wChar >= 32) + { + // Generate a null-terminating string for our character + wchar_t wUNICODE[2] = {wChar, '\0'}; + + // Convert our UTF character into an ANSI string + SString strANSI = UTF16ToMbUTF8(wUNICODE); + + // Call our character event + CLuaArguments Arguments; + Arguments.PushString(strANSI); + m_pRootEntity->CallEvent("onClientCharacter", Arguments, false); + } + } + + return false; +} + +void CClientGame::StaticProcessClientKeyBind(CKeyFunctionBind* pBind) +{ + g_pClientGame->ProcessClientKeyBind(pBind); +} + +void CClientGame::ProcessClientKeyBind(CKeyFunctionBind* pBind) +{ + m_pScriptKeyBinds->ProcessKey(pBind->boundKey->szKey, pBind->bHitState, SCRIPT_KEY_BIND_FUNCTION); +} + +void CClientGame::StaticProcessClientControlBind(CControlFunctionBind* pBind) +{ + g_pClientGame->ProcessClientControlBind(pBind); +} + +void CClientGame::ProcessClientControlBind(CControlFunctionBind* pBind) +{ + m_pScriptKeyBinds->ProcessKey(pBind->control->szControl, pBind->bHitState, SCRIPT_KEY_BIND_CONTROL_FUNCTION); +} + +void CClientGame::StaticProcessServerKeyBind(CKeyFunctionBind* pBind) +{ + g_pClientGame->ProcessServerKeyBind(pBind); +} + +void CClientGame::ProcessServerKeyBind(CKeyFunctionBind* pBind) +{ + const char* szName = pBind->boundKey->szKey; + unsigned char ucNameLength = (unsigned char)strlen(szName); + CBitStream bitStream; + bitStream.pBitStream->WriteBit(false); + bitStream.pBitStream->WriteBit(pBind->bHitState); + bitStream.pBitStream->Write(szName, ucNameLength); + m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); +} + +void CClientGame::StaticProcessServerControlBind(CControlFunctionBind* pBind) +{ + g_pClientGame->ProcessServerControlBind(pBind); +} + +void CClientGame::ProcessServerControlBind(CControlFunctionBind* pBind) +{ + const char* szName = pBind->control->szControl; + unsigned char ucNameLength = (unsigned char)strlen(szName); + CBitStream bitStream; + bitStream.pBitStream->WriteBit(true); + bitStream.pBitStream->WriteBit(pBind->bHitState); + bitStream.pBitStream->Write(szName, ucNameLength); + m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); +} + +bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + bool bCursorForcedVisible = g_pCore->IsCursorForcedVisible(); + bool bMenuVisible = g_pCore->IsMenuVisible(); + bool bConsoleVisible = g_pCore->GetConsole()->IsVisible(); + + if (bCursorForcedVisible) + { + if (!bMenuVisible && !bConsoleVisible) + { + if (m_bCursorEventsEnabled) + { + unsigned char ucButtonHit = 0xFF; + switch (uMsg) + { + case WM_LBUTTONDOWN: + ucButtonHit = 0; + break; + case WM_LBUTTONUP: + ucButtonHit = 1; + break; + case WM_MBUTTONDOWN: + ucButtonHit = 2; + break; + case WM_MBUTTONUP: + ucButtonHit = 3; + break; + case WM_RBUTTONDOWN: + ucButtonHit = 4; + break; + case WM_RBUTTONUP: + ucButtonHit = 5; + break; + } + if (ucButtonHit != 0xFF) + { + int iX = LOWORD(lParam); + int iY = HIWORD(lParam); + + CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); + + /* + // (IJs) why are these relative? it doesn't make sense + CVector2D vecCursorPosition ( ( ( float ) iX ) / vecResolution.fX, + ( ( float ) iY ) / vecResolution.fY ); + */ + + CVector2D vecCursorPosition((float)iX, (float)iY); + + CVector vecOrigin, vecTarget, vecScreen((float)iX, (float)iY, 300.0f); + g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); + + // Grab the camera position + CCamera* pCamera = g_pGame->GetCamera(); + CCam* pCam = pCamera->GetCam(pCamera->GetActiveCam()); + CMatrix matCamera; + pCamera->GetMatrix(&matCamera); + vecOrigin = matCamera.vPos; + + CColPoint* pColPoint = NULL; + CEntity* pGameEntity = NULL; + + // Grab the collision point/entity + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pGameEntity); + + CVector vecCollision; + ElementID CollisionEntityID = INVALID_ELEMENT_ID; + CClientEntity* pCollisionEntity = NULL; + if (bCollision && pColPoint) + { + vecCollision = pColPoint->GetPosition(); + if (pGameEntity) + { + CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity); + if (pEntity) + { + pCollisionEntity = pEntity; + if (!pEntity->IsLocalEntity()) + CollisionEntityID = pEntity->GetID(); + } + } + } + else + { + vecCollision = vecTarget; + } + + // Destroy the colpoint so we don't get a leak + if (pColPoint) + { + pColPoint->Destroy(); + } + + const char* szButton = NULL; + const char* szState = NULL; + switch (ucButtonHit) + { + case 0: + szButton = "left"; + szState = "down"; + break; + case 1: + szButton = "left"; + szState = "up"; + break; + case 2: + szButton = "middle"; + szState = "down"; + break; + case 3: + szButton = "middle"; + szState = "up"; + break; + case 4: + szButton = "right"; + szState = "down"; + break; + case 5: + szButton = "right"; + szState = "up"; + break; + } + if (szButton && szState) + { + if (std::isnan(vecCollision.fX)) + vecCollision.fX = 0; + if (std::isnan(vecCollision.fY)) + vecCollision.fY = 0; + if (std::isnan(vecCollision.fZ)) + vecCollision.fZ = 0; + + // Call the event for the client + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(vecCursorPosition.fX); + Arguments.PushNumber(vecCursorPosition.fY); + Arguments.PushNumber(vecCollision.fX); + Arguments.PushNumber(vecCollision.fY); + Arguments.PushNumber(vecCollision.fZ); + if (pCollisionEntity) + Arguments.PushElement(pCollisionEntity); + else + Arguments.PushBoolean(false); + m_pRootEntity->CallEvent("onClientClick", Arguments, false); + + // Send the button, cursor position, 3d position and the entity collided with + CBitStream bitStream; + + SMouseButtonSync button; + button.data.ucButton = ucButtonHit; + bitStream.pBitStream->Write(&button); + + bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fX)); + bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fY)); + + SPositionSync position(false); + position.data.vecPosition = vecCollision; + bitStream.pBitStream->Write(&position); + + if (CollisionEntityID != INVALID_ELEMENT_ID) + { + bitStream.pBitStream->WriteBit(true); + bitStream.pBitStream->Write(CollisionEntityID); + } + else + bitStream.pBitStream->WriteBit(false); + + m_pNetAPI->RPC(CURSOR_EVENT, bitStream.pBitStream); + + if (strcmp(szState, "down") == 0) + { + CVector2D vecDelta = m_vecLastCursorPosition - vecCursorPosition; + + if ((GetTickCount32() - m_ulLastClickTick) < DOUBLECLICK_TIMEOUT && vecDelta.Length() <= DOUBLECLICK_MOVE_THRESHOLD) + { + // Call the event for the client + CLuaArguments DoubleClickArguments; + DoubleClickArguments.PushString(szButton); + DoubleClickArguments.PushNumber(vecCursorPosition.fX); + DoubleClickArguments.PushNumber(vecCursorPosition.fY); + DoubleClickArguments.PushNumber(vecCollision.fX); + DoubleClickArguments.PushNumber(vecCollision.fY); + DoubleClickArguments.PushNumber(vecCollision.fZ); + if (pCollisionEntity) + DoubleClickArguments.PushElement(pCollisionEntity); + else + DoubleClickArguments.PushBoolean(false); + m_pRootEntity->CallEvent("onClientDoubleClick", DoubleClickArguments, false); + } + + m_ulLastClickTick = GetTickCount32(); + m_vecLastCursorPosition = vecCursorPosition; + } + + return true; + } + } + } + } + } + switch (uMsg) + { + case WM_MOUSEMOVE: + { + int iX = LOWORD(lParam), iY = HIWORD(lParam); + static int iPreviousX = 0, iPreviousY = 0; + if (iX != iPreviousX || iY != iPreviousY) + { + iPreviousX = iX, iPreviousY = iY; + + CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); + CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); + + CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); + g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); + + // Call the onClientCursorMove event + CLuaArguments Arguments; + Arguments.PushNumber((double)vecCursorPosition.fX); + Arguments.PushNumber((double)vecCursorPosition.fY); + Arguments.PushNumber((double)iX); + Arguments.PushNumber((double)iY); + Arguments.PushNumber((double)vecTarget.fX); + Arguments.PushNumber((double)vecTarget.fY); + Arguments.PushNumber((double)vecTarget.fZ); + m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); + } + break; + } + } + return false; +} + +CClientPlayer* CClientGame::GetClosestRemotePlayer(const CVector& vecPosition, float fMaxDistance) +{ + CClientPlayer* pClosest = NULL; + float fDistance = 0.0f, fTemp; + CVector vecTemp; + CClientPlayer* pPlayer; + vector::const_iterator iter = m_pPlayerManager->IterBegin(); + for (; iter != m_pPlayerManager->IterEnd(); ++iter) + { + pPlayer = *iter; + if (!pPlayer->IsLocalPlayer() && !pPlayer->IsDeadOnNetwork() && pPlayer->GetHealth() > 0) + { + // Ensure remote player is alive and sending position updates + ulong ulTimeSinceLastPuresync = CClientTime::GetTime() - pPlayer->GetLastPuresyncTime(); + if (ulTimeSinceLastPuresync < static_cast(g_TickRateSettings.iPureSync) * 2) + { + pPlayer->GetPosition(vecTemp); + fTemp = DistanceBetweenPoints3D(vecPosition, vecTemp); + if (fTemp < fMaxDistance) + { + if (!pClosest || fTemp < fDistance) + { + pClosest = pPlayer; + fDistance = fTemp; + } + } + } + } + } + return pClosest; +} + +void CClientGame::SetGameSpeed(float fSpeed) +{ + g_pGame->SetGameSpeed(fSpeed); + m_fGameSpeed = fSpeed; +} + +void CClientGame::SetMinuteDuration(unsigned long ulDelay) +{ + g_pGame->SetMinuteDuration(ulDelay); + m_ulMinuteDuration = ulDelay; +} + +void CClientGame::SetMoney(long lMoney, bool bInstant) +{ + g_pGame->GetPlayerInfo()->SetPlayerMoney(lMoney, bInstant); + m_lMoney = lMoney; +} + +void CClientGame::SetWanted(DWORD dwWanted) +{ + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(dwWanted); + m_dwWanted = dwWanted; +} + +void CClientGame::AddBuiltInEvents(void) +{ + // Resource events + m_Events.AddEvent("onClientResourceStart", "resource", NULL, false); + m_Events.AddEvent("onClientResourceStop", "resource", NULL, false); + + // Element events + m_Events.AddEvent("onClientElementDataChange", "name", NULL, false); + m_Events.AddEvent("onClientElementStreamIn", "", NULL, false); + m_Events.AddEvent("onClientElementStreamOut", "", NULL, false); + m_Events.AddEvent("onClientElementDestroy", "", NULL, false); + + // Player events + m_Events.AddEvent("onClientPlayerJoin", "", NULL, false); + m_Events.AddEvent("onClientPlayerQuit", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerTarget", "target", NULL, false); + m_Events.AddEvent("onClientPlayerSpawn", "team", NULL, false); + m_Events.AddEvent("onClientPlayerChangeNick", "oldNick", NULL, false); + m_Events.AddEvent("onClientPlayerVehicleEnter", "vehicle, seat", NULL, false); + m_Events.AddEvent("onClientPlayerVehicleExit", "vehicle, seat", NULL, false); + m_Events.AddEvent("onClientPlayerTask", "priority, slot, name", NULL, false); + m_Events.AddEvent("onClientPlayerWeaponSwitch", "previous, current", NULL, false); + m_Events.AddEvent("onClientPlayerStuntStart", "type", NULL, false); + m_Events.AddEvent("onClientPlayerStuntFinish", "type, time, distance", NULL, false); + m_Events.AddEvent("onClientPlayerRadioSwitch", "", NULL, false); + m_Events.AddEvent("onClientPlayerDamage", "attacker, weapon, bodypart", NULL, false); + m_Events.AddEvent("onClientPlayerWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPlayerWasted", "", NULL, false); + m_Events.AddEvent("onClientPlayerChoke", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceStart", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceStop", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoicePause", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceResumed", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerStealthKill", "target", NULL, false); + m_Events.AddEvent("onClientPlayerHitByWaterCannon", "vehicle", NULL, false); + m_Events.AddEvent("onClientPlayerHeliKilled", "heli", NULL, false); + m_Events.AddEvent("onClientPlayerPickupHit", "pickup, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPlayerPickupLeave", "pickup, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPlayerNetworkStatus", "type, ticks", NULL, false); + + // Ped events + m_Events.AddEvent("onClientPedDamage", "attacker, weapon, bodypart", NULL, false); + m_Events.AddEvent("onClientPedWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPedWasted", "", NULL, false); + m_Events.AddEvent("onClientPedChoke", "", NULL, false); + m_Events.AddEvent("onClientPedHeliKilled", "heli", NULL, false); + m_Events.AddEvent("onClientPedHitByWaterCannon", "vehicle", NULL, false); + + // Vehicle events + m_Events.AddEvent("onClientVehicleRespawn", "", NULL, false); + m_Events.AddEvent("onClientVehicleEnter", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleExit", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleStartEnter", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleStartExit", "player, seat", NULL, false); + m_Events.AddEvent("onClientTrailerAttach", "towedBy", NULL, false); + m_Events.AddEvent("onClientTrailerDetach", "towedBy", NULL, false); + m_Events.AddEvent("onClientVehicleExplode", "", NULL, false); + m_Events.AddEvent("onClientVehicleCollision", "collidedelement, damageImpulseMag, bodypart, x, y, z, velX, velY, velZ", NULL, false); + m_Events.AddEvent("onClientVehicleDamage", "attacker, weapon, loss, x, y, z, tyre", NULL, false); + m_Events.AddEvent("onClientVehicleNitroStateChange", "activated", NULL, false); + + // GUI events + m_Events.AddEvent("onClientGUIClick", "button, state, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIDoubleClick", "button, state, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIMouseDown", "button, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIMouseUp", "button, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIScroll", "element", NULL, false); + m_Events.AddEvent("onClientGUIChanged", "element", NULL, false); + m_Events.AddEvent("onClientGUIAccepted", "element", NULL, false); + // m_Events.AddEvent ( "onClientGUIClose", "element", NULL, false ); + // m_Events.AddEvent ( "onClientGUIKeyDown", "element", NULL, false ); + m_Events.AddEvent("onClientGUITabSwitched", "element", NULL, false); + m_Events.AddEvent("onClientGUIComboBoxAccepted", "element", NULL, false); + + // Input events + m_Events.AddEvent("onClientDoubleClick", "button, screenX, screenY, worldX, worldY, worldZ, element", NULL, false); + m_Events.AddEvent("onClientMouseMove", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseEnter", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseLeave", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseWheel", "", NULL, false); + m_Events.AddEvent("onClientGUIMove", "", NULL, false); + m_Events.AddEvent("onClientGUISize", "", NULL, false); + m_Events.AddEvent("onClientGUIFocus", "", NULL, false); + m_Events.AddEvent("onClientGUIBlur", "", NULL, false); + m_Events.AddEvent("onClientKey", "key, state", NULL, false); + m_Events.AddEvent("onClientCharacter", "character", NULL, false); + + // Console events + m_Events.AddEvent("onClientConsole", "text", NULL, false); + + // Chat events + m_Events.AddEvent("onClientChatMessage", "test, r, g, b", NULL, false); + + // Debug events + m_Events.AddEvent("onClientDebugMessage", "message, level, file, line", NULL, false); + + // Game events + m_Events.AddEvent("onClientPreRender", "", NULL, false); + m_Events.AddEvent("onClientHUDRender", "", NULL, false); + m_Events.AddEvent("onClientRender", "", NULL, false); + m_Events.AddEvent("onClientMinimize", "", NULL, false); + m_Events.AddEvent("onClientRestore", "", NULL, false); + + // Cursor events + m_Events.AddEvent("onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false); + m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); + + // Transfer box event + m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); + + // Marker events + m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); + + // Marker events + m_Events.AddEvent("onClientPickupHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPickupLeave", "entity, matchingDimension", NULL, false); + + // Col-shape events + m_Events.AddEvent("onClientColShapeHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientColShapeLeave", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientElementColShapeHit", "colShape, matchingDimension", NULL, false); + m_Events.AddEvent("onClientElementColShapeLeave", "colShape, matchingDimension", NULL, false); + + // Explosion events + m_Events.AddEvent("onClientExplosion", "x, y, z, type", NULL, false); + + // Projectile events + m_Events.AddEvent("onClientProjectileCreation", "creator", NULL, false); + + // Sound events + m_Events.AddEvent("onClientSoundStream", "success, length, streamName, error", NULL, false); + m_Events.AddEvent("onClientSoundFinishedDownload", "length", NULL, false); + m_Events.AddEvent("onClientSoundChangedMeta", "streamTitle", NULL, false); + m_Events.AddEvent("onClientSoundStarted", "reason", NULL, false); + m_Events.AddEvent("onClientSoundStopped", "reason", NULL, false); + m_Events.AddEvent("onClientSoundBeat", "time", NULL, false); + + // Object events + m_Events.AddEvent("onClientObjectDamage", "loss, attacker", NULL, false); + m_Events.AddEvent("onClientObjectBreak", "attacker", NULL, false); + + // Web events + m_Events.AddEvent("onClientBrowserWhitelistChange", "newPages", NULL, false); + m_Events.AddEvent("onClientBrowserCreated", "", NULL, false); + m_Events.AddEvent("onClientBrowserLoadingStart", "url, mainframe", NULL, false); + m_Events.AddEvent("onClientBrowserDocumentReady", "url", NULL, false); + m_Events.AddEvent("onClientBrowserLoadingFailed", "url, errorcode, errordescription", NULL, false); + m_Events.AddEvent("onClientBrowserNavigate", "url, isblocked", NULL, false); + m_Events.AddEvent("onClientBrowserPopup", "targeturl, openerurl, ispopup", NULL, false); + m_Events.AddEvent("onClientBrowserCursorChange", "cursor", NULL, false); + m_Events.AddEvent("onClientBrowserTooltip", "text", NULL, false); + m_Events.AddEvent("onClientBrowserInputFocusChanged", "gainedfocus", NULL, false); + m_Events.AddEvent("onClientBrowserResourceBlocked", "url, domain, reason", NULL, false); + + // Misc events + m_Events.AddEvent("onClientFileDownloadComplete", "fileName, success", NULL, false); + + m_Events.AddEvent("onClientWeaponFire", "ped, x, y, z", NULL, false); +} + +void CClientGame::DrawFPS(void) +{ + // Draw the background + float fResWidth = static_cast(g_pCore->GetGraphics()->GetViewportWidth()); + float fResHeight = static_cast(g_pCore->GetGraphics()->GetViewportHeight()); + g_pCore->GetGraphics()->DrawRectangle(0.75f * fResWidth, 0.22f * fResHeight, 0.25f * fResWidth, 0.04f * fResHeight, 0x78000000); + + static char x = 0; + static float fDisp = 0.0f; + if (x == 20) + { + x = 0; + fDisp = g_pGame->GetFPS(); + } + else + x++; + SString strBuffer("FrameRate: %4.2f\n", fDisp); + + // Print it + m_pDisplayManager->DrawText2D(strBuffer, CVector(0.76f, 0.23f, 0), 1.0f, 0xFFFFFFFF); +} + +#ifdef MTA_DEBUG + +void CClientGame::DrawTasks(CClientPlayer* pPlayer) +{ + CTask* pTask = NULL; + CTask* pSubTask = NULL; + + // Got a local player model + if (pPlayer) + { + CTaskManager* man = pPlayer->GetTaskManager(); + if (man == NULL) + return; + if ((unsigned long)man == 0xDDDDDDDD) + { + m_pDisplayManager->DrawText2D("HELP! MANAGER FUCKED", CVector(0.05f, 0.5f, 0), 1.0f); + return; + } + + // Grab the current task + SString strOutput; + SString strSubOutput; + + pTask = man->GetTask(TASK_PRIORITY_PHYSICAL_RESPONSE); + strOutput += SString("Physical Response: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_TEMP); + strOutput += SString("Event Response Temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_NONTEMP); + strOutput += SString("Event Response Non-temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_PRIMARY); + strOutput += SString("Primary: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_DEFAULT); + strOutput += SString("Default: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_ATTACK); + strOutput += SString("Secondary Attack: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_DUCK); + strOutput += SString("Secondary Duck: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_SAY); + strOutput += SString("Secondary Say: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX); + strOutput += SString("Secondary Facial Complex: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM); + strOutput += SString("Secondary Partial Anim: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_IK); + strOutput += SString("Secondary IK: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + m_pDisplayManager->DrawText2D(strOutput, CVector(0.05f, 0.5f, 0), 1.0f); + m_pDisplayManager->DrawText2D(strSubOutput, CVector(0.5f, 0.5f, 0), 1.0f); + } +} + +int iPlayerTask = 0; +void CClientGame::DrawPlayerDetails(CClientPlayer* pPlayer) +{ + // Get the info + CControllerState cs; + + pPlayer->GetControllerState(cs); + + CVector vecPosition; + pPlayer->GetPosition(vecPosition); + + float fRotation = pPlayer->GetCurrentRotation(); + float fCameraRotation = pPlayer->GetCameraRotation(); + float fHealth = pPlayer->GetHealth(); + bool bIsDucked = pPlayer->IsDucked(); + bool bWearingGoggles = pPlayer->IsWearingGoggles(); + bool bInVehicle = pPlayer->GetOccupiedVehicle() != NULL; + float fWeaponRange = 0.0f; + + unsigned char ucWeapon = 0; + unsigned char ucWeaponState = 0; + unsigned short usWeaponAmmo = 0; + CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); + if (pWeapon) + { + ucWeapon = static_cast(pWeapon->GetType()); + ucWeaponState = static_cast(pWeapon->GetState()); + usWeaponAmmo = static_cast(pWeapon->GetAmmoInClip()); + float fSkill = pPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(pWeapon->GetType())); + CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(pWeapon->GetType(), fSkill); + fWeaponRange = pWeaponInfo->GetWeaponRange(); + } + + float fAimX, fAimY; + pPlayer->GetAim(fAimX, fAimY); + const CVector& vecAimSource = pPlayer->GetAimSource(); + const CVector& vecAimTarget = pPlayer->GetAimTarget(); + unsigned char ucDrivebyAim = pPlayer->GetVehicleAimAnim(); + + g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x10DE1212, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x90DE1212, false); + + CTask* pPrimaryTask = pPlayer->GetCurrentPrimaryTask(); + int iPrimaryTask = pPrimaryTask ? pPrimaryTask->GetTaskType() : -1; + + // Copy the stuff + SString strBuffer( + "Orient:\n" + "Position: %f %f %f\n" + "Rotation/camera: %f %f\n" + "Health: %f\n" + "\n" + "Keys:\n" + "LeftShoulder1: %hi\n" + "RightShoulder1: %hi\n" + "ButtonSquare: %hi\n" + "ButtonCross: %hi\n" + "ButtonCircle: %hi\n" + "ShockButtonL: %hi\n" + "PedWalk: %hi\n" + "VehicleMouseLook: %hi\n" + "LeftStickX: %hi\n" + "LeftStickY: %hi\n" + "\n" + "Misc:\n" + "Primary task: %d\n" + "Ducked: %u\n" + "Goggles: %u\n" + "In vehicle: %u\n" + "Weapon: %u\n" + "Weapon state: %u\n" + "Weapon ammo: %u\n" + "Weapon range: %f\n" + "Aim: %f %f\n" + "Aim source: %f %f %f\n" + "Aim target: %f %f %f\n" + "Driveby aim: %u\n" + "Frozen: %u\n", + vecPosition.fX, vecPosition.fY, vecPosition.fZ, fRotation, fCameraRotation, fHealth, cs.LeftShoulder1, cs.RightShoulder1, cs.ButtonSquare, + cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.m_bPedWalk, cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, iPrimaryTask, bIsDucked, + bWearingGoggles, bInVehicle, ucWeapon, ucWeaponState, usWeaponAmmo, fWeaponRange, fAimX, fAimY, vecAimSource.fX, vecAimSource.fY, vecAimSource.fZ, + vecAimTarget.fX, vecAimTarget.fY, vecAimTarget.fZ, ucDrivebyAim, pPlayer->IsFrozen()); + + // Draw it + m_pDisplayManager->DrawText2D(strBuffer, CVector(0.45f, 0.05f, 0), 1.0f, 0xFFFFFFFF); +} + +void CClientGame::DrawWeaponsyncData(CClientPlayer* pPlayer) +{ + CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); + + if (pWeapon) + { + CVector vecSource; + CVector vecTarget; + + // red line: Draw their synced aim line + pPlayer->GetShotData(&vecSource, &vecTarget); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x10DE1212, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x90DE1212, false); + + // green line: Set muzzle as origin and perform a collision test for the target + CColPoint* pCollision; + CVector vecTemp; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecSource, &vecTarget, &pCollision, NULL); + if (pCollision) + { + if (bCollision) + { + CVector vecBullet = pCollision->GetPosition() - vecSource; + vecBullet.Normalize(); + CVector vecTarget = vecSource + (vecBullet * 200); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x1012DE12, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x9012DE12, false); + } + pCollision->Destroy(); + } + + if (m_pLocalPlayer != pPlayer) + { + // Draw information about their weapon state, total ammo and ammo in clip + CVector vecScreenPosition; + CVector vecPosition; + + pPlayer->GetPosition(vecPosition); + + vecPosition.fZ += 1.0f; + g_pCore->GetGraphics()->CalcScreenCoors(&vecPosition, &vecScreenPosition); + + SString strTemp; + int yoffset; + + yoffset = 0; + strTemp.Format("Ammo in clip: %d", pWeapon->GetAmmoInClip()); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + + yoffset = 15; + strTemp.Format("State: %d", pWeapon->GetState()); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + } + } +} + +void CClientGame::UpdateMimics(void) +{ + // Got a local player? + if (m_pLocalPlayer) + { + unsigned char ucWeaponType = 0; + unsigned char ucWeaponState = 0; + unsigned long ulWeaponAmmoInClip = 0; + eWeaponSlot weaponSlot = WEAPONSLOT_TYPE_UNARMED; + + CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(m_pLocalPlayer->GetCurrentWeaponSlot()); + if (pPlayerWeapon) + { + ucWeaponType = static_cast(pPlayerWeapon->GetType()); + ucWeaponState = static_cast(pPlayerWeapon->GetState()); + weaponSlot = pPlayerWeapon->GetSlot(); + ulWeaponAmmoInClip = pPlayerWeapon->GetAmmoInClip(); + } + + // Simulate lag (or not) + if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) + { + m_ulLastMimicLag = CClientTime::GetTime(); + + // Grab the local data + CControllerState Controller; + m_pLocalPlayer->GetControllerState(Controller); + CVector vecPosition; + m_pLocalPlayer->GetPosition(vecPosition); + float fRotation = m_pLocalPlayer->GetCurrentRotation(); + CVector vecMoveSpeed; + m_pLocalPlayer->GetMoveSpeed(vecMoveSpeed); + float fHealth = m_pLocalPlayer->GetHealth(); + float fArmor = m_pLocalPlayer->GetArmor(); + float fCameraRotation = g_pGame->GetCamera()->GetCameraRotation(); + bool bDucked = m_pLocalPlayer->IsDucked(); + bool bWearingGoggles = m_pLocalPlayer->IsWearingGoggles(true); + bool bHasJetpack = m_pLocalPlayer->HasJetPack(); + bool bChoking = m_pLocalPlayer->IsChoking(); + bool bSunbathing = m_pLocalPlayer->IsSunbathing(); + bool bDoingDriveby = m_pLocalPlayer->IsDoingGangDriveby(); + bool bStealthAiming = m_pLocalPlayer->IsStealthAiming(); + + // Is the current weapon goggles (44 or 45) or a camera (43), or a detonator (40), don't apply the fire key + if (weaponSlot == 11 || weaponSlot == 12 || ucWeaponType == 43) + Controller.ButtonCircle = 0; + + CClientVehicle* pVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + unsigned int uiSeat = m_pLocalPlayer->GetOccupiedVehicleSeat(); + + CShotSyncData* pShotSync = g_pMultiplayer->GetLocalShotSyncData(); + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + float fAimX = pShotSync->m_fArmDirectionX; + float fAimY = pShotSync->m_fArmDirectionY; + char cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; + bool bAkimboUp = g_pMultiplayer->GetAkimboTargetUp(); + + /* + static CClientMarker *pOriginCorona = NULL, *pTargetCorona = NULL; + if ( pOriginCorona == NULL ) + { + pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); + pOriginCorona->SetColor ( 0, 255, 0, 255 ); + pOriginCorona->SetSize ( 0.5f ); + } + else + pOriginCorona->SetPosition ( vecOrigin ); + + if ( pTargetCorona == NULL ) + { + pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); + pTargetCorona->SetColor ( 255, 0, 0, 255 ); + pTargetCorona->SetSize ( 0.5f ); + } + else + pTargetCorona->SetPosition ( vecTarget );*/ + + // Apply this to each of our mimic players + unsigned int uiMimicIndex = 0; + list::const_iterator iterMimics = m_Mimics.begin(); + for (; iterMimics != m_Mimics.end(); ++iterMimics, ++uiMimicIndex) + { + vecPosition.fX += 4.0f; + vecOrigin.fX += 4.0f; + vecTarget.fX += 4.0f; + + CClientPlayer* pMimic = *iterMimics; + + pMimic->SetHealth(fHealth); + pMimic->LockHealth(fHealth); + pMimic->SetArmor(fArmor); + pMimic->LockArmor(fArmor); + pMimic->SetWearingGoggles(bWearingGoggles); + pMimic->SetHasJetPack(bHasJetpack); + pMimic->SetChoking(bChoking); + pMimic->SetSunbathing(bSunbathing); + pMimic->SetDoingGangDriveby(bDoingDriveby); + pMimic->SetStealthAiming(bStealthAiming); + + Controller.ShockButtonL = 0; + + if (m_bMimicLag) + { + pMimic->SetTargetPosition(vecPosition, TICK_RATE); + pMimic->SetMoveSpeed(vecMoveSpeed); + pMimic->SetControllerState(Controller); + pMimic->SetTargetRotation(fRotation); + pMimic->SetCameraRotation(fCameraRotation); + pMimic->Duck(bDucked); + } + else + { + pMimic->SetPosition(vecPosition); + pMimic->SetMoveSpeed(vecMoveSpeed); + pMimic->SetTargetRotation(fRotation); + pMimic->SetCameraRotation(fCameraRotation); + pMimic->SetControllerState(Controller); + pMimic->Duck(bDucked); + } + + if (ucWeaponType != 0) + { + if (ucWeaponType == 44 || ucWeaponType == 45) + { + Controller.ButtonCircle = 0; + } + + if (m_bMimicLag) + { + pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); + pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); + + pMimic->AddChangeWeapon(TICK_RATE, weaponSlot, (unsigned char)ulWeaponAmmoInClip); + } + else + { + CWeapon* pPlayerWeapon = pMimic->GetWeapon(); + eWeaponType eCurrentWeapon = static_cast(ucWeaponType); + if ((pPlayerWeapon && pPlayerWeapon->GetType() != eCurrentWeapon) || !pPlayerWeapon) + { + pPlayerWeapon = pMimic->GiveWeapon(eCurrentWeapon, ulWeaponAmmoInClip); + if (pPlayerWeapon) + { + pPlayerWeapon->SetAsCurrentWeapon(); + } + } + + if (pPlayerWeapon) + { + pPlayerWeapon->SetAmmoTotal(9999); + pPlayerWeapon->SetAmmoInClip(ulWeaponAmmoInClip); + pPlayerWeapon->SetState(static_cast(ucWeaponState)); + } + pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); + pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); + } + } + else + { + pMimic->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); + } + + CClientVehicle* pMimicVehicle = pMimic->GetOccupiedVehicle(); + if (pVehicle) + { + unsigned int uiModel; + CVector vecPosition, vecRotationDegrees; + CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; + float fHealth; + + uiModel = pVehicle->GetModel(); + pVehicle->GetPosition(vecPosition); + pVehicle->GetRotationDegrees(vecRotationDegrees); + pVehicle->GetMoveSpeed(vecMoveSpeed); + pVehicle->GetTurnSpeed(vecTurnSpeed); + fHealth = pVehicle->GetHealth(); + + if (pMimicVehicle && pMimicVehicle->GetModel() != uiModel) + { + delete pMimicVehicle; + pMimicVehicle = NULL; + } + + vecPosition.fX += ((float)(uiMimicIndex + 1) * 10.0f); + + if (pMimicVehicle == NULL) + { + pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, uiModel, 0, 0); + pMimicVehicle->SetPosition(vecPosition); + + const SSlotStates& usUpgrades = pVehicle->GetUpgrades()->GetSlotStates(); + for (unsigned char uc = 0; uc < VEHICLE_UPGRADE_SLOTS; uc++) + { + if (usUpgrades[uc]) + { + pMimicVehicle->GetUpgrades()->AddUpgrade(usUpgrades[uc], true); + } + } + + m_vecLastMimicPos = vecPosition; + } + + if (m_bMimicLag) + { + pMimicVehicle->SetTargetPosition(vecPosition, TICK_RATE); + pMimicVehicle->SetTargetRotation(vecRotationDegrees, TICK_RATE); + pMimicVehicle->SetMoveSpeed(vecMoveSpeed); + pMimicVehicle->SetTurnSpeed(vecTurnSpeed); + } + else + { + pMimicVehicle->SetPosition(vecPosition); + pMimicVehicle->SetRotationDegrees(vecRotationDegrees); + pMimicVehicle->SetMoveSpeed(vecMoveSpeed); + pMimicVehicle->SetTurnSpeed(vecTurnSpeed); + } + pMimicVehicle->SetHealth(fHealth); + if (pMimic->GetOccupiedVehicle() != pMimicVehicle) + pMimic->WarpIntoVehicle(pMimicVehicle, uiSeat); + + unsigned int uiTrailerLoop = 0; + CClientVehicle* pTrailer = pVehicle->GetTowedVehicle(); + CClientVehicle* pMimicTrailer = NULL; + while (pTrailer) + { + uiModel = pTrailer->GetModel(); + pTrailer->GetPosition(vecPosition); + pTrailer->GetRotationDegrees(vecRotationDegrees); + pTrailer->GetMoveSpeed(vecMoveSpeed); + pTrailer->GetTurnSpeed(vecTurnSpeed); + fHealth = pTrailer->GetHealth(); + + pMimicTrailer = DynamicCast(CElementIDs::GetElement(static_cast(450 + uiMimicIndex + uiTrailerLoop))); + + if (pMimicTrailer && pMimicTrailer->GetModel() != uiModel) + { + delete pMimicTrailer; + pMimicTrailer = NULL; + } + + if (!pMimicTrailer) + { + pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, + static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); + pMimicVehicle->SetTowedVehicle(pMimicTrailer); + } + + pTrailer = pTrailer->GetTowedVehicle(); + pMimicTrailer = pMimicTrailer->GetTowedVehicle(); + uiTrailerLoop++; + } + if (pMimicTrailer) + { + if (pMimicTrailer->GetTowedByVehicle()) + { + pMimicTrailer->GetTowedByVehicle()->SetTowedVehicle(NULL); + } + } + } + else if (pMimicVehicle) + { + pMimic->RemoveFromVehicle(); + delete pMimicVehicle; + } + } + } + } +} + +void CClientGame::DoPaintballs(void) +{ + if (m_pLocalPlayer) + { + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + + CColPoint* pCollision = NULL; + CEntity* pCollisionEntity = NULL; + m_pLocalPlayer->WorldIgnore(true); + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionEntity); + m_pLocalPlayer->WorldIgnore(false); + + static list paintBalls; + if (paintBalls.size() >= 5) + { + CClientMarker* pCorona = paintBalls.back(); + delete pCorona; + paintBalls.pop_back(); + } + + CClientMarker* pCorona = new CClientMarker(m_pManager, INVALID_ELEMENT_ID, CClientMarker::MARKER_CORONA); + paintBalls.push_front(pCorona); + pCorona->SetSize(0.2f); + if (bCollision && pCollision) + { + pCorona->SetPosition(pCollision->GetPosition()); + pCorona->SetColor(SColorRGBA(255, 0, 0, 255)); + } + else + { + pCorona->SetPosition(vecTarget); + pCorona->SetColor(SColorRGBA(255, 255, 0, 255)); + } + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + } +} + +#endif + +void CClientGame::QuitPlayer(CClientPlayer* pPlayer, eQuitReason Reason) +{ + // Get the nick pointer and echo the quit message to the chat + const char* szNick = pPlayer->GetNick(); + const char* szReason = "Unknown"; + switch (Reason) + { + case QUIT_QUIT: + szReason = "Quit"; + break; + case QUIT_KICK: + szReason = "Kicked"; + break; + case QUIT_BAN: + szReason = "Banned"; + break; + case QUIT_CONNECTION_DESYNC: + szReason = "Bad Connection"; + break; + case QUIT_TIMEOUT: + szReason = "Timed Out"; + break; + } + + // In debug, make sure we don't look at this player's details +#ifdef MTA_DEBUG + if (m_pShowPlayer == pPlayer) + { + m_pShowPlayer = NULL; + } +#endif + + // Call our onClientPlayerQuit event + CLuaArguments Arguments; + Arguments.PushString(szReason); + pPlayer->CallEvent("onClientPlayerQuit", Arguments, true); + + // Detach the camera from this player if we're watching them + m_pManager->GetCamera()->UnreferencePlayer(pPlayer); + + // Was this player jacking us? + if (m_bIsGettingJacked && m_pGettingJackedBy == pPlayer) + { + ResetVehicleInOut(); + m_pLocalPlayer->RemoveFromVehicle(false); + m_pLocalPlayer->SetVehicleInOutState(VEHICLE_INOUT_NONE); + } + + // Delete the player + delete pPlayer; +} + +void CClientGame::Event_OnIngame(void) +{ + // Unpause the game + g_pGame->Pause(false); + + // Disable parts of the Hud + CHud* pHud = g_pGame->GetHud(); + pHud->SetComponentVisible(HUD_HELP_TEXT, false); + pHud->SetComponentVisible(HUD_VITAL_STATS, false); + pHud->SetComponentVisible(HUD_AREA_NAME, false); + + g_pMultiplayer->DeleteAndDisableGangTags(); + + // Switch off peds and traffic + SFixedArray vecs = {CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), + CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0)}; + g_pGame->GetPathFind()->SwitchRoadsOffInArea(&vecs[0], &vecs[1]); + g_pGame->GetPathFind()->SwitchPedRoadsOffInArea(&vecs[2], &vecs[3]); + g_pGame->GetPathFind()->SetPedDensity(0.0f); + g_pGame->GetPathFind()->SetVehicleDensity(0.0f); + + g_pGame->GetWorld()->ClearRemovedBuildingLists(); + g_pGame->GetWorld()->SetOcclusionsEnabled(true); + + g_pGame->ResetModelLodDistances(); + g_pGame->ResetAlphaTransparencies(); + + // Make sure we can access all areas + g_pGame->GetStats()->ModifyStat(CITIES_PASSED, 2.0); + + // This is to prevent the 'white arrows in checkpoints' bug (#274) + g_pGame->Get3DMarkers()->CreateMarker(87654, (e3DMarkerType)5, &vecs[4], 1, 0.2f, 0, 0, 0, 0); + + // Stop us getting 4 stars if we visit the SF or LV + // g_pGame->GetPlayerInfo()->GetWanted()->SetMaximumWantedLevel ( 0 ); + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(0); + + // Reset anything from last game + ResetMapInfo(); + g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level + g_pGame->GetWaterManager()->SetWaterDrawnLast(true); + m_pCamera->SetCameraClip(true, true); + + // Create a local player for us + m_pLocalPlayer = new CClientPlayer(m_pManager, m_LocalID, true); + if (m_pLocalPlayer) + { + // Set our parent the root entity + m_pLocalPlayer->SetParent(m_pRootEntity); + + // Give the local player our nickname + m_pLocalPlayer->SetNick(m_strLocalNick); + + // Freeze the player at some location we won't see + m_pLocalPlayer->SetHealth(100); + m_pLocalPlayer->SetPosition(CVector(0, 0, 0)); + m_pLocalPlayer->SetFrozen(true); + m_pLocalPlayer->ResetInterpolation(); + + // Reset him + m_pLocalPlayer->ResetStats(); + } + else + { + RaiseFatalError(2); + } + + // Make sure we never get tired + g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true); + + // Tell doggy we got the game running + WatchDogCompletedSection("L1"); +} + +void CClientGame::Event_OnIngameAndConnected(void) +{ + m_ulVerifyTimeStart = CClientTime::GetTime(); + + // Keep criminal records of how many times they've connected to servers + SetApplicationSettingInt("times-connected", GetApplicationSettingInt("times-connected") + 1); + if (m_ServerType == SERVER_TYPE_EDITOR) + SetApplicationSettingInt("times-connected-editor", GetApplicationSettingInt("times-connected-editor") + 1); + + // Notify the server telling we're ingame + m_pNetAPI->RPC(PLAYER_INGAME_NOTICE); +} + +bool CClientGame::StaticBreakTowLinkHandler(CVehicle* pTowingVehicle) +{ + return g_pClientGame->BreakTowLinkHandler(pTowingVehicle); +} + +void CClientGame::StaticDrawRadarAreasHandler(void) +{ + g_pClientGame->DrawRadarAreasHandler(); +} + +bool CClientGame::StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent) +{ + return g_pClientGame->DamageHandler(pDamagePed, pEvent); +} + +void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart) +{ + g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart); +} + +void CClientGame::StaticFireHandler(CFire* pFire) +{ + g_pClientGame->FireHandler(pFire); +} + +void CClientGame::StaticRender3DStuffHandler(void) +{ + g_pClientGame->Render3DStuffHandler(); +} + +void CClientGame::StaticPreRenderSkyHandler(void) +{ + g_pClientGame->PreRenderSkyHandler(); +} + +void CClientGame::StaticRenderHeliLightHandler() +{ + g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); +} + +bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) +{ + return g_pClientGame->ChokingHandler(ucWeaponType); +} + +void CClientGame::StaticCAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) +{ + g_pClientGame->CAnimBlendAssocDestructorHandler(pThis); +} + +CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) +{ + return g_pClientGame->AddAnimationHandler(pClump, animGroup, animID); +} + +CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, + AssocGroupId animGroup, AnimationId animID) +{ + return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); +} + +bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) +{ + return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); +} + +bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, + int* pFlags, RpClump* pClump) +{ + return g_pClientGame->BlendAnimationHierarchyHandler(pAnimAssoc, pOutAnimHierarchy, pFlags, pClump); +} + +void CClientGame::StaticPreWorldProcessHandler(void) +{ + g_pClientGame->PreWorldProcessHandler(); +} + +void CClientGame::StaticPostWorldProcessHandler(void) +{ + g_pClientGame->PostWorldProcessHandler(); +} + +void CClientGame::StaticPreFxRenderHandler(void) +{ + g_pCore->OnPreFxRender(); +} + +void CClientGame::StaticPreHudRenderHandler(void) +{ + g_pCore->OnPreHUDRender(); +} + +bool CClientGame::StaticProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) +{ + return g_pClientGame->ProcessCollisionHandler(pThisInterface, pOtherInterface); +} + +bool CClientGame::StaticVehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, + float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, + CVector vecCollisionVelocity) +{ + return g_pClientGame->VehicleCollisionHandler(pCollidingVehicle, pCollidedVehicle, iModelIndex, fDamageImpulseMag, fCollidingDamageImpulseMag, usPieceType, + vecCollisionPos, vecCollisionVelocity); +} + +bool CClientGame::StaticVehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, + const CVector& vecDamagePos, uchar ucTyre) +{ + return g_pClientGame->VehicleDamageHandler(pVehicleInterface, fLoss, pAttackerInterface, weaponType, vecDamagePos, ucTyre); +} + +bool CClientGame::StaticHeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) +{ + return g_pClientGame->HeliKillHandler(pHeliInterface, pHitInterface); +} + +bool CClientGame::StaticObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) +{ + return g_pClientGame->ObjectDamageHandler(pObjectInterface, fLoss, pAttackerInterface); +} + +bool CClientGame::StaticObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) +{ + return g_pClientGame->ObjectBreakHandler(pObjectInterface, pAttackerInterface); +} + +bool CClientGame::StaticWaterCannonHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) +{ + return g_pClientGame->WaterCannonHitHandler(pCannonVehicle, pHitPed); +} + +bool CClientGame::StaticVehicleFellThroughMapHandler(CVehicleSAInterface* pVehicle) +{ + return g_pClientGame->VehicleFellThroughMapHandler(pVehicle); +} + +void CClientGame::StaticGameObjectDestructHandler(CEntitySAInterface* pObject) +{ + g_pClientGame->GameObjectDestructHandler(pObject); +} + +void CClientGame::StaticGameVehicleDestructHandler(CEntitySAInterface* pVehicle) +{ + g_pClientGame->GameVehicleDestructHandler(pVehicle); +} + +void CClientGame::StaticGamePlayerDestructHandler(CEntitySAInterface* pPlayer) +{ + g_pClientGame->GamePlayerDestructHandler(pPlayer); +} + +void CClientGame::StaticGameProjectileDestructHandler(CEntitySAInterface* pProjectile) +{ + g_pClientGame->GameProjectileDestructHandler(pProjectile); +} + +void CClientGame::StaticGameModelRemoveHandler(ushort usModelId) +{ + g_pClientGame->GameModelRemoveHandler(usModelId); +} + +void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) +{ + if (pGameEntity) + { + // Map to client entity and pass to the texture replacer + CClientEntity* pClientEntity = g_pClientGame->GetGameEntityXRefManager()->FindClientEntity(pGameEntity); + if (pClientEntity) + { + int iTypeMask; + ushort usModelId = 0xFFFF; + switch (pClientEntity->GetType()) + { + case CCLIENTPED: + case CCLIENTPLAYER: + iTypeMask = TYPE_MASK_PED; + usModelId = (ushort) static_cast(pClientEntity)->GetModel(); + break; + case CCLIENTVEHICLE: + iTypeMask = TYPE_MASK_VEHICLE; + break; + case CCLIENTOBJECT: + iTypeMask = TYPE_MASK_OBJECT; + break; + default: + iTypeMask = TYPE_MASK_OTHER; + break; + } + g_pGame->GetRenderWare()->SetRenderingClientEntity(pClientEntity, usModelId, iTypeMask); + return; + } + } + + g_pGame->GetRenderWare()->SetRenderingClientEntity(NULL, 0xFFFF, TYPE_MASK_WORLD); +} + +void CClientGame::StaticTaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) +{ + g_pClientGame->TaskSimpleBeHitHandler(pPedAttacker, hitBodyPart, hitBodySide, weaponId); +} + +void CClientGame::StaticFxSystemDestructionHandler(void* pFxSAInterface) +{ + g_pClientGame->GetManager()->GetEffectManager()->SAEffectDestroyed(pFxSAInterface); +} + +AnimationId CClientGame::StaticDrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId) +{ + return g_pClientGame->DrivebyAnimationHandler(animGroup, animId); +} + +void CClientGame::DrawRadarAreasHandler(void) +{ + m_pRadarAreaManager->DoPulse(); +} + +bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle) +{ + CClientVehicle* pVehicle = m_pVehicleManager->Get(pTowedVehicle, false); + if (pVehicle) + { + // Check if this is a legal break + bool bLegal = ((pVehicle->GetControllingPlayer() == m_pLocalPlayer) || (m_pUnoccupiedVehicleSync->Exists(static_cast(pVehicle)))); + + // Not a legal break? + if (!bLegal) + { + // Save the time it broke (used in UpdateTrailers) + pVehicle->SetIllegalTowBreakTime(GetTickCount32()); + } + } + + // Allow it to break + return true; +} + +void CClientGame::FireHandler(CFire* pFire) +{ + // Disable spreading fires + pFire->SetNumGenerationsAllowed(0); +} + +void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) +{ + if (pProjectile->IsLocal()) + { + // Did the local player create this projectile? + if (m_pLocalPlayer && pProjectile->GetCreator() == m_pLocalPlayer) + { + // Physics says our projectile should start off at our velocity + CVector vecVelocity, vecPlayerVelocity; + pProjectile->GetVelocity(vecVelocity); + m_pLocalPlayer->GetMoveSpeed(vecPlayerVelocity); + vecVelocity += vecPlayerVelocity; + pProjectile->SetVelocity(vecVelocity); + } + + SendProjectileSync(pProjectile); + } + + // Renew the interior and dimension + if (pProjectile->GetCreator()) + { + pProjectile->SetInterior(pProjectile->GetCreator()->GetInterior()); + pProjectile->SetDimension(pProjectile->GetCreator()->GetDimension()); + } + + // Validate the projectile for our element tree + pProjectile->SetParent(m_pRootEntity); + + // Call our creation event + CLuaArguments Arguments; + Arguments.PushElement(pProjectile->GetCreator()); + pProjectile->CallEvent("onClientProjectileCreation", Arguments, true); +} + +void CClientGame::Render3DStuffHandler(void) +{ +} + +void CClientGame::PreRenderSkyHandler(void) +{ + g_pCore->GetGraphics()->GetRenderItemManager()->PreDrawWorld(); +} + +void CClientGame::PreWorldProcessHandler(void) +{ +} + +void CClientGame::PostWorldProcessHandler(void) +{ + m_pManager->GetMarkerManager()->DoPulse(); + m_pManager->GetPointLightsManager()->DoPulse(); + m_pManager->GetObjectManager()->DoPulse(); + + // Update frame time slice + uint uiCurrentTick = GetTickCount32(); + if (m_uiLastFrameTick) + { + m_uiFrameTimeSlice = uiCurrentTick - m_uiLastFrameTick; + m_uiFrameCount++; + + // Call onClientPreRender LUA event + CLuaArguments Arguments; + Arguments.PushNumber(m_uiFrameTimeSlice); + m_pRootEntity->CallEvent("onClientPreRender", Arguments, false); + } + m_uiLastFrameTick = uiCurrentTick; +} + +void CClientGame::IdleHandler(void) +{ + // If we are minimized we do the pulsing here + if (g_pCore->IsWindowMinimized()) + { + if (!m_bWasMinimized) + { + m_bWasMinimized = true; + // Call onClientMinimize LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); + + bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); + + // Apply mute on minimize options + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) + g_pGame->GetAudio()->SetMusicMasterVolume(0); + + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) + g_pGame->GetAudio()->SetEffectsMasterVolume(0); + + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) + m_pManager->GetSoundManager()->SetMinimizeMuted(true); + } + } + + // Ensure dummy progress graphic will be displayed when using alt pulse order + g_pCore->SetDummyProgressUpdateAlways(true); + + // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) + DoPulses2(true); + + g_pCore->SetDummyProgressUpdateAlways(false); +} + +bool CClientGame::ChokingHandler(unsigned char ucWeaponType) +{ + if (!m_pLocalPlayer) + return true; + CLuaArguments Arguments; + Arguments.PushNumber(ucWeaponType); + return m_pLocalPlayer->CallEvent("onClientPlayerChoke", Arguments, true); +} + +void CClientGame::CAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) +{ + // printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID); + RemoveAnimationAssociationFromMap(pThis); +} + +CAnimBlendAssociationSAInterface* CClientGame::AddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) +{ + // printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); + return nullptr; +} + +CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, + AssocGroupId animGroup, AnimationId animID) +{ + // printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); + return nullptr; +} + +bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) +{ + bool isCustomAnimationToPlay = false; + CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); + auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); + auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); + auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); + auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); + + CClientPed* pClientPed = GetClientPedByClump(*pClump); + if (pClientPed != nullptr) + { + auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); + if (pReplacedAnimation != nullptr) + { + std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); + InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); + + // Play our custom animation instead of default + auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); + pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); + pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); + pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); + isCustomAnimationToPlay = true; + } + } + + if (!isCustomAnimationToPlay) + { + auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); + + // Play default internal animation + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); + } + return isCustomAnimationToPlay; +} + +bool CClientGame::BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags, + RpClump* pClump) +{ + bool isCustomAnimationToPlay = false; + CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); + CClientPed* pClientPed = GetClientPedByClump(*pClump); + if (pClientPed != nullptr) + { + if (pClientPed->IsNextAnimationCustom()) + { + std::shared_ptr pIFP = pClientPed->GetCustomAnimationIFP(); + if (pIFP) + { + const SString& strAnimationName = pClientPed->GetNextAnimationCustomName(); + auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy(strAnimationName); + if (pCustomAnimBlendHierarchy != nullptr) + { + std::shared_ptr pIFPAnimations = pIFP->GetIFPAnimationsPointer(); + InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); + + pClientPed->SetCurrentAnimationCustom(true); + pClientPed->SetNextAnimationNormal(); + + if (pIFP->IsUnloading()) + { + pClientPed->DereferenceCustomAnimationBlock(); + } + *pOutAnimHierarchy = pCustomAnimBlendHierarchy; + isCustomAnimationToPlay = true; + return isCustomAnimationToPlay; + } + } + } + + pClientPed->SetCurrentAnimationCustom(false); + pClientPed->SetNextAnimationNormal(); + } + return isCustomAnimationToPlay; +} + +bool CClientGame::ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) +{ + if (pThisInterface == pOtherInterface) + return true; + + if (!m_BuiltCollisionMapThisFrame) + { + // Build a map of CPhysicalSAInterface*/CClientEntity*'s that have collision disabled + m_BuiltCollisionMapThisFrame = true; + m_CachedCollisionMap.clear(); + + std::map::iterator iter = m_AllDisabledCollisions.begin(); + for (; iter != m_AllDisabledCollisions.end(); ++iter) + { + CClientEntity* pEntity = iter->first; + CEntity* pGameEntity = pEntity->GetGameEntity(); + CEntitySAInterface* pInterface = pGameEntity ? pGameEntity->GetInterface() : NULL; + + if (pInterface) + m_CachedCollisionMap[pInterface] = pEntity; + } + } + + // Check both elements appear in the cached map before doing extra processing + std::map::iterator iter1 = m_CachedCollisionMap.find((CEntitySAInterface*)pThisInterface); + if (iter1 != m_CachedCollisionMap.end()) + { + std::map::iterator iter2 = m_CachedCollisionMap.find((CEntitySAInterface*)pOtherInterface); + if (iter2 != m_CachedCollisionMap.end()) + { + // Re-get the entity pointers using a safer method + CEntity* pGameEntity = g_pGame->GetPools()->GetEntity((DWORD*)pThisInterface); + CEntity* pGameColEntity = g_pGame->GetPools()->GetEntity((DWORD*)pOtherInterface); + + if (pGameEntity && pGameColEntity) + { + CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity, true); + CClientEntity* pColEntity = m_pManager->FindEntity(pGameColEntity, true); + + if (pEntity && pColEntity) + { + #if MTA_DEBUG + CClientEntity* ppThisEntity2 = iter1->second; + CClientEntity* ppOtherEntity2 = iter2->second; + // These should match, but its not essential. + assert(ppThisEntity2 == pEntity); + assert(ppOtherEntity2 == pColEntity); + #endif + if (!pEntity->IsCollidableWith(pColEntity)) + return false; + } + } + } + } + + return true; +} + +// +// On demand files +// +void CClientGame::DownloadSingularResourceFiles(void) +{ + if (!IsTransferringSingularFiles()) + return; + + if (!g_pNet->IsConnected()) + return; + + CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES); + if (!pHTTP->ProcessQueuedFiles()) + { + // Downloading + } + else + { + // Can't clear list until all files have been processed + if (m_pSingularFileDownloadManager->AllComplete()) + { + SetTransferringSingularFiles(false); + m_pSingularFileDownloadManager->ClearList(); + } + } +} + +// Get relevant death anim for animation purposes during death situation +void GetDeathAnim(CClientPed* pDamagedPed, CEventDamage* pEvent, AssocGroupId& outAnimGroup, AnimationId& outAnimID) +{ + if (pEvent) + { + pEvent->ComputeDeathAnim(pDamagedPed->GetGamePlayer(), false); + outAnimGroup = pEvent->GetAnimGroup(); + outAnimID = pEvent->GetAnimId(); + } + else + { + // Using same numbers as CClientGame::DoWastedCheck defaults + outAnimGroup = 0; + outAnimID = 15; + } +} + +// +// DamageHandler seems to be called 3 times for each bit of damage: +// +// pass 1 - preApplyDamage +// is pass 1 if: fDamage == zero && fCurrentHealth == fPreviousHealth +// returning false stops any damage being inflicted +// returning true applies damage and allows pass 2 +// pass 2 - postApplyDamage/preApplyAnim +// is pass 2 if: fDamage > zero && fCurrentHealth != fPreviousHealth +// returning false stops damage anim +// returning true allows damage anim and allows pass 3 +// pass 3 - postApplyAnim +// is pass 3 if: fDamage > zero && fCurrentHealth == fPreviousHealth +// returning false ?? +// returning true ?? +// +bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) +{ + // CEventDamage::AffectsPed: This is/can be called more than once for each bit of damage (and may not actually take any more health (even if we return + // true)) + + // Grab some data from the event + CEntity* pInflictor = pEvent->GetInflictingEntity(); + eWeaponType weaponUsed = pEvent->GetWeaponUsed(); + ePedPieceTypes hitZone = pEvent->GetPedPieceType(); + CWeaponInfo* pWeaponInfo = g_pGame->GetWeaponInfo(weaponUsed); + float fDamage = pEvent->GetDamageApplied(); + EDamageReasonType damageReason = pEvent->GetDamageReason(); + + /* Causes too much desync right now + // Is this shotgun damage? + if ( weaponUsed == WEAPONTYPE_SHOTGUN || weaponUsed == WEAPONTYPE_SPAS12_SHOTGUN ) + { + // Make the ped fall down + pEvent->MakePedFallDown (); + } */ + + // Grab the damaged ped + CClientPed* pDamagedPed = NULL; + if (pDamagePed) + pDamagedPed = m_pPedManager->Get(dynamic_cast(pDamagePed), true, true); + + // Grab the inflictor + CClientEntity* pInflictingEntity = NULL; + if (pInflictor) + pInflictingEntity = m_pManager->FindEntity(pInflictor, true); + + // If the damage was caused by an explosion + if (weaponUsed == WEAPONTYPE_EXPLOSION) + { + CClientEntity* pLastExplosionCreator = m_pManager->GetExplosionManager()->m_pLastCreator; + + // If we don't have an inflictor, look for the last explosion creator + if (!pInflictor && pLastExplosionCreator) + pInflictingEntity = pLastExplosionCreator; + + // Change the weapon used to whatever created the explosion + weaponUsed = m_pManager->GetExplosionManager()->m_LastWeaponType; + } + + // Do we have a damaged ped? + if (pDamagedPed) + { + /////////////////////////////////////////////////////////////////////////// + // + // Pass 1 stuff + // + // return false to stop any damage being inflicted + // + /////////////////////////////////////////////////////////////////////////// + + // Pass 1 checks for double shots + if (fDamage == 0.0f && damageReason != EDamageReason::PISTOL_WHIP) + { + // Only check for remote players + CClientPlayer* pInflictingPlayer = DynamicCast(pInflictingEntity); + if (pInflictingPlayer && !pInflictingPlayer->IsLocalPlayer()) + { + bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon + bool bBulletSyncWeapon = GetWeaponTypeUsesBulletSync(weaponUsed); + + if (bBulletSyncShot) + { + if (g_iDamageEventLimit == 0) + { + AddReportLog(5501, SString("2nd pass 1 for BulletSyncShot damage. weaponUsed:%d", weaponUsed)); + return false; + } + g_iDamageEventLimit--; + if (!bBulletSyncWeapon) + { + AddReportLog(5502, SString("BulletSyncShot but not bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); + return false; + } + } + else + { + if (bBulletSyncWeapon) + { + AddReportLog(5503, SString("not BulletSyncShot but bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); + return false; + } + } + } + } + + // Is the damaged ped a player? + if (IS_PLAYER(pDamagedPed)) + { + CClientPlayer* pDamagedPlayer = static_cast(pDamagedPed); + + // Do we have an inflicting entity? + if (pInflictingEntity) + { + // Grab the inflicting player + CClientPlayer* pInflictingPlayer = NULL; + + switch (pInflictingEntity->GetType()) + { + case CCLIENTPLAYER: + { + pInflictingPlayer = static_cast(pInflictingEntity); + break; + } + case CCLIENTVEHICLE: + { + CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); + if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) + { + CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); + if (pPed && pPed->GetType() == CCLIENTPLAYER) + pInflictingPlayer = static_cast(pPed); + } + break; + } + default: + break; + } + if (pInflictingPlayer) + { + // Is the damaged player on a team + CClientTeam* pTeam = pDamagedPlayer->GetTeam(); + if (pTeam) + { + // Is this friendly-fire from a team-mate? + if (pDamagedPlayer->IsOnMyTeam(pInflictingPlayer) && !pTeam->GetFriendlyFire() && pDamagedPlayer != pInflictingPlayer) + return false; + } + } + } + } + /////////////////////////////////////////////////////////////////////////// + // Pass 1 end + /////////////////////////////////////////////////////////////////////////// + + return ApplyPedDamageFromGame(weaponUsed, fDamage, hitZone, pDamagedPed, pInflictingEntity, pEvent); + } + + // No damage anim for fire + if (weaponUsed == WEAPONTYPE_FLAMETHROWER) + return false; + + // Allow the damage processing to continue + return true; +} + +// +// Check GTA stored health with our stored health and do stuff +// +bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, uchar hitZone, CClientPed* pDamagedPed, CClientEntity* pInflictingEntity, + CEventDamage* pEvent) +{ + float fPreviousHealth = pDamagedPed->m_fHealth; + float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); + float fPreviousArmor = pDamagedPed->m_fArmor; + float fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); + + // Have we taken any damage here? + if ((fPreviousHealth != fCurrentHealth || fPreviousArmor != fCurrentArmor) && fDamage != 0.0f) + { + /////////////////////////////////////////////////////////////////////////// + /// + // Pass 2 stuff - (GTA has applied the damage) + // + // return false to stop damage anim (incl. death task) + // + /////////////////////////////////////////////////////////////////////////// + + g_fApplyDamageLastAmount = fDamage; + g_ucApplyDamageLastHitZone = hitZone; + g_pApplyDamageLastDamagedPed = pDamagedPed; + + CLuaArguments Arguments; + if (pInflictingEntity) + Arguments.PushElement(pInflictingEntity); + else + Arguments.PushBoolean(false); + Arguments.PushNumber(static_cast(weaponUsed)); + Arguments.PushNumber(static_cast(hitZone)); + Arguments.PushNumber(fDamage); + + // Call our event + if ((IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPlayerDamage", Arguments, true)) || + (!IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPedDamage", Arguments, true))) + { + // Stop here if they cancelEvent it + if (pDamagedPed->IsLocalPlayer()) + { + // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) + fPreviousHealth = pDamagedPed->m_fHealth; + fPreviousArmor = pDamagedPed->m_fArmor; + } + pDamagedPed->GetGamePlayer()->SetHealth(fPreviousHealth); + pDamagedPed->GetGamePlayer()->SetArmor(fPreviousArmor); + return false; + } + + if (pDamagedPed->IsLocalPlayer()) + { + // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) + fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); + fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); + } + + bool bIsBeingShotWhilstAiming = (weaponUsed >= WEAPONTYPE_PISTOL && weaponUsed <= WEAPONTYPE_MINIGUN && pDamagedPed->IsUsingGun()); + bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); + + bool bAllowChoke = true; + // Is this is a remote player? + if (!pDamagedPed->IsLocalPlayer()) + { + // Don't allow GTA to start the choking task + if (weaponUsed == WEAPONTYPE_TEARGAS || weaponUsed == WEAPONTYPE_SPRAYCAN || weaponUsed == WEAPONTYPE_EXTINGUISHER) + bAllowChoke = false; + } + + // Check if their health or armor is locked, and if so prevent applying the damage locally + if (pDamagedPed->IsHealthLocked() || pDamagedPed->IsArmorLocked()) + { + // Restore health+armor + pDamagedPed->GetGamePlayer()->SetHealth(pDamagedPed->GetHealth()); + pDamagedPed->GetGamePlayer()->SetArmor(pDamagedPed->GetArmor()); + + if (bOldBehaviour) + { + // Don't play the animation if it's going to be a death one, or if it's going to interrupt aiming + if (fCurrentHealth == 0.0f || bIsBeingShotWhilstAiming) + return false; + + // Allow animation for remote players (if currently we don't need block choke) + return bAllowChoke; + } + + // No hit animation for remote players + return false; + } + + // Update our stored health/armor + pDamagedPed->m_fHealth = fCurrentHealth; + pDamagedPed->m_fArmor = fCurrentArmor; + + ElementID damagerID = INVALID_ELEMENT_ID; + if (pInflictingEntity && !pInflictingEntity->IsLocalEntity()) + damagerID = pInflictingEntity->GetID(); + + // Is it the local player? + if (pDamagedPed->IsLocalPlayer()) + { + // Update our stored damage stuff + m_ucDamageWeapon = static_cast(weaponUsed); + m_ucDamageBodyPiece = static_cast(hitZone); + m_pDamageEntity = pInflictingEntity; + m_ulDamageTime = CClientTime::GetTime(); + m_DamagerID = damagerID; + m_bDamageSent = false; + } + // Does this damage kill the player? + if (fCurrentHealth == 0.0f) + { + if (pDamagedPed->GetType() == CCLIENTPLAYER) + { + // Is the local player dying? + if (pDamagedPed->IsLocalPlayer() && fPreviousHealth > 0.0f) + { + // Grab our death animation + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + + // Check if we're dead + DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); + } + + // Allow GTA to kill us if we've fell to our death + if (pDamagedPed->IsLocalPlayer() && weaponUsed == WEAPONTYPE_FALL) + return true; + + // Don't let GTA start the death task + return false; + } + else + { + if (pDamagedPed->IsLocalEntity() && fPreviousHealth > 0.0f) + { + // Client-side ped + pDamagedPed->CallEvent("onClientPedWasted", Arguments, true); + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + pDamagedPed->Kill(weaponUsed, hitZone, false, false, animGroup, animID); + return true; + } + if (fPreviousHealth > 0.0f) + { + // Grab our death animation + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + + SendPedWastedPacket(pDamagedPed, damagerID, weaponUsed, hitZone, animGroup, animID); + } + } + } + + // Disallow choke task if it's necessary + if (!bAllowChoke) + return false; + + // Inhibit hit-by-gun animation for local player if required + if (bOldBehaviour) + if (pDamagedPed->IsLocalPlayer() && bIsBeingShotWhilstAiming) + return false; + + /////////////////////////////////////////////////////////////////////////// + // Pass 2 end + /////////////////////////////////////////////////////////////////////////// + } + + // No damage anim for fire + if (weaponUsed == WEAPONTYPE_FLAMETHROWER) + return false; + + // Allow the damage processing to continue + return true; +} + +void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, unsigned char ucBodyPart) +{ + CClientPed* pKilledPed = m_pPedManager->Get(dynamic_cast(pKilledPedSA), true, true); + + if (!pKilledPed) + return; + + // Not required for remote players. Local player is handled in DoPulses->DoWastedCheck + if (IS_PLAYER(pKilledPed)) + return; + + // Set the health to zero (this is safe as GTA will do it anyway in a few ticks) + pKilledPed->SetHealth(0.0f); + + // Call Lua + CLuaArguments Arguments; + Arguments.PushBoolean(false); + Arguments.PushNumber(ucDeathReason); + Arguments.PushNumber(ucBodyPart); + + pKilledPed->CallEvent("onClientPedWasted", Arguments, true); + + // Notify the server + SendPedWastedPacket(pKilledPed, INVALID_ELEMENT_ID, ucDeathReason, ucBodyPart); +} + +bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, + float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) +{ + if (pCollidingVehicle && pCollidedWith) + { + CVehicle* pColliderVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidingVehicle); + CClientEntity* pVehicleClientEntity = m_pManager->FindEntity(pColliderVehicle, true); + if (pVehicleClientEntity) + { + CClientVehicle* pClientVehicle = static_cast(pVehicleClientEntity); + + CEntity* pCollidedWithEntity = g_pGame->GetPools()->GetEntity((DWORD*)pCollidedWith); + CClientEntity* pCollidedWithClientEntity = NULL; + if (pCollidedWithEntity) + { + if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pCollidedWithVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithVehicle, true); + } + else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_OBJECT) + { + CObject* pCollidedWithObject = g_pGame->GetPools()->GetObject((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithObject, true); + } + else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pCollidedWithPed = g_pGame->GetPools()->GetPed((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithPed, true); + } + } + CLuaArguments Arguments; + if (pCollidedWithClientEntity) + { + Arguments.PushElement(pCollidedWithClientEntity); + } + else + { + Arguments.PushNil(); + } + Arguments.PushNumber(fDamageImpulseMag); + Arguments.PushNumber(usPieceType); + Arguments.PushNumber(vecCollisionPos.fX); + Arguments.PushNumber(vecCollisionPos.fY); + Arguments.PushNumber(vecCollisionPos.fZ); + Arguments.PushNumber(vecCollisionVelocity.fX); + Arguments.PushNumber(vecCollisionVelocity.fY); + Arguments.PushNumber(vecCollisionVelocity.fZ); + Arguments.PushNumber(fCollidingDamageImpulseMag); + Arguments.PushNumber(iModelIndex); + + pVehicleClientEntity->CallEvent("onClientVehicleCollision", Arguments, true); + // Alocate a BitStream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + // Make sure it created + if (pBitStream) + { + if (pBitStream->Version() >= 0x028) + { + // Sync Stuff + // if it's not a local vehicle + it collided with the local player + if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) + { + // is it below the anti spam threshold? + if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) + { + // if there is no controlling player + if (!pClientVehicle->GetControllingPlayer()) + { + CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); + // if We aren't already syncing the vehicle + if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) + { + // Write the vehicle ID + pBitStream->Write(pVehicleClientEntity->GetID()); + // Send! + g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, + PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); + // Reset our push time + pClientVehicle->ResetLastPushTime(); + } + } + } + } + } + g_pNet->DeallocateNetBitStream(pBitStream); + } + return true; + } + } + return false; +} + +bool CClientGame::HeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) +{ + if (pHeliInterface && pHitInterface) + { + // Get our heli and client heli + CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); + CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); + if (pHeli && pClientHeli && pClientHeli->AreHeliBladeCollisionsEnabled()) + { + // Get our ped and client ped + CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitInterface); + CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); + // Was our client ped valid + if (pClientPed) + { + // Get our heli and client heli + CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); + CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); + + // Iterate our "stored" cancel state and find the heli in question + std::pair::iterator, std::multimap::iterator> iterators = + m_HeliCollisionsMap.equal_range(pClientHeli); + std::multimap::const_iterator iter = iterators.first; + for (; iter != iterators.second; ++iter) + { + // If the Heli and ped collided within the clear rate return false + if ((*iter).first == pClientHeli && (*iter).second == pClientPed) + return false; + } + + CLuaArguments Arguments; + if (pClientHeli) + { + // Push our heli + Arguments.PushElement(pClientHeli); + } + else + { + Arguments.PushNil(); + } + + // Trigger our event + bool bContinue; + if (IS_PLAYER(pClientPed)) + bContinue = pClientPed->CallEvent("onClientPlayerHeliKilled", Arguments, true); + else + bContinue = pClientPed->CallEvent("onClientPedHeliKilled", Arguments, true); + + // Was our event cancelled + if (!bContinue) + { + // Add our heli and ped pair to the list + std::pair pair = std::pair(pClientHeli, pClientPed); + m_HeliCollisionsMap.insert(pair); + } + // Return if it was cancelled + return bContinue; + } + } + else + { + return false; + } + } + return true; +} + +bool CClientGame::VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, + const CVector& vecDamagePos, uchar ucTyre) +{ + bool bAllowDamage = true; + CClientVehicle* pClientVehicle = GetGameEntityXRefManager()->FindClientVehicle(pVehicleInterface); + if (pClientVehicle) + { + CClientEntity* pClientAttacker = GetGameEntityXRefManager()->FindClientEntity(pAttackerInterface); + + // Compose arguments + // attacker, weapon, loss, damagepos, tyreIdx + CLuaArguments Arguments; + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + if (weaponType != WEAPONTYPE_INVALID) + Arguments.PushNumber(weaponType); + else + Arguments.PushNil(); + Arguments.PushNumber(fLoss); + Arguments.PushNumber(vecDamagePos.fX); + Arguments.PushNumber(vecDamagePos.fY); + Arguments.PushNumber(vecDamagePos.fZ); + if (ucTyre != UCHAR_INVALID_INDEX) + Arguments.PushNumber(ucTyre); + else + Arguments.PushNil(); + + if (!pClientVehicle->CallEvent("onClientVehicleDamage", Arguments, true)) + { + bAllowDamage = false; + } + } + + return bAllowDamage; +} + +bool CClientGame::ObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) +{ + if (pObjectInterface) + { + // Get our object and client object + CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); + CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); + + // Is our client vehicle valid? + if (pClientObject) + { + CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); + CClientEntity* pClientAttacker = NULL; + if (pAttacker) + { + if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); + } + else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerPed); + } + } + + CLuaArguments Arguments; + Arguments.PushNumber(fLoss); + + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + + return pClientObject->CallEvent("onClientObjectDamage", Arguments, true); + } + } + return true; +} + +bool CClientGame::ObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) +{ + if (pObjectInterface) + { + // Get our object and client object + CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); + CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); + + // Is our client vehicle valid? + if (pClientObject) + { + if (!pClientObject->IsBreakable(false)) + return false; + + // Apply to MTA's "internal storage", too + pClientObject->SetHealth(0.0f); + + CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); + CClientEntity* pClientAttacker = NULL; + if (pAttacker) + { + if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); + } + else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerPed); + } + } + + CLuaArguments Arguments; + + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + + return pClientObject->CallEvent("onClientObjectBreak", Arguments, true); + } + } + return true; +} + +bool CClientGame::WaterCannonHitHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) +{ + if (pCannonVehicle && pHitPed) + { + // Get our vehicle and client vehicle + CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCannonVehicle); + CClientVehicle* pCannonClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); + // Was our client vehicle valid + if (pCannonClientVehicle) + { + // Get our ped and client ped + CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitPed); + CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); + + CLuaArguments Arguments; + if (pClientPed) + { + // Push our ped + Arguments.PushElement(pClientPed); + } + else + { + Arguments.PushNil(); + } + + // Trigger our event + bool bContinue = true; + if (!IS_PLAYER(pClientPed)) + bContinue = pCannonClientVehicle->CallEvent("onClientPedHitByWaterCannon", Arguments, true); + else + bContinue = pCannonClientVehicle->CallEvent("onClientPlayerHitByWaterCannon", Arguments, true); + + // Return if it was cancelled + return bContinue; + } + } + return false; +} + +bool CClientGame::VehicleFellThroughMapHandler(CVehicleSAInterface* pVehicleInterface) +{ + if (pVehicleInterface) + { + // Get our vehicle and client vehicle + CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pVehicleInterface); + CClientVehicle* pClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); + if (pClientVehicle) + { + // handle or don't + return pClientVehicle->OnVehicleFallThroughMap(); + } + } + // unhandled + return false; +} + +// Validate known objects +void CClientGame::GameObjectDestructHandler(CEntitySAInterface* pObject) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pObject); +} + +void CClientGame::GameVehicleDestructHandler(CEntitySAInterface* pVehicle) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pVehicle); +} + +void CClientGame::GamePlayerDestructHandler(CEntitySAInterface* pPlayer) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pPlayer); +} + +void CClientGame::GameProjectileDestructHandler(CEntitySAInterface* pProjectile) +{ + CClientProjectile* pClientProjectile = m_pManager->GetProjectileManager()->Get(pProjectile); + // Happens when destroyElement is called rather than letting the projectile expire + // Normal code path is destruction from CProjectileSAInterface -> CProjectileSA -> CClientProjectile + // destroyElement is CClientProjectile -> CProjectileSA -> CProjectileSAInterface + // which means the CClientProjectile element is deleted when we get here + if (pClientProjectile) + CStaticFunctionDefinitions::DestroyElement(*pClientProjectile); +} + +void CClientGame::GameModelRemoveHandler(ushort usModelId) +{ + m_pGameEntityXRefManager->OnGameModelRemove(usModelId); +} + +void CClientGame::TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) +{ + bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); + if (bOldBehaviour) + return; + + CClientPed* pClientPedAttacker = DynamicCast(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedAttacker)); + + // Make sure cause was networked ped + if (pClientPedAttacker && !pClientPedAttacker->IsLocalEntity()) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write((ushort)TASK_SIMPLE_BE_HIT); + pBitStream->Write(pClientPedAttacker->GetID()); + pBitStream->Write((uchar)hitBodyPart); + pBitStream->Write((uchar)hitBodySide); + pBitStream->Write((uchar)weaponId); + g_pNet->SendPacket(PACKET_ID_PED_TASK, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +bool CClientGame::StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (g_pClientGame) + { + return g_pClientGame->ProcessMessage(hwnd, uMsg, wParam, lParam); + } + + return false; +} + +bool CClientGame::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (ProcessMessageForCursorEvents(hwnd, uMsg, wParam, lParam)) + { + return true; + } + + return false; +} + +void CClientGame::ProcessVehicleInOutKey(bool bPassenger) +{ + // Are we already sending an in/out request or not allowed to create a new in/out? + if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? + || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) + || m_bIsGettingJacked // Make sure we're not currently getting carjacked && + || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... + || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... + || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon + ) + { + return; + } + + // Reset the "is jacking" bit + m_bIsJackingVehicle = false; + + // Got a local player model? + if (!m_pLocalPlayer) + { + // No local player. Stop. + return; + } + + // If the player is in a vehicle we need to leave the vehicle. + CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + if (pOccupiedVehicle) + { + // Only let us leave the vehicle if: + // - we press F (as driver) + // - we press either F or G as a passenger + if (bPassenger && m_pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + // Driver pressed G, so stop. + return; + } + + // We're about to exit a vehicle + // Send an in request + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!pBitStream) + { + return; + } + + // Write the vehicle id to it and that we're requesting to get out of it + pBitStream->Write(pOccupiedVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_REQUEST_OUT); + pBitStream->WriteBits(&ucAction, 4); + + unsigned char ucDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pLocalPlayer->GetGamePlayer(), pOccupiedVehicle->GetGameVehicle()); + if (ucDoor >= 2 && ucDoor <= 5) + { + ucDoor -= 2; + pBitStream->WriteBits(&ucDoor, 2); + } + + // Send and destroy it + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're now exiting a vehicle + m_bIsGettingOutOfVehicle = true; + m_ulLastVehicleInOutTime = CClientTime::GetTime(); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_out"); +#endif + return; + } + + // + // We're going to enter a vehicle + // + + // If the Jump task is playing and we are in water - I know right + // Kill the task. + // + CTask* pTask = m_pLocalPlayer->GetCurrentPrimaryTask(); + if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter + { + CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, nullptr, nullptr, 20.0f); + if (pVehicle && + (pVehicle->IsInWater() || + m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) + { + m_pLocalPlayer->KillTask(3, true); // Kill jump task if we are about to warp in + } + } + + // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle' + // task will replace it and fuck it up! + // + if (m_pLocalPlayer->GetCurrentPrimaryTask()) + { + // We already have a primary task, so stop. + return; + } + + // Are we holding the aim_weapon key? + SBindableGTAControl* pBind = g_pCore->GetKeyBinds()->GetBindableFromControl("aim_weapon"); + if (pBind && pBind->bState) + { + // Stop because the player is probably using rshift + f/g + return; + } + + if (m_pLocalPlayer->IsClimbing() // Make sure we're not currently climbing + || m_pLocalPlayer->HasJetPack() // Make sure we don't have a jetpack + || m_pLocalPlayer->IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway + || m_pLocalPlayer->IsRunningAnimation() // Make sure we aren't running an animation + ) + { + return; + } + + // Grab the closest vehicle + unsigned int uiDoor = 0; + CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, &uiDoor, nullptr, 20.0f); + unsigned int uiSeat = uiDoor; + + if (bPassenger && uiDoor == 0) + { + // We're trying to enter as a passenger, yet our closest door + // is the driver's door. Force an enter for the passenger seat. + uiSeat = 1; + } + else if (!bPassenger) + { + // We want to drive. Force our seat to the driver's seat. + uiSeat = 0; + } + + if (!pVehicle || !pVehicle->IsEnterable()) + { + // Stop if there isn't a vehicle, or the vehicle is not enterable + return; + } + + // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly) + if (pVehicle->GetVehicleType() == CLIENTVEHICLE_BOAT && m_pLocalPlayer->GetContactEntity() != pVehicle) + { + return; + } + + // Call the onClientVehicleStartEnter event for remote players + // Local player triggered before sending packet in CClientGame + CLuaArguments Arguments; + Arguments.PushElement(m_pLocalPlayer); // player + Arguments.PushNumber(uiSeat); // seat + Arguments.PushNumber(uiDoor); // Door + + if (!pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true)) + { + // Event has been cancelled + return; + } + + // Send an in request + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!pBitStream) + { + return; + } + + // Write the vehicle id to it and that we're requesting to get into it + pBitStream->Write(pVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_REQUEST_IN); + unsigned char ucSeat = static_cast(uiSeat); + bool bIsOnWater = pVehicle->IsOnWater(); + unsigned char ucDoor = static_cast(uiDoor); + pBitStream->WriteBits(&ucAction, 4); + pBitStream->WriteBits(&ucSeat, 4); + pBitStream->WriteBit(bIsOnWater); + pBitStream->WriteBits(&ucDoor, 3); + + // Send and destroy it + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're now entering a vehicle + m_bIsGettingIntoVehicle = true; + m_ulLastVehicleInOutTime = CClientTime::GetTime(); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_in"); +#endif +} + +// Shot compensation (Jax): +// Positions the local player where he should of been on the shooting player's screen when he +// fired remotely. (the position we !reported! around the time he shot) +bool bShotCompensation = true; + +// Temporary pointers for pre- and post-functions +CVector vecWeaponFirePosition, vecRemoteWeaponFirePosition; +CPlayerPed* pWeaponFirePed = NULL; + +bool CClientGame::PreWeaponFire(CPlayerPed* pPlayerPed, bool bStopIfUsingBulletSync) +{ + pWeaponFirePed = pPlayerPed; + + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pWeaponFirePed) + { + CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); + + // Get the CClientNetPlayer class with the specified player ped + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(pWeaponFirePed, true); + + // Move both players to where they should be for shot compensation + if (pPlayer && !pPlayer->IsLocalPlayer()) + { + if (bStopIfUsingBulletSync && pPlayer->IsCurrentWeaponUsingBulletSync()) + return false; // Don't apply shot compensation & tell caller to not do bullet trace + + if (bShotCompensation) + { + if (!pVehicle || pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + // Warp back in time to where we were when this player shot (their latency) + + // We don't account for interpolation here, +250ms seems to work better + // ** Changed ajustment to +125ms as the position of this clients player on the firers screen + // has been changed. See CClientPed::UpdateTargetPosition() ** + CVector vecPosition; + unsigned short usLatency = (pPlayer->GetLatency() + 125); + g_pClientGame->m_pNetAPI->GetInterpolation(vecPosition, usLatency); + + // Move the entity back + if (pVehicle) + { + pVehicle->GetPosition(vecWeaponFirePosition); + pVehicle->SetPosition(vecPosition, false, false); + } + else + { + pLocalPlayer->GetPosition(vecWeaponFirePosition); + pLocalPlayer->SetPosition(vecPosition, false, false); + } + } + } + } + } + return true; +} + +void CClientGame::PostWeaponFire(void) +{ + // Send bullet sync with local damage info + if (g_bBulletFireVectorsValid) + { + g_bBulletFireVectorsValid = false; + CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer) + { + eWeaponType weaponType = pLocalPlayer->GetCurrentWeaponType(); + if (g_pClientGame->GetWeaponTypeUsesBulletSync(weaponType)) + { + g_pClientGame->GetNetAPI()->SendBulletSyncFire(weaponType, g_vecBulletFireStartPosition, g_vecBulletFireEndPosition, g_fApplyDamageLastAmount, + g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); + } + } + } + + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pWeaponFirePed) + { + CClientPed* pPed = g_pClientGame->GetPedManager()->Get(pWeaponFirePed, true, true); + if (pPed) + { + if (pPed->GetType() == CCLIENTPLAYER) + { + if (bShotCompensation) + { + // Restore compensated positions + if (!pPed->IsLocalPlayer()) + { + CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); + if (!pVehicle) + { + pLocalPlayer->SetPosition(vecWeaponFirePosition, false, false); + } + else if (pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + pVehicle->SetPosition(vecWeaponFirePosition, false, false); + } + } + } + } + + // Call some events + CWeapon* pWeapon = pPed->GetWeapon(); + if (pWeapon) + { + CVector vecCollision; + CClientEntity* pCollisionEntity = NULL; + + if (pPed->GetBulletImpactData(&pCollisionEntity, &vecCollision) == false) + { + CShotSyncData* pShotsyncData = pPed->m_shotSyncData; + CVector vecOrigin, vecTarget; + pPed->GetShotData(&vecOrigin, &vecTarget); + + CColPoint* pCollision = NULL; + CEntity* pCollisionGameEntity = NULL; + vecCollision = vecTarget; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionGameEntity); + if (bCollision && pCollision) + vecCollision = pCollision->GetPosition(); + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + + if (pCollisionGameEntity) + pCollisionEntity = g_pClientGame->m_pManager->FindEntity(pCollisionGameEntity); + } + else + { + pPed->ClearBulletImpactData(); + } + + // Call our lua event + CLuaArguments Arguments; + Arguments.PushNumber((double)pWeapon->GetType()); + Arguments.PushNumber((double)pWeapon->GetAmmoTotal()); + Arguments.PushNumber((double)pWeapon->GetAmmoInClip()); + Arguments.PushNumber((double)vecCollision.fX); + Arguments.PushNumber((double)vecCollision.fY); + Arguments.PushNumber((double)vecCollision.fZ); + if (pCollisionEntity) + Arguments.PushElement(pCollisionEntity); + else + Arguments.PushNil(); + + if (IS_PLAYER(pPed)) + { + CVector vecOrigin; + pPed->GetShotData(&vecOrigin); + Arguments.PushNumber((double)vecOrigin.fX); + Arguments.PushNumber((double)vecOrigin.fY); + Arguments.PushNumber((double)vecOrigin.fZ); + pPed->CallEvent("onClientPlayerWeaponFire", Arguments, true); + } + else + pPed->CallEvent("onClientPedWeaponFire", Arguments, true); + } + pPed->PostWeaponFire(); +#ifdef MTA_DEBUG + if (pPed->IsLocalPlayer() && g_pClientGame->m_bDoPaintballs) + { + g_pClientGame->DoPaintballs(); + } +#endif + } + } + pWeaponFirePed = NULL; +} + +void CClientGame::BulletImpact(CPed* pInitiator, CEntity* pVictim, const CVector* pStartPosition, const CVector* pEndPosition) +{ + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pInitiator) + { + // Find the client ped that initiated the bullet impact + CClientPed* pInitiatorPed = g_pClientGame->GetPedManager()->Get(dynamic_cast(pInitiator), true, true); + + if (pInitiatorPed) + { + // Calculate the collision of the bullet + CVector vecCollision; + CColPoint* pCollision = NULL; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(pStartPosition, pEndPosition, &pCollision, NULL); + if (bCollision && pCollision) + { + vecCollision = pCollision->GetPosition(); + } + else + { + // If we don't have a collision, use the end of the ray that the bullet is tracing. + vecCollision = *pEndPosition; + } + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + + // Find the client entity for the victim. + CClientEntity* pClientVictim = NULL; + if (pVictim) + { + pClientVictim = g_pClientGame->m_pManager->FindEntity(pVictim); + } + + // Store the data in the bullet fire initiator. + pInitiatorPed->SetBulletImpactData(pClientVictim, vecCollision); + } + } +} + +void CClientGame::BulletFire(CPed* pInitiator, const CVector* pStartPosition, const CVector* pEndPosition) +{ + g_bBulletFireVectorsValid = false; + g_fApplyDamageLastAmount = 0; + g_ucApplyDamageLastHitZone = 0; + g_pApplyDamageLastDamagedPed = NULL; + + // Got a local player model? + CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pLocalPlayer->GetGamePlayer() == pInitiator) + { + g_bBulletFireVectorsValid = true; + g_vecBulletFireStartPosition = *pStartPosition; + g_vecBulletFireEndPosition = *pEndPosition; + } +} + +bool CClientGame::StaticProcessPacket(unsigned char ucPacketID, NetBitStreamInterface& bitStream) +{ + if (g_pClientGame) + { + g_pCore->UpdateDummyProgress(); + g_pClientGame->GetManager()->GetPacketRecorder()->RecordPacket(ucPacketID, bitStream); + return g_pClientGame->m_pPacketHandler->ProcessPacket(ucPacketID, bitStream); + } + + return false; +} + +void CClientGame::SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin) +{ + SPositionSync position(false); + position.data.vecPosition = vecPosition; + + // Create the bitstream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write our origin id + if (pOrigin) + { + pBitStream->WriteBit(true); + pBitStream->Write(pOrigin->GetID()); + + // Convert position + CVector vecTemp; + pOrigin->GetPosition(vecTemp); + position.data.vecPosition -= vecTemp; + } + else + pBitStream->WriteBit(false); + + // Write the position and the type + pBitStream->Write(&position); + + SExplosionTypeSync explosionType; + explosionType.data.uiType = Type; + pBitStream->Write(&explosionType); + + // Destroy it + g_pNet->SendPacket(PACKET_ID_EXPLOSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +void CClientGame::SendFireSync(CFire* pFire) +{ +#ifdef MTA_DEBUG + CVector* vecPos = pFire->GetPosition(); + if (vecPos) + g_pCore->GetConsole()->Printf("we're sending fire: %f %f %f %f", pFire->GetStrength(), vecPos->fX, vecPos->fY, vecPos->fZ); + else + g_pCore->GetConsole()->Printf("we're sending a fire!"); +#endif +} + +void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) +{ + // Create the bitstream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + SPositionSync origin(false); + CClientEntity* pOriginSource = NULL; + eWeaponType weaponType = pProjectile->GetWeaponType(); + CClientEntity* pTarget = pProjectile->GetTargetEntity(); + origin.data.vecPosition = *pProjectile->GetOrigin(); + + // Is this a heatseaking missile with a target? sync it relative to the target + if (weaponType == WEAPONTYPE_ROCKET_HS && pTarget && !pTarget->IsLocalEntity()) + pOriginSource = pTarget; + + // Write the source of the projectile, if it has + if (pOriginSource) + { + CVector vecTemp; + pOriginSource->GetPosition(vecTemp); + origin.data.vecPosition -= vecTemp; + + pBitStream->WriteBit(true); + pBitStream->Write(pOriginSource->GetID()); + } + else + pBitStream->WriteBit(false); + + // Write the origin position + pBitStream->Write(&origin); + + // Write the creator weapon type + SWeaponTypeSync weaponTypeSync; + weaponTypeSync.data.ucWeaponType = static_cast(weaponType); + pBitStream->Write(&weaponTypeSync); + + // Write the projectile's model + if (pBitStream->Version() >= 0x4F) + if (pBitStream->Version() >= 0x52 || pOriginSource) // Fix possible error for 0x51 server + pBitStream->Write(pProjectile->GetModel()); + + switch (weaponType) + { + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_TEARGAS: + case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: + { + SFloatSync<7, 17> projectileForce; + projectileForce.data.fValue = pProjectile->GetForce(); + pBitStream->Write(&projectileForce); + + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); + + break; + } + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKET_HS: + { + if (pTarget) + { + pBitStream->WriteBit(true); + pBitStream->Write(pTarget->GetID()); + } + else + pBitStream->WriteBit(false); + + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); + + SRotationRadiansSync rotation(true); + pProjectile->GetRotationRadians(rotation.data.vecRotation); + pBitStream->Write(&rotation); + + break; + } + case WEAPONTYPE_FLARE: + case WEAPONTYPE_FREEFALL_BOMB: + break; + } + g_pNet->SendPacket(PACKET_ID_PROJECTILE, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + + // Destroy it + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +void CClientGame::ResetAmmoInClip(void) +{ + memset(&m_wasWeaponAmmoInClip[0], 0, sizeof(m_wasWeaponAmmoInClip)); +} + +void CClientGame::ResetMapInfo(void) +{ + // Restore some game stuff + // Keybinds + g_pCore->GetKeyBinds()->SetAllControlsEnabled(true, true, true); + + // Radarmap + m_pRadarMap->SetForcedState(false); + + // Camera + m_pCamera->FadeOut(0.0f, 0, 0, 0); + g_pGame->GetWorld()->SetCurrentArea(0); + m_pCamera->SetFocusToLocalPlayer(); + g_pGame->GetSettings()->ResetFieldOfViewFromScript(); + + // Dimension + SetAllDimensions(0); + + // Hud + g_pGame->GetHud()->SetComponentVisible(HUD_ALL, true); + // Disable area names as they are on load until camera unfades + g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); + g_pGame->GetHud()->SetComponentVisible(HUD_VITAL_STATS, false); + + m_bHudAreaNameDisabled = false; + + // Gravity + g_pMultiplayer->SetLocalPlayerGravity(DEFAULT_GRAVITY); + g_pMultiplayer->SetGlobalGravity(DEFAULT_GRAVITY); + g_pGame->SetGravity(DEFAULT_GRAVITY); + + // Gamespeed + SetGameSpeed(DEFAULT_GAME_SPEED); + + // Game minute duration + SetMinuteDuration(DEFAULT_MINUTE_DURATION); + + // Wanted-level + SetWanted(0); + + // Money + SetMoney(0, true); + + // Weather + m_pBlendedWeather->SetWeather(0); + + // Rain + g_pGame->GetWeather()->ResetAmountOfRain(); + + // Wind + g_pMultiplayer->RestoreWindVelocity(); + + // Far clip distance + g_pMultiplayer->RestoreFarClipDistance(); + + // Near clip distance + g_pMultiplayer->RestoreNearClipDistance(); + + // Fog distance + g_pMultiplayer->RestoreFogDistance(); + + // Vehicles LOD distance + g_pGame->GetSettings()->ResetVehiclesLODDistance(); + + // Peds LOD distance + g_pGame->GetSettings()->ResetPedsLODDistance(); + + // Sun color + g_pMultiplayer->ResetSunColor(); + + // Sun size + g_pMultiplayer->ResetSunSize(); + + // Sky-gradient + g_pMultiplayer->ResetSky(); + + // Heat haze + g_pMultiplayer->ResetHeatHaze(); + + // Water-colour + g_pMultiplayer->ResetWater(); + + // Water + GetManager()->GetWaterManager()->ResetWorldWaterLevel(); + + // Re-enable interior sounds and furniture + g_pMultiplayer->SetInteriorSoundsEnabled(true); + for (int i = 0; i <= 4; ++i) + g_pMultiplayer->SetInteriorFurnitureEnabled(i, true); + + // Clouds + g_pMultiplayer->SetCloudsEnabled(true); + g_pClientGame->SetCloudsEnabled(true); + + // Birds + g_pMultiplayer->DisableBirds(false); + g_pClientGame->SetBirdsEnabled(true); + + // Ambient sounds + g_pGame->GetAudio()->ResetAmbientSounds(); + + // World sounds + g_pGame->GetAudio()->ResetWorldSounds(); + + // Cheats + g_pGame->ResetCheats(); + + // Players + m_pPlayerManager->ResetAll(); + + // Jetpack max height + g_pGame->GetWorld()->SetJetpackMaxHeight(DEFAULT_JETPACK_MAXHEIGHT); + + // Aircraft max height + g_pGame->GetWorld()->SetAircraftMaxHeight(DEFAULT_AIRCRAFT_MAXHEIGHT); + + // Aircraft max velocity + g_pGame->GetWorld()->SetAircraftMaxVelocity(DEFAULT_AIRCRAFT_MAXVELOCITY); + + // Moon size + g_pMultiplayer->ResetMoonSize(); + + // Disable the change of any player stats + g_pMultiplayer->SetLocalStatsStatic(true); + + // Restore blur +#ifdef MTA_DEBUG + g_pGame->SetBlurLevel(0); +#else + g_pGame->SetBlurLevel(DEFAULT_BLUR_LEVEL); +#endif + + // Close all garages + CGarage* pGarage = NULL; + CGarages* pGarages = g_pCore->GetGame()->GetGarages(); + + for (unsigned char i = 0; (pGarage = pGarages->GetGarage(i)) != NULL; i++) + { + pGarage->SetOpen(false); + } + + // Player specific stuff + if (m_pLocalPlayer) + { + // Interior + m_pLocalPlayer->SetInterior(0); + + // Headless state + m_pLocalPlayer->SetHeadless(false); + + // Frozen state + m_pLocalPlayer->SetFrozen(false); + + // Voice + short sVoiceType, sVoiceID; + m_pLocalPlayer->GetModelInfo()->GetVoice(&sVoiceType, &sVoiceID); + m_pLocalPlayer->SetVoice(sVoiceType, sVoiceID); + + m_pLocalPlayer->DestroySatchelCharges(false, true); + // Tell the server we want to destroy our satchels + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + g_pNet->SendPacket(PACKET_ID_DESTROY_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, + AnimationId animID) +{ + if (Ped && Ped->GetHealth() == 0.0f) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write some death info + pBitStream->WriteCompressed(animGroup); + pBitStream->WriteCompressed(animID); + + pBitStream->Write(damagerID); + + SWeaponTypeSync weapon; + weapon.data.ucWeaponType = ucWeapon; + pBitStream->Write(&weapon); + + SBodypartSync bodyPart; + bodyPart.data.uiBodypart = ucBodyPiece; + pBitStream->Write(&bodyPart); + + // Write the position we died in + SPositionSync pos(false); + Ped->GetPosition(pos.data.vecPosition); + pBitStream->Write(&pos); + + pBitStream->Write(Ped->GetID()); + + // The ammo in our weapon and write the ammo total + CWeapon* pPlayerWeapon = Ped->GetWeapon(); + SWeaponAmmoSync ammo(ucWeapon, true, false); + ammo.data.usTotalAmmo = 0; + if (pPlayerWeapon) + ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); + pBitStream->Write(&ammo); + + // Send the packet + g_pNet->SendPacket(PACKET_ID_PED_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, AnimationId animID) +{ + // Are we not already marked as dead? and have we run out of health? + if (!m_pLocalPlayer->IsDeadOnNetwork() && m_pLocalPlayer->GetHealth() == 0.0f) + { + // Send the "i am dead" packet + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + m_pLocalPlayer->SetDeadOnNetwork(true); + + // Call the onClientPlayerWasted event + CClientEntity* pKiller = (damagerID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(damagerID) : NULL; + CLuaArguments Arguments; + if (pKiller) + Arguments.PushElement(pKiller); + else + Arguments.PushBoolean(false); + if (ucWeapon != 0xFF) + Arguments.PushNumber(ucWeapon); + else + Arguments.PushBoolean(false); + if (ucBodyPiece != 0xFF) + Arguments.PushNumber(ucBodyPiece); + else + Arguments.PushBoolean(false); + Arguments.PushBoolean(false); + m_pLocalPlayer->CallEvent("onClientPlayerWasted", Arguments, true); + + // Write some death info + pBitStream->WriteCompressed(animGroup); + pBitStream->WriteCompressed(animID); + + pBitStream->Write(damagerID); + + SWeaponTypeSync weapon; + weapon.data.ucWeaponType = ucWeapon; + pBitStream->Write(&weapon); + + SBodypartSync bodyPart; + bodyPart.data.uiBodypart = ucBodyPiece; + pBitStream->Write(&bodyPart); + + // Write the position we died in + SPositionSync pos(false); + m_pLocalPlayer->GetPosition(pos.data.vecPosition); + pBitStream->Write(&pos); + + // The ammo in our weapon and write the ammo total + CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(); + SWeaponAmmoSync ammo(ucWeapon, true, false); + ammo.data.usTotalAmmo = 0; + if (pPlayerWeapon) + ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); + pBitStream->Write(&ammo); + + // Send the packet + g_pNet->SendPacket(PACKET_ID_PLAYER_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +bool CClientGame::OnKeyDown(CGUIKeyEventArgs Args) +{ + return true; +} + +bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + const char* szState = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIClick", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseDoubleClick(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + const char* szState = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIDoubleClick", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIMouseDown", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseButtonUp(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIMouseUp", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseMove(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseMove", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseEnter(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + if (Args.pSwitchedWindow) + { + CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); + if (GetGUIManager()->Exists(pGUISwitchedElement)) + Arguments.PushElement(pGUISwitchedElement); + } + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseEnter", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseLeave(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + if (Args.pSwitchedWindow) + { + CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); + if (GetGUIManager()->Exists(pGUISwitchedElement)) + Arguments.PushElement(pGUISwitchedElement); + } + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseLeave", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseWheel(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.wheelChange); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseWheel", Arguments, true); + + return true; +} + +bool CClientGame::OnMove(CGUIElement* pElement) +{ + if (!pElement) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); + if (pGUIElement && GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientGUIMove", Arguments, true); + + return true; +} + +bool CClientGame::OnSize(CGUIElement* pElement) +{ + if (!pElement) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientGUISize", Arguments, true); + + return true; +} + +bool CClientGame::OnFocusGain(CGUIFocusEventArgs Args) +{ + if (!Args.pActivatedWindow) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pActivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pActivatedWindow); + + if (Args.pDeactivatedWindow) + { + CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); + if (GetGUIManager()->Exists(pDeactivatedGUIElement)) + pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); + } + + if (GetGUIManager()->Exists(pActivatedGUIElement)) + pActivatedGUIElement->CallEvent("onClientGUIFocus", Arguments, true); + + return true; +} + +bool CClientGame::OnFocusLoss(CGUIFocusEventArgs Args) +{ + if (!Args.pDeactivatedWindow) + return false; + + CLuaArguments Arguments; + + if (Args.pActivatedWindow) + { + // pDeactivatedWindow looses focus but an other window is now gaining it so we let CClientGame::OnFocusGain trigger both events in the right order + return true; + } + + CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); + if (GetGUIManager()->Exists(pDeactivatedGUIElement)) + pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); + + return true; +} + +// +// Display a progress dialog if a big packet is coming in +// +void CClientGame::NotifyBigPacketProgress(unsigned long ulBytesReceived, unsigned long ulTotalSize) +{ + // Should display progress box? + if (ulBytesReceived >= ulTotalSize || ulTotalSize < 50000) + { + if (m_bReceivingBigPacket) + { + // Switch off progress box + m_bReceivingBigPacket = false; + m_pBigPacketTransferBox->Hide(); + } + return; + } + + // Update progress box + if (!m_bReceivingBigPacket || m_ulBigPacketSize != ulTotalSize) + { + m_bReceivingBigPacket = true; + m_ulBigPacketSize = ulTotalSize; + m_pBigPacketTransferBox->Hide(); + m_pBigPacketTransferBox->AddToTotalSize(ulTotalSize); + m_pBigPacketTransferBox->Show(); + } + + m_pBigPacketTransferBox->DoPulse(); + m_pBigPacketTransferBox->SetInfo(std::min(ulTotalSize, ulBytesReceived), CTransferBox::PACKET); +} + +bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled) +{ + if (ucGlitch < NUM_GLITCHES && bEnabled != m_Glitches[ucGlitch]) + { + m_Glitches[ucGlitch] = bEnabled; + if (ucGlitch == GLITCH_QUICKRELOAD) + g_pMultiplayer->DisableQuickReload(!bEnabled); + if (ucGlitch == GLITCH_CLOSEDAMAGE) + g_pMultiplayer->DisableCloseRangeDamage(!bEnabled); + return true; + } + return false; +} + +bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) +{ + return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; +} + +bool CClientGame::SetCloudsEnabled(bool bEnabled) +{ + m_bCloudsEnabled = bEnabled; + return true; +} +bool CClientGame::GetCloudsEnabled(void) +{ + return m_bCloudsEnabled; +} + +bool CClientGame::SetBirdsEnabled(bool bEnabled) +{ + m_bBirdsEnabled = bEnabled; + return true; +} +bool CClientGame::GetBirdsEnabled(void) +{ + return m_bBirdsEnabled; +} + +#pragma code_seg(".text") +bool CClientGame::VerifySADataFiles(int iEnableClientChecks) +{ + int& iCheckStatus = g_pGame->GetCheckStatus(); + + if (!g_pGame->VerifySADataFileNames()) + iCheckStatus |= (1 << 11); + + __declspec(allocate(".text")) static char szVerifyData[][32] = {"data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", + "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", + "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", + "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", + "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", + "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", + "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", + "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", + "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", + "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", + "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", + "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74"}; + + CMD5Hasher hasher; + for (int i = 0; i < NUMELMS(szVerifyData); i += 2) + { + MD5 md5; + if (!hasher.Calculate(szVerifyData[i], md5) || memcmp(md5.data, szVerifyData[i + 1], 0x10)) + { + iCheckStatus |= (1 << i); + } + } + + if (iCheckStatus & iEnableClientChecks) + { + g_pCore->InitiateDataFilesFix(); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + return true; +} + +void CClientGame::InitVoice(bool bEnabled, unsigned int uiServerSampleRate, unsigned char ucQuality, unsigned int uiBitrate) +{ + if (m_pVoiceRecorder) + { + m_pVoiceRecorder->Init(bEnabled, uiServerSampleRate, ucQuality, uiBitrate); + } +} + +// +// If debug render mode is on, allow each element in range to draw some stuff +// +void CClientGame::DebugElementRender(void) +{ + if (!GetDevelopmentMode() || !GetShowCollision()) + return; + + CVector vecCameraPos; + m_pCamera->GetPosition(vecCameraPos); + float fDrawRadius = 200.f; + + // Get all entities within range + CClientEntityResult result; + GetClientSpatialDatabase()->SphereQuery(result, CSphere(vecCameraPos, fDrawRadius)); + + // For each entity found + for (CClientEntityResult::const_iterator it = result.begin(); it != result.end(); ++it) + { + CClientEntity* pEntity = *it; + if (pEntity->GetParent()) + pEntity->DebugRender(vecCameraPos, fDrawRadius); + } +} + +////////////////////////////////////////////////////////////////// +// Click +// +void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString& strTag, uint uiQuality, uint uiMaxBandwidth, uint uiMaxPacketSize, + CResource* pResource, uint uiServerSentTime) +{ + if (!pResource) + return; + + bool bAllowScreenUploadEnabled = 1; + g_pCore->GetCVars()->Get("allow_screen_upload", bAllowScreenUploadEnabled); + bool bWindowMinimized = g_pCore->IsWindowMinimized(); + + if (bWindowMinimized || !bAllowScreenUploadEnabled) + { + // If alt-tabbed or opt-out + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!bAllowScreenUploadEnabled) + pBitStream->Write((uchar)EPlayerScreenShotResult::DISABLED); + else + pBitStream->Write((uchar)EPlayerScreenShotResult::MINIMIZED); + pBitStream->Write(uiServerSentTime); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); + g_pNet->DeallocateNetBitStream(pBitStream); + } + else + { + // Do grab and send + SScreenShotArgs screenShotArgs; + screenShotArgs.uiMaxBandwidth = uiMaxBandwidth; + screenShotArgs.uiMaxPacketSize = uiMaxPacketSize; + screenShotArgs.usResourceNetId = pResource->GetNetID(); + screenShotArgs.strTag = strTag; + screenShotArgs.uiServerSentTime = uiServerSentTime; + m_ScreenShotArgList.push_back(screenShotArgs); + g_pCore->GetGraphics()->GetScreenGrabber()->QueueScreenShot(uiSizeX, uiSizeY, uiQuality, &CClientGame::StaticGottenPlayerScreenShot); + } +} + +////////////////////////////////////////////////////////////////// +// Callback from TakePlayerScreendsShot +// +void CClientGame::StaticGottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strError) +{ + if (g_pClientGame) + g_pClientGame->GottenPlayerScreenShot(pBuffer, uiTimeSpentInQueue, strError); +} + +////////////////////////////////////////////////////////////////// +// Break data into packets and put into delayed send list +// +void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strInError) +{ + SString strError = strInError; + + // Pop saved args + if (m_ScreenShotArgList.empty()) + return; + + SScreenShotArgs screenShotArgs = m_ScreenShotArgList.front(); + m_ScreenShotArgList.pop_front(); + const uint uiMaxBandwidth = Clamp(100, screenShotArgs.uiMaxBandwidth, 1000000); + const uint uiMaxPacketSize = Clamp(100, screenShotArgs.uiMaxPacketSize, 100000); + const ushort usResourceNetId = screenShotArgs.usResourceNetId; + const SString strTag = screenShotArgs.strTag; + const uint uiServerGrabTime = screenShotArgs.uiServerSentTime + uiTimeSpentInQueue; + + // Silently ignore if resource has been stopped + CResource* pResource = GetResourceManager()->GetResourceFromNetID(usResourceNetId); + if (!pResource) + return; + + // Validate buffer + if (strError.empty()) + { + if (!pBuffer || pBuffer->GetSize() == 0) + strError = "Buffer empty"; + } + + // Handle error + if (!strError.empty()) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write((uchar)EPlayerScreenShotResult::ERROR_); + pBitStream->Write(uiServerGrabTime); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + if (pBitStream->Version() >= 0x053) + pBitStream->WriteString(strError); + g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); + g_pNet->DeallocateNetBitStream(pBitStream); + return; + } + + // Calc constants stuff + const uint uiSendRate = Clamp(5, uiMaxBandwidth / uiMaxPacketSize, 20); + const long long llPacketInterval = 1000 / uiSendRate; + const uint uiTotalByteSize = pBuffer->GetSize(); + const char* pData = pBuffer->GetData(); + const uint uiBytesPerPart = std::min(std::min(std::max(100U, uiMaxBandwidth / uiSendRate), uiTotalByteSize), 30000U); + const uint uiNumParts = std::max(1U, (uiTotalByteSize + uiBytesPerPart - 1) / uiBytesPerPart); + + // Calc variables stuff + CTickCount tickCount = CTickCount::Now() + CTickCount(llPacketInterval); + uint uiBytesRemaining = uiTotalByteSize; + m_usNextScreenShotId++; + + // Make each packet + for (uint i = 0; i < uiNumParts; i++) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + + ushort usPartNumber = i; + ushort usBytesThisPart = std::min(uiBytesRemaining, uiBytesPerPart); + assert(usBytesThisPart != 0); + + pBitStream->Write((uchar)EPlayerScreenShotResult::SUCCESS); + pBitStream->Write(m_usNextScreenShotId); + pBitStream->Write(usPartNumber); + pBitStream->Write(usBytesThisPart); + pBitStream->Write(pData, usBytesThisPart); + + // Write more info if first part + if (usPartNumber == 0) + { + pBitStream->Write(uiServerGrabTime); + pBitStream->Write(uiTotalByteSize); + pBitStream->Write((ushort)uiNumParts); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + } + + // Add to delay send list + SDelayedPacketInfo delayedPacketInfo; + delayedPacketInfo.useTickCount = tickCount; + delayedPacketInfo.ucPacketID = PACKET_ID_PLAYER_SCREENSHOT; + delayedPacketInfo.pBitStream = pBitStream; + delayedPacketInfo.packetPriority = PACKET_PRIORITY_LOW; + delayedPacketInfo.packetReliability = PACKET_RELIABILITY_RELIABLE_ORDERED; + delayedPacketInfo.packetOrdering = PACKET_ORDERING_DATA_TRANSFER; + m_DelayedSendList.push_back(delayedPacketInfo); + + // Increment stuff + pData += usBytesThisPart; + uiBytesRemaining -= usBytesThisPart; + tickCount += CTickCount(llPacketInterval); + } + + assert(uiBytesRemaining == 0); +} + +////////////////////////////////////////////////////////////////// +// Process delay send list +// +void CClientGame::ProcessDelayedSendList(void) +{ + CTickCount tickCount = CTickCount::Now(); + + while (!m_DelayedSendList.empty()) + { + SDelayedPacketInfo& info = m_DelayedSendList.front(); + if (info.useTickCount > tickCount) + break; + + g_pNet->SendPacket(info.ucPacketID, info.pBitStream, info.packetPriority, info.packetReliability, info.packetOrdering); + g_pNet->DeallocateNetBitStream(info.pBitStream); + m_DelayedSendList.pop_front(); + } +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetWeaponTypesUsingBulletSync +// +// Set whether the local player will send bulletsync messages for the supplied weapon type +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetWeaponTypesUsingBulletSync(const std::set& weaponTypesUsingBulletSync) +{ + m_weaponTypesUsingBulletSync = weaponTypesUsingBulletSync; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::GetWeaponTypeUsesBulletSync +// +// Get whether the local player should send bulletsync messages for the supplied weapon type +// +////////////////////////////////////////////////////////////////// +bool CClientGame::GetWeaponTypeUsesBulletSync(eWeaponType weaponType) +{ + return MapContains(m_weaponTypesUsingBulletSync, weaponType); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetDevelopmentMode +// +// Special mode which enables commands such as showcol and showsound +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetDevelopmentMode(bool bEnable, bool bEnableWeb) +{ + m_bDevelopmentMode = bEnable; + + if (m_bDevelopmentMode) + g_pGame->GetAudio()->SetWorldSoundHandler(CClientGame::StaticWorldSoundHandler); + else + g_pGame->GetAudio()->SetWorldSoundHandler(NULL); + + if (g_pCore->IsWebCoreLoaded()) + g_pCore->GetWebCore()->SetTestModeEnabled(bEnableWeb); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::StaticWorldSoundHandler +// +// Handle callback from CAudioSA when a world sound is played +// +////////////////////////////////////////////////////////////////// +void CClientGame::StaticWorldSoundHandler(uint uiGroup, uint uiIndex) +{ + g_pClientGame->WorldSoundHandler(uiGroup, uiIndex); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::WorldSoundHandler +// +// Handle callback from CAudioSA when a world sound is played +// +////////////////////////////////////////////////////////////////// +void CClientGame::WorldSoundHandler(uint uiGroup, uint uiIndex) +{ + if (m_bShowSound) + m_pScriptDebugging->LogInformation(NULL, "%s - World sound group:%d index:%d", *GetLocalTimeString(false, true), uiGroup, uiIndex); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::IsUsingAlternatePulseOrder +// +// Returns true if should be using alternate pulse order +// +////////////////////////////////////////////////////////////////// +bool CClientGame::IsUsingAlternatePulseOrder(bool bAdvanceDelayCounter) +{ + if (m_MiscGameSettings.bUseAltPulseOrder) + { + // Only actually start using alternate pulse order after 100 frames + if (m_uiAltPulseOrderCounter >= 100) + return true; + else if (bAdvanceDelayCounter) + m_uiAltPulseOrderCounter++; + } + + return false; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::OutputServerInfo +// +// Output info about the connected server for player +// +////////////////////////////////////////////////////////////////// +void CClientGame::OutputServerInfo(void) +{ + SString strTotalOutput; + strTotalOutput += SString("Server info for %s", g_pNet->GetConnectedServer(true)); + strTotalOutput += "\n"; + strTotalOutput += SString("Ver: %s\n", *GetServerVersionSortable()); + strTotalOutput += SString("AC: %s\n", *m_strACInfo); + + { + SString strVoice; + if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) + strVoice += SString("Enabled - Sample rate:%d Quality:%d", m_pVoiceRecorder->GetSampleRate(), m_pVoiceRecorder->GetSampleQuality()); + else + strVoice += "Disabled"; + + strTotalOutput += SString("Voice: %s\n", *strVoice); + } + + { + SString strEnabledGlitches; + const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", + "Bad driveby hitboxes", "Quick stand"}; + for (uint i = 0; i < NUM_GLITCHES; i++) + { + if (IsGlitchEnabled(i)) + { + if (!strEnabledGlitches.empty()) + strEnabledGlitches += ", "; + if (i < NUMELMS(szGlitchNames)) + strEnabledGlitches += szGlitchNames[i]; + else + strEnabledGlitches += SString("Unknown(#%d)", i + 1); + } + } + if (strEnabledGlitches.empty()) + strEnabledGlitches = "None"; + strTotalOutput += SString("Glitches: %s\n", *strEnabledGlitches); + } + + { + SString strEnabledBulletSync; + for (std::set::iterator iter = m_weaponTypesUsingBulletSync.begin(); iter != m_weaponTypesUsingBulletSync.end(); ++iter) + { + eWeaponType weaponType = *iter; + if (!strEnabledBulletSync.empty()) + strEnabledBulletSync += ","; + strEnabledBulletSync += SString("%d", weaponType); + } + if (strEnabledBulletSync.empty()) + strEnabledBulletSync = "None"; + strTotalOutput += SString("Bullet sync weapons: %s\n", *strEnabledBulletSync); + } + + { + SString strVehExtrapolate; + if (m_VehExtrapolateSettings.bEnabled) + strVehExtrapolate += SString("Amount:%d%% (LimitMs:%d)", m_VehExtrapolateSettings.iScalePercent, m_VehExtrapolateSettings.iMaxMs); + else + strVehExtrapolate += "Disabled"; + + strTotalOutput += SString("Vehicle extrapolation: %s\n", *strVehExtrapolate); + } + + { + SString strTickRates; + strTickRates += SString("Plr:%d Cam:%d Ped:%d UnocVeh:%d KeyRot:%d KeyJoy:%d", g_TickRateSettings.iPureSync, g_TickRateSettings.iCamSync, + g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, + g_TickRateSettings.iKeySyncAnalogMove); + + strTotalOutput += SString("Tick rates: %s\n", *strTickRates); + } + + { + SString strSyncerDists; + strSyncerDists += SString("Ped:%d UnoccupiedVehicle:%d ", g_TickRateSettings.iPedSyncerDistance, g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); + + strTotalOutput += SString("Syncer distances: %s\n", *strSyncerDists); + } + + g_pCore->GetConsole()->Print(strTotalOutput); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::TellServerSomethingImportant +// +// Report misc important warnings/errors to the current server +// +////////////////////////////////////////////////////////////////// +void CClientGame::TellServerSomethingImportant(uint uiId, const SString& strMessage, uint uiSendLimitForThisId) +{ + g_pCore->GetConsole()->Print(strMessage); + AddReportLog(3400 + uiId, strMessage + g_pNet->GetConnectedServer(true), 10); + + if (uiSendLimitForThisId) + { + uint& uiCount = MapGet(m_SentMessageIds, uiId); + if (uiCount++ >= uiSendLimitForThisId) + return; + } + + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->WriteString(SString("%d,%s", uiId, *strMessage)); + g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE); + g_pNet->DeallocateNetBitStream(pBitStream); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::ChangeFloatPrecision +// +// Manage the change to high floating point precision +// +////////////////////////////////////////////////////////////////// +void CClientGame::ChangeFloatPrecision(bool bHigh) +{ + if (bHigh) + { + // Switch to 53 bit floating point precision on the first call + if (m_uiPrecisionCallDepth++ == 0) + _controlfp(_PC_53, MCW_PC); + } + else + { + // Even though is should never happen, m_uiPrecisionCallDepth is sometimes zero here + dassert(m_uiPrecisionCallDepth != 0); + if (m_uiPrecisionCallDepth != 0) + m_uiPrecisionCallDepth--; + // Switch back to 24 bit floating point precision on the last call + if (m_uiPrecisionCallDepth == 0) + _controlfp(_PC_24, MCW_PC); + } +} + +bool CClientGame::IsHighFloatPrecision(void) const +{ + return m_uiPrecisionCallDepth != 0; +} + +AnimationId CClientGame::DrivebyAnimationHandler(AnimationId animId, AssocGroupId animGroupId) +{ + // Only apply if all clients support the fix + if (!GetMiscGameSettings().bAllowBadDrivebyHitboxFix) + return animId; + + // If the glitch is enabled, don't apply the fix + if (IsGlitchEnabled(GLITCH_BADDRIVEBYHITBOX)) + return animId; + + // Bad animations are 232 and 236 of assoc group 72 + if (animGroupId != 72) + return animId; + + if (animId == 232) + return 235; + else if (animId == 236) + return 231; + + return animId; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetFileCacheRoot +// +// Figure out which directory to use for the client resource file cache +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetFileCacheRoot(void) +{ + if (g_pCore->GetCVars()->GetValue("share_file_cache") == false) + { + // Not sharing, so use current mod directory + m_strFileCacheRoot = GetModRoot(); + AddReportLog(7410, SString("CClientGame::SetFileCacheRoot - Not shared '%s'", *m_strFileCacheRoot)); + } + else + { + // Get shared directory + SString strFileCachePath = GetCommonRegistryValue("", "File Cache Path"); + // Check exists + if (!strFileCachePath.empty() && DirectoryExists(strFileCachePath)) + { + // Check writable + SString strTestFileName = PathJoin(strFileCachePath, "resources", "_test.tmp"); + if (FileSave(strTestFileName, "x")) + { + FileDelete(strTestFileName); + strTestFileName = PathJoin(strFileCachePath, "priv", "_test.tmp"); + if (FileSave(strTestFileName, "x")) + { + FileDelete(strTestFileName); + // Use shared directory + m_strFileCacheRoot = strFileCachePath; + AddReportLog(7411, SString("CClientGame::SetFileCacheRoot - Is shared '%s'", *m_strFileCacheRoot)); + return; + } + } + } + + // Otherwise set this install mod directory as shared + m_strFileCacheRoot = GetModRoot(); + SetCommonRegistryValue("", "File Cache Path", m_strFileCacheRoot); + + if (strFileCachePath.empty()) + AddReportLog(7412, SString("CClientGame::SetFileCacheRoot - Initial setting '%s'", *m_strFileCacheRoot)); + else + AddReportLog(7413, SString("CClientGame::SetFileCacheRoot - Change shared from '%s' to '%s'", *strFileCachePath, *m_strFileCacheRoot)); + } +} + +bool CClientGame::TriggerBrowserRequestResultEvent(const std::unordered_set& newPages) +{ + CLuaArguments Arguments; + CLuaArguments LuaTable; + int i = 0; + + for (auto& domain : newPages) + { + LuaTable.PushNumber(++i); + LuaTable.PushString(domain); + } + Arguments.PushTable(&LuaTable); + + return GetRootEntity()->CallEvent("onClientBrowserWhitelistChange", Arguments, false); +} + +void CClientGame::RestreamModel(unsigned short usModel) +{ + // Is this a vehicle ID? + if (CClientVehicleManager::IsValidModel(usModel)) + { + // Stream the vehicles of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetVehicleManager()->RestreamVehicles(usModel); + } + + // Is this an object ID? + else if (CClientObjectManager::IsValidModel(usModel)) + { + if (CClientPedManager::IsValidWeaponModel(usModel)) + { + // Stream the weapon of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetPedManager()->RestreamWeapon(usModel); + m_pManager->GetPickupManager()->RestreamPickups(usModel); + } + // Stream the objects of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetObjectManager()->RestreamObjects(usModel); + g_pGame->GetModelInfo(usModel)->RestreamIPL(); + } + // Is this an ped ID? + else if (CClientPlayerManager::IsValidModel(usModel)) + { + // Stream the ped of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetPedManager()->RestreamPeds(usModel); + } + else + + // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect + if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) + m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); +} + +void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) +{ + m_mapOfIfpPointers[u32BlockNameHash] = pIFP; +} + +std::shared_ptr CClientGame::GetIFPPointerFromMap(const unsigned int u32BlockNameHash) +{ + auto it = m_mapOfIfpPointers.find(u32BlockNameHash); + if (it != m_mapOfIfpPointers.end()) + { + return it->second; + } + return nullptr; +} + +void CClientGame::RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash) +{ + m_mapOfIfpPointers.erase(u32BlockNameHash); +} + +void CClientGame::InsertPedPointerToSet(CClientPed* pPed) +{ + m_setOfPedPointers.insert(pPed); +} + +void CClientGame::RemovePedPointerFromSet(CClientPed* pPed) +{ + m_setOfPedPointers.erase(pPed); +} + +CClientPed* CClientGame::GetClientPedByClump(const RpClump& Clump) +{ + for (auto& pPed : m_setOfPedPointers) + { + CEntity* pEntity = pPed->GetGameEntity(); + if (pEntity != nullptr) + { + if (pEntity->GetRpClump() != nullptr) + { + const RpClump& entityClump = *pEntity->GetRpClump(); + if (std::addressof(entityClump) == std::addressof(Clump)) + { + return pPed; + } + } + } + } + return nullptr; +} + +void CClientGame::OnClientIFPUnload(const std::shared_ptr& IFP) +{ + IFP->MarkAsUnloading(); + for (auto& pPed : m_setOfPedPointers) + { + // Remove IFP animations from replaced animations of peds/players + pPed->RestoreAnimations(IFP); + + // Make sure that streamed in pulses or changing model does not accidently + // play our custom animation. We can do that by making the custom animation + // untriggerable + if (pPed->GetCustomAnimationBlockNameHash() == IFP->GetBlockNameHash()) + { + if (pPed->IsCustomAnimationPlaying()) + { + pPed->SetCustomAnimationUntriggerable(); + } + + // Important! As we are using a shared_ptr, we need to decrement the reference counter + // by setting the shared_ptr to nullptr, this will avoid memory leak + if (!pPed->IsNextAnimationCustom() && pPed->IsCurrentAnimationCustom()) + { + pPed->DereferenceCustomAnimationBlock(); + } + } + } +} + +void CClientGame::InsertAnimationAssociationToMap(CAnimBlendAssociationSAInterface* pAnimAssociation, const std::shared_ptr& pIFPAnimations) +{ + m_mapOfCustomAnimationAssociations[pAnimAssociation] = pIFPAnimations; +} + +void CClientGame::RemoveAnimationAssociationFromMap(CAnimBlendAssociationSAInterface* pAnimAssociation) +{ + m_mapOfCustomAnimationAssociations.erase(pAnimAssociation); +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index 9445398f4cb..d98579e147f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -1,3887 +1,3877 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto - * LICENSE: See LICENSE in the top level directory - * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp - * PURPOSE: Lua definitions class - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#include "StdInc.h" - -void CLuaGUIDefs::LoadFunctions(void) -{ - CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); - CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); - CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); - CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); - - CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); - CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); - CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); - CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); - CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); - CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); - - CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); - CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); - CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); - - CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); - CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); - CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); - CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); - CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); - CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); - CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); - CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); - CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); - CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); - CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); - CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); - CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); - CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); - CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); - CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); - - CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); - CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); - CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); - CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); - CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); - - CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); - CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); - CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); - CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); - CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); - CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); - CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); - CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); - CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); - CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); - CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); - CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); - CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); - CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); - CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); - CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); - CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); - CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); - CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); - CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); - CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); - CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); - - CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); - CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); - CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); - CLuaCFunctions::AddFunction("guiSetText", GUISetText); - CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); - CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); - CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); - CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); - - CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); - CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); - - CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); - - CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); - CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); - CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); - CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); - CLuaCFunctions::AddFunction("guiGetText", GUIGetText); - CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); - CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); - CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); - CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); - CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); - - CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); - - CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); - CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); - - CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); - - CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); - CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); - CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); - CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); - CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); - CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); - - CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); - CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); - CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); - CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); - CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); - CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); - - CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); - CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); - - CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); - CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); - - CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); - - CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); - CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); - CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); - CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); - CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); - CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); - CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); -} - -void CLuaGUIDefs::AddClass(lua_State* luaVM) -{ - AddGuiElementClass(luaVM); - AddGuiFontClass(luaVM); - AddGuiWindowClass(luaVM); - AddGuiButtonClass(luaVM); - AddGuiEditClass(luaVM); - AddGuiLabelClass(luaVM); - AddGuiMemoClass(luaVM); - AddGuiImageClass(luaVM); - AddGuiComboBoxClass(luaVM); - AddGuiCheckBoxClass(luaVM); - AddGuiRadioButtonClass(luaVM); - AddGuiScrollPaneClass(luaVM); - AddGuiScrollBarClass(luaVM); - AddGuiProgressBarClass(luaVM); - AddGuiGridlistClass(luaVM); - AddGuiTabPanelClass(luaVM); - AddGuiTabClass(luaVM); -} - -// TODO: vector class -void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "bringToFront", "guiBringToFront"); - lua_classfunction(luaVM, "moveToBack", "guiMoveToBack"); - - lua_classfunction(luaVM, "isChatBoxInputActive", "isChatBoxInputActive"); - lua_classfunction(luaVM, "isConsoleActive", "isConsoleActive"); - lua_classfunction(luaVM, "isDebugViewActive", "isDebugViewActive"); - lua_classfunction(luaVM, "setDebugViewActive", "setDebugViewActive"); - lua_classfunction(luaVM, "isMainMenuActive", "isMainMenuActive"); - lua_classfunction(luaVM, "isMTAWindowActive", "isMTAWindowActive"); - lua_classfunction(luaVM, "isTransferBoxActive", "isTransferBoxActive"); - lua_classfunction(luaVM, "isInputEnabled", "guiGetInputEnabled"); - lua_classfunction(luaVM, "getInputMode", "guiGetInputMode"); - lua_classfunction(luaVM, "getCursorType", "guiGetCursorType"); - - lua_classfunction(luaVM, "getScreenSize", "guiGetScreenSize"); - lua_classfunction(luaVM, "getProperties", "guiGetProperties"); - lua_classfunction(luaVM, "getAlpha", "guiGetAlpha"); - lua_classfunction(luaVM, "getFont", "guiGetFont"); - lua_classfunction(luaVM, "getEnabled", "guiGetEnabled"); - lua_classfunction(luaVM, "getVisible", "guiGetVisible"); - lua_classfunction(luaVM, "getText", "guiGetText"); - lua_classfunction(luaVM, "getPosition", "guiGetPosition"); - lua_classfunction(luaVM, "getSize", "guiGetSize"); - lua_classfunction(luaVM, "getProperty", "guiGetProperty"); - - lua_classfunction(luaVM, "setInputEnabled", "guiSetInputEnabled"); - lua_classfunction(luaVM, "setAlpha", "guiSetAlpha"); - lua_classfunction(luaVM, "setEnabled", "guiSetEnabled"); - lua_classfunction(luaVM, "setFont", "guiSetFont"); - lua_classfunction(luaVM, "setVisible", "guiSetVisible"); - lua_classfunction(luaVM, "setText", "guiSetText"); - lua_classfunction(luaVM, "setInputMode", "guiSetInputMode"); - lua_classfunction(luaVM, "setProperty", "guiSetProperty"); - lua_classfunction(luaVM, "setPosition", "guiSetPosition"); - lua_classfunction(luaVM, "setSize", "guiSetSize"); - - lua_classvariable(luaVM, "chatBoxInputActive", NULL, "isChatBoxInputActive"); - lua_classvariable(luaVM, "consoleActive", NULL, "isConsoleActive"); - lua_classvariable(luaVM, "debugViewActive", "setDebugViewActive", "isDebugViewActive"); - lua_classvariable(luaVM, "mainMenuActive", NULL, "isMainMenuActive"); - lua_classvariable(luaVM, "mtaWindowActive", NULL, "isMTAWindowActive"); - lua_classvariable(luaVM, "transferBoxActive", NULL, "isTransferBoxActive"); - lua_classvariable(luaVM, "inputEnabled", "guiSetInputEnabled", "guiGetInputEnabled"); - lua_classvariable(luaVM, "inputMode", "guiGetInputMode", "guiSetInputMode"); - lua_classvariable(luaVM, "cursorAlpha", "setCursorAlpha", "getCursorAlpha"); - lua_classvariable(luaVM, "cursorType", NULL, "guiGetCursorType"); - lua_classvariable(luaVM, "font", "guiSetFont", "guiGetFont"); - lua_classvariable(luaVM, "visible", "guiSetVisible", "guiGetVisible"); - lua_classvariable(luaVM, "properties", NULL, "guiGetProperties"); - lua_classvariable(luaVM, "alpha", "guiSetAlpha", "guiGetAlpha"); - lua_classvariable(luaVM, "enabled", "guiSetEnabled", "guiGetEnabled"); - lua_classvariable(luaVM, "text", "guiSetText", "guiGetText"); - lua_classvariable(luaVM, "size", "guiSetSize", "guiGetSize"); - lua_classvariable(luaVM, "position", "guiSetPosition", "guiGetPosition"); - lua_classvariable(luaVM, "screenSize", NULL, "guiGetScreenSize"); - // lua_classvariable ( luaVM, "property" "guiSetProperty", "guiGetProperty" ); todo: .property[name] = value - - lua_registerclass(luaVM, "GuiElement", "Element"); -} - -void CLuaGUIDefs::AddGuiWindowClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateWindow"); - lua_classfunction(luaVM, "setMovable", "guiWindowSetMovable"); - lua_classfunction(luaVM, "setSizable", "guiWindowSetSizable"); - - lua_classvariable(luaVM, "movable", "guiWindowSetMovable", NULL); - lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", NULL); - - lua_registerclass(luaVM, "GuiWindow", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiButtonClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateButton"); - - lua_registerclass(luaVM, "GuiButton", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateEdit"); - lua_classfunction(luaVM, "getCaretIndex", "guiEditGetCaretIndex"); - lua_classfunction(luaVM, "setCaretIndex", "guiEditSetCaretIndex"); - lua_classfunction(luaVM, "setReadOnly", "guiEditSetReadOnly"); - lua_classfunction(luaVM, "setMasked", "guiEditSetMasked"); - lua_classfunction(luaVM, "setMaxLength", "guiEditSetMaxLength"); - - lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); - lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", "guiEditIsReadOnly"); - lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); - lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); - - lua_registerclass(luaVM, "GuiEdit", "GuiElement"); -} - -// TODO: specials -void CLuaGUIDefs::AddGuiLabelClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateLabel"); - - lua_classfunction(luaVM, "getFontHeight", "guiLabelGetFontHeight"); - lua_classfunction(luaVM, "getTextExtent", "guiLabelGetTextExtent"); - lua_classfunction(luaVM, "getColor", "guiLabelGetColor"); - - lua_classfunction(luaVM, "setColor", "guiLabelSetColor"); - lua_classfunction(luaVM, "setHorizontalAlign", "guiLabelSetHorizontalAlign"); - lua_classfunction(luaVM, "setVerticalAlign", "guiLabelSetVerticalAlign"); - - lua_classvariable(luaVM, "horizontalAlign", "guiLabelSetHorizontalAlign", NULL); - lua_classvariable(luaVM, "verticalAlign", "guiLabelSetVerticalAlign", NULL); - lua_classvariable(luaVM, "fontHeight", NULL, "guiLabelGetFontHeight"); - lua_classvariable(luaVM, "textExtent", NULL, "guiLabelGetTextExtent"); - // lua_classvariable ( luaVM, "color", "guiLabelGetColor", "guiLabelSetColor" ); - - lua_registerclass(luaVM, "GuiLabel", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiMemoClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateMemo"); - - lua_classfunction(luaVM, "getCaretIndex", "guiMemoGetCaretIndex"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); - - lua_classfunction(luaVM, "setCaretIndex", "guiMemoSetCaretIndex"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiMemoSetVerticalScrollPosition"); - lua_classfunction(luaVM, "setReadOnly", "guiMemoSetReadOnly"); - - lua_classvariable(luaVM, "caretIndex", "guiMemoSetCaretIndex", "guiMemoGetCaretIndex"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiMemoSetVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); - lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", "guiMemoIsReadOnly"); - - lua_registerclass(luaVM, "GuiMemo", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiImageClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateStaticImage"); - lua_classfunction(luaVM, "loadImage", "guiStaticImageLoadImage"); - - lua_classvariable(luaVM, "image", "guiStaticImageLoadImage", NULL); - - lua_registerclass(luaVM, "GuiStaticImage", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiComboBoxClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateComboBox"); - lua_classfunction(luaVM, "addItem", "guiComboBoxAddItem"); - lua_classfunction(luaVM, "clear", "guiComboBoxClear"); - lua_classfunction(luaVM, "removeItem", "guiComboBoxRemoveItem"); - - lua_classfunction(luaVM, "getSelected", "guiComboBoxGetSelected"); - lua_classfunction(luaVM, "getItemText", "guiComboBoxGetItemText"); - - lua_classfunction(luaVM, "setItemText", "guiComboBoxSetItemText"); - lua_classfunction(luaVM, "setSelected", "guiComboBoxSetSelected"); - - lua_classvariable(luaVM, "selected", "guiComboBoxSetSelected", "guiComboBoxGetSelected"); - - lua_registerclass(luaVM, "GuiComboBox", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiCheckBoxClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateCheckBox"); - - lua_classfunction(luaVM, "getSelected", "guiCheckBoxGetSelected"); - - lua_classfunction(luaVM, "setSelected", "guiCheckBoxSetSelected"); - - lua_classvariable(luaVM, "selected", "guiCheckBoxSetSelected", "guiCheckBoxGetSelected"); - - lua_registerclass(luaVM, "GuiCheckBox", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiRadioButtonClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateRadioButton"); - - lua_classfunction(luaVM, "getSelected", "guiRadioButtonGetSelected"); - - lua_classfunction(luaVM, "setSelected", "guiRadioButtonSetSelected"); - - lua_classvariable(luaVM, "selected", "guiRadioButtonSetSelected", "guiRadioButtonGetSelected"); - - lua_registerclass(luaVM, "GuiRadioButton", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiScrollPaneClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateScrollPane"); - - lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); - - lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition"); - lua_classfunction(luaVM, "setScrollBars", "guiScrollPaneSetScrollBars"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition"); - - lua_classvariable(luaVM, "horizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); - - lua_registerclass(luaVM, "GuiScrollPane", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiScrollBarClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateScrollBar"); - - lua_classfunction(luaVM, "getScrollPosition", "guiScrollBarGetScrollPosition"); - - lua_classfunction(luaVM, "setScrollPosition", "guiScrollBarSetScrollPosition"); - - lua_classvariable(luaVM, "scrollPosition", "guiScrollBarSetScrollPosition", "guiScrollBarGetScrollPosition"); - - lua_registerclass(luaVM, "GuiScrollBar", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiProgressBarClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateProgressBar"); - - lua_classfunction(luaVM, "getProgress", "guiProgressBarGetProgress"); - - lua_classfunction(luaVM, "setProgress", "guiProgressBarSetProgress"); - - lua_classvariable(luaVM, "progress", "guiProgressBarSetProgress", "guiProgressBarGetProgress"); - - lua_registerclass(luaVM, "GuiProgressBar", "GuiElement"); -} - -// TODO: special tables -void CLuaGUIDefs::AddGuiGridlistClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateGridList"); - lua_classfunction(luaVM, "addColumn", "guiGridListAddColumn"); - lua_classfunction(luaVM, "addRow", "guiGridListAddRow"); - lua_classfunction(luaVM, "autoSizeColumn", "guiGridListAutoSizeColumn"); - lua_classfunction(luaVM, "clear", "guiGridListClear"); - lua_classfunction(luaVM, "insertRowAfter", "guiGridListInsertRowAfter"); - lua_classfunction(luaVM, "removeColumn", "guiGridListRemoveColumn"); - lua_classfunction(luaVM, "removeRow", "guiGridListRemoveRow"); - - lua_classfunction(luaVM, "getItemData", "guiGridListGetItemData"); - lua_classfunction(luaVM, "getItemText", "guiGridListGetItemText"); - lua_classfunction(luaVM, "getRowCount", "guiGridListGetRowCount"); - lua_classfunction(luaVM, "getSelectedItem", "guiGridListGetSelectedItem"); - lua_classfunction(luaVM, "getItemColor", "guiGridListGetItemColor"); - lua_classfunction(luaVM, "getColumnTitle", "guiGridListGetColumnTitle"); - lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); - lua_classfunction(luaVM, "getSelectedCount", "guiGridListGetSelectedCount"); - lua_classfunction(luaVM, "getSelectedItems", "guiGridListGetSelectedItems"); - lua_classfunction(luaVM, "getColumnCount", "guiGridListGetColumnCount"); - - lua_classfunction(luaVM, "setItemData", "guiGridListSetItemData"); - lua_classfunction(luaVM, "setItemText", "guiGridListSetItemText"); - lua_classfunction(luaVM, "setScrollBars", "guiGridListSetScrollBars"); - lua_classfunction(luaVM, "setSelectedItem", "guiGridListSetSelectedItem"); - lua_classfunction(luaVM, "setSelectionMode", "guiGridListSetSelectionMode"); - lua_classfunction(luaVM, "setSortingEnabled", "guiGridListSetSortingEnabled"); - lua_classfunction(luaVM, "setColumnWidth", "guiGridListSetColumnWidth"); - lua_classfunction(luaVM, "setItemColor", "guiGridListSetItemColor"); - lua_classfunction(luaVM, "setColumnTitle", "guiGridListSetColumnTitle"); - lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiGridListSetHorizontalScrollPosition"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiGridListSetVerticalScrollPosition"); - - lua_classvariable(luaVM, "rowCount", NULL, "guiGridListGetRowCount"); - lua_classvariable(luaVM, "selectedCount", NULL, "guiGridListGetSelectedCount"); - lua_classvariable(luaVM, "selectedItems", NULL, "guiGridListGetSelectedItems"); - lua_classvariable(luaVM, "columnCount", NULL, "guiGridListGetColumnCount"); - lua_classvariable(luaVM, "selectionMode", "guiGridListSetSelectionMode", NULL); - lua_classvariable(luaVM, "sortingEnabled", "guiGridListSetSortingEnabled", NULL); - lua_classvariable(luaVM, "horizontalScrollPosition", "guiGridListSetHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiGridListGetVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); - // lua_classvariable ( luaVM, "selectedItem", NULL, "guiGridListGetSelectedItem" ); table - // lua_classvariable ( luaVM, "selectedItem", "guiGridListSetSelectedItem", NULL ); .selectedItem[column] = row (row in column) table - // lua_classvariable ( luaVM, "itemColor", "setItemColor", "getItemColor" ); table - // lua_classvariable ( luaVM, "columnTitle", "setColumnTitle", "getColumnTitle" ); table - - lua_registerclass(luaVM, "GuiGridList", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiTabPanelClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateTabPanel"); - - lua_classfunction(luaVM, "getSelectedTab", "guiGetSelectedTab"); - - lua_classfunction(luaVM, "setSelectedTab", "guiSetSelectedTab"); - - lua_classvariable(luaVM, "selectedTab", "guiSetSelectedTab", "guiGetSelectedTab"); - - lua_registerclass(luaVM, "GuiTabPanel", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiTabClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateTab"); - lua_classfunction(luaVM, "delete", "guiDeleteTab"); - - lua_registerclass(luaVM, "GuiTab", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiFontClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateFont"); - - lua_registerclass(luaVM, "GuiFont", "Element"); -} - -int CLuaGUIDefs::GUIGetInputEnabled(lua_State* luaVM) -{ - lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIGetInputEnabled()); - return 1; -} - -int CLuaGUIDefs::GUISetInputEnabled(lua_State* luaVM) -{ - // bool guiSetInputEnabled ( bool enabled ) - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetInputMode(enabled ? INPUTMODE_NO_BINDS : INPUTMODE_ALLOW_BINDS); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetInputMode(lua_State* luaVM) -{ - // bool guiSetInputMode ( string mode ) - eInputMode mode; - - CScriptArgReader argStream(luaVM); - argStream.ReadEnumString(mode); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetInputMode(mode); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetInputMode(lua_State* luaVM) -{ - eInputMode mode = CStaticFunctionDefinitions::GUIGetInputMode(); - lua_pushstring(luaVM, EnumToString(mode)); - return 1; -} - -int CLuaGUIDefs::GUIIsChatBoxInputActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsChatInputEnabled()); - return 1; -} - -int CLuaGUIDefs::GUIIsConsoleActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->GetConsole()->IsVisible()); - return 1; -} - -int CLuaGUIDefs::GUIIsDebugViewActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsDebugVisible()); - return 1; -} - -int CLuaGUIDefs::GUISetDebugViewActive(lua_State* luaVM) -{ - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - g_pCore->SetDebugVisible(enabled); - - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIIsMainMenuActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsMenuVisible()); - return 1; -} - -int CLuaGUIDefs::GUIIsMTAWindowActive(lua_State* luaVM) -{ - bool bActive = - (g_pCore->IsChatInputEnabled() || g_pCore->IsMenuVisible() || g_pCore->GetConsole()->IsVisible() || g_pClientGame->GetTransferBox()->IsVisible()); - - lua_pushboolean(luaVM, bActive); - return 1; -} - -int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); - return 1; -} - -int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) -{ - bool bEnabled; - CScriptArgReader argStream(luaVM); - argStream.ReadBool(bEnabled); - - if (!argStream.HasErrors()) - { - bool bAllowed = false; - g_pCore->GetCVars()->Get("allow_server_control_transfebox", bAllowed); - if (bAllowed) - { - g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - { - lua_pushboolean(luaVM, false); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - return 1; -} - -int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); - return 1; -} - -int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) -{ - // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) - CVector2D position; - CVector2D size; - SString titleBarText; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(titleBarText); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateWindow(*pLuaMain, position, size, titleBarText, relative); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateLabel(lua_State* luaVM) -{ - // element guiCreateLabel ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateLabel(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateStaticImage(lua_State* luaVM) -{ - // element guiCreateStaticImage ( float x, float y, float width, float height, string path, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString path; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(path); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CResource* pResource = pLuaMain->GetResource(); - SString strPath; - if (CResourceManager::ParseResourcePathInput(path, pResource, &strPath)) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateStaticImage(*pLuaMain, position, size, strPath, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - else - argStream.SetCustomError(path, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateButton(lua_State* luaVM) -{ - // element guiCreateButton ( float x, float y, float width, float height, string text, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateButton(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateProgressBar(lua_State* luaVM) -{ - // element guiCreateProgressBar ( float x, float y, float width, float height, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateProgressBar(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateCheckBox(lua_State* luaVM) -{ - // element guiCreateCheckBox ( float x, float y, float width, float height, string text, bool selected, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool selected; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(selected); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateCheckBox(*pLuaMain, position, size, text, selected, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateRadioButton(lua_State* luaVM) -{ - // element guiCreateRadioButton ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateRadioButton(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateEdit(lua_State* luaVM) -{ - // gui-edit guiCreateEdit ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateEdit(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateMemo(lua_State* luaVM) -{ - // gui-memo guiCreateMemo ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateMemo(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateGridList(lua_State* luaVM) -{ - // element guiCreateGridList ( float x, float y, float width, float height, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateGridList(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateScrollPane(lua_State* luaVM) -{ - // element guiCreateScrollPane( float x, float y, float width, float height, bool relative, [gui-element parent = nil]) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollPane(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateScrollBar(lua_State* luaVM) -{ - // gui-scrollbar guiCreateScrollBar ( float x, float y, float width, float height, bool horizontal, bool relative, [gui-element parent = nil]) - CVector2D position; - CVector2D size; - bool horizontal; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(horizontal); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollBar(*pLuaMain, position, size, horizontal, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateTabPanel(lua_State* luaVM) -{ - // element guiCreateTabPanel ( float x, float y, float width, float height, bool relative, [element parent = nil ] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTabPanel(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIStaticImageLoadImage(lua_State* luaVM) -{ - // bool guiStaticImageLoadImage ( element theElement, string filename ) - CClientGUIElement* theElement; - SString filename; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadString(filename); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CResource* pResource = pLuaMain->GetResource(); - SString strPath; - if (CResourceManager::ParseResourcePathInput(filename, pResource, &strPath)) - { - if (CStaticFunctionDefinitions::GUIStaticImageLoadImage(*theElement, strPath)) - { - lua_pushboolean(luaVM, true); - return 1; - } - else - argStream.SetCustomError(filename, "Error loading image"); - } - else - argStream.SetCustomError(filename, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIStaticImageGetNativeSize(lua_State* luaVM) -{ - // bool guiStaticImageGetNativeSize ( element theElement, string filename ) - CClientGUIElement* theElement; - CVector2D vecSize; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - if (CStaticFunctionDefinitions::GUIStaticImageGetNativeSize(*theElement, vecSize)) - { - lua_pushnumber(luaVM, vecSize.fX); - lua_pushnumber(luaVM, vecSize.fY); - return 2; - } - - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateTab(lua_State* luaVM) -{ - // element guiCreateTab ( string text, element parent ) - SString text; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadString(text); - argStream.ReadUserData(parent); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTab(*pLuaMain, text, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetSelectedTab(lua_State* luaVM) -{ - // element guiGetSelectedTab ( element tabPanel ) - CClientGUIElement* tabPanel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabPanel); - - if (!argStream.HasErrors()) - { - CClientGUIElement* pTab = CStaticFunctionDefinitions::GUIGetSelectedTab(*tabPanel); - lua_pushelement(luaVM, pTab); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetSelectedTab(lua_State* luaVM) -{ - // bool guiSetSelectedTab ( element tabPanel, element theTab ) - CClientGUIElement* tabPanel; - CClientGUIElement* theTab; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabPanel); - argStream.ReadUserData(theTab); - - if (!argStream.HasErrors()) - { - if (CStaticFunctionDefinitions::GUISetSelectedTab(*tabPanel, *theTab)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIDeleteTab(lua_State* luaVM) -{ - // bool guiDeleteTab ( element tabToDelete, element tabPanel ) - CClientGUIElement* tabToDelete; - CClientGUIElement* tabPanel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabToDelete); - argStream.ReadUserData(tabPanel); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - if (CStaticFunctionDefinitions::GUIDeleteTab(*pLuaMain, tabToDelete, tabPanel)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetText(lua_State* luaVM) -{ - // bool guiSetText ( element guiElement, string text ) - CClientGUIElement* guiElement; - SString text; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(text); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetText(*guiElement, text); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetFont(lua_State* luaVM) -{ - // bool guiSetFont ( element guiElement, mixed font ) - CClientGUIElement* guiElement; - SString strFontName; - CClientGuiFont* pGuiFontElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - MixedReadGuiFontString(argStream, strFontName, "default-normal", pGuiFontElement); - - if (!argStream.HasErrors()) - { - if (guiElement->SetFont(strFontName, pGuiFontElement)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIBringToFront(lua_State* luaVM) -{ - // bool guiBringToFront ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - if (CStaticFunctionDefinitions::GUIBringToFront(*guiElement)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMoveToBack(lua_State* luaVM) -{ - // bool guiMoveToBack( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMoveToBack(*guiElement); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIRadioButtonSetSelected(lua_State* luaVM) -{ - // bool guiRadioButtonSetSelected ( element guiRadioButton, bool state ) - CClientGUIElement* guiRadioButton; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiRadioButton); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIRadioButtonSetSelected(*guiRadioButton, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICheckBoxSetSelected(lua_State* luaVM) -{ - // bool guiCheckBoxSetSelected ( element theCheckbox, bool state ) - CClientGUIElement* theCheckbox; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theCheckbox); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUICheckBoxSetSelected(*theCheckbox, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIRadioButtonGetSelected(lua_State* luaVM) -{ - // bool guiRadioButtonGetSelected( element guiRadioButton ) - CClientGUIElement* guiRadioButton; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiRadioButton); - - if (!argStream.HasErrors()) - { - bool bResult = static_cast(guiRadioButton->GetCGUIElement())->GetSelected(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICheckBoxGetSelected(lua_State* luaVM) -{ - // bool guiCheckBoxGetSelected ( element theCheckbox ) - CClientGUIElement* theCheckbox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theCheckbox); - - if (!argStream.HasErrors()) - { - bool bResult = static_cast(theCheckbox->GetCGUIElement())->GetSelected(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIProgressBarSetProgress(lua_State* luaVM) -{ - // bool guiProgressBarSetProgress ( progressBar theProgressbar, float progress ) - CClientGUIElement* theProgressbar; - float progress; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theProgressbar); - argStream.ReadNumber(progress); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIProgressBarSetProgress(*theProgressbar, static_cast(progress)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollBarSetScrollPosition(lua_State* luaVM) -{ - // bool guiScrollBarSetScrollPosition ( gui-scrollBar theScrollBar, float amount ) - CClientGUIElement* theScrollBar; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollBar); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollBarSetScrollPosition(*theScrollBar, static_cast(amount)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetHorizontalScrollPosition(lua_State* luaVM) -{ - // bool guiScrollPaneSetHorizontalScrollPosition ( gui-scrollPane theScrollPane, float amount ) - CClientGUIElement* theScrollPane; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetHorizontalScrollPosition(*theScrollPane, amount); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiScrollPaneSetVerticalScrollPosition ( gui-scrollPane theScrollPane, float amount ) - CClientGUIElement* theScrollPane; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetVerticalScrollPosition(*theScrollPane, amount); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIProgressBarGetProgress(lua_State* luaVM) -{ - // float guiProgressBarGetProgress ( progressBar theProgressbar ); - CClientGUIElement* theProgressbar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theProgressbar); - - if (!argStream.HasErrors()) - { - int iProgress = (int)(static_cast(theProgressbar->GetCGUIElement())->GetProgress() * 100.0f + 0.5f); - lua_pushnumber(luaVM, iProgress); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneGetHorizontalScrollPosition(lua_State* luaVM) -{ - // float guiScrollPaneGetHorizontalScrollPosition ( gui-scrollPane theScrollPane ) - CClientGUIElement* theScrollPane; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - - if (!argStream.HasErrors()) - { - float fPos = static_cast(theScrollPane->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiScrollPaneGetVerticalScrollPosition ( gui-scrollPane theScrollPane ) - CClientGUIElement* theScrollPane; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - - if (!argStream.HasErrors()) - { - float fPos = static_cast(theScrollPane->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollBarGetScrollPosition(lua_State* luaVM) -{ - // float guiScrollBarGetScrollPosition ( gui-scrollBar theScrollBar ) - CClientGUIElement* theScrollBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollBar); - - if (!argStream.HasErrors()) - { - int iPos = (int)(static_cast(theScrollBar->GetCGUIElement())->GetScrollPosition() * 100.0f); - lua_pushnumber(luaVM, iPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetText(lua_State* luaVM) -{ - // string guiGetText ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - SString strText = guiElement->GetCGUIElement()->GetText(); - lua_pushstring(luaVM, strText); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetFont(lua_State* luaVM) -{ - // string,font guiGetFont ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - CClientGuiFont* pGuiFontElement; - SString strFontName = guiElement->GetFont(&pGuiFontElement); - - if (strFontName != "") - lua_pushstring(luaVM, strFontName); - else - lua_pushnil(luaVM); - lua_pushelement(luaVM, pGuiFontElement); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetSize(lua_State* luaVM) -{ - // float float guiGetSize ( element theElement, bool relative ) - CClientGUIElement* theElement; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CVector2D Size; - theElement->GetCGUIElement()->GetSize(Size, relative); - - lua_pushnumber(luaVM, Size.fX); - lua_pushnumber(luaVM, Size.fY); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetScreenSize(lua_State* luaVM) -{ - const CVector2D Size = CStaticFunctionDefinitions::GUIGetScreenSize(); - - lua_pushnumber(luaVM, Size.fX); - lua_pushnumber(luaVM, Size.fY); - return 2; -} - -int CLuaGUIDefs::GUIGetPosition(lua_State* luaVM) -{ - // float, float guiGetPosition ( element guiElement, bool relative ) - CClientGUIElement* guiElement; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CVector2D Pos; - guiElement->GetCGUIElement()->GetPosition(Pos, relative); - - lua_pushnumber(luaVM, Pos.fX); - lua_pushnumber(luaVM, Pos.fY); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetAlpha(lua_State* luaVM) -{ - // bool guiSetAlpha ( element guielement, float alpha ) - CClientGUIElement* guiElement; - float alpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(alpha); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetAlpha(*guiElement, Clamp(0.0f, alpha, 1.0f)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetAlpha(lua_State* luaVM) -{ - // int guiGetAlpha ( element guiElement [, bool effectiveAlpha = false] ) - CClientGUIElement* guiElement; - bool bEffectiveAlpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(bEffectiveAlpha, false); - - if (!argStream.HasErrors()) - { - float fAlpha = !bEffectiveAlpha ? guiElement->GetCGUIElement()->GetAlpha() : guiElement->GetCGUIElement()->GetEffectiveAlpha(); - lua_pushnumber(luaVM, fAlpha); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetVisible(lua_State* luaVM) -{ - // bool guiSetVisible ( element guiElement, bool state ) - CClientGUIElement* guiElement; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetVisible(*guiElement, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetEnabled(lua_State* luaVM) -{ - // bool guiSetEnabled ( element guiElement, bool enabled ) - CClientGUIElement* guiElement; - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetEnabled(*guiElement, enabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetProperty(lua_State* luaVM) -{ - // bool guiSetProperty ( element guiElement, string property, string value ) - CClientGUIElement* guiElement; - SString property; - SString value; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(property); - argStream.ReadString(value); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetProperty(*guiElement, property, value); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetVisible(lua_State* luaVM) -{ - // bool guiGetVisible ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - bool bResult = guiElement->GetCGUIElement()->IsVisible(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetEnabled(lua_State* luaVM) -{ - // bool guiGetEnabled ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - bool bResult = guiElement->GetCGUIElement()->IsEnabled(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetProperty(lua_State* luaVM) -{ - // string guiGetProperty ( element guiElement, string property ) - CClientGUIElement* guiElement; - SString property; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(property); - - if (!argStream.HasErrors()) - { - SString strValue = guiElement->GetCGUIElement()->GetProperty(property); - lua_pushstring(luaVM, strValue); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetProperties(lua_State* luaVM) -{ - // table guiGetProperties ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - // Create a new table - lua_newtable(luaVM); - - // Add all our properties to the table on top of the given lua main's stack - unsigned int uiIndex = 0; - CGUIPropertyIter iter = guiElement->GetCGUIElement()->GetPropertiesBegin(); - CGUIPropertyIter iterEnd = guiElement->GetCGUIElement()->GetPropertiesEnd(); - for (; iter != iterEnd; iter++) - { - const char* szKey = (*iter)->strKey; - const char* szValue = (*iter)->strValue; - - // Add it to the table - lua_pushstring(luaVM, szKey); - lua_pushstring(luaVM, szValue); - lua_settable(luaVM, -3); - } - - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetSize(lua_State* luaVM) -{ - // bool guiSetSize ( element guiElement, float width, float height, bool relative ) - CClientGUIElement* guiElement; - float width; - float height; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(width); - argStream.ReadNumber(height); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetSize(*guiElement, CVector2D(width, height), relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetPosition(lua_State* luaVM) -{ - // bool guiSetPosition ( element guiElement, float x, float y, bool relative ) - CClientGUIElement* guiElement; - float x; - float y; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(x); - argStream.ReadNumber(y); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetPosition(*guiElement, CVector2D(x, y), relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSortingEnabled(lua_State* luaVM) -{ - // bool guiGridListSetSortingEnabled ( element guiGridlist, bool enabled ) - CClientGUIElement* guiGridlist; - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSortingEnabled(*guiGridlist, enabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAddColumn(lua_State* luaVM) -{ - // int guiGridListAddColumn ( element gridList, string title, float width ) - CClientGUIElement* guiGridlist; - SString title; - float width; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadString(title); - argStream.ReadNumber(width); - - if (!argStream.HasErrors()) - { - uint id = CStaticFunctionDefinitions::GUIGridListAddColumn(*guiGridlist, title, width); - lua_pushnumber(luaVM, id); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListRemoveColumn(lua_State* luaVM) -{ - // bool guiGridListRemoveColumn ( element guiGridlist, int columnIndex ) - CClientGUIElement* guiGridlist; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListRemoveColumn(*guiGridlist, columnIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetColumnWidth(lua_State* luaVM) -{ - // bool guiGridListSetColumnWidth ( element gridList, int columnIndex, number width, bool relative ) - CClientGUIElement* guiGridlist; - int columnIndex; - float width; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - argStream.ReadNumber(width); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetColumnWidth(*guiGridlist, columnIndex, width, relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnWidth(lua_State* luaVM) -{ - // float guiGridListGetColumnWidth ( element gridList, int columnIndex, bool relative ) - CClientGUIElement* pGridList; - int columnIndex; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pGridList); - argStream.ReadNumber(columnIndex); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - float width; - if (static_cast(pGridList->GetCGUIElement())->GetColumnWidth(columnIndex, width, relative)) - { - lua_pushnumber(luaVM, width); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetColumnTitle(lua_State* luaVM) -{ - // bool guiGridListSetColumnTitle ( element guiGridlist, int columnIndex, string title ) - CClientGUIElement* guiGridlist; - int iColumnIndex; - SString sTitle; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(iColumnIndex); - argStream.ReadString(sTitle); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) - { - CStaticFunctionDefinitions::GUIGridListSetColumnTitle(*guiGridlist, iColumnIndex, sTitle); - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnTitle(lua_State* luaVM) -{ - // string guiGridListGetColumnTitle ( element guiGridlist, int columnIndex ) - CClientGUIElement* guiGridlist; - int iColumnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(iColumnIndex); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) - { - const char* szTitle = static_cast(guiGridlist->GetCGUIElement())->GetColumnTitle(iColumnIndex); - lua_pushstring(luaVM, szTitle); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAddRow(lua_State* luaVM) -{ - // int guiGridListAddRow ( element gridList ) - // int guiGridListAddRow ( element gridList, int/string itemText1, int/string itemText2 ... ) - CClientGUIElement* guiGridlist; - CLuaArguments Arguments; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadLuaArguments(Arguments); - - if (!argStream.HasErrors()) - { - int iRet = 0; - if (Arguments.Count() == 0) - iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true); - else - { - // Vector containing our string arguments. We add a bool to store whether it was originally a number. - std::vector > m_items; - std::vector::const_iterator it = Arguments.IterBegin(); - for (it; it != Arguments.IterEnd(); it++) - { - CLuaArgument* pArgument = *it; - SString strItemText; - bool bNumber = false; - - // Check the type of the argument and convert it to a string we can process - uint type = pArgument->GetType(); - if (type == LUA_TNUMBER) - { - // Grab the lua string and its size - const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); - size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); - - // Set our string - strItemText.assign(szLuaString, sizeLuaString); - bNumber = true; - } - else if (type == LUA_TSTRING) - strItemText = pArgument->GetString(); - else - continue; - - m_items.push_back(std::make_pair(strItemText, bNumber)); - } - iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true, &m_items); - } - - if (iRet >= 0) - { - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushnumber(luaVM, iRet); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListInsertRowAfter(lua_State* luaVM) -{ - // int guiGridListInsertRowAfter ( element gridList, int rowIndex ) - // int guiGridListInsertRowAfter ( element gridList, int rowIndex, int/string itemText1, int/string itemText2 ... ) - CClientGUIElement* guiGridlist; - int rowIndex; - CLuaArguments Arguments; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadLuaArguments(Arguments); - - if (!argStream.HasErrors()) - { - int iRet = 0; - if (Arguments.Count() == 0) - iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex); - else - { - // Vector containing our string arguments. We add a bool to store whether it was originally a number. - std::vector > m_items; - std::vector::const_iterator it = Arguments.IterBegin(); - for (it; it != Arguments.IterEnd(); it++) - { - CLuaArgument* pArgument = *it; - SString strItemText; - bool bNumber = false; - - // Check the type of the argument and convert it to a string we can process - uint type = pArgument->GetType(); - if (type == LUA_TNUMBER) - { - // Grab the lua string and its size - const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); - size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); - - // Set our string - strItemText.assign(szLuaString, sizeLuaString); - bNumber = true; - } - else if (type == LUA_TSTRING) - strItemText = pArgument->GetString(); - else - continue; - - m_items.push_back(std::make_pair(strItemText, bNumber)); - } - iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex, &m_items); - } - - if (iRet >= 0) - { - lua_pushnumber(luaVM, iRet); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAutoSizeColumn(lua_State* luaVM) -{ - // bool guiGridListAutoSizeColumn ( element gridList, int columnIndex ) - CClientGUIElement* guiGridlist; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListAutoSizeColumn(*guiGridlist, columnIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListClear(lua_State* luaVM) -{ - // bool guiGridListClear ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListClear(*guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSelectionMode(lua_State* luaVM) -{ - // bool guiGridListSetSelectionMode ( guiElement gridlist, int mode ) - CClientGUIElement* guiGridlist; - int mode; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(mode); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSelectionMode(*guiGridlist, mode); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedItem(lua_State* luaVM) -{ - // int, int guiGridListGetSelectedItem ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iRow = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemRow(); - int iColumn = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemColumn(); - lua_pushnumber(luaVM, iRow); - lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedItems(lua_State* luaVM) -{ - // table guiGridListGetSelectedItems ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - CGUIGridList* pList = static_cast(guiGridlist->GetCGUIElement()); - CGUIListItem* pItem = NULL; - - lua_newtable(luaVM); - - for (int i = 1; i <= pList->GetSelectedCount(); i++) - { - pItem = pList->GetNextSelectedItem(pItem); - if (!pItem) - break; - - lua_pushnumber(luaVM, i); - lua_newtable(luaVM); - - // column - lua_pushstring(luaVM, "column"); - lua_pushnumber(luaVM, pList->GetItemColumnIndex(pItem)); - lua_settable(luaVM, -3); - - // row - lua_pushstring(luaVM, "row"); - lua_pushnumber(luaVM, pList->GetItemRowIndex(pItem)); - lua_settable(luaVM, -3); - - // push to main table - lua_settable(luaVM, -3); - } - - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedCount(lua_State* luaVM) -{ - // int guiGridListGetSelectedCount ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iCount = static_cast(guiGridlist->GetCGUIElement())->GetSelectedCount(); - lua_pushnumber(luaVM, iCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSelectedItem(lua_State* luaVM) -{ - // bool guiGridListSetSelectedItem ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - bool bReset; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadBool(bReset, true); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSelectedItem(*guiGridlist, rowIndex, columnIndex, bReset); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListRemoveRow(lua_State* luaVM) -{ - // bool guiGridListRemoveRow ( element gridList, int rowIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListRemoveRow(*guiGridlist, rowIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemText(lua_State* luaVM) -{ - // string guiGridListGetItemText ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - const char* szText = static_cast(guiGridlist->GetCGUIElement())->GetItemText(rowIndex, columnIndex); - lua_pushstring(luaVM, szText); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemData(lua_State* luaVM) -{ - // string guiGridListGetItemData ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - void* pData = static_cast(guiGridlist->GetCGUIElement())->GetItemData(rowIndex, columnIndex); - CLuaArgument* pVariable = reinterpret_cast(pData); - if (pVariable) - pVariable->Push(luaVM); - else - lua_pushnil(luaVM); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemColor(lua_State* luaVM) -{ - // int int int int guiGridListGetItemColor ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255, ucAlpha = 255; - if (static_cast(guiGridlist->GetCGUIElement())->GetItemColor(rowIndex, columnIndex, ucRed, ucGreen, ucBlue, ucAlpha)) - { - lua_pushnumber(luaVM, ucRed); - lua_pushnumber(luaVM, ucGreen); - lua_pushnumber(luaVM, ucBlue); - lua_pushnumber(luaVM, ucAlpha); - return 4; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetHorizontalScrollPosition(lua_State* luaVM) -{ - // float guiGridListGetHorizontalScrollPosition ( element guiGridlist ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPosition); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiGridListGetVerticalScrollPosition ( element guiGridlist ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPosition); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemText(lua_State* luaVM) -{ - // bool guiGridListSetItemText ( element gridList, int rowIndex, int columnIndex, string text, bool section, bool number ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - SString text; - bool section; - bool number; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadString(text); - argStream.ReadBool(section); - argStream.ReadBool(number); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetItemText(*guiGridlist, rowIndex, columnIndex, text, section, number, true); - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemData(lua_State* luaVM) -{ - // bool guiGridListSetItemData ( element gridList, int rowIndex, int columnIndex, string data ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - CLuaArgument data; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadLuaArgument(data); - - if (!argStream.HasErrors()) - { - CLuaArgument* pData = new CLuaArgument(data); - CStaticFunctionDefinitions::GUIGridListSetItemData(*guiGridlist, rowIndex, columnIndex, pData); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemColor(lua_State* luaVM) -{ - // bool guiGridListSetItemColor ( element gridList, int rowIndex, int columnIndex, int red, int green, int blue[, int alpha = 255 ] ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - int red; - int green; - int blue; - int alpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadNumber(red); - argStream.ReadNumber(green); - argStream.ReadNumber(blue); - argStream.ReadNumber(alpha, 255); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetItemColor(*guiGridlist, rowIndex, columnIndex, red, green, blue, alpha); - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetScrollBars(lua_State* luaVM) -{ - // bool guiGridListSetScrollBars ( element guiGridlist, bool horizontalBar, bool verticalBar ) - CClientGUIElement* guiGridlist; - bool horizontalBar; - bool verticalBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadBool(horizontalBar); - argStream.ReadBool(verticalBar); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetScrollBars(*guiGridlist, horizontalBar, verticalBar); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetHorizontalScrollPosition(lua_State* luaVM) -{ - // bool guiGridListSetHorizontalScrollPosition ( element guiGridlist, float fPosition ) - CClientGUIElement* guiGridlist; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetHorizontalScrollPosition(*guiGridlist, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiGridListSetVerticalScrollPosition ( element guiGridlist, float fPosition ) - CClientGUIElement* guiGridlist; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetVerticalScrollPosition(*guiGridlist, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetScrollBars(lua_State* luaVM) -{ - // bool guiScrollPaneSetScrollBars ( element scrollPane, bool horizontal, bool vertical ) - CClientGUIElement* scrollPane; - bool horizontalBar; - bool verticalBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(scrollPane); - argStream.ReadBool(horizontalBar); - argStream.ReadBool(verticalBar); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetScrollBars(*scrollPane, horizontalBar, verticalBar); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetRowCount(lua_State* luaVM) -{ - // int guiGridListGetRowCount ( element theList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iRowCount = static_cast(guiGridlist->GetCGUIElement())->GetRowCount(); - lua_pushnumber(luaVM, iRowCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnCount(lua_State* luaVM) -{ - // int guiGridListGetColumnCount ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - lua_pushnumber(luaVM, iColumnCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) -{ - // bool guiEditSetReadOnly ( element editField, bool status ) - CClientGUIElement* editField; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetReadOnly(*editField, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) -{ - // bool guiEditIsReadOnly( element editField ) - CClientGUIElement* editField; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) -{ - // bool guiMemoSetReadOnly ( gui-memo theMemo, bool status ) - CClientGUIElement* theMemo; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetReadOnly(*theMemo, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) -{ - // bool guiMemoIsReadOnly( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) -{ - // bool guiEditSetMasked ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) -{ - // bool guiEditSetMaxLength ( element theElement, int length ) - CClientGUIElement* theElement; - int length; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(length); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetMaxLength(*theElement, length); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) -{ - // bool guiEditSetCaretIndex ( element theElement, int index ) - CClientGUIElement* theElement; - int index; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(index); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetCaretIndex(*theElement, index); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) -{ - // int guiEditGetCaretIndex ( element theElement ) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - lua_pushnumber(luaVM, static_cast(theElement->GetCGUIElement())->GetCaretIndex()); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) -{ - // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) - CClientGUIElement* theMemo; - int index; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(index); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetCaretIndex(*theMemo, index); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiMemoSetVerticalScrollPosition ( gui-memo theMemo, float fPosition ) - CClientGUIElement* theMemo; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) -{ - // bool guiMemoGetCaretIndex ( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - lua_pushnumber(luaVM, static_cast(theMemo->GetCGUIElement())->GetCaretIndex()); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiMemoGetVerticalScrollPosition ( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); - float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) -{ - // bool guiWindowSetMovable ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIWindowSetMovable(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) -{ - // bool guiWindowSetSizable ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIWindowSetSizable(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) -{ - // float guiLabelGetTextExtent ( element theLabel ) - CClientGUIElement* theLabel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - - if (!argStream.HasErrors()) - { - float fExtent = static_cast(theLabel->GetCGUIElement())->GetTextExtent(); - lua_pushnumber(luaVM, fExtent); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetFontHeight(lua_State* luaVM) -{ - // float guiLabelGetFontHeight ( element theLabel ) - CClientGUIElement* theLabel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - - if (!argStream.HasErrors()) - { - float fHeight = static_cast(theLabel->GetCGUIElement())->GetFontHeight(); - lua_pushnumber(luaVM, fHeight); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetColor(lua_State* luaVM) -{ - // bool guiLabelSetColor ( element theElement, int red, int green, int blue ) - CClientGUIElement* theElement; - int red; - int green; - int blue; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(red); - argStream.ReadNumber(green); - argStream.ReadNumber(blue); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUILabelSetColor(*theElement, red, green, blue); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetColor(lua_State* luaVM) -{ - // int r, int g, int b guiLabelGetColor ( element theElement ) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255; - static_cast(theElement->GetCGUIElement())->GetTextColor(ucRed, ucGreen, ucBlue); - lua_pushnumber(luaVM, ucRed); - lua_pushnumber(luaVM, ucGreen); - lua_pushnumber(luaVM, ucBlue); - return 3; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetVerticalAlign(lua_State* luaVM) -{ - // bool guiLabelSetVerticalAlign ( element theLabel, string align ) - CClientGUIElement* theLabel; - CGUIVerticalAlign align; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - argStream.ReadEnumString(align); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUILabelSetVerticalAlign(*theLabel, align); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetHorizontalAlign(lua_State* luaVM) -{ - // bool guiLabelSetHorizontalAlign ( element theLabel, string align, [ bool wordwrap = false ] ) - CClientGUIElement* theLabel; - CGUIHorizontalAlign align; - bool wordwrap; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - argStream.ReadEnumString(align); - argStream.ReadBool(wordwrap, false); - - if (!argStream.HasErrors()) - { - if (wordwrap) - align = (CGUIHorizontalAlign)(align + 4); - CStaticFunctionDefinitions::GUILabelSetHorizontalAlign(*theLabel, align); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) -{ - //* chat_font - Returns the chatbox font - //* chat_lines - Returns how many lines the chatbox has - //* chat_color - Returns the background color of the chatbox - //* chat_text_color - Returns the chatbox text color - //* chat_input_color - Returns the background color of the chatbox input - //* chat_input_prefix_color - Returns the color of the input prefix text - //* chat_input_text_color - Returns the color of the text in the chatbox input - //* chat_scale - Returns the scale of the text in the chatbox - //* chat_position_offset_x - Returns the position offset of the chatbox on the x axis - //* chat_position_offset_y - Returns the position offset of the chatbox on the y axis - //* chat_position_horizontal - Returns the horizontal position of the chatbox - //* chat_position_vertical - Returns the vertical position of the chatbox - //* chat_text_alignment - Returns the horizontal alignment of the chatbox text - //* chat_width - Returns the scale of the background width - //* chat_css_style_text - Returns whether text fades out over time - //* chat_css_style_background - Returns whether the background fades out over time - //* chat_line_life - Returns how long it takes for text to start fading out - //* chat_line_fade_out - Returns how long takes for text to fade out - //* chat_use_cegui - Returns whether CEGUI is used to render the chatbox - //* text_scale - Returns text scale - - CCVarsInterface* pCVars = g_pCore->GetCVars(); - int iNumber; - float fNumber; - pCVars->Get("chat_font", fNumber); - lua_newtable(luaVM); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_font"); - pCVars->Get("chat_lines", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_lines"); - pCVars->Get("chat_width", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_width"); - pCVars->Get("chat_position_offset_x", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_x"); - pCVars->Get("chat_position_offset_y", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_y"); - pCVars->Get("chat_position_horizontal", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_horizontal"); - pCVars->Get("chat_position_vertical", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_vertical"); - pCVars->Get("chat_text_alignment", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_text_alignment"); - pCVars->Get("chat_css_style_text", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_text"); - pCVars->Get("chat_css_style_background", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_background"); - pCVars->Get("chat_line_life", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_life"); - pCVars->Get("chat_line_fade_out", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_fade_out"); - pCVars->Get("text_scale", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "text_scale"); - pCVars->Get("chat_use_cegui", fNumber); - lua_pushboolean(luaVM, fNumber ? true : false); - lua_setfield(luaVM, -2, "chat_use_cegui"); - std::string strCVar; - std::stringstream ss; - int iR, iG, iB, iA; - pCVars->Get("chat_color", strCVar); - if (!strCVar.empty()) - { - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_color"); - } - pCVars->Get("chat_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_text_color"); - } - pCVars->Get("chat_input_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_color"); - } - pCVars->Get("chat_input_prefix_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_prefix_color"); - } - pCVars->Get("chat_input_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_text_color"); - } - pCVars->Get("chat_scale", strCVar); - if (!strCVar.empty()) - { - float fX, fY; - ss.clear(); - ss.str(strCVar); - ss >> fX >> fY; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, fX); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, fY); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_scale"); - } - - return 1; -} - -int CLuaGUIDefs::GUICreateComboBox(lua_State* luaVM) -{ - // element guiCreateComboBox ( float x, float y, float width, float height, string caption, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - SString caption; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(caption); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateComboBox(*pLuaMain, position, size, caption, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxAddItem(lua_State* luaVM) -{ - // int guiComboBoxAddItem( element comboBox, string value ) - CClientGUIElement* comboBox; - SString value; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadString(value); - - if (!argStream.HasErrors()) - { - int newId = CStaticFunctionDefinitions::GUIComboBoxAddItem(*comboBox, value); - lua_pushnumber(luaVM, newId); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxRemoveItem(lua_State* luaVM) -{ - // bool guiComboBoxRemoveItem( element comboBox, int itemId ) - CClientGUIElement* comboBox; - int itemId; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxRemoveItem(*comboBox, itemId); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxClear(lua_State* luaVM) -{ - // bool guiComboBoxClear ( element comboBox ) - CClientGUIElement* comboBox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxClear(*comboBox); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxGetSelected(lua_State* luaVM) -{ - // int guiComboBoxGetSelected ( element comboBox ) - CClientGUIElement* comboBox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - - if (!argStream.HasErrors()) - { - int selected = CStaticFunctionDefinitions::GUIComboBoxGetSelected(*comboBox); - lua_pushnumber(luaVM, selected); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxSetSelected(lua_State* luaVM) -{ - // bool guiComboBoxSetSelected ( element comboBox, int itemIndex ) - CClientGUIElement* comboBox; - int itemIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemIndex); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxSetSelected(*comboBox, itemIndex); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxGetItemText(lua_State* luaVM) -{ - // string guiComboBoxGetItemText ( element comboBox, int itemId ) - CClientGUIElement* comboBox; - int itemId; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - - if (!argStream.HasErrors()) - { - SString ret = CStaticFunctionDefinitions::GUIComboBoxGetItemText(*comboBox, itemId); - lua_pushstring(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxSetItemText(lua_State* luaVM) -{ - // bool guiComboBoxSetItemText ( element comboBox, int itemId, string text ) - CClientGUIElement* comboBox; - int itemId; - SString text; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - argStream.ReadString(text); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxSetItemText(*comboBox, itemId, text); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateFont(lua_State* luaVM) -{ - // element guiCreateFont( string filepath [, int size=9 ] ) - SString strFilePath; - int iSize; - - CScriptArgReader argStream(luaVM); - argStream.ReadString(strFilePath); - argStream.ReadNumber(iSize, 9); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CResource* pParentResource = pLuaMain->GetResource(); - CResource* pFileResource = pParentResource; - SString strPath, strMetaPath; - if (CResourceManager::ParseResourcePathInput(strFilePath, pFileResource, &strPath, &strMetaPath)) - { - if (FileExists(strPath)) - { - SString strUniqueName = SString("%s*%s*%s", pParentResource->GetName(), pFileResource->GetName(), strMetaPath.c_str()).Replace("\\", "/"); - CClientGuiFont* pGuiFont = g_pClientGame->GetManager()->GetRenderElementManager()->CreateGuiFont(strPath, strUniqueName, iSize); - if (pGuiFont) - { - // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's - // ElementGroup? ** - pGuiFont->SetParent(pParentResource->GetResourceDynamicEntity()); - lua_pushelement(luaVM, pGuiFont); - return 1; - } - argStream.SetCustomError(strFilePath, "Error creating font"); - } - else - argStream.SetCustomError(strFilePath, "File not found"); - } - else - argStream.SetCustomError(strFilePath, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) -{ - // string guiGetCursorType ( ) - auto eType = CStaticFunctionDefinitions::GUIGetCursorType(); - lua_pushstring(luaVM, EnumToString(eType)); - return 1; -} +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp + * PURPOSE: Lua definitions class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" + +void CLuaGUIDefs::LoadFunctions(void) +{ + CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); + CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); + CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); + CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); + + CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); + CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); + CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); + CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); + CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); + CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); + + CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); + CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); + CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); + + CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); + CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); + CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); + CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); + CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); + CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); + CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); + CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); + CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); + CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); + CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); + CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); + CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); + CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); + CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); + CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); + + CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); + CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); + CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); + CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); + CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); + + CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); + CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); + CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); + CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); + CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); + CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); + CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); + CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); + CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); + CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); + CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); + CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); + CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); + CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); + CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); + CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); + CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); + CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); + CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); + CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); + CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); + CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); + CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); + CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); + CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); + CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); + CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); + CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); + CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); + + CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); + CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); + CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); + CLuaCFunctions::AddFunction("guiSetText", GUISetText); + CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); + CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); + CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); + CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); + + CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); + CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); + + CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); + CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); + + CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); + CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); + CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); + CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); + CLuaCFunctions::AddFunction("guiGetText", GUIGetText); + CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); + CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); + CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); + CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); + CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); + + CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); + CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); + + CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); + CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); + + CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); + + CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); + CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); + CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); + CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); + CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); + CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); + + CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); + CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); + CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); + CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); + CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); + CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); + CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); + CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); + + CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); + CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); + + CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); + CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); + + CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); + + CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); + CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); + CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); + CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); + CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); + CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); + CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); +} + +void CLuaGUIDefs::AddClass(lua_State* luaVM) +{ + AddGuiElementClass(luaVM); + AddGuiFontClass(luaVM); + AddGuiWindowClass(luaVM); + AddGuiButtonClass(luaVM); + AddGuiEditClass(luaVM); + AddGuiLabelClass(luaVM); + AddGuiMemoClass(luaVM); + AddGuiImageClass(luaVM); + AddGuiComboBoxClass(luaVM); + AddGuiCheckBoxClass(luaVM); + AddGuiRadioButtonClass(luaVM); + AddGuiScrollPaneClass(luaVM); + AddGuiScrollBarClass(luaVM); + AddGuiProgressBarClass(luaVM); + AddGuiGridlistClass(luaVM); + AddGuiTabPanelClass(luaVM); + AddGuiTabClass(luaVM); +} + +// TODO: vector class +void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "bringToFront", "guiBringToFront"); + lua_classfunction(luaVM, "moveToBack", "guiMoveToBack"); + + lua_classfunction(luaVM, "isChatBoxInputActive", "isChatBoxInputActive"); + lua_classfunction(luaVM, "isConsoleActive", "isConsoleActive"); + lua_classfunction(luaVM, "isDebugViewActive", "isDebugViewActive"); + lua_classfunction(luaVM, "setDebugViewActive", "setDebugViewActive"); + lua_classfunction(luaVM, "isMainMenuActive", "isMainMenuActive"); + lua_classfunction(luaVM, "isMTAWindowActive", "isMTAWindowActive"); + lua_classfunction(luaVM, "isTransferBoxActive", "isTransferBoxActive"); + lua_classfunction(luaVM, "isInputEnabled", "guiGetInputEnabled"); + lua_classfunction(luaVM, "getInputMode", "guiGetInputMode"); + lua_classfunction(luaVM, "getCursorType", "guiGetCursorType"); + + lua_classfunction(luaVM, "getScreenSize", "guiGetScreenSize"); + lua_classfunction(luaVM, "getProperties", "guiGetProperties"); + lua_classfunction(luaVM, "getAlpha", "guiGetAlpha"); + lua_classfunction(luaVM, "getFont", "guiGetFont"); + lua_classfunction(luaVM, "getEnabled", "guiGetEnabled"); + lua_classfunction(luaVM, "getVisible", "guiGetVisible"); + lua_classfunction(luaVM, "getText", "guiGetText"); + lua_classfunction(luaVM, "getPosition", "guiGetPosition"); + lua_classfunction(luaVM, "getSize", "guiGetSize"); + lua_classfunction(luaVM, "getProperty", "guiGetProperty"); + + lua_classfunction(luaVM, "setInputEnabled", "guiSetInputEnabled"); + lua_classfunction(luaVM, "setAlpha", "guiSetAlpha"); + lua_classfunction(luaVM, "setEnabled", "guiSetEnabled"); + lua_classfunction(luaVM, "setFont", "guiSetFont"); + lua_classfunction(luaVM, "setVisible", "guiSetVisible"); + lua_classfunction(luaVM, "setText", "guiSetText"); + lua_classfunction(luaVM, "setInputMode", "guiSetInputMode"); + lua_classfunction(luaVM, "setProperty", "guiSetProperty"); + lua_classfunction(luaVM, "setPosition", "guiSetPosition"); + lua_classfunction(luaVM, "setSize", "guiSetSize"); + + lua_classvariable(luaVM, "chatBoxInputActive", NULL, "isChatBoxInputActive"); + lua_classvariable(luaVM, "consoleActive", NULL, "isConsoleActive"); + lua_classvariable(luaVM, "debugViewActive", "setDebugViewActive", "isDebugViewActive"); + lua_classvariable(luaVM, "mainMenuActive", NULL, "isMainMenuActive"); + lua_classvariable(luaVM, "mtaWindowActive", NULL, "isMTAWindowActive"); + lua_classvariable(luaVM, "transferBoxActive", NULL, "isTransferBoxActive"); + lua_classvariable(luaVM, "inputEnabled", "guiSetInputEnabled", "guiGetInputEnabled"); + lua_classvariable(luaVM, "inputMode", "guiGetInputMode", "guiSetInputMode"); + lua_classvariable(luaVM, "cursorAlpha", "setCursorAlpha", "getCursorAlpha"); + lua_classvariable(luaVM, "cursorType", NULL, "guiGetCursorType"); + lua_classvariable(luaVM, "font", "guiSetFont", "guiGetFont"); + lua_classvariable(luaVM, "visible", "guiSetVisible", "guiGetVisible"); + lua_classvariable(luaVM, "properties", NULL, "guiGetProperties"); + lua_classvariable(luaVM, "alpha", "guiSetAlpha", "guiGetAlpha"); + lua_classvariable(luaVM, "enabled", "guiSetEnabled", "guiGetEnabled"); + lua_classvariable(luaVM, "text", "guiSetText", "guiGetText"); + lua_classvariable(luaVM, "size", "guiSetSize", "guiGetSize"); + lua_classvariable(luaVM, "position", "guiSetPosition", "guiGetPosition"); + lua_classvariable(luaVM, "screenSize", NULL, "guiGetScreenSize"); + // lua_classvariable ( luaVM, "property" "guiSetProperty", "guiGetProperty" ); todo: .property[name] = value + + lua_registerclass(luaVM, "GuiElement", "Element"); +} + +void CLuaGUIDefs::AddGuiWindowClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateWindow"); + lua_classfunction(luaVM, "setMovable", "guiWindowSetMovable"); + lua_classfunction(luaVM, "setSizable", "guiWindowSetSizable"); + + lua_classvariable(luaVM, "movable", "guiWindowSetMovable", NULL); + lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", NULL); + + lua_registerclass(luaVM, "GuiWindow", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiButtonClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateButton"); + + lua_registerclass(luaVM, "GuiButton", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateEdit"); + lua_classfunction(luaVM, "getCaretIndex", "guiEditGetCaretIndex"); + lua_classfunction(luaVM, "setCaretIndex", "guiEditSetCaretIndex"); + lua_classfunction(luaVM, "setReadOnly", "guiEditSetReadOnly"); + lua_classfunction(luaVM, "setMasked", "guiEditSetMasked"); + lua_classfunction(luaVM, "setMaxLength", "guiEditSetMaxLength"); + + lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); + lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", "guiEditIsReadOnly"); + lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); + lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); + + lua_registerclass(luaVM, "GuiEdit", "GuiElement"); +} + +// TODO: specials +void CLuaGUIDefs::AddGuiLabelClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateLabel"); + + lua_classfunction(luaVM, "getFontHeight", "guiLabelGetFontHeight"); + lua_classfunction(luaVM, "getTextExtent", "guiLabelGetTextExtent"); + lua_classfunction(luaVM, "getColor", "guiLabelGetColor"); + + lua_classfunction(luaVM, "setColor", "guiLabelSetColor"); + lua_classfunction(luaVM, "setHorizontalAlign", "guiLabelSetHorizontalAlign"); + lua_classfunction(luaVM, "setVerticalAlign", "guiLabelSetVerticalAlign"); + + lua_classvariable(luaVM, "horizontalAlign", "guiLabelSetHorizontalAlign", NULL); + lua_classvariable(luaVM, "verticalAlign", "guiLabelSetVerticalAlign", NULL); + lua_classvariable(luaVM, "fontHeight", NULL, "guiLabelGetFontHeight"); + lua_classvariable(luaVM, "textExtent", NULL, "guiLabelGetTextExtent"); + // lua_classvariable ( luaVM, "color", "guiLabelGetColor", "guiLabelSetColor" ); + + lua_registerclass(luaVM, "GuiLabel", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiMemoClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateMemo"); + + lua_classfunction(luaVM, "getCaretIndex", "guiMemoGetCaretIndex"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); + + lua_classfunction(luaVM, "setCaretIndex", "guiMemoSetCaretIndex"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiMemoSetVerticalScrollPosition"); + lua_classfunction(luaVM, "setReadOnly", "guiMemoSetReadOnly"); + + lua_classvariable(luaVM, "caretIndex", "guiMemoSetCaretIndex", "guiMemoGetCaretIndex"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiMemoSetVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); + lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", "guiMemoIsReadOnly"); + + lua_registerclass(luaVM, "GuiMemo", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiImageClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateStaticImage"); + lua_classfunction(luaVM, "loadImage", "guiStaticImageLoadImage"); + + lua_classvariable(luaVM, "image", "guiStaticImageLoadImage", NULL); + + lua_registerclass(luaVM, "GuiStaticImage", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiComboBoxClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateComboBox"); + lua_classfunction(luaVM, "addItem", "guiComboBoxAddItem"); + lua_classfunction(luaVM, "clear", "guiComboBoxClear"); + lua_classfunction(luaVM, "removeItem", "guiComboBoxRemoveItem"); + + lua_classfunction(luaVM, "getSelected", "guiComboBoxGetSelected"); + lua_classfunction(luaVM, "getItemText", "guiComboBoxGetItemText"); + + lua_classfunction(luaVM, "setItemText", "guiComboBoxSetItemText"); + lua_classfunction(luaVM, "setSelected", "guiComboBoxSetSelected"); + + lua_classvariable(luaVM, "selected", "guiComboBoxSetSelected", "guiComboBoxGetSelected"); + + lua_registerclass(luaVM, "GuiComboBox", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiCheckBoxClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateCheckBox"); + + lua_classfunction(luaVM, "getSelected", "guiCheckBoxGetSelected"); + + lua_classfunction(luaVM, "setSelected", "guiCheckBoxSetSelected"); + + lua_classvariable(luaVM, "selected", "guiCheckBoxSetSelected", "guiCheckBoxGetSelected"); + + lua_registerclass(luaVM, "GuiCheckBox", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiRadioButtonClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateRadioButton"); + + lua_classfunction(luaVM, "getSelected", "guiRadioButtonGetSelected"); + + lua_classfunction(luaVM, "setSelected", "guiRadioButtonSetSelected"); + + lua_classvariable(luaVM, "selected", "guiRadioButtonSetSelected", "guiRadioButtonGetSelected"); + + lua_registerclass(luaVM, "GuiRadioButton", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiScrollPaneClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateScrollPane"); + + lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); + + lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition"); + lua_classfunction(luaVM, "setScrollBars", "guiScrollPaneSetScrollBars"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition"); + + lua_classvariable(luaVM, "horizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); + + lua_registerclass(luaVM, "GuiScrollPane", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiScrollBarClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateScrollBar"); + + lua_classfunction(luaVM, "getScrollPosition", "guiScrollBarGetScrollPosition"); + + lua_classfunction(luaVM, "setScrollPosition", "guiScrollBarSetScrollPosition"); + + lua_classvariable(luaVM, "scrollPosition", "guiScrollBarSetScrollPosition", "guiScrollBarGetScrollPosition"); + + lua_registerclass(luaVM, "GuiScrollBar", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiProgressBarClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateProgressBar"); + + lua_classfunction(luaVM, "getProgress", "guiProgressBarGetProgress"); + + lua_classfunction(luaVM, "setProgress", "guiProgressBarSetProgress"); + + lua_classvariable(luaVM, "progress", "guiProgressBarSetProgress", "guiProgressBarGetProgress"); + + lua_registerclass(luaVM, "GuiProgressBar", "GuiElement"); +} + +// TODO: special tables +void CLuaGUIDefs::AddGuiGridlistClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateGridList"); + lua_classfunction(luaVM, "addColumn", "guiGridListAddColumn"); + lua_classfunction(luaVM, "addRow", "guiGridListAddRow"); + lua_classfunction(luaVM, "autoSizeColumn", "guiGridListAutoSizeColumn"); + lua_classfunction(luaVM, "clear", "guiGridListClear"); + lua_classfunction(luaVM, "insertRowAfter", "guiGridListInsertRowAfter"); + lua_classfunction(luaVM, "removeColumn", "guiGridListRemoveColumn"); + lua_classfunction(luaVM, "removeRow", "guiGridListRemoveRow"); + + lua_classfunction(luaVM, "getItemData", "guiGridListGetItemData"); + lua_classfunction(luaVM, "getItemText", "guiGridListGetItemText"); + lua_classfunction(luaVM, "getRowCount", "guiGridListGetRowCount"); + lua_classfunction(luaVM, "getSelectedItem", "guiGridListGetSelectedItem"); + lua_classfunction(luaVM, "getItemColor", "guiGridListGetItemColor"); + lua_classfunction(luaVM, "getColumnTitle", "guiGridListGetColumnTitle"); + lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); + lua_classfunction(luaVM, "getSelectedCount", "guiGridListGetSelectedCount"); + lua_classfunction(luaVM, "getSelectedItems", "guiGridListGetSelectedItems"); + lua_classfunction(luaVM, "getColumnCount", "guiGridListGetColumnCount"); + + lua_classfunction(luaVM, "setItemData", "guiGridListSetItemData"); + lua_classfunction(luaVM, "setItemText", "guiGridListSetItemText"); + lua_classfunction(luaVM, "setScrollBars", "guiGridListSetScrollBars"); + lua_classfunction(luaVM, "setSelectedItem", "guiGridListSetSelectedItem"); + lua_classfunction(luaVM, "setSelectionMode", "guiGridListSetSelectionMode"); + lua_classfunction(luaVM, "setSortingEnabled", "guiGridListSetSortingEnabled"); + lua_classfunction(luaVM, "setColumnWidth", "guiGridListSetColumnWidth"); + lua_classfunction(luaVM, "setItemColor", "guiGridListSetItemColor"); + lua_classfunction(luaVM, "setColumnTitle", "guiGridListSetColumnTitle"); + lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiGridListSetHorizontalScrollPosition"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiGridListSetVerticalScrollPosition"); + + lua_classvariable(luaVM, "rowCount", NULL, "guiGridListGetRowCount"); + lua_classvariable(luaVM, "selectedCount", NULL, "guiGridListGetSelectedCount"); + lua_classvariable(luaVM, "selectedItems", NULL, "guiGridListGetSelectedItems"); + lua_classvariable(luaVM, "columnCount", NULL, "guiGridListGetColumnCount"); + lua_classvariable(luaVM, "selectionMode", "guiGridListSetSelectionMode", NULL); + lua_classvariable(luaVM, "sortingEnabled", "guiGridListSetSortingEnabled", NULL); + lua_classvariable(luaVM, "horizontalScrollPosition", "guiGridListSetHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiGridListGetVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); + // lua_classvariable ( luaVM, "selectedItem", NULL, "guiGridListGetSelectedItem" ); table + // lua_classvariable ( luaVM, "selectedItem", "guiGridListSetSelectedItem", NULL ); .selectedItem[column] = row (row in column) table + // lua_classvariable ( luaVM, "itemColor", "setItemColor", "getItemColor" ); table + // lua_classvariable ( luaVM, "columnTitle", "setColumnTitle", "getColumnTitle" ); table + + lua_registerclass(luaVM, "GuiGridList", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiTabPanelClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateTabPanel"); + + lua_classfunction(luaVM, "getSelectedTab", "guiGetSelectedTab"); + + lua_classfunction(luaVM, "setSelectedTab", "guiSetSelectedTab"); + + lua_classvariable(luaVM, "selectedTab", "guiSetSelectedTab", "guiGetSelectedTab"); + + lua_registerclass(luaVM, "GuiTabPanel", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiTabClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateTab"); + lua_classfunction(luaVM, "delete", "guiDeleteTab"); + + lua_registerclass(luaVM, "GuiTab", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiFontClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateFont"); + + lua_registerclass(luaVM, "GuiFont", "Element"); +} + +int CLuaGUIDefs::GUIGetInputEnabled(lua_State* luaVM) +{ + lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIGetInputEnabled()); + return 1; +} + +int CLuaGUIDefs::GUISetInputEnabled(lua_State* luaVM) +{ + // bool guiSetInputEnabled ( bool enabled ) + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetInputMode(enabled ? INPUTMODE_NO_BINDS : INPUTMODE_ALLOW_BINDS); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetInputMode(lua_State* luaVM) +{ + // bool guiSetInputMode ( string mode ) + eInputMode mode; + + CScriptArgReader argStream(luaVM); + argStream.ReadEnumString(mode); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetInputMode(mode); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetInputMode(lua_State* luaVM) +{ + eInputMode mode = CStaticFunctionDefinitions::GUIGetInputMode(); + lua_pushstring(luaVM, EnumToString(mode)); + return 1; +} + +int CLuaGUIDefs::GUIIsChatBoxInputActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsChatInputEnabled()); + return 1; +} + +int CLuaGUIDefs::GUIIsConsoleActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->GetConsole()->IsVisible()); + return 1; +} + +int CLuaGUIDefs::GUIIsDebugViewActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsDebugVisible()); + return 1; +} + +int CLuaGUIDefs::GUISetDebugViewActive(lua_State* luaVM) +{ + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + g_pCore->SetDebugVisible(enabled); + + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIIsMainMenuActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsMenuVisible()); + return 1; +} + +int CLuaGUIDefs::GUIIsMTAWindowActive(lua_State* luaVM) +{ + bool bActive = + (g_pCore->IsChatInputEnabled() || g_pCore->IsMenuVisible() || g_pCore->GetConsole()->IsVisible() || g_pClientGame->GetTransferBox()->IsVisible()); + + lua_pushboolean(luaVM, bActive); + return 1; +} + +int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); + return 1; +} + +int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) +{ + bool bEnabled; + CScriptArgReader argStream(luaVM); + argStream.ReadBool(bEnabled); + + if (!argStream.HasErrors()) + { + g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + return 1; +} + +int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); + return 1; +} + +int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) +{ + // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) + CVector2D position; + CVector2D size; + SString titleBarText; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(titleBarText); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateWindow(*pLuaMain, position, size, titleBarText, relative); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateLabel(lua_State* luaVM) +{ + // element guiCreateLabel ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateLabel(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateStaticImage(lua_State* luaVM) +{ + // element guiCreateStaticImage ( float x, float y, float width, float height, string path, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString path; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(path); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CResource* pResource = pLuaMain->GetResource(); + SString strPath; + if (CResourceManager::ParseResourcePathInput(path, pResource, &strPath)) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateStaticImage(*pLuaMain, position, size, strPath, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + else + argStream.SetCustomError(path, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateButton(lua_State* luaVM) +{ + // element guiCreateButton ( float x, float y, float width, float height, string text, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateButton(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateProgressBar(lua_State* luaVM) +{ + // element guiCreateProgressBar ( float x, float y, float width, float height, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateProgressBar(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateCheckBox(lua_State* luaVM) +{ + // element guiCreateCheckBox ( float x, float y, float width, float height, string text, bool selected, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool selected; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(selected); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateCheckBox(*pLuaMain, position, size, text, selected, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateRadioButton(lua_State* luaVM) +{ + // element guiCreateRadioButton ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateRadioButton(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateEdit(lua_State* luaVM) +{ + // gui-edit guiCreateEdit ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateEdit(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateMemo(lua_State* luaVM) +{ + // gui-memo guiCreateMemo ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateMemo(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateGridList(lua_State* luaVM) +{ + // element guiCreateGridList ( float x, float y, float width, float height, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateGridList(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateScrollPane(lua_State* luaVM) +{ + // element guiCreateScrollPane( float x, float y, float width, float height, bool relative, [gui-element parent = nil]) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollPane(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateScrollBar(lua_State* luaVM) +{ + // gui-scrollbar guiCreateScrollBar ( float x, float y, float width, float height, bool horizontal, bool relative, [gui-element parent = nil]) + CVector2D position; + CVector2D size; + bool horizontal; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(horizontal); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollBar(*pLuaMain, position, size, horizontal, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateTabPanel(lua_State* luaVM) +{ + // element guiCreateTabPanel ( float x, float y, float width, float height, bool relative, [element parent = nil ] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTabPanel(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIStaticImageLoadImage(lua_State* luaVM) +{ + // bool guiStaticImageLoadImage ( element theElement, string filename ) + CClientGUIElement* theElement; + SString filename; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadString(filename); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CResource* pResource = pLuaMain->GetResource(); + SString strPath; + if (CResourceManager::ParseResourcePathInput(filename, pResource, &strPath)) + { + if (CStaticFunctionDefinitions::GUIStaticImageLoadImage(*theElement, strPath)) + { + lua_pushboolean(luaVM, true); + return 1; + } + else + argStream.SetCustomError(filename, "Error loading image"); + } + else + argStream.SetCustomError(filename, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIStaticImageGetNativeSize(lua_State* luaVM) +{ + // bool guiStaticImageGetNativeSize ( element theElement, string filename ) + CClientGUIElement* theElement; + CVector2D vecSize; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + if (CStaticFunctionDefinitions::GUIStaticImageGetNativeSize(*theElement, vecSize)) + { + lua_pushnumber(luaVM, vecSize.fX); + lua_pushnumber(luaVM, vecSize.fY); + return 2; + } + + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateTab(lua_State* luaVM) +{ + // element guiCreateTab ( string text, element parent ) + SString text; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadString(text); + argStream.ReadUserData(parent); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTab(*pLuaMain, text, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetSelectedTab(lua_State* luaVM) +{ + // element guiGetSelectedTab ( element tabPanel ) + CClientGUIElement* tabPanel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabPanel); + + if (!argStream.HasErrors()) + { + CClientGUIElement* pTab = CStaticFunctionDefinitions::GUIGetSelectedTab(*tabPanel); + lua_pushelement(luaVM, pTab); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetSelectedTab(lua_State* luaVM) +{ + // bool guiSetSelectedTab ( element tabPanel, element theTab ) + CClientGUIElement* tabPanel; + CClientGUIElement* theTab; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabPanel); + argStream.ReadUserData(theTab); + + if (!argStream.HasErrors()) + { + if (CStaticFunctionDefinitions::GUISetSelectedTab(*tabPanel, *theTab)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIDeleteTab(lua_State* luaVM) +{ + // bool guiDeleteTab ( element tabToDelete, element tabPanel ) + CClientGUIElement* tabToDelete; + CClientGUIElement* tabPanel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabToDelete); + argStream.ReadUserData(tabPanel); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + if (CStaticFunctionDefinitions::GUIDeleteTab(*pLuaMain, tabToDelete, tabPanel)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetText(lua_State* luaVM) +{ + // bool guiSetText ( element guiElement, string text ) + CClientGUIElement* guiElement; + SString text; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(text); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetText(*guiElement, text); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetFont(lua_State* luaVM) +{ + // bool guiSetFont ( element guiElement, mixed font ) + CClientGUIElement* guiElement; + SString strFontName; + CClientGuiFont* pGuiFontElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + MixedReadGuiFontString(argStream, strFontName, "default-normal", pGuiFontElement); + + if (!argStream.HasErrors()) + { + if (guiElement->SetFont(strFontName, pGuiFontElement)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIBringToFront(lua_State* luaVM) +{ + // bool guiBringToFront ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + if (CStaticFunctionDefinitions::GUIBringToFront(*guiElement)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMoveToBack(lua_State* luaVM) +{ + // bool guiMoveToBack( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMoveToBack(*guiElement); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIRadioButtonSetSelected(lua_State* luaVM) +{ + // bool guiRadioButtonSetSelected ( element guiRadioButton, bool state ) + CClientGUIElement* guiRadioButton; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiRadioButton); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIRadioButtonSetSelected(*guiRadioButton, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICheckBoxSetSelected(lua_State* luaVM) +{ + // bool guiCheckBoxSetSelected ( element theCheckbox, bool state ) + CClientGUIElement* theCheckbox; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theCheckbox); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUICheckBoxSetSelected(*theCheckbox, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIRadioButtonGetSelected(lua_State* luaVM) +{ + // bool guiRadioButtonGetSelected( element guiRadioButton ) + CClientGUIElement* guiRadioButton; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiRadioButton); + + if (!argStream.HasErrors()) + { + bool bResult = static_cast(guiRadioButton->GetCGUIElement())->GetSelected(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICheckBoxGetSelected(lua_State* luaVM) +{ + // bool guiCheckBoxGetSelected ( element theCheckbox ) + CClientGUIElement* theCheckbox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theCheckbox); + + if (!argStream.HasErrors()) + { + bool bResult = static_cast(theCheckbox->GetCGUIElement())->GetSelected(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIProgressBarSetProgress(lua_State* luaVM) +{ + // bool guiProgressBarSetProgress ( progressBar theProgressbar, float progress ) + CClientGUIElement* theProgressbar; + float progress; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theProgressbar); + argStream.ReadNumber(progress); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIProgressBarSetProgress(*theProgressbar, static_cast(progress)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollBarSetScrollPosition(lua_State* luaVM) +{ + // bool guiScrollBarSetScrollPosition ( gui-scrollBar theScrollBar, float amount ) + CClientGUIElement* theScrollBar; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollBar); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollBarSetScrollPosition(*theScrollBar, static_cast(amount)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetHorizontalScrollPosition(lua_State* luaVM) +{ + // bool guiScrollPaneSetHorizontalScrollPosition ( gui-scrollPane theScrollPane, float amount ) + CClientGUIElement* theScrollPane; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetHorizontalScrollPosition(*theScrollPane, amount); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiScrollPaneSetVerticalScrollPosition ( gui-scrollPane theScrollPane, float amount ) + CClientGUIElement* theScrollPane; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetVerticalScrollPosition(*theScrollPane, amount); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIProgressBarGetProgress(lua_State* luaVM) +{ + // float guiProgressBarGetProgress ( progressBar theProgressbar ); + CClientGUIElement* theProgressbar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theProgressbar); + + if (!argStream.HasErrors()) + { + int iProgress = (int)(static_cast(theProgressbar->GetCGUIElement())->GetProgress() * 100.0f + 0.5f); + lua_pushnumber(luaVM, iProgress); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneGetHorizontalScrollPosition(lua_State* luaVM) +{ + // float guiScrollPaneGetHorizontalScrollPosition ( gui-scrollPane theScrollPane ) + CClientGUIElement* theScrollPane; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + + if (!argStream.HasErrors()) + { + float fPos = static_cast(theScrollPane->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiScrollPaneGetVerticalScrollPosition ( gui-scrollPane theScrollPane ) + CClientGUIElement* theScrollPane; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + + if (!argStream.HasErrors()) + { + float fPos = static_cast(theScrollPane->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollBarGetScrollPosition(lua_State* luaVM) +{ + // float guiScrollBarGetScrollPosition ( gui-scrollBar theScrollBar ) + CClientGUIElement* theScrollBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollBar); + + if (!argStream.HasErrors()) + { + int iPos = (int)(static_cast(theScrollBar->GetCGUIElement())->GetScrollPosition() * 100.0f); + lua_pushnumber(luaVM, iPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetText(lua_State* luaVM) +{ + // string guiGetText ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + SString strText = guiElement->GetCGUIElement()->GetText(); + lua_pushstring(luaVM, strText); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetFont(lua_State* luaVM) +{ + // string,font guiGetFont ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + CClientGuiFont* pGuiFontElement; + SString strFontName = guiElement->GetFont(&pGuiFontElement); + + if (strFontName != "") + lua_pushstring(luaVM, strFontName); + else + lua_pushnil(luaVM); + lua_pushelement(luaVM, pGuiFontElement); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetSize(lua_State* luaVM) +{ + // float float guiGetSize ( element theElement, bool relative ) + CClientGUIElement* theElement; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CVector2D Size; + theElement->GetCGUIElement()->GetSize(Size, relative); + + lua_pushnumber(luaVM, Size.fX); + lua_pushnumber(luaVM, Size.fY); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetScreenSize(lua_State* luaVM) +{ + const CVector2D Size = CStaticFunctionDefinitions::GUIGetScreenSize(); + + lua_pushnumber(luaVM, Size.fX); + lua_pushnumber(luaVM, Size.fY); + return 2; +} + +int CLuaGUIDefs::GUIGetPosition(lua_State* luaVM) +{ + // float, float guiGetPosition ( element guiElement, bool relative ) + CClientGUIElement* guiElement; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CVector2D Pos; + guiElement->GetCGUIElement()->GetPosition(Pos, relative); + + lua_pushnumber(luaVM, Pos.fX); + lua_pushnumber(luaVM, Pos.fY); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetAlpha(lua_State* luaVM) +{ + // bool guiSetAlpha ( element guielement, float alpha ) + CClientGUIElement* guiElement; + float alpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(alpha); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetAlpha(*guiElement, Clamp(0.0f, alpha, 1.0f)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetAlpha(lua_State* luaVM) +{ + // int guiGetAlpha ( element guiElement [, bool effectiveAlpha = false] ) + CClientGUIElement* guiElement; + bool bEffectiveAlpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(bEffectiveAlpha, false); + + if (!argStream.HasErrors()) + { + float fAlpha = !bEffectiveAlpha ? guiElement->GetCGUIElement()->GetAlpha() : guiElement->GetCGUIElement()->GetEffectiveAlpha(); + lua_pushnumber(luaVM, fAlpha); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetVisible(lua_State* luaVM) +{ + // bool guiSetVisible ( element guiElement, bool state ) + CClientGUIElement* guiElement; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetVisible(*guiElement, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetEnabled(lua_State* luaVM) +{ + // bool guiSetEnabled ( element guiElement, bool enabled ) + CClientGUIElement* guiElement; + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetEnabled(*guiElement, enabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetProperty(lua_State* luaVM) +{ + // bool guiSetProperty ( element guiElement, string property, string value ) + CClientGUIElement* guiElement; + SString property; + SString value; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(property); + argStream.ReadString(value); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetProperty(*guiElement, property, value); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetVisible(lua_State* luaVM) +{ + // bool guiGetVisible ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + bool bResult = guiElement->GetCGUIElement()->IsVisible(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetEnabled(lua_State* luaVM) +{ + // bool guiGetEnabled ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + bool bResult = guiElement->GetCGUIElement()->IsEnabled(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetProperty(lua_State* luaVM) +{ + // string guiGetProperty ( element guiElement, string property ) + CClientGUIElement* guiElement; + SString property; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(property); + + if (!argStream.HasErrors()) + { + SString strValue = guiElement->GetCGUIElement()->GetProperty(property); + lua_pushstring(luaVM, strValue); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetProperties(lua_State* luaVM) +{ + // table guiGetProperties ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + // Create a new table + lua_newtable(luaVM); + + // Add all our properties to the table on top of the given lua main's stack + unsigned int uiIndex = 0; + CGUIPropertyIter iter = guiElement->GetCGUIElement()->GetPropertiesBegin(); + CGUIPropertyIter iterEnd = guiElement->GetCGUIElement()->GetPropertiesEnd(); + for (; iter != iterEnd; iter++) + { + const char* szKey = (*iter)->strKey; + const char* szValue = (*iter)->strValue; + + // Add it to the table + lua_pushstring(luaVM, szKey); + lua_pushstring(luaVM, szValue); + lua_settable(luaVM, -3); + } + + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetSize(lua_State* luaVM) +{ + // bool guiSetSize ( element guiElement, float width, float height, bool relative ) + CClientGUIElement* guiElement; + float width; + float height; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(width); + argStream.ReadNumber(height); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetSize(*guiElement, CVector2D(width, height), relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetPosition(lua_State* luaVM) +{ + // bool guiSetPosition ( element guiElement, float x, float y, bool relative ) + CClientGUIElement* guiElement; + float x; + float y; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(x); + argStream.ReadNumber(y); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetPosition(*guiElement, CVector2D(x, y), relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSortingEnabled(lua_State* luaVM) +{ + // bool guiGridListSetSortingEnabled ( element guiGridlist, bool enabled ) + CClientGUIElement* guiGridlist; + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSortingEnabled(*guiGridlist, enabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAddColumn(lua_State* luaVM) +{ + // int guiGridListAddColumn ( element gridList, string title, float width ) + CClientGUIElement* guiGridlist; + SString title; + float width; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadString(title); + argStream.ReadNumber(width); + + if (!argStream.HasErrors()) + { + uint id = CStaticFunctionDefinitions::GUIGridListAddColumn(*guiGridlist, title, width); + lua_pushnumber(luaVM, id); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListRemoveColumn(lua_State* luaVM) +{ + // bool guiGridListRemoveColumn ( element guiGridlist, int columnIndex ) + CClientGUIElement* guiGridlist; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListRemoveColumn(*guiGridlist, columnIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetColumnWidth(lua_State* luaVM) +{ + // bool guiGridListSetColumnWidth ( element gridList, int columnIndex, number width, bool relative ) + CClientGUIElement* guiGridlist; + int columnIndex; + float width; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + argStream.ReadNumber(width); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetColumnWidth(*guiGridlist, columnIndex, width, relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnWidth(lua_State* luaVM) +{ + // float guiGridListGetColumnWidth ( element gridList, int columnIndex, bool relative ) + CClientGUIElement* pGridList; + int columnIndex; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pGridList); + argStream.ReadNumber(columnIndex); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + float width; + if (static_cast(pGridList->GetCGUIElement())->GetColumnWidth(columnIndex, width, relative)) + { + lua_pushnumber(luaVM, width); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetColumnTitle(lua_State* luaVM) +{ + // bool guiGridListSetColumnTitle ( element guiGridlist, int columnIndex, string title ) + CClientGUIElement* guiGridlist; + int iColumnIndex; + SString sTitle; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(iColumnIndex); + argStream.ReadString(sTitle); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) + { + CStaticFunctionDefinitions::GUIGridListSetColumnTitle(*guiGridlist, iColumnIndex, sTitle); + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnTitle(lua_State* luaVM) +{ + // string guiGridListGetColumnTitle ( element guiGridlist, int columnIndex ) + CClientGUIElement* guiGridlist; + int iColumnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(iColumnIndex); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) + { + const char* szTitle = static_cast(guiGridlist->GetCGUIElement())->GetColumnTitle(iColumnIndex); + lua_pushstring(luaVM, szTitle); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAddRow(lua_State* luaVM) +{ + // int guiGridListAddRow ( element gridList ) + // int guiGridListAddRow ( element gridList, int/string itemText1, int/string itemText2 ... ) + CClientGUIElement* guiGridlist; + CLuaArguments Arguments; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadLuaArguments(Arguments); + + if (!argStream.HasErrors()) + { + int iRet = 0; + if (Arguments.Count() == 0) + iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true); + else + { + // Vector containing our string arguments. We add a bool to store whether it was originally a number. + std::vector > m_items; + std::vector::const_iterator it = Arguments.IterBegin(); + for (it; it != Arguments.IterEnd(); it++) + { + CLuaArgument* pArgument = *it; + SString strItemText; + bool bNumber = false; + + // Check the type of the argument and convert it to a string we can process + uint type = pArgument->GetType(); + if (type == LUA_TNUMBER) + { + // Grab the lua string and its size + const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); + size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); + + // Set our string + strItemText.assign(szLuaString, sizeLuaString); + bNumber = true; + } + else if (type == LUA_TSTRING) + strItemText = pArgument->GetString(); + else + continue; + + m_items.push_back(std::make_pair(strItemText, bNumber)); + } + iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true, &m_items); + } + + if (iRet >= 0) + { + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushnumber(luaVM, iRet); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListInsertRowAfter(lua_State* luaVM) +{ + // int guiGridListInsertRowAfter ( element gridList, int rowIndex ) + // int guiGridListInsertRowAfter ( element gridList, int rowIndex, int/string itemText1, int/string itemText2 ... ) + CClientGUIElement* guiGridlist; + int rowIndex; + CLuaArguments Arguments; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadLuaArguments(Arguments); + + if (!argStream.HasErrors()) + { + int iRet = 0; + if (Arguments.Count() == 0) + iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex); + else + { + // Vector containing our string arguments. We add a bool to store whether it was originally a number. + std::vector > m_items; + std::vector::const_iterator it = Arguments.IterBegin(); + for (it; it != Arguments.IterEnd(); it++) + { + CLuaArgument* pArgument = *it; + SString strItemText; + bool bNumber = false; + + // Check the type of the argument and convert it to a string we can process + uint type = pArgument->GetType(); + if (type == LUA_TNUMBER) + { + // Grab the lua string and its size + const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); + size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); + + // Set our string + strItemText.assign(szLuaString, sizeLuaString); + bNumber = true; + } + else if (type == LUA_TSTRING) + strItemText = pArgument->GetString(); + else + continue; + + m_items.push_back(std::make_pair(strItemText, bNumber)); + } + iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex, &m_items); + } + + if (iRet >= 0) + { + lua_pushnumber(luaVM, iRet); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAutoSizeColumn(lua_State* luaVM) +{ + // bool guiGridListAutoSizeColumn ( element gridList, int columnIndex ) + CClientGUIElement* guiGridlist; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListAutoSizeColumn(*guiGridlist, columnIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListClear(lua_State* luaVM) +{ + // bool guiGridListClear ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListClear(*guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSelectionMode(lua_State* luaVM) +{ + // bool guiGridListSetSelectionMode ( guiElement gridlist, int mode ) + CClientGUIElement* guiGridlist; + int mode; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(mode); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSelectionMode(*guiGridlist, mode); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedItem(lua_State* luaVM) +{ + // int, int guiGridListGetSelectedItem ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iRow = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemRow(); + int iColumn = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemColumn(); + lua_pushnumber(luaVM, iRow); + lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedItems(lua_State* luaVM) +{ + // table guiGridListGetSelectedItems ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + CGUIGridList* pList = static_cast(guiGridlist->GetCGUIElement()); + CGUIListItem* pItem = NULL; + + lua_newtable(luaVM); + + for (int i = 1; i <= pList->GetSelectedCount(); i++) + { + pItem = pList->GetNextSelectedItem(pItem); + if (!pItem) + break; + + lua_pushnumber(luaVM, i); + lua_newtable(luaVM); + + // column + lua_pushstring(luaVM, "column"); + lua_pushnumber(luaVM, pList->GetItemColumnIndex(pItem)); + lua_settable(luaVM, -3); + + // row + lua_pushstring(luaVM, "row"); + lua_pushnumber(luaVM, pList->GetItemRowIndex(pItem)); + lua_settable(luaVM, -3); + + // push to main table + lua_settable(luaVM, -3); + } + + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedCount(lua_State* luaVM) +{ + // int guiGridListGetSelectedCount ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iCount = static_cast(guiGridlist->GetCGUIElement())->GetSelectedCount(); + lua_pushnumber(luaVM, iCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSelectedItem(lua_State* luaVM) +{ + // bool guiGridListSetSelectedItem ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + bool bReset; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadBool(bReset, true); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSelectedItem(*guiGridlist, rowIndex, columnIndex, bReset); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListRemoveRow(lua_State* luaVM) +{ + // bool guiGridListRemoveRow ( element gridList, int rowIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListRemoveRow(*guiGridlist, rowIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemText(lua_State* luaVM) +{ + // string guiGridListGetItemText ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + const char* szText = static_cast(guiGridlist->GetCGUIElement())->GetItemText(rowIndex, columnIndex); + lua_pushstring(luaVM, szText); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemData(lua_State* luaVM) +{ + // string guiGridListGetItemData ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + void* pData = static_cast(guiGridlist->GetCGUIElement())->GetItemData(rowIndex, columnIndex); + CLuaArgument* pVariable = reinterpret_cast(pData); + if (pVariable) + pVariable->Push(luaVM); + else + lua_pushnil(luaVM); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemColor(lua_State* luaVM) +{ + // int int int int guiGridListGetItemColor ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255, ucAlpha = 255; + if (static_cast(guiGridlist->GetCGUIElement())->GetItemColor(rowIndex, columnIndex, ucRed, ucGreen, ucBlue, ucAlpha)) + { + lua_pushnumber(luaVM, ucRed); + lua_pushnumber(luaVM, ucGreen); + lua_pushnumber(luaVM, ucBlue); + lua_pushnumber(luaVM, ucAlpha); + return 4; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetHorizontalScrollPosition(lua_State* luaVM) +{ + // float guiGridListGetHorizontalScrollPosition ( element guiGridlist ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPosition); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiGridListGetVerticalScrollPosition ( element guiGridlist ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPosition); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemText(lua_State* luaVM) +{ + // bool guiGridListSetItemText ( element gridList, int rowIndex, int columnIndex, string text, bool section, bool number ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + SString text; + bool section; + bool number; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadString(text); + argStream.ReadBool(section); + argStream.ReadBool(number); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetItemText(*guiGridlist, rowIndex, columnIndex, text, section, number, true); + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemData(lua_State* luaVM) +{ + // bool guiGridListSetItemData ( element gridList, int rowIndex, int columnIndex, string data ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + CLuaArgument data; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadLuaArgument(data); + + if (!argStream.HasErrors()) + { + CLuaArgument* pData = new CLuaArgument(data); + CStaticFunctionDefinitions::GUIGridListSetItemData(*guiGridlist, rowIndex, columnIndex, pData); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemColor(lua_State* luaVM) +{ + // bool guiGridListSetItemColor ( element gridList, int rowIndex, int columnIndex, int red, int green, int blue[, int alpha = 255 ] ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + int red; + int green; + int blue; + int alpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadNumber(red); + argStream.ReadNumber(green); + argStream.ReadNumber(blue); + argStream.ReadNumber(alpha, 255); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetItemColor(*guiGridlist, rowIndex, columnIndex, red, green, blue, alpha); + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetScrollBars(lua_State* luaVM) +{ + // bool guiGridListSetScrollBars ( element guiGridlist, bool horizontalBar, bool verticalBar ) + CClientGUIElement* guiGridlist; + bool horizontalBar; + bool verticalBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadBool(horizontalBar); + argStream.ReadBool(verticalBar); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetScrollBars(*guiGridlist, horizontalBar, verticalBar); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetHorizontalScrollPosition(lua_State* luaVM) +{ + // bool guiGridListSetHorizontalScrollPosition ( element guiGridlist, float fPosition ) + CClientGUIElement* guiGridlist; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetHorizontalScrollPosition(*guiGridlist, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiGridListSetVerticalScrollPosition ( element guiGridlist, float fPosition ) + CClientGUIElement* guiGridlist; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetVerticalScrollPosition(*guiGridlist, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetScrollBars(lua_State* luaVM) +{ + // bool guiScrollPaneSetScrollBars ( element scrollPane, bool horizontal, bool vertical ) + CClientGUIElement* scrollPane; + bool horizontalBar; + bool verticalBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(scrollPane); + argStream.ReadBool(horizontalBar); + argStream.ReadBool(verticalBar); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetScrollBars(*scrollPane, horizontalBar, verticalBar); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetRowCount(lua_State* luaVM) +{ + // int guiGridListGetRowCount ( element theList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iRowCount = static_cast(guiGridlist->GetCGUIElement())->GetRowCount(); + lua_pushnumber(luaVM, iRowCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnCount(lua_State* luaVM) +{ + // int guiGridListGetColumnCount ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + lua_pushnumber(luaVM, iColumnCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) +{ + // bool guiEditSetReadOnly ( element editField, bool status ) + CClientGUIElement* editField; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(editField); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetReadOnly(*editField, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) +{ + // bool guiEditIsReadOnly( element editField ) + CClientGUIElement* editField; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(editField); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) +{ + // bool guiMemoSetReadOnly ( gui-memo theMemo, bool status ) + CClientGUIElement* theMemo; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetReadOnly(*theMemo, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) +{ + // bool guiMemoIsReadOnly( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) +{ + // bool guiEditSetMasked ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) +{ + // bool guiEditSetMaxLength ( element theElement, int length ) + CClientGUIElement* theElement; + int length; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(length); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetMaxLength(*theElement, length); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) +{ + // bool guiEditSetCaretIndex ( element theElement, int index ) + CClientGUIElement* theElement; + int index; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(index); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetCaretIndex(*theElement, index); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) +{ + // int guiEditGetCaretIndex ( element theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, static_cast(theElement->GetCGUIElement())->GetCaretIndex()); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) +{ + // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) + CClientGUIElement* theMemo; + int index; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadNumber(index); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetCaretIndex(*theMemo, index); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiMemoSetVerticalScrollPosition ( gui-memo theMemo, float fPosition ) + CClientGUIElement* theMemo; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) +{ + // bool guiMemoGetCaretIndex ( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, static_cast(theMemo->GetCGUIElement())->GetCaretIndex()); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiMemoGetVerticalScrollPosition ( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); + float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) +{ + // bool guiWindowSetMovable ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIWindowSetMovable(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) +{ + // bool guiWindowSetSizable ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIWindowSetSizable(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) +{ + // float guiLabelGetTextExtent ( element theLabel ) + CClientGUIElement* theLabel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + + if (!argStream.HasErrors()) + { + float fExtent = static_cast(theLabel->GetCGUIElement())->GetTextExtent(); + lua_pushnumber(luaVM, fExtent); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetFontHeight(lua_State* luaVM) +{ + // float guiLabelGetFontHeight ( element theLabel ) + CClientGUIElement* theLabel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + + if (!argStream.HasErrors()) + { + float fHeight = static_cast(theLabel->GetCGUIElement())->GetFontHeight(); + lua_pushnumber(luaVM, fHeight); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetColor(lua_State* luaVM) +{ + // bool guiLabelSetColor ( element theElement, int red, int green, int blue ) + CClientGUIElement* theElement; + int red; + int green; + int blue; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(red); + argStream.ReadNumber(green); + argStream.ReadNumber(blue); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUILabelSetColor(*theElement, red, green, blue); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetColor(lua_State* luaVM) +{ + // int r, int g, int b guiLabelGetColor ( element theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255; + static_cast(theElement->GetCGUIElement())->GetTextColor(ucRed, ucGreen, ucBlue); + lua_pushnumber(luaVM, ucRed); + lua_pushnumber(luaVM, ucGreen); + lua_pushnumber(luaVM, ucBlue); + return 3; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetVerticalAlign(lua_State* luaVM) +{ + // bool guiLabelSetVerticalAlign ( element theLabel, string align ) + CClientGUIElement* theLabel; + CGUIVerticalAlign align; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + argStream.ReadEnumString(align); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUILabelSetVerticalAlign(*theLabel, align); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetHorizontalAlign(lua_State* luaVM) +{ + // bool guiLabelSetHorizontalAlign ( element theLabel, string align, [ bool wordwrap = false ] ) + CClientGUIElement* theLabel; + CGUIHorizontalAlign align; + bool wordwrap; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + argStream.ReadEnumString(align); + argStream.ReadBool(wordwrap, false); + + if (!argStream.HasErrors()) + { + if (wordwrap) + align = (CGUIHorizontalAlign)(align + 4); + CStaticFunctionDefinitions::GUILabelSetHorizontalAlign(*theLabel, align); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) +{ + //* chat_font - Returns the chatbox font + //* chat_lines - Returns how many lines the chatbox has + //* chat_color - Returns the background color of the chatbox + //* chat_text_color - Returns the chatbox text color + //* chat_input_color - Returns the background color of the chatbox input + //* chat_input_prefix_color - Returns the color of the input prefix text + //* chat_input_text_color - Returns the color of the text in the chatbox input + //* chat_scale - Returns the scale of the text in the chatbox + //* chat_position_offset_x - Returns the position offset of the chatbox on the x axis + //* chat_position_offset_y - Returns the position offset of the chatbox on the y axis + //* chat_position_horizontal - Returns the horizontal position of the chatbox + //* chat_position_vertical - Returns the vertical position of the chatbox + //* chat_text_alignment - Returns the horizontal alignment of the chatbox text + //* chat_width - Returns the scale of the background width + //* chat_css_style_text - Returns whether text fades out over time + //* chat_css_style_background - Returns whether the background fades out over time + //* chat_line_life - Returns how long it takes for text to start fading out + //* chat_line_fade_out - Returns how long takes for text to fade out + //* chat_use_cegui - Returns whether CEGUI is used to render the chatbox + //* text_scale - Returns text scale + + CCVarsInterface* pCVars = g_pCore->GetCVars(); + int iNumber; + float fNumber; + pCVars->Get("chat_font", fNumber); + lua_newtable(luaVM); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_font"); + pCVars->Get("chat_lines", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_lines"); + pCVars->Get("chat_width", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_width"); + pCVars->Get("chat_position_offset_x", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_position_offset_x"); + pCVars->Get("chat_position_offset_y", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_position_offset_y"); + pCVars->Get("chat_position_horizontal", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_position_horizontal"); + pCVars->Get("chat_position_vertical", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_position_vertical"); + pCVars->Get("chat_text_alignment", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_text_alignment"); + pCVars->Get("chat_css_style_text", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_css_style_text"); + pCVars->Get("chat_css_style_background", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_css_style_background"); + pCVars->Get("chat_line_life", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_line_life"); + pCVars->Get("chat_line_fade_out", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_line_fade_out"); + pCVars->Get("text_scale", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "text_scale"); + pCVars->Get("chat_use_cegui", fNumber); + lua_pushboolean(luaVM, fNumber ? true : false); + lua_setfield(luaVM, -2, "chat_use_cegui"); + std::string strCVar; + std::stringstream ss; + int iR, iG, iB, iA; + pCVars->Get("chat_color", strCVar); + if (!strCVar.empty()) + { + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_color"); + } + pCVars->Get("chat_text_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_text_color"); + } + pCVars->Get("chat_input_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_color"); + } + pCVars->Get("chat_input_prefix_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_prefix_color"); + } + pCVars->Get("chat_input_text_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_text_color"); + } + pCVars->Get("chat_scale", strCVar); + if (!strCVar.empty()) + { + float fX, fY; + ss.clear(); + ss.str(strCVar); + ss >> fX >> fY; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, fX); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, fY); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_scale"); + } + + return 1; +} + +int CLuaGUIDefs::GUICreateComboBox(lua_State* luaVM) +{ + // element guiCreateComboBox ( float x, float y, float width, float height, string caption, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + SString caption; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(caption); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateComboBox(*pLuaMain, position, size, caption, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxAddItem(lua_State* luaVM) +{ + // int guiComboBoxAddItem( element comboBox, string value ) + CClientGUIElement* comboBox; + SString value; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadString(value); + + if (!argStream.HasErrors()) + { + int newId = CStaticFunctionDefinitions::GUIComboBoxAddItem(*comboBox, value); + lua_pushnumber(luaVM, newId); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxRemoveItem(lua_State* luaVM) +{ + // bool guiComboBoxRemoveItem( element comboBox, int itemId ) + CClientGUIElement* comboBox; + int itemId; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxRemoveItem(*comboBox, itemId); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxClear(lua_State* luaVM) +{ + // bool guiComboBoxClear ( element comboBox ) + CClientGUIElement* comboBox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxClear(*comboBox); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxGetSelected(lua_State* luaVM) +{ + // int guiComboBoxGetSelected ( element comboBox ) + CClientGUIElement* comboBox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + int selected = CStaticFunctionDefinitions::GUIComboBoxGetSelected(*comboBox); + lua_pushnumber(luaVM, selected); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxSetSelected(lua_State* luaVM) +{ + // bool guiComboBoxSetSelected ( element comboBox, int itemIndex ) + CClientGUIElement* comboBox; + int itemIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemIndex); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxSetSelected(*comboBox, itemIndex); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxGetItemText(lua_State* luaVM) +{ + // string guiComboBoxGetItemText ( element comboBox, int itemId ) + CClientGUIElement* comboBox; + int itemId; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + + if (!argStream.HasErrors()) + { + SString ret = CStaticFunctionDefinitions::GUIComboBoxGetItemText(*comboBox, itemId); + lua_pushstring(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxSetItemText(lua_State* luaVM) +{ + // bool guiComboBoxSetItemText ( element comboBox, int itemId, string text ) + CClientGUIElement* comboBox; + int itemId; + SString text; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + argStream.ReadString(text); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxSetItemText(*comboBox, itemId, text); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateFont(lua_State* luaVM) +{ + // element guiCreateFont( string filepath [, int size=9 ] ) + SString strFilePath; + int iSize; + + CScriptArgReader argStream(luaVM); + argStream.ReadString(strFilePath); + argStream.ReadNumber(iSize, 9); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CResource* pParentResource = pLuaMain->GetResource(); + CResource* pFileResource = pParentResource; + SString strPath, strMetaPath; + if (CResourceManager::ParseResourcePathInput(strFilePath, pFileResource, &strPath, &strMetaPath)) + { + if (FileExists(strPath)) + { + SString strUniqueName = SString("%s*%s*%s", pParentResource->GetName(), pFileResource->GetName(), strMetaPath.c_str()).Replace("\\", "/"); + CClientGuiFont* pGuiFont = g_pClientGame->GetManager()->GetRenderElementManager()->CreateGuiFont(strPath, strUniqueName, iSize); + if (pGuiFont) + { + // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's + // ElementGroup? ** + pGuiFont->SetParent(pParentResource->GetResourceDynamicEntity()); + lua_pushelement(luaVM, pGuiFont); + return 1; + } + argStream.SetCustomError(strFilePath, "Error creating font"); + } + else + argStream.SetCustomError(strFilePath, "File not found"); + } + else + argStream.SetCustomError(strFilePath, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) +{ + // string guiGetCursorType ( ) + auto eType = CStaticFunctionDefinitions::GUIGetCursorType(); + lua_pushstring(luaVM, EnumToString(eType)); + return 1; +} From ea9986667d57a0a0fdde77afc150608b83a44fe4 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 17:36:38 +0200 Subject: [PATCH 11/27] Revert "Revert "added option to allow server control transfer box"" This reverts commit df074aeb286fab6423654dcb5f052cdab7604224. --- Client/core/CClientVariables.cpp | 1 + Client/core/CSettings.cpp | 21 +- Client/core/CSettings.h | 4 + Client/mods/deathmatch/logic/CClientGame.cpp | 13748 ++++++++-------- .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 7764 ++++----- 5 files changed, 10786 insertions(+), 10752 deletions(-) diff --git a/Client/core/CClientVariables.cpp b/Client/core/CClientVariables.cpp index 4516a4813b6..e8b9a2245ee 100644 --- a/Client/core/CClientVariables.cpp +++ b/Client/core/CClientVariables.cpp @@ -330,6 +330,7 @@ void CClientVariables::LoadDefaults(void) DEFAULT("high_detail_vehicles", 0); // Disable rendering high detail vehicles all the time DEFAULT("fast_clothes_loading", 1); // 0-off 1-auto 2-on DEFAULT("allow_screen_upload", 1); // 0-off 1-on + DEFAULT("allow_server_control_transfebox", 1); // 0-off 1-on DEFAULT("max_clientscript_log_kb", 5000); // Max size in KB (0-No limit) DEFAULT("display_fullscreen_style", 0); // 0-standard 1-borderless 2-borderless keep res 3-borderless stretch DEFAULT("display_windowed", 0); // 0-off 1-on diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 13ce2ee374b..5dab8377fa5 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -376,6 +376,11 @@ void CSettings::CreateGUI(void) m_pCheckBoxAllowScreenUpload->GetPosition(vecTemp, false); m_pCheckBoxAllowScreenUpload->AutoSize(NULL, 20.0f); + m_pCheckBoxAllowControlTransferBox = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Allow server to control transfer box"), true)); + m_pCheckBoxAllowControlTransferBox->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); + m_pCheckBoxAllowControlTransferBox->GetPosition(vecTemp, false); + m_pCheckBoxAllowControlTransferBox->AutoSize(NULL, 20.0f); + m_pCheckBoxCustomizedSAFiles = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Use customized GTA:SA files"), true)); m_pCheckBoxCustomizedSAFiles->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); m_pCheckBoxCustomizedSAFiles->GetPosition(vecTemp, false); @@ -1488,6 +1493,11 @@ void CSettings::UpdateVideoTab(void) CVARS_GET("allow_screen_upload", bAllowScreenUploadEnabled); m_pCheckBoxAllowScreenUpload->SetSelected(bAllowScreenUploadEnabled); + // Allow screen upload + bool bAllowServerTransferBoxControl; + CVARS_GET("allow_server_control_transfebox", bAllowServerTransferBoxControl); + m_pCheckBoxAllowControlTransferBox->SetSelected(bAllowServerTransferBoxControl); + // Customized sa files m_pCheckBoxCustomizedSAFiles->SetSelected(GetApplicationSettingInt("customized-sa-files-request") != 0); m_pCheckBoxCustomizedSAFiles->SetVisible(GetApplicationSettingInt("customized-sa-files-show") != 0); @@ -3294,9 +3304,13 @@ void CSettings::SaveData(void) CVARS_SET("show_unsafe_resolutions", bShowUnsafeResolutions); // Allow screen upload - bool bAllowScreenUploadEnabled = m_pCheckBoxAllowScreenUpload->GetSelected(); + bAllowScreenUploadEnabled = m_pCheckBoxAllowScreenUpload->GetSelected(); CVARS_SET("allow_screen_upload", bAllowScreenUploadEnabled); + // Allow screen upload + bool m_pCheckBoxAllowScreenUpload = m_pCheckBoxAllowControlTransferBox->GetSelected(); + CVARS_SET("allow_server_control_transfebox", m_pCheckBoxAllowScreenUpload); + // Grass bool bGrassEnabled = m_pCheckBoxGrass->GetSelected(); CVARS_SET("grass", bGrassEnabled); @@ -4534,3 +4548,8 @@ bool CSettings::IsActive(void) { return m_pWindow->IsActive(); } + +bool CSettings::IsTransferBoxControlEnabled(void) +{ + return bAllowScreenUploadEnabled; +} diff --git a/Client/core/CSettings.h b/Client/core/CSettings.h index 0fb9c252a20..b46dec45061 100644 --- a/Client/core/CSettings.h +++ b/Client/core/CSettings.h @@ -117,6 +117,7 @@ class CSettings void TabSkip(bool bBackwards); bool IsActive(void); + bool IsTransferBoxControlEnabled(void); void SetSelectedIndex(unsigned int uiIndex); @@ -151,6 +152,7 @@ class CSettings CGUICheckBox* m_pCheckBoxDeviceSelectionDialog; CGUICheckBox* m_pCheckBoxShowUnsafeResolutions; CGUICheckBox* m_pCheckBoxAllowScreenUpload; + CGUICheckBox* m_pCheckBoxAllowControlTransferBox; CGUICheckBox* m_pCheckBoxCustomizedSAFiles; CGUICheckBox* m_pCheckBoxGrass; CGUICheckBox* m_pCheckBoxHeatHaze; @@ -443,4 +445,6 @@ class CSettings int m_iMaxAnisotropic; std::list m_pKeyBindSections; + + bool bAllowScreenUploadEnabled; }; diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index cef5af3a459..80cb359d464 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -1,6874 +1,6874 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto v1.0 - * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/CClientGame.cpp - * PURPOSE: Client game manager - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#include "StdInc.h" -#include -#include "game/CAnimBlendAssocGroup.h" -#include "game/CAnimBlendAssociation.h" -#include "game/CAnimBlendHierarchy.h" - -SString StringZeroPadout(const SString& strInput, uint uiPadoutSize) -{ - SString strResult = strInput; - while (strResult.length() < uiPadoutSize) - strResult += '\0'; - return strResult; -} - -using SharedUtil::CalcMTASAPath; -using std::list; -using std::vector; - -// Hide the "conversion from 'unsigned long' to 'DWORD*' of greater size" warning -#pragma warning(disable:4312) - -// Used within this file by the packet handler to grab the this pointer of CClientGame -extern CClientGame* g_pClientGame; -extern int g_iDamageEventLimit; -float g_fApplyDamageLastAmount; -uchar g_ucApplyDamageLastHitZone; -CClientPed* g_pApplyDamageLastDamagedPed; -bool g_bBulletFireVectorsValid; -CVector g_vecBulletFireStartPosition; -CVector g_vecBulletFireEndPosition; - -#define DEFAULT_GRAVITY 0.008f -#define DEFAULT_GAME_SPEED 1.0f -#define DEFAULT_BLUR_LEVEL 36 -#define DEFAULT_JETPACK_MAXHEIGHT 100 -#define DEFAULT_AIRCRAFT_MAXHEIGHT 800 -#define DEFAULT_AIRCRAFT_MAXVELOCITY 1.5f -#define DEFAULT_MINUTE_DURATION 1000 -#define DOUBLECLICK_TIMEOUT 330 -#define DOUBLECLICK_MOVE_THRESHOLD 10.0f - -CClientGame::CClientGame(bool bLocalPlay) -{ - // Init the global var with ourself - g_pClientGame = this; - - // Packet handler - m_pPacketHandler = new CPacketHandler(); - - // Init - m_bLocalPlay = bLocalPlay; - m_bErrorStartingLocal = false; - m_iLocalConnectAttempts = 0; - m_Status = CClientGame::STATUS_CONNECTING; - m_ulVerifyTimeStart = 0; - m_ulLastClickTick = 0; - m_pLocalPlayer = NULL; - m_LocalID = INVALID_ELEMENT_ID; - m_bShowNametags = true; - m_bWaitingForLocalConnect = false; - m_bShowRadar = false; - m_bGameLoaded = false; - m_bTriggeredIngameAndConnected = false; - m_bGracefulDisconnect = false; - m_ulLastVehicleInOutTime = 0; - m_bIsGettingOutOfVehicle = false; - m_bIsGettingIntoVehicle = false; - m_bIsGettingJacked = false; - m_bIsJackingVehicle = false; - m_VehicleInOutID = INVALID_ELEMENT_ID; - m_pGettingJackedBy = NULL; - m_ucVehicleInOutSeat = 0xFF; - m_pTargetedEntity = NULL; - m_TargetedPlayerID = INVALID_ELEMENT_ID; - m_pDamageEntity = NULL; - m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageBodyPiece = 0xFF; - m_ucDamageWeapon = 0xFF; - m_ulDamageTime = 0; - m_bDamageSent = true; - m_bShowNetstat = false; - m_bShowFPS = false; - m_bHudAreaNameDisabled = false; - m_fGameSpeed = 1.0f; - m_lMoney = 0; - m_dwWanted = 0; - m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) - ResetAmmoInClip(); - - m_bNoNewVehicleTask = false; - m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; - - m_bCursorEventsEnabled = false; - m_bInitiallyFadedOut = true; - - m_bIsPlayingBack = false; - m_bFirstPlaybackFrame = false; - - // Setup game glitch defaults ( false = disabled ). Remember to update these serverside if you alter them! - m_Glitches[GLITCH_QUICKRELOAD] = false; - g_pMultiplayer->DisableQuickReload(true); - m_Glitches[GLITCH_FASTFIRE] = false; - m_Glitches[GLITCH_FASTMOVE] = false; - m_Glitches[GLITCH_CROUCHBUG] = false; - m_Glitches[GLITCH_CLOSEDAMAGE] = false; - g_pMultiplayer->DisableCloseRangeDamage(true); - m_Glitches[GLITCH_HITANIM] = false; - m_Glitches[GLITCH_FASTSPRINT] = false; - m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; - m_Glitches[GLITCH_QUICKSTAND] = false; - g_pMultiplayer->DisableBadDrivebyHitboxes(true); - - // Remove Night & Thermal vision view (if enabled). - g_pMultiplayer->SetNightVisionEnabled(false); - g_pMultiplayer->SetThermalVisionEnabled(false); - - m_bCloudsEnabled = true; - - m_bBirdsEnabled = true; - - m_bWasMinimized = false; - - // Grab the mod path - m_strModRoot = g_pCore->GetModInstallRoot("deathmatch"); - - // Figure out which directory to use for the client resource file cache - SetFileCacheRoot(); - - // Override CGUI's global events - g_pCore->GetGUI()->SetKeyDownHandler(INPUT_MOD, GUI_CALLBACK_KEY(&CClientGame::OnKeyDown, this)); - g_pCore->GetGUI()->SetMouseClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseClick, this)); - g_pCore->GetGUI()->SetMouseDoubleClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseDoubleClick, this)); - g_pCore->GetGUI()->SetMouseButtonDownHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonDown, this)); - g_pCore->GetGUI()->SetMouseButtonUpHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonUp, this)); - g_pCore->GetGUI()->SetMouseMoveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseMove, this)); - g_pCore->GetGUI()->SetMouseEnterHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseEnter, this)); - g_pCore->GetGUI()->SetMouseLeaveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseLeave, this)); - g_pCore->GetGUI()->SetMouseWheelHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseWheel, this)); - g_pCore->GetGUI()->SetMovedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnMove, this)); - g_pCore->GetGUI()->SetSizedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnSize, this)); - g_pCore->GetGUI()->SetFocusGainedHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusGain, this)); - g_pCore->GetGUI()->SetFocusLostHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusLoss, this)); - g_pCore->GetGUI()->SelectInputHandlers(INPUT_MOD); - - // Startup "entities from root" optimization for getElementsByType - CClientEntity::StartupEntitiesFromRoot(); - - // Startup game entity tracking manager - m_pGameEntityXRefManager = NewGameEntityXRefManager(); - m_pModelCacheManager = NewClientModelCacheManager(); - - // Initialize our root entity with an invalid id, we dont know the true id until map-start - m_pRootEntity = new CClientDummy(NULL, INVALID_ELEMENT_ID, "root"); - m_pRootEntity->MakeSystemEntity(); - - m_pDebugHookManager = new CDebugHookManager(); - - // Movings objects manager - m_pMovingObjectsManager = new CMovingObjectsManager(); - - // Create the manager and grab the most important pointers - m_pManager = new CClientManager; - m_pCamera = m_pManager->GetCamera(); - m_pMarkerManager = m_pManager->GetMarkerManager(); - m_pObjectManager = m_pManager->GetObjectManager(); - m_pPickupManager = m_pManager->GetPickupManager(); - m_pPlayerManager = m_pManager->GetPlayerManager(); - m_pRadarAreaManager = m_pManager->GetRadarAreaManager(); - m_pDisplayManager = m_pManager->GetDisplayManager(); - m_pVehicleManager = m_pManager->GetVehicleManager(); - m_pRadarMarkerManager = m_pManager->GetRadarMarkerManager(); - m_pPathManager = m_pManager->GetPathManager(); - m_pTeamManager = m_pManager->GetTeamManager(); - m_pPedManager = m_pManager->GetPedManager(); - m_pGUIManager = m_pManager->GetGUIManager(); - m_pResourceManager = m_pManager->GetResourceManager(); - m_pProjectileManager = m_pManager->GetProjectileManager(); - m_pLocalServer = NULL; - - m_pLatentTransferManager = new CLatentTransferManager(); - m_pZoneNames = new CZoneNames; - m_pScriptKeyBinds = new CScriptKeyBinds; - m_pRemoteCalls = new CRemoteCalls(); - m_pResourceFileDownloadManager = new CResourceFileDownloadManager(); - - // Create our net API - m_pNetAPI = new CNetAPI(m_pManager); - m_pNetworkStats = new CNetworkStats(m_pDisplayManager); - m_pSyncDebug = new CSyncDebug(m_pManager); - - // Create our blended weather class - m_pBlendedWeather = new CBlendedWeather; - - // Create our RPC class - m_pRPCFunctions = new CRPCFunctions(this); - - // Our management classes - m_pUnoccupiedVehicleSync = new CUnoccupiedVehicleSync(m_pVehicleManager); - m_pPedSync = new CPedSync(m_pPedManager); -#ifdef WITH_OBJECT_SYNC - m_pObjectSync = new CObjectSync(m_pObjectManager); -#endif - m_pNametags = new CNametags(m_pManager); - m_pRadarMap = new CRadarMap(m_pManager); - - // Set the screenshot path - /* This is now done in CCore, to maintain a global screenshot path - SString strScreenShotPath = SString::Printf ( "%s\\screenshots", m_szModRoot ); - g_pCore->SetScreenShotPath ( strScreenShotPath ); - */ - - // Create the transfer boxes (GUI) - m_pTransferBox = new CTransferBox(); - m_pBigPacketTransferBox = new CTransferBox(); - - // Store the time we started on - if (bLocalPlay) - m_ulTimeStart = 0; - else - m_ulTimeStart = CClientTime::GetTime(); - - // MTA Voice - m_pVoiceRecorder = new CVoiceRecorder(); - - // Singular file download manager - m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); - - // Register the message and the net packet handler - g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); - g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); - g_pMultiplayer->SetBulletImpactHandler(CClientGame::BulletImpact); - g_pMultiplayer->SetBulletFireHandler(CClientGame::BulletFire); - g_pMultiplayer->SetExplosionHandler(CClientExplosionManager::Hook_StaticExplosionCreation); - g_pMultiplayer->SetBreakTowLinkHandler(CClientGame::StaticBreakTowLinkHandler); - g_pMultiplayer->SetDrawRadarAreasHandler(CClientGame::StaticDrawRadarAreasHandler); - g_pMultiplayer->SetDamageHandler(CClientGame::StaticDamageHandler); - g_pMultiplayer->SetDeathHandler(CClientGame::StaticDeathHandler); - g_pMultiplayer->SetFireHandler(CClientGame::StaticFireHandler); - g_pMultiplayer->SetProjectileStopHandler(CClientProjectileManager::Hook_StaticProjectileAllow); - g_pMultiplayer->SetProjectileHandler(CClientProjectileManager::Hook_StaticProjectileCreation); - g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); - g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); - g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); - g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); - g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); - g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); - g_pMultiplayer->SetPreFxRenderHandler(CClientGame::StaticPreFxRenderHandler); - g_pMultiplayer->SetPreHudRenderHandler(CClientGame::StaticPreHudRenderHandler); - g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(CClientGame::StaticCAnimBlendAssocDestructorHandler); - g_pMultiplayer->SetAddAnimationHandler(CClientGame::StaticAddAnimationHandler); - g_pMultiplayer->SetAddAnimationAndSyncHandler(CClientGame::StaticAddAnimationAndSyncHandler); - g_pMultiplayer->SetAssocGroupCopyAnimationHandler(CClientGame::StaticAssocGroupCopyAnimationHandler); - g_pMultiplayer->SetBlendAnimationHierarchyHandler(CClientGame::StaticBlendAnimationHierarchyHandler); - g_pMultiplayer->SetProcessCollisionHandler(CClientGame::StaticProcessCollisionHandler); - g_pMultiplayer->SetVehicleCollisionHandler(CClientGame::StaticVehicleCollisionHandler); - g_pMultiplayer->SetVehicleDamageHandler(CClientGame::StaticVehicleDamageHandler); - g_pMultiplayer->SetHeliKillHandler(CClientGame::StaticHeliKillHandler); - g_pMultiplayer->SetObjectDamageHandler(CClientGame::StaticObjectDamageHandler); - g_pMultiplayer->SetObjectBreakHandler(CClientGame::StaticObjectBreakHandler); - g_pMultiplayer->SetWaterCannonHitHandler(CClientGame::StaticWaterCannonHandler); - g_pMultiplayer->SetVehicleFellThroughMapHandler(CClientGame::StaticVehicleFellThroughMapHandler); - g_pMultiplayer->SetGameObjectDestructHandler(CClientGame::StaticGameObjectDestructHandler); - g_pMultiplayer->SetGameVehicleDestructHandler(CClientGame::StaticGameVehicleDestructHandler); - g_pMultiplayer->SetGamePlayerDestructHandler(CClientGame::StaticGamePlayerDestructHandler); - g_pMultiplayer->SetGameProjectileDestructHandler(CClientGame::StaticGameProjectileDestructHandler); - g_pMultiplayer->SetGameModelRemoveHandler(CClientGame::StaticGameModelRemoveHandler); - g_pMultiplayer->SetGameEntityRenderHandler(CClientGame::StaticGameEntityRenderHandler); - g_pMultiplayer->SetFxSystemDestructionHandler(CClientGame::StaticFxSystemDestructionHandler); - g_pMultiplayer->SetDrivebyAnimationHandler(CClientGame::StaticDrivebyAnimationHandler); - g_pGame->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); - g_pGame->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); - g_pGame->SetTaskSimpleBeHitHandler(CClientGame::StaticTaskSimpleBeHitHandler); - g_pCore->SetMessageProcessor(CClientGame::StaticProcessMessage); - g_pCore->GetKeyBinds()->SetKeyStrokeHandler(CClientGame::StaticKeyStrokeHandler); - g_pCore->GetKeyBinds()->SetCharacterKeyHandler(CClientGame::StaticCharacterKeyHandler); - g_pNet->RegisterPacketHandler(CClientGame::StaticProcessPacket); - - m_pLuaManager = new CLuaManager(this); - m_pScriptDebugging = new CScriptDebugging(m_pLuaManager); - m_pScriptDebugging->SetLogfile(CalcMTASAPath("mta\\logs\\clientscript.log"), 3); - - CStaticFunctionDefinitions(m_pLuaManager, &m_Events, g_pCore, g_pGame, this, m_pManager); - CLuaFunctionDefs::Initialize(m_pLuaManager, m_pScriptDebugging, this); - CLuaDefs::Initialize(this, m_pLuaManager, m_pScriptDebugging); - - // Start async task scheduler - m_pAsyncTaskScheduler = new SharedUtil::CAsyncTaskScheduler(2); - - // Disable the enter/exit vehicle key button (we want to handle this button ourselves) - g_pMultiplayer->DisableEnterExitVehicleKey(true); - - // Disable GTA's pickup processing as we want to confirm the hits with the server - m_pPickupManager->SetPickupProcessingDisabled(true); - - // Key-bind for fire-key (for handling satchels and stealth-kills) - g_pCore->GetKeyBinds()->AddControlFunction("fire", CClientGame::StaticUpdateFireKey, true); - - // Init big packet progress vars - m_bReceivingBigPacket = false; - m_ulBigPacketSize = 0; - m_ulBigPacketBytesReceivedBase = 0; - - m_bBeingDeleted = false; - - #if defined (MTA_DEBUG) || defined (MTA_BETA) - m_bShowSyncingInfo = false; - #endif - - #ifdef MTA_DEBUG - m_pShowPlayer = m_pShowPlayerTasks = NULL; - m_bMimicLag = false; - m_ulLastMimicLag = 0; - m_bDoPaintballs = false; - m_bShowInterpolation = false; - #endif - - // Add our lua events - AddBuiltInEvents(); - - // Init debugger class - m_Foo.Init(this); - - // Load some stuff from the core config - float fScale; - g_pCore->GetCVars()->Get("text_scale", fScale); - CClientTextDisplay::SetGlobalScale(fScale); - - // Reset async loading script settings to default - g_pGame->SetAsyncLoadingFromScript(true, false); - - // Reset test mode script settings to default - g_pCore->GetGraphics()->GetRenderItemManager()->SetTestMode(DX_TEST_MODE_NONE); -} - -CClientGame::~CClientGame(void) -{ - m_bBeingDeleted = true; - // Stop all explosions. Unfortunately this doesn't fix the crash - // if a vehicle is destroyed while it explodes. - g_pGame->GetExplosionManager()->RemoveAllExplosions(); - - // Reset camera shaking - g_pGame->GetCamera()->SetShakeForce(0.0f); - - // Stop playing the continious sounds - // if the game was loaded. This is done by - // playing these special IDS. - if (m_bGameLoaded) - { - g_pGame->GetAudio()->PlayFrontEndSound(35); - g_pGame->GetAudio()->PlayFrontEndSound(48); - } - - // Reset the GUI input mode - g_pCore->GetGUI()->SetGUIInputMode(INPUTMODE_NO_BINDS_ON_EDIT); - - // Reset CGUI's global events - g_pCore->GetGUI()->ClearInputHandlers(INPUT_MOD); - - // Destroy mimics - #ifdef MTA_DEBUG - list::const_iterator iterMimics = m_Mimics.begin(); - for (; iterMimics != m_Mimics.end(); iterMimics++) - { - CClientPlayer* pPlayer = *iterMimics; - CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); - if (pVehicle) - delete pVehicle; - - delete pPlayer; - } - #endif - - // Hide the transfer box incase it is showing - m_pTransferBox->Hide(); - m_pBigPacketTransferBox->Hide(); - - // Stop async task scheduler - SAFE_DELETE(m_pAsyncTaskScheduler); - - SAFE_DELETE(m_pVoiceRecorder); - - // Singular file download manager - SAFE_DELETE(m_pSingularFileDownloadManager); - - // NULL the message/net stuff - g_pMultiplayer->SetPreContextSwitchHandler(NULL); - g_pMultiplayer->SetPostContextSwitchHandler(NULL); - g_pMultiplayer->SetPreWeaponFireHandler(NULL); - g_pMultiplayer->SetPostWeaponFireHandler(NULL); - g_pMultiplayer->SetBulletImpactHandler(NULL); - g_pMultiplayer->SetBulletFireHandler(NULL); - g_pMultiplayer->SetExplosionHandler(NULL); - g_pMultiplayer->SetBreakTowLinkHandler(NULL); - g_pMultiplayer->SetDrawRadarAreasHandler(NULL); - g_pMultiplayer->SetDamageHandler(NULL); - g_pMultiplayer->SetFireHandler(NULL); - g_pMultiplayer->SetProjectileStopHandler(NULL); - g_pMultiplayer->SetProjectileHandler(NULL); - g_pMultiplayer->SetProcessCamHandler(nullptr); - g_pMultiplayer->SetRender3DStuffHandler(NULL); - g_pMultiplayer->SetPreRenderSkyHandler(NULL); - g_pMultiplayer->SetRenderHeliLightHandler(nullptr); - g_pMultiplayer->SetChokingHandler(NULL); - g_pMultiplayer->SetPreWorldProcessHandler(NULL); - g_pMultiplayer->SetPostWorldProcessHandler(NULL); - g_pMultiplayer->SetPreFxRenderHandler(NULL); - g_pMultiplayer->SetPreHudRenderHandler(NULL); - g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(NULL); - g_pMultiplayer->SetAddAnimationHandler(NULL); - g_pMultiplayer->SetAddAnimationAndSyncHandler(NULL); - g_pMultiplayer->SetAssocGroupCopyAnimationHandler(NULL); - g_pMultiplayer->SetBlendAnimationHierarchyHandler(NULL); - g_pMultiplayer->SetProcessCollisionHandler(NULL); - g_pMultiplayer->SetVehicleCollisionHandler(NULL); - g_pMultiplayer->SetVehicleDamageHandler(NULL); - g_pMultiplayer->SetHeliKillHandler(NULL); - g_pMultiplayer->SetObjectDamageHandler(NULL); - g_pMultiplayer->SetObjectBreakHandler(NULL); - g_pMultiplayer->SetWaterCannonHitHandler(NULL); - g_pMultiplayer->SetGameObjectDestructHandler(NULL); - g_pMultiplayer->SetGameVehicleDestructHandler(NULL); - g_pMultiplayer->SetGamePlayerDestructHandler(NULL); - g_pMultiplayer->SetGameProjectileDestructHandler(NULL); - g_pMultiplayer->SetGameModelRemoveHandler(NULL); - g_pMultiplayer->SetGameEntityRenderHandler(NULL); - g_pMultiplayer->SetDrivebyAnimationHandler(nullptr); - g_pGame->SetPreWeaponFireHandler(NULL); - g_pGame->SetPostWeaponFireHandler(NULL); - g_pGame->SetTaskSimpleBeHitHandler(NULL); - g_pGame->GetAudio()->SetWorldSoundHandler(NULL); - g_pCore->SetMessageProcessor(NULL); - g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); - g_pCore->GetKeyBinds()->SetCharacterKeyHandler(NULL); - g_pNet->StopNetwork(); - g_pNet->RegisterPacketHandler(NULL); - CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); - pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessClientKeyBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessClientControlBind); - pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessServerKeyBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessServerControlBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticUpdateFireKey); - pKeyBinds->SetAllControlsEnabled(true, true, true); - g_pCore->ForceCursorVisible(false); - SetCursorEventsEnabled(false); - - // Destroy our stuff - SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop - SAFE_DELETE(m_pNametags); - SAFE_DELETE(m_pSyncDebug); - SAFE_DELETE(m_pNetworkStats); - SAFE_DELETE(m_pNetAPI); - SAFE_DELETE(m_pRPCFunctions); - SAFE_DELETE(m_pUnoccupiedVehicleSync); - SAFE_DELETE(m_pPedSync); -#ifdef WITH_OBJECT_SYNC - SAFE_DELETE(m_pObjectSync); -#endif - SAFE_DELETE(m_pBlendedWeather); - SAFE_DELETE(m_pMovingObjectsManager); - SAFE_DELETE(m_pRadarMap); - SAFE_DELETE(m_pRemoteCalls); - SAFE_DELETE(m_pLuaManager); - SAFE_DELETE(m_pLatentTransferManager); - SAFE_DELETE(m_pResourceFileDownloadManager); - - SAFE_DELETE(m_pRootEntity); - - SAFE_DELETE(m_pModelCacheManager); - SAFE_DELETE(m_pGameEntityXRefManager); - SAFE_DELETE(m_pZoneNames); - SAFE_DELETE(m_pScriptKeyBinds); - - // Delete the scriptdebugger - SAFE_DELETE(m_pScriptDebugging); - - // Delete the transfer boxes - SAFE_DELETE(m_pTransferBox); - SAFE_DELETE(m_pBigPacketTransferBox); - - SAFE_DELETE(m_pLocalServer); - SAFE_DELETE(m_pDebugHookManager); - - // Packet handler - SAFE_DELETE(m_pPacketHandler); - - // Delete PerfStatManager - delete CClientPerfStatManager::GetSingleton(); - - // NULL the global CClientGame var - g_pClientGame = NULL; - m_bBeingDeleted = false; -} - -/* -bool CClientGame::StartGame ( void ) // for an offline game (e.g. editor) -{ - m_Status = STATUS_OFFLINE; - g_pCore->SetOfflineMod ( true ); // hide chatbox etc - g_pCore->SetConnected ( true ); // not sure, but its required :) - g_pCore->HideMainMenu (); // duh - - // If the game isn't started, start it - if ( g_pGame->GetSystemState () == 7 ) - { - g_pGame->StartGame (); - } - return true; -} -*/ - -#include -//#define _CRTDBG_CHECK_EVERY_16_DF 0x00100000 /* check heap every 16 heap ops */ -//#define _CRTDBG_CHECK_EVERY_128_DF 0x00800000 /* check heap every 128 heap ops */ -//#define _CRTDBG_CHECK_EVERY_1024_DF 0x04000000 /* check heap every 1024 heap ops */ - -void CClientGame::EnablePacketRecorder(const char* szFilename) -{ - m_pManager->GetPacketRecorder()->StartRecord(szFilename, true); -} - -void CClientGame::StartPlayback(void) -{ - // strcpy ( m_szNick, "Playback" ); - - m_bIsPlayingBack = true; - m_bFirstPlaybackFrame = true; - m_pManager->GetPacketRecorder()->SetPacketHandler(CClientGame::StaticProcessPacket); - - if (!m_pManager->IsGameLoaded()) - { - g_pGame->StartGame(); - } -} - -bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerType Type) -{ - m_ServerType = Type; - // int dbg = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ); - // dbg |= _CRTDBG_ALLOC_MEM_DF; - // dbg |= _CRTDBG_CHECK_ALWAYS_DF; - // dbg |= _CRTDBG_DELAY_FREE_MEM_DF; - // dbg |= _CRTDBG_LEAK_CHECK_DF; - //_CrtSetDbgFlag(dbg); - - // Verify that the nickname is valid - if (!IsNickValid(szNick)) - { - g_pCore->ShowMessageBox(_("Error") + _E("CD01"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - // Store our nickname - m_strLocalNick.AssignLeft(szNick, MAX_PLAYER_NICK_LENGTH); - - // Are we connected? - if (g_pNet->IsConnected() || m_bIsPlayingBack) - { - // Hide the console when connecting.. - if (g_pCore->GetConsole()->IsVisible()) - g_pCore->GetConsole()->SetVisible(false); - - // Display the status box - g_pCore->ShowMessageBox(_("CONNECTING"), _("Entering the game ..."), MB_ICON_INFO); - - // Send the initial data to the server - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Hash the password if neccessary - MD5 Password; - memset(Password.data, 0, sizeof(MD5)); - if (szPassword) - { - // Is it long enough? - size_t sizePassword = strlen(szPassword); - if (sizePassword > 0) - { - // Hash the password and put it in the struct - CMD5Hasher Hasher; - Hasher.Calculate(szPassword, sizePassword, Password); - } - } - - // Append version information - pBitStream->Write(static_cast(MTA_DM_NETCODE_VERSION)); - pBitStream->Write(static_cast(MTA_DM_VERSION)); - pBitStream->Write(static_cast(MTA_DM_BITSTREAM_VERSION)); - - SString strPlayerVersion("%d.%d.%d-%d.%05d.%d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, - MTASA_VERSION_BUILD, g_pNet->GetNetRev()); - pBitStream->WriteString(strPlayerVersion); - - pBitStream->WriteBit(g_pCore->IsOptionalUpdateInfoRequired(g_pNet->GetConnectedServer(true))); - - pBitStream->Write(static_cast(g_pGame->GetGameVersion())); - - // Append user details - SString strTemp = StringZeroPadout(m_strLocalNick, MAX_PLAYER_NICK_LENGTH); - pBitStream->Write(strTemp.c_str(), MAX_PLAYER_NICK_LENGTH); - pBitStream->Write(reinterpret_cast(Password.data), sizeof(MD5)); - - // Append community information (Removed) - std::string strUser; - pBitStream->Write(strUser.c_str(), MAX_SERIAL_LENGTH); - - // Send the packet as joindata - g_pNet->SendPacket(PACKET_ID_PLAYER_JOINDATA, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - return true; - } - } - else - { - g_pCore->ShowMessageBox(_("Error") + _E("CD02"), _("Not connected; please use Quick Connect or the 'connect' command to connect to a server."), - MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - } - - return false; -} - -void CClientGame::SetupLocalGame(eServerType Type) -{ - SString strConfig = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; - m_bWaitingForLocalConnect = true; - if (!m_pLocalServer) - m_pLocalServer = new CLocalServer(strConfig); -} - -bool CClientGame::StartLocalGame(eServerType Type, const char* szPassword) -{ - // Verify that the nickname is valid - std::string strNick; - g_pCore->GetCVars()->Get("nick", strNick); - - if (!IsNickValid(strNick.c_str())) - { - g_pCore->ShowMessageBox(_("Error") + _E("CD03"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - m_bWaitingForLocalConnect = false; - m_ServerType = Type; - SString strTemp = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; - - SAFE_DELETE(m_pLocalServer); - - // Store our nickname - m_strLocalNick.AssignLeft(strNick.c_str(), MAX_PLAYER_NICK_LENGTH); - - // Got a server? - if (m_bLocalPlay) - { - // Start the server locally - if (!m_Server.Start(strTemp)) - { - m_bWaitingForLocalConnect = true; - m_bErrorStartingLocal = true; - g_pCore->ShowMessageBox(_("Error") + _E("CD04"), _("The server is not installed"), MB_ICON_ERROR | MB_BUTTON_OK); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - if (szPassword) - m_Server.SetPassword(szPassword); - - // Display the status box<<<<< - m_OnCancelLocalGameClick = GUI_CALLBACK(&CClientGame::OnCancelLocalGameClick, this); - g_pCore->ShowMessageBox(_("Local Server"), _("Starting local server ..."), MB_BUTTON_CANCEL | MB_ICON_INFO, &m_OnCancelLocalGameClick); - } - else - { - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - // We're waiting for connection - m_bWaitingForLocalConnect = true; - return true; -} - -bool CClientGame::OnCancelLocalGameClick(CGUIElement* pElement) -{ - if (m_bLocalPlay && m_bWaitingForLocalConnect) - { - g_pCore->RemoveMessageBox(); - g_pCore->GetModManager()->RequestUnload(); - return true; - } - return false; -} - -void CClientGame::DoPulsePreFrame(void) -{ - if (m_Status == CClientGame::STATUS_JOINED) - { - if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) - { - m_pVoiceRecorder->DoPulse(); - } - } -} - -void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRenderTargets) -{ - // Allow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); - - // If appropriate, call onClientRestore - if (bDidUnminimize) - { - CLuaArguments Arguments; - Arguments.PushBoolean(bDidRecreateRenderTargets); - m_pRootEntity->CallEvent("onClientRestore", Arguments, false); - m_bWasMinimized = false; - - // Reverse any mute on minimize effects - g_pGame->GetAudio()->SetEffectsMasterVolume(g_pGame->GetSettings()->GetSFXVolume()); - g_pGame->GetAudio()->SetMusicMasterVolume(g_pGame->GetSettings()->GetRadioVolume()); - m_pManager->GetSoundManager()->SetMinimizeMuted(false); - } - - // Call onClientHUDRender LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientHUDRender", Arguments, false); - - // Disallow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); - - // Restore in case script forgets - g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); - - DebugElementRender(); -} - -void CClientGame::DoPulsePostFrame(void) -{ - TIMING_CHECKPOINT("+CClientGame::DoPulsePostFrame"); - #ifdef DEBUG_KEYSTATES - // Get the controller state - CControllerState cs; - g_pGame->GetPad()->GetCurrentControllerState(&cs); - - SString strBuffer; - strBuffer = SString::Printf( - "LeftShoulder1: %u\n" - "LeftShoulder2: %u\n" - "RightShoulder1: %u\n" - "RightShoulder2: %u\n" - "DPadUp: %u\n" - "DPadDown: %u\n" - "DPadLeft: %u\n" - "DPadRight: %u\n" - "Start: %u\n" - "Select: %u\n" - "ButtonSquare: %u\n" - "ButtonTriangle: %u\n" - "ButtonCross: %u\n" - "ButtonCircle: %u\n" - "ShockButtonL: %u\n" - "ShockButtonR: %u\n" - "PedWalk: %u\n", - cs.LeftShoulder1, cs.LeftShoulder2, cs.RightShoulder1, cs.RightShoulder2, cs.DPadUp, cs.DPadDown, cs.DPadLeft, cs.DPadRight, cs.Start, cs.Select, - cs.ButtonSquare, cs.ButtonTriangle, cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.ShockButtonR, cs.m_bPedWalk); - - g_pCore->GetGraphics()->DrawTextTTF(300, 10, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); - - strBuffer = SString::Printf( - "VehicleMouseLook: %u\n" - "LeftStickX: %u\n" - "LeftStickY: %u\n" - "RightStickX: %u\n" - "RightStickY: %u", - cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, cs.RightStickX, cs.RightStickY); - - g_pCore->GetGraphics()->DrawTextTTF(300, 320, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); - #endif - - UpdateModuleTickCount64(); - - if (m_pManager->IsGameLoaded()) - { - // Pulse the nametags before anything that changes player positions, we'll be 1 frame behind, but so is the camera - // If nametags are enabled, pulse the nametag manager - if (m_bShowNametags) - { - m_pNametags->DoPulse(); - } - - // Sync debug - m_pSyncDebug->OnPulse(); - - // Also eventually draw FPS - if (m_bShowFPS) - { - DrawFPS(); - } - - CGraphicsInterface* pGraphics = g_pCore->GetGraphics(); - unsigned int uiHeight = pGraphics->GetViewportHeight(); - unsigned int uiWidth = pGraphics->GetViewportWidth(); - - // Draw a little star in the corner if async is on - if (g_pGame->IsASyncLoadingEnabled(true)) - { - unsigned int uiPosY = g_pGame->IsASyncLoadingEnabled() ? uiHeight - 7 : uiHeight - 12; - pGraphics->DrawString(uiWidth - 5, uiPosY, 0x80ffffff, 1, "*"); - } - - // Draw notice text if dx test mode is enabled - if (g_pCore->GetGraphics()->GetRenderItemManager()->GetTestMode()) - { - unsigned int uiPosY = uiHeight - 30; - pGraphics->DrawString(uiWidth - 155, uiPosY, 0x40ffffff, 1, "dx test mode enabled"); - } - - // Draw notice text if diagnostic mode enabled - EDiagnosticDebugType diagnosticDebug = g_pCore->GetDiagnosticDebug(); - if (diagnosticDebug == EDiagnosticDebug::LOG_TIMING_0000) - { - unsigned int uiPosY = uiHeight - 30; - pGraphics->DrawString(uiWidth - 185, uiPosY, 0xffffff00, 1, "Debug setting: #0000 Log timing"); - } - - // Draw network trouble message if required - if (m_pNetAPI->IsNetworkTrouble()) - { - int iPosX = uiWidth / 2; // Half way across - int iPosY = uiHeight * 45 / 100; // 45/100 down - g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, - DT_NOCLIP | DT_CENTER); - } - - // Adjust the streaming memory limit. - unsigned int uiStreamingMemoryPrev; - g_pCore->GetCVars()->Get("streaming_memory", uiStreamingMemoryPrev); - uint uiStreamingMemory = SharedUtil::Clamp(g_pCore->GetMinStreamingMemory(), uiStreamingMemoryPrev, g_pCore->GetMaxStreamingMemory()); - if (uiStreamingMemory != uiStreamingMemoryPrev) - g_pCore->GetCVars()->Set("streaming_memory", uiStreamingMemory); - - int iStreamingMemoryBytes = static_cast(uiStreamingMemory) * 1024 * 1024; - if (g_pMultiplayer->GetLimits()->GetStreamingMemory() != iStreamingMemoryBytes) - g_pMultiplayer->GetLimits()->SetStreamingMemory(iStreamingMemoryBytes); - - // If we're in debug mode and are supposed to show task data, do it - #ifdef MTA_DEBUG - if (m_pShowPlayerTasks) - { - DrawTasks(m_pShowPlayerTasks); - } - - if (m_pShowPlayer) - { - DrawPlayerDetails(m_pShowPlayer); - } - - std::vector::const_iterator iter = m_pPlayerManager->IterBegin(); - for (; iter != m_pPlayerManager->IterEnd(); ++iter) - { - CClientPlayer* pPlayer = *iter; - if (pPlayer->IsStreamedIn() && pPlayer->IsShowingWepdata()) - DrawWeaponsyncData(pPlayer); - } - #endif - - #if defined (MTA_DEBUG) || defined (MTA_BETA) - if (m_bShowSyncingInfo) - { - // Draw the header boxz - CVector vecPosition = CVector(0.05f, 0.32f, 0); - m_pDisplayManager->DrawText2D("Syncing vehicles:", vecPosition, 1.0f, 0xFFFFFFFF); - - // Print each vehicle we're syncing - CDeathmatchVehicle* pVehicle; - list::const_iterator iter = m_pUnoccupiedVehicleSync->IterBegin(); - for (; iter != m_pUnoccupiedVehicleSync->IterEnd(); iter++) - { - vecPosition.fY += 0.03f; - pVehicle = *iter; - - SString strBuffer("ID: %u (%s)", pVehicle->GetID(), pVehicle->GetNamePointer()); - - m_pDisplayManager->DrawText2D(strBuffer, vecPosition, 1.0f, 0xFFFFFFFF); - } - } - #endif - // Heli Clear time - if (m_LastClearTime.Get() > HeliKill_List_Clear_Rate) - { - // Clear our list now - m_HeliCollisionsMap.clear(); - m_LastClearTime.Reset(); - } - - CClientPerfStatManager::GetSingleton()->DoPulse(); - } - - m_pRadarMap->DoRender(); - m_pManager->DoRender(); - DoPulses(); - - // If we're supposed to show netstat, draw them infront of everything else - if (m_bShowNetstat) - { - m_pNetworkStats->Draw(); - } -} - -void CClientGame::DoPulses(void) -{ - TIMING_CHECKPOINT("-CClientGame::DoPulsePostFrame"); - - g_pCore->ApplyFrameRateLimit(); - - TIMING_CHECKPOINT("+CClientGame::DoPulses"); - - m_BuiltCollisionMapThisFrame = false; - - if (m_bIsPlayingBack && m_bFirstPlaybackFrame && m_pManager->IsGameLoaded()) - { - g_pCore->GetConsole()->Printf("First playback frame, starting"); - m_pManager->GetPacketRecorder()->StartPlayback("log.rec", false); - m_bFirstPlaybackFrame = false; - } - - // Call debug code if debug mode - m_Foo.DoPulse(); - - // Output stuff from our internal server eventually - m_Server.DoPulse(); - - if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED && GetTickCount64_() - m_llLastTransgressionTime > 60000) - { - uint uiLevel = 0; - uint uiInform = 0; - SString strMessage; - - // Is the player a cheater? - if (!m_pManager->GetAntiCheat().PerformChecks()) - { - uiLevel = 1; - uiInform = 2; - } - else - { - strMessage = g_pNet->GetNextBuffer(); - if (strMessage.length()) - { - uiLevel = atoi(strMessage.SplitLeft(":", &strMessage)); - uiInform = atoi(strMessage.SplitLeft(":", &strMessage)); - } - } - - // Send message to the server - if (uiLevel) - { - SString strPrefix = (uiInform == 2) ? "AC" : (uiInform == 1) ? "VF" : "SD"; - SString strMessageCombo = SString("%s #%d %s", *strPrefix, uiLevel, strMessage.c_str()).TrimEnd(" "); - m_llLastTransgressionTime = GetTickCount64_(); - AddReportLog(3100, strMessageCombo + SString(" (%d)", uiInform)); - - if (uiInform > 0) - { - // The server will use the whole message as supplied here - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write(uiLevel); - pBitStream->WriteString(strMessageCombo); - g_pNet->SendPacket(PACKET_ID_PLAYER_TRANSGRESSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - else - { - // Otherwise, disconnect here - AddReportLog(7105, SString("Core - Kicked (%s)", *strMessageCombo)); - g_pCore->ShowMessageBox(_("Error") + _E("CD05"), SString(_("You were kicked from the game ( %s )"), *strMessageCombo), - MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - } - - // Send diagnostic info - if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED) - { - // Retrieve data - SString strMessage = g_pNet->GetDiagnosticStatus(); - - // Send to the server if changed - if (strMessage != m_strLastDiagnosticStatus) - { - m_strLastDiagnosticStatus = strMessage; - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->WriteString(strMessage); - g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } - - // Pulse the network interface - - // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) - DoPulses2(false); - - m_pUnoccupiedVehicleSync->DoPulse(); - m_pPedSync->DoPulse(); -#ifdef WITH_OBJECT_SYNC - m_pObjectSync->DoPulse(); -#endif - m_pLatentTransferManager->DoPulse(); - m_pLuaManager->DoPulse(); - m_pScriptDebugging->UpdateLogOutput(); - - GetModelCacheManager()->DoPulse(); - - #ifdef MTA_DEBUG - UpdateMimics(); - #endif - - // Grab the current time - unsigned long ulCurrentTime = CClientTime::GetTime(); - - // Waiting for a connect? - if (m_bWaitingForLocalConnect) - { - // Connected? - if (g_pNet->IsConnected()) - { - // No longer waiting for connect - m_bWaitingForLocalConnect = false; - - // Assume local server has the same bitstream version - g_pNet->SetServerBitStreamVersion(MTA_DM_BITSTREAM_VERSION); - - // Run the game normally. - StartGame(m_strLocalNick, m_Server.GetPassword().c_str(), m_ServerType); - } - else - { - // Going to try connecting? Do this when the internal server has booted - // and we haven't started the connecting. - if (m_Server.IsReady() && m_iLocalConnectAttempts == 0) - { - g_pCore->ShowMessageBox(_("Local Server"), _("Connecting to local server..."), MB_ICON_INFO); - - // Connect - if (g_pNet->StartNetwork("localhost", 22010)) - { - // We're waiting for connection - m_iLocalConnectAttempts = 1; - m_ulTimeStart = CClientTime::GetTime(); - } - else - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD06"), _("Error connecting to server.")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - - // Timeout? - if (m_ulTimeStart != 0 && CClientTime::GetTime() >= m_ulTimeStart + 5000) - { - // Show timeout message and disconnect - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD07"), _("Connecting to local server timed out. See console for details.")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - } - - // If the game is loaded ... - if (m_pManager->IsGameLoaded()) - { - // Pulse the blended weather manager - m_pBlendedWeather->DoPulse(); - - // If we weren't ingame last frame; call the on ingame event - if (!m_bGameLoaded) - { - // Fix for gta not being focused sometimes - SetActiveWindow(g_pCore->GetHookedWindow()); - SetFocus(g_pCore->GetHookedWindow()); - - m_bGameLoaded = true; - Event_OnIngame(); - } - - // Check if the player is hitting the enter vehicle button - DoVehicleInKeyCheck(); - - // Pulse some stuff - m_pMovingObjectsManager->DoPulse(); - - // Get rid of our deleted elements - m_ElementDeleter.DoDeleteAll(); - m_pLuaManager->ProcessPendingDeleteList(); - - // Get rid of deleted GUI elements - g_pCore->GetGUI()->CleanDeadPool(); - - // Allow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); - - // Call onClientRender LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientRender", Arguments, false); - - // Disallow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); - - // Restore in case script forgets - g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); - - // Ensure replaced/restored textures for models in the GTA map are correct - g_pGame->FlushPendingRestreamIPL(); - - // Respawn objects in respawn pool - m_ObjectRespawner.DoRespawnAll(); - } - - // Are we connecting? - if (m_Status == CClientGame::STATUS_CONNECTING) - { - if (m_bErrorStartingLocal) - { - g_pCore->GetModManager()->RequestUnload(); - return; - } - - // Timed out? - if (!m_bWaitingForLocalConnect && ulCurrentTime >= m_ulTimeStart + NET_CONNECT_TIMEOUT) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD08"), _("Connection timed out"), "connect-timed-out", true); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - else if (m_Status == CClientGame::STATUS_JOINED) - { - // Pulse DownloadFiles if we're transferring stuff - GetResourceFileDownloadManager()->DoPulse(); - DownloadSingularResourceFiles(); - GetRemoteCalls()->ProcessQueuedFiles(); - } - - // Not waiting for local connect? - if (!m_bWaitingForLocalConnect) - { - // Trigger the ingame and connected event - if (!m_bTriggeredIngameAndConnected && m_pManager->IsGameLoaded() && g_pCore->IsConnected()) - { - m_bTriggeredIngameAndConnected = true; - Event_OnIngameAndConnected(); - - // Initialize the game - g_pCore->GetGame()->Initialize(); - } - - unsigned char ucError = g_pNet->GetConnectionError(); - - // Lost connection? - if (!g_pNet->IsConnected() && !m_bGracefulDisconnect && !m_bIsPlayingBack) - { - // See if we can figure out what specifically it was - if (ucError == 0) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD09"), _("Connection with the server was lost")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - else - { - SString strError; - SString strErrorCode; - switch (ucError) - { - case RID_RSA_PUBLIC_KEY_MISMATCH: - strError = _("Disconnected: unknown protocol error"); - strErrorCode = _E("CD10"); // encryption key mismatch - break; - case RID_REMOTE_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected remotely"); - strErrorCode = _E("CD11"); - break; - case RID_REMOTE_CONNECTION_LOST: - strError = _("Disconnected: connection lost remotely"); - strErrorCode = _E("CD12"); - break; - case RID_CONNECTION_BANNED: - strError = _("Disconnected: you are banned from this server"); - strErrorCode = _E("CD13"); - break; - case RID_NO_FREE_INCOMING_CONNECTIONS: - strError = _("Disconnected: the server is currently full"); - strErrorCode = _E("CD14"); - break; - case RID_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected from the server"); - strErrorCode = _E("CD15"); - break; - case RID_CONNECTION_LOST: - strError = _("Disconnected: connection to the server was lost"); - strErrorCode = _E("CD16"); - break; - case RID_INVALID_PASSWORD: - strError = _("Disconnected: invalid password specified"); - strErrorCode = _E("CD17"); - break; - default: - strError = _("Disconnected: connection was refused"); - strErrorCode = _E("CD18"); - break; - } - - // Display an error, reset the error status and exit - g_pCore->ShowNetErrorMessageBox(_("Error") + strErrorCode, strError); - g_pNet->SetConnectionError(0); - g_pCore->GetModManager()->RequestUnload(); - } - } - - // If we're in the verificating status - if (m_Status == CClientGame::STATUS_JOINING) - { - // Time out the verification if it takes too long - if (m_ulVerifyTimeStart != 0 && ulCurrentTime >= m_ulVerifyTimeStart + CLIENT_VERIFICATION_TIMEOUT) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD19"), _("MTA Client verification failed!")); - g_pCore->GetModManager()->RequestUnload(); - } - } - } - - // Check for radar input - m_pRadarMap->DoPulse(); - g_pCore->GetGraphics()->SetAspectRatioAdjustmentSuspended(m_pRadarMap->IsRadarShowing()); - - // Got a local player? - if (m_pLocalPlayer) - { - // Network updates - UpdateVehicleInOut(); - UpdatePlayerTarget(); - UpdatePlayerWeapons(); - // UpdateTrailers (); // Test: Does it always work without this check? - UpdateStunts(); - // Clear last damager if more than 2 seconds old - if (CClientTime::GetTime() - m_ulDamageTime > 2000) - { - m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageWeapon = 0xFF; - m_ucDamageBodyPiece = 0xFF; - } - DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); - } - - // Game hacks, restore certain variables - // game-speed changes after spawning - g_pGame->SetGameSpeed(m_fGameSpeed); - // money changes on death/getting into taxis - g_pGame->GetPlayerInfo()->SetPlayerMoney(m_lMoney); - // wanted to stop it changing on skin change etc - if (m_pLocalPlayer) - { - if (m_dwWanted != g_pGame->GetPlayerInfo()->GetWanted()->GetWantedLevel()) - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevelNoFlash(m_dwWanted); - } - // stop players dying from starvation - g_pGame->GetPlayerInfo()->SetLastTimeEaten(0); - // reset weapon logs (for preventing quickreload) - - // Update streaming - m_pManager->UpdateStreamers(); - - // Send screen shot data - ProcessDelayedSendList(); - - // Collect async task scheduler results - m_pAsyncTaskScheduler->CollectResults(); - - TIMING_CHECKPOINT("-CClientGame::DoPulses"); -} - -// Extrapolation test -void CClientGame::DoPulses2(bool bCalledFromIdle) -{ - bool bIsUsingAlternatePulseOrder = IsUsingAlternatePulseOrder(!bCalledFromIdle); - - // Figure out which pulses to do - bool bDoStandardPulses; - bool bDoVehicleManagerPulse; - - if (!bIsUsingAlternatePulseOrder) - { - // With std pulse order, do pulses when not called from idle - bDoStandardPulses = !bCalledFromIdle; - bDoVehicleManagerPulse = !bCalledFromIdle; - } - else - { - // With alt pulse order, do pulses when called from idle - bDoStandardPulses = bCalledFromIdle; - bDoVehicleManagerPulse = bCalledFromIdle; - - // Except when watching a remote synced vehicle - if (CClientVehicle* pTargetVehicle = DynamicCast(m_pCamera->GetTargetEntity())) - if (pTargetVehicle->GetControllingPlayer() != m_pPlayerManager->GetLocalPlayer()) - bDoVehicleManagerPulse = !bDoVehicleManagerPulse; - } - - if (bDoStandardPulses) - { - // Change to high precision so arguments in element data and events can - // be rounded to look more like what is expected - ChangeFloatPrecision(true); - - // Pulse the network interface - TIMING_CHECKPOINT("+NetPulse"); - g_pNet->DoPulse(); - TIMING_CHECKPOINT("-NetPulse"); - - // Change precision back, and check we are in low precision mode 4 sure - ChangeFloatPrecision(false); - assert(!IsHighFloatPrecision()); - } - - m_pManager->DoPulse(bDoStandardPulses, bDoVehicleManagerPulse); - - if (bDoStandardPulses) - { - m_pNetAPI->DoPulse(); - } -} - -void CClientGame::HandleException(CExceptionInformation* pExceptionInformation) -{ -} - -void CClientGame::HandleRadioNext(CControlFunctionBind*) -{ - if (g_pClientGame) - { - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); - if (pPlayer) - { - pPlayer->NextRadioChannel(); - } - } -} - -void CClientGame::HandleRadioPrevious(CControlFunctionBind*) -{ - if (g_pClientGame) - { - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); - if (pPlayer) - { - pPlayer->PreviousRadioChannel(); - } - } -} -bool CClientGame::IsNametagValid(const char* szNick) -{ - // Grab the size of the nametag. Check that it's not to long or short - size_t sizeNick = MbUTF8ToUTF16(szNick).size(); - if (sizeNick < MIN_PLAYER_NAMETAG_LENGTH || sizeNick > MAX_PLAYER_NAMETAG_LENGTH) - { - return false; - } - - // Check that each character is valid (Anything above 32) - unsigned char ucTemp; - for (size_t i = 0; i < sizeNick; i++) - { - ucTemp = szNick[i]; - if (ucTemp < 32) - { - return false; - } - } - - // nametag is valid, return true - return true; -} - -bool CClientGame::IsNickValid(const char* szNick) -{ - // Grab the size of the nick. Check that it's within the player - size_t sizeNick = strlen(szNick); - if (sizeNick < MIN_PLAYER_NICK_LENGTH || sizeNick > MAX_PLAYER_NICK_LENGTH) - { - return false; - } - - // Check that each character is valid (visible characters exluding space) - unsigned char ucTemp; - for (size_t i = 0; i < sizeNick; i++) - { - ucTemp = szNick[i]; - if (ucTemp < 33 || ucTemp > 126) - { - return false; - } - } - - // Nickname is valid, return true - return true; -} - -void CClientGame::ShowNetstat(int iCmd) -{ - bool bShow = (iCmd == 1) ? true : (iCmd == 0) ? false : !m_bShowNetstat; - - if (bShow && !m_bShowNetstat) - { - m_pNetworkStats->Reset(); - } - m_bShowNetstat = bShow; -} - -void CClientGame::ShowEaeg(bool) -{ - if (m_pLocalPlayer) - m_pLocalPlayer->SetStat(0x2329, 1.0f); -} - -#ifdef MTA_WEPSYNCDBG -void CClientGame::ShowWepdata(const char* szNick) -{ - CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); - if (pPlayer) - { - pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); - } -} -#endif - -#ifdef MTA_DEBUG - -void CClientGame::ShowWepdata(const char* szNick) -{ - CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); - if (pPlayer) - { - pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); - } -} - -void CClientGame::ShowPlayer(const char* szNick) -{ - m_pShowPlayer = m_pPlayerManager->Get(szNick); -} - -void CClientGame::ShowTasks(const char* szNick) -{ - m_pShowPlayerTasks = m_pPlayerManager->Get(szNick); -} - -void CClientGame::SetMimic(unsigned int uiMimicCount) -{ - // Check if we're within the max mimics boundary - if (uiMimicCount > MAX_MIMICS) - return; - - // Create neccessary players - while (m_Mimics.size() < uiMimicCount) - { - CClientPlayer* pPlayer = new CClientPlayer(m_pManager, static_cast(MAX_NET_PLAYERS_REAL + (int)m_Mimics.size())); - pPlayer->SetNick("Mimic"); - m_Mimics.push_back(pPlayer); - } - - // Destroy neccessary players - while (m_Mimics.size() > uiMimicCount) - { - CClientPlayer* pPlayer = m_Mimics.back(); - CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); - if (pVehicle) - delete pVehicle; - - delete pPlayer; - m_Mimics.pop_back(); - } -} - -#endif - -void CClientGame::DoVehicleInKeyCheck(void) -{ - // Grab the controller state - CControllerState cs; - g_pGame->GetPad()->GetCurrentControllerState(&cs); - static bool bButtonTriangleWasDown = false; - if (cs.ButtonTriangle) - { - if (!bButtonTriangleWasDown) - { - bButtonTriangleWasDown = true; - - // Process the hit - ProcessVehicleInOutKey(false); - } - } - else - { - bButtonTriangleWasDown = false; - } -} - -void CClientGame::UpdateVehicleInOut(void) -{ - // We got told by the server to animate into a certain vehicle? - if (m_VehicleInOutID != INVALID_ELEMENT_ID) - { - // Grab the vehicle we're getting in/out of - CDeathmatchVehicle* pInOutVehicle = static_cast(m_pVehicleManager->Get(m_VehicleInOutID)); - - // In or out? - if (m_bIsGettingOutOfVehicle) - { - // If we aren't working on leaving the car (he's eiter finished or cancelled/failed leaving) - if (!m_pLocalPlayer->IsLeavingVehicle()) - { - // Are we outside the car? - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - if (!pVehicle) - { - // Tell the server that we successfully left the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction = VEHICLE_NOTIFY_OUT; - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself out (so we're sure the records are correct) - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it, and damagable if we're syncing it - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - }*/ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - - // Reset the vehicle in out stuff so we're ready for another car entry/leave. - // Don't allow a new entry/leave until we've gotten the notify return packet - ElementID ReasonVehicleID = m_VehicleInOutID; - g_pClientGame->ResetVehicleInOut(); - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = ReasonVehicleID; - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_out"); -#endif - } - // Are we still inside the car? - else - { - // Warp us out now to keep in sync with the server - m_pLocalPlayer->RemoveFromVehicle(); - } - } - } - - // Are we getting into a vehicle? - else if (m_bIsGettingIntoVehicle) - { - // If we aren't working on entering the car (he's either finished or cancelled) - if (!m_pLocalPlayer->IsEnteringVehicle()) - { - // Is he in a vehicle now? - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - if (pVehicle) - { - // Tell the server that we successfully entered the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction; - - if (m_bIsJackingVehicle) - { - ucAction = static_cast(VEHICLE_NOTIFY_JACK); -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack"); -#endif - } - else - { - ucAction = static_cast(VEHICLE_NOTIFY_IN); -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in"); -#endif - } - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself in (so we're sure the records are correct) - pVehicle->AllowDoorRatioSetting(m_pLocalPlayer->m_ucEnteringDoor, true); - m_pLocalPlayer->WarpIntoVehicle(pVehicle, m_ucVehicleInOutSeat); - - /* - // Make it damagable - if ( pInOutVehicle ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - */ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - } - else - { - // Tell the server that we aborted entered the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction; - if (m_bIsJackingVehicle) - { - ucAction = static_cast(VEHICLE_NOTIFY_JACK_ABORT); - pBitStream->WriteBits(&ucAction, 4); - - // Did we start jacking them? - bool bAlreadyStartedJacking = false; - CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); - if (pVehicle) - { - CClientPed* pJackedPlayer = pVehicle->GetOccupant(); - if (pJackedPlayer) - { - // Jax: have we already started to jack the other player? - if (pJackedPlayer->IsGettingJacked()) - { - bAlreadyStartedJacking = true; - } - } - unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; - pBitStream->WriteBits(&ucDoor, 3); - SDoorOpenRatioSync door; - door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); - pBitStream->Write(&door); - } - pBitStream->WriteBit(bAlreadyStartedJacking); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack_abort"); -#endif - } - else - { - ucAction = static_cast(VEHICLE_NOTIFY_IN_ABORT); - pBitStream->WriteBits(&ucAction, 4); - CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); - if (pVehicle) - { - unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; - pBitStream->WriteBits(&ucDoor, 3); - SDoorOpenRatioSync door; - door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); - pBitStream->Write(&door); - } - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in_abort"); -#endif - } - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself out again (so we're sure the records are correct) - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it, and damagable if we're syncing it - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - } - */ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - } - - // Reset - // Don't allow a new entry/leave until we've gotten the notify return packet - ElementID ReasonID = m_VehicleInOutID; - ResetVehicleInOut(); - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = ReasonID; - } - } - } - else - { - // If we aren't getting jacked - if (!m_bIsGettingJacked) - { - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - - // Jax: this was commented, re-comment if it was there for a reason (..and give the reason!) - // Are we in a vehicle we aren't supposed to be in? - if (pVehicle && !pOccupiedVehicle) - { - g_pCore->GetConsole()->Print("You shouldn't be in this vehicle"); - m_pLocalPlayer->RemoveFromVehicle(); - } - - // Are we supposed to be in a vehicle? But aren't? - if (pOccupiedVehicle && !pVehicle) - { - // Jax: this happens when we try to warp into a streamed out vehicle, including when we use CClientVehicle::StreamInNow - // ..maybe we need a different way to detect bike falls? - - // Tell the server - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Vehicle id - pBitStream->Write(pOccupiedVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_NOTIFY_FELL_OFF); - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're not allowed to enter any vehicle before we get a confirm - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = pOccupiedVehicle->GetID(); - - // Remove him from the vehicle - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it - CDeathmatchVehicle* pInOutVehicle = static_cast < CDeathmatchVehicle* > ( pOccupiedVehicle ); - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - } - */ - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_fell_off"); -#endif - } - } - } - } -} - -void CClientGame::UpdatePlayerTarget(void) -{ - CControllerState ControllerState; - m_pLocalPlayer->GetControllerState(ControllerState); - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - - // Ignore the local player so we don't get hit - m_pLocalPlayer->WorldIgnore(true); - - // Run a process line of sight and look for an entity we target - CEntity* pColEntity = NULL; - CColPoint* pColPoint = NULL; - g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pColEntity); - - // Unignore the local player again - m_pLocalPlayer->WorldIgnore(false); - - // Kill the colpoint or we get a severe memoryleak - if (pColPoint) - pColPoint->Destroy(); - - if (pColEntity != m_pTargetedGameEntity) - { - m_pTargetedGameEntity = pColEntity; - - if (pColEntity) - { - m_pTargetedEntity = m_pManager->FindEntity(pColEntity); - } - else - m_pTargetedEntity = NULL; - - // Store the last targeted player's id - if (m_pTargetedEntity && m_pTargetedEntity->GetType() == CCLIENTPLAYER) - { - m_TargetedPlayerID = m_pTargetedEntity->GetID(); - } - else - m_TargetedPlayerID = INVALID_ELEMENT_ID; - - // Send the target - ElementID TargetID = INVALID_ELEMENT_ID; - if (m_pTargetedEntity && !m_pTargetedEntity->IsLocalEntity()) - { - TargetID = m_pTargetedEntity->GetID(); - } - - CBitStream bitStream; - bitStream.pBitStream->Write(TargetID); - m_pNetAPI->RPC(PLAYER_TARGET, bitStream.pBitStream); - - // Call our onClientPlayerTarget event - CLuaArguments Arguments; - if (m_pTargetedEntity) - Arguments.PushElement(m_pTargetedEntity); - else - Arguments.PushBoolean(false); - m_pLocalPlayer->CallEvent("onClientPlayerTarget", Arguments, true); - } -} - -void CClientGame::UpdatePlayerWeapons(void) -{ - // Check whether we changed weapon slots - eWeaponSlot currentSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - if (currentSlot != m_lastWeaponSlot) - { - CLuaArguments Arguments; - Arguments.PushNumber(m_lastWeaponSlot); - Arguments.PushNumber(currentSlot); - bool bCancelled = !m_pLocalPlayer->CallEvent("onClientPlayerWeaponSwitch", Arguments, true); - - if (bCancelled) - { - // Save the current ammo in clip - unsigned short usAmmoInClip = 0; - CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); - if (pWeapon) - usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); - - // Force it back to the old slot - m_pLocalPlayer->SetCurrentWeaponSlot(m_lastWeaponSlot); - - // Restore the ammo in clip that there was in that slot - if (usAmmoInClip > 0) - m_pLocalPlayer->GetWeapon()->SetAmmoInClip(usAmmoInClip); - } - else - { - CBitStream bitStream; - CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(); - NetBitStreamInterface& BitStream = *(bitStream.pBitStream); - SWeaponSlotSync slot; - - // Always send bit in case server is not in sync - if ((BitStream.Version() >= 0x44 && m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN) || BitStream.Version() >= 0x4D) - { - CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); - if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && - (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || - (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) - BitStream.WriteBit(true); - else - BitStream.WriteBit(false); - } - - if (pWeapon) - { - /* Send a packet to the server with info about the new weapon, - so the server stays in sync reliably */ - unsigned int uiSlot = static_cast(pWeapon->GetSlot()); - slot.data.uiSlot = uiSlot; - BitStream.Write(&slot); - - if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) - { - SWeaponAmmoSync ammo(pWeapon->GetType(), true, true); - ammo.data.usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); - ammo.data.usTotalAmmo = static_cast(pWeapon->GetAmmoTotal()); - BitStream.Write(&ammo); - } - } - else - { - slot.data.uiSlot = 0; - BitStream.Write(&slot); - } - - m_pNetAPI->RPC(PLAYER_WEAPON, bitStream.pBitStream); - m_lastWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - } - } -} - -void CClientGame::UpdateTrailers(void) -{ - // This function is here to re-attach trailers if they fall off - - unsigned long ulCurrentTime = GetTickCount32(); - - CClientVehicle * pVehicle = NULL, *pTrailer = NULL; - CVehicle * pGameVehicle = NULL, *pGameTrailer = NULL; - unsigned long ulIllegalTowBreakTime; - vector::const_iterator iterVehicles = m_pVehicleManager->StreamedBegin(); - for (; iterVehicles != m_pVehicleManager->StreamedEnd(); iterVehicles++) - { - pVehicle = *iterVehicles; - ulIllegalTowBreakTime = pVehicle->GetIllegalTowBreakTime(); - - // Do we have an illegal break? - if (ulIllegalTowBreakTime != 0) - { - // Has it been atleast 1 second since the break - if (ulCurrentTime > (ulIllegalTowBreakTime + 1000)) - { - // Try to re-attach them - CClientVehicle* pTowedBy = pVehicle->GetTowedByVehicle(); - if (pTowedBy) - { - // Little hack to keep illegaly detached trailers close to their tower - CVector vecPosition; - pVehicle->GetPosition(vecPosition); - pVehicle->SetPosition(vecPosition); - - pGameVehicle = pTowedBy->GetGameVehicle(); - pGameTrailer = pVehicle->GetGameVehicle(); - if (pGameVehicle && pGameTrailer) - { - // pGameTrailer->SetTowLink ( pGameVehicle ); - CVector vecRotation; - pTowedBy->GetRotationRadians(vecRotation); - pVehicle->SetRotationRadians(vecRotation); - pTowedBy->InternalSetTowLink(pVehicle); - } - } - - // Reset the break time, even if we couldnt re-attach it - pVehicle->SetIllegalTowBreakTime(0); - } - } - } -} - -void CClientGame::UpdateFireKey(void) -{ - if (m_pLocalPlayer) - { - SBindableGTAControl* pControl = g_pCore->GetKeyBinds()->GetBindableFromControl("fire"); - - // Is our 'fire' control enabled? - if (pControl->bEnabled) - { - // ** Satchel charge detonation ** - { - // Do we have a detonator in our hand? - if (m_pLocalPlayer->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_DETONATOR) - { - // Planted any satchels? - if (m_pLocalPlayer->CountProjectiles(WEAPONTYPE_REMOTE_SATCHEL_CHARGE) > 0) - { - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - - // Tell the server we want to detonate our satchels - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - g_pNet->SendPacket(PACKET_ID_DETONATE_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } - // Remove the detonator if we dont have any satchels planted - else - { - m_pLocalPlayer->RemoveWeapon(WEAPONTYPE_DETONATOR); - } - } - } - - // Has our control state been cut short? - if (!pControl->bState) - return; - - // ** Stealth kill ** - { - if (m_pLocalPlayer->IsStealthAiming()) - { - // Do we have a target ped? - CClientPed* pTargetPed = m_pLocalPlayer->GetTargetedPed(); - if (pTargetPed) - { - // Do we have a target player? - if (IS_PLAYER(pTargetPed)) - { - CClientPlayer* pTargetPlayer = static_cast(pTargetPed); - - // Is the targetted player on a team - CClientTeam* pTeam = pTargetPlayer->GetTeam(); - if (pTeam) - { - // Is this friendly-fire? - if (pTargetPlayer->IsOnMyTeam(m_pLocalPlayer) && !pTeam->GetFriendlyFire()) - { - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - return; - } - } - } - CPlayerPed* pGameTarget = static_cast(pTargetPed)->GetGamePlayer(); - if (pGameTarget) - { - // Would GTA let us stealth kill now? - if (m_pLocalPlayer->GetGamePlayer()->GetPedIntelligence()->TestForStealthKill(pGameTarget, false)) - { - // Grab our local position - CVector vecLocalPosition; - m_pLocalPlayer->GetPosition(vecLocalPosition); - - // Grab the target's position - CVector vecTargetPosition; - pTargetPed->GetPosition(vecTargetPosition); - - // Work out an angle between the players, and set this as we initiate our knife kill - float fAngle = AngleBetweenPoints2D(vecLocalPosition, vecTargetPosition); - m_pLocalPlayer->SetCurrentRotation(fAngle); - - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - CLuaArguments Arguments; - Arguments.PushElement(pTargetPed); - if (m_pLocalPlayer->CallEvent("onClientPlayerStealthKill", Arguments, false)) - { - if (pTargetPed->IsLocalEntity()) - { - CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, 4 /*WEAPONTYPE_KNIFE*/, 9 /*BODYPART_HEAD*/, true); - return; - } - - // Lets request a stealth kill - CBitStream bitStream; - bitStream.pBitStream->Write(pTargetPed->GetID()); - m_pNetAPI->RPC(REQUEST_STEALTH_KILL, bitStream.pBitStream); - } - else - { - return; - } - } - } - } - } - } - } - } -} - -void CClientGame::UpdateStunts(void) -{ - // * Two wheeler * - static unsigned long ulLastCarTwoWheelCounter = 0; - static float fLastCarTwoWheelDist = 0.0f; - unsigned long ulTemp = g_pGame->GetPlayerInfo()->GetCarTwoWheelCounter(); - // Did we start a stunt? - if (ulLastCarTwoWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("2wheeler"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastCarTwoWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("2wheeler"); - Arguments.PushNumber(ulLastCarTwoWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastCarTwoWheelCounter = ulTemp; - fLastCarTwoWheelDist = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); - - // * Wheelie * - static unsigned long ulLastBikeRearWheelCounter = 0; - static float fLastBikeRearWheelDist = 0.0f; - ulTemp = g_pGame->GetPlayerInfo()->GetBikeRearWheelCounter(); - // Did we start a stunt? - if (ulLastBikeRearWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("wheelie"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastBikeRearWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("wheelie"); - Arguments.PushNumber(ulLastBikeRearWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastBikeRearWheelCounter = ulTemp; - fLastBikeRearWheelDist = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); - - // * Stoppie * - static unsigned long ulLastBikeFrontWheelCounter = 0; - static float fLastBikeFrontWheelDist = 0.0f; - ulTemp = g_pGame->GetPlayerInfo()->GetBikeFrontWheelCounter(); - // Did we start a stunt? - if (ulLastBikeFrontWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("stoppie"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastBikeFrontWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("stoppie"); - Arguments.PushNumber(ulLastBikeFrontWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastBikeFrontWheelCounter = ulTemp; - fLastBikeFrontWheelDist = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); -} - -void CClientGame::StaticUpdateFireKey(CControlFunctionBind* pBind) -{ - g_pClientGame->UpdateFireKey(); -} - -void CClientGame::ChangeVehicleWeapon(bool bNext) -{ - if (m_pLocalPlayer && m_pLocalPlayer->GetRealOccupiedVehicle()) - { - eWeaponSlot currentWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - eWeaponSlot weaponSlot = currentWeaponSlot; - CWeapon* pWeapon = NULL; - while (!pWeapon || pWeapon->GetType() == WEAPONTYPE_UNARMED) - { - if (bNext) - { - if (weaponSlot == WEAPONSLOT_TYPE_DETONATOR) - { - weaponSlot = WEAPONSLOT_TYPE_UNARMED; - break; - } - - weaponSlot = (eWeaponSlot)(weaponSlot + 1); - - if (weaponSlot == currentWeaponSlot) - break; - - pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); - } - else - { - if (weaponSlot == WEAPONSLOT_TYPE_UNARMED) - { - if (weaponSlot != currentWeaponSlot) - break; - weaponSlot = WEAPONSLOT_TYPE_DETONATOR; - } - - weaponSlot = (eWeaponSlot)(weaponSlot - 1); - - if (weaponSlot == currentWeaponSlot) - break; - - pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); - } - } - if (pWeapon || weaponSlot == WEAPONSLOT_TYPE_UNARMED) - { - m_pLocalPlayer->SetCurrentWeaponSlot(weaponSlot); - } - } -} - -void CClientGame::ResetVehicleInOut(void) -{ - m_ulLastVehicleInOutTime = 0; - m_bIsGettingOutOfVehicle = false; - m_bIsGettingIntoVehicle = false; - m_bIsJackingVehicle = false; - m_bIsGettingJacked = false; - m_VehicleInOutID = INVALID_ELEMENT_ID; - m_ucVehicleInOutSeat = 0xFF; - m_bNoNewVehicleTask = false; - m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; - m_pGettingJackedBy = NULL; -} - -void CClientGame::SetAllDimensions(unsigned short usDimension) -{ - m_pManager->GetMarkerStreamer()->SetDimension(usDimension); - m_pManager->GetObjectStreamer()->SetDimension(usDimension); - m_pManager->GetObjectLodStreamer()->SetDimension(usDimension); - m_pManager->GetPickupStreamer()->SetDimension(usDimension); - m_pManager->GetPlayerStreamer()->SetDimension(usDimension); - m_pManager->GetRadarAreaManager()->SetDimension(usDimension); - m_pManager->GetVehicleStreamer()->SetDimension(usDimension); - m_pManager->GetRadarMarkerManager()->SetDimension(usDimension); - m_pManager->GetSoundManager()->SetDimension(usDimension); - m_pManager->GetPointLightsManager()->SetDimension(usDimension); - m_pManager->GetWaterManager()->SetDimension(usDimension); - m_pNametags->SetDimension(usDimension); - m_pCamera->SetDimension(usDimension); -} - -bool CClientGame::StaticKeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) -{ - return g_pClientGame->KeyStrokeHandler(strKey, bState, bIsConsoleInputKey); -} - -bool CClientGame::KeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) -{ - // Do we have a root yet? - if (m_pRootEntity) - { - // Ignore keydown/up pair if main menu is displayed, or console input will use the character - bool bIgnore = false; - if (bState) - { - auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; - bool isMouseKey = strKey.substr(0, 5) == "mouse"; - - if (g_pCore->IsMenuVisible() || (g_pCore->GetConsole()->IsInputActive() && bIsConsoleInputKey) || - (pFocusedBrowser && !pFocusedBrowser->IsLocal() && !isMouseKey)) - - bIgnore = true; // Ignore this keydown and the matching keyup - else - MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup - } - else - { - if (!MapContains(m_AllowKeyUpMap, strKey)) - bIgnore = true; // Ignore this keyup - else - MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup - } - - if (!bIgnore) - { - bool bAllow = true; - // Call our key-stroke event - CLuaArguments Arguments; - Arguments.PushString(strKey); - Arguments.PushBoolean(bState); - bAllow = m_pRootEntity->CallEvent("onClientKey", Arguments, false); - if (bState == true) - { - if (bAllow == false && strKey == "escape") - { - if (m_bLastKeyWasEscapeCancelled) - { - // Escape cannot be skipped twice - bAllow = true; - m_bLastKeyWasEscapeCancelled = false; - } - else - m_bLastKeyWasEscapeCancelled = true; - } - else - m_bLastKeyWasEscapeCancelled = false; - } - return bAllow; - } - } - m_bLastKeyWasEscapeCancelled = false; - return true; -} - -bool CClientGame::StaticCharacterKeyHandler(WPARAM wChar) -{ - return g_pClientGame->CharacterKeyHandler(wChar); -} - -bool CClientGame::CharacterKeyHandler(WPARAM wChar) -{ - // Do we have a root yet? - if (m_pRootEntity && g_pCore->IsMenuVisible() == false && g_pCore->GetConsole()->IsInputActive() == false) - { - // Cancel event if remote browser is focused - auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; - if (pFocusedBrowser && !pFocusedBrowser->IsLocal()) - return false; - - // Safe character? - if (wChar >= 32) - { - // Generate a null-terminating string for our character - wchar_t wUNICODE[2] = {wChar, '\0'}; - - // Convert our UTF character into an ANSI string - SString strANSI = UTF16ToMbUTF8(wUNICODE); - - // Call our character event - CLuaArguments Arguments; - Arguments.PushString(strANSI); - m_pRootEntity->CallEvent("onClientCharacter", Arguments, false); - } - } - - return false; -} - -void CClientGame::StaticProcessClientKeyBind(CKeyFunctionBind* pBind) -{ - g_pClientGame->ProcessClientKeyBind(pBind); -} - -void CClientGame::ProcessClientKeyBind(CKeyFunctionBind* pBind) -{ - m_pScriptKeyBinds->ProcessKey(pBind->boundKey->szKey, pBind->bHitState, SCRIPT_KEY_BIND_FUNCTION); -} - -void CClientGame::StaticProcessClientControlBind(CControlFunctionBind* pBind) -{ - g_pClientGame->ProcessClientControlBind(pBind); -} - -void CClientGame::ProcessClientControlBind(CControlFunctionBind* pBind) -{ - m_pScriptKeyBinds->ProcessKey(pBind->control->szControl, pBind->bHitState, SCRIPT_KEY_BIND_CONTROL_FUNCTION); -} - -void CClientGame::StaticProcessServerKeyBind(CKeyFunctionBind* pBind) -{ - g_pClientGame->ProcessServerKeyBind(pBind); -} - -void CClientGame::ProcessServerKeyBind(CKeyFunctionBind* pBind) -{ - const char* szName = pBind->boundKey->szKey; - unsigned char ucNameLength = (unsigned char)strlen(szName); - CBitStream bitStream; - bitStream.pBitStream->WriteBit(false); - bitStream.pBitStream->WriteBit(pBind->bHitState); - bitStream.pBitStream->Write(szName, ucNameLength); - m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); -} - -void CClientGame::StaticProcessServerControlBind(CControlFunctionBind* pBind) -{ - g_pClientGame->ProcessServerControlBind(pBind); -} - -void CClientGame::ProcessServerControlBind(CControlFunctionBind* pBind) -{ - const char* szName = pBind->control->szControl; - unsigned char ucNameLength = (unsigned char)strlen(szName); - CBitStream bitStream; - bitStream.pBitStream->WriteBit(true); - bitStream.pBitStream->WriteBit(pBind->bHitState); - bitStream.pBitStream->Write(szName, ucNameLength); - m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); -} - -bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - bool bCursorForcedVisible = g_pCore->IsCursorForcedVisible(); - bool bMenuVisible = g_pCore->IsMenuVisible(); - bool bConsoleVisible = g_pCore->GetConsole()->IsVisible(); - - if (bCursorForcedVisible) - { - if (!bMenuVisible && !bConsoleVisible) - { - if (m_bCursorEventsEnabled) - { - unsigned char ucButtonHit = 0xFF; - switch (uMsg) - { - case WM_LBUTTONDOWN: - ucButtonHit = 0; - break; - case WM_LBUTTONUP: - ucButtonHit = 1; - break; - case WM_MBUTTONDOWN: - ucButtonHit = 2; - break; - case WM_MBUTTONUP: - ucButtonHit = 3; - break; - case WM_RBUTTONDOWN: - ucButtonHit = 4; - break; - case WM_RBUTTONUP: - ucButtonHit = 5; - break; - } - if (ucButtonHit != 0xFF) - { - int iX = LOWORD(lParam); - int iY = HIWORD(lParam); - - CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); - - /* - // (IJs) why are these relative? it doesn't make sense - CVector2D vecCursorPosition ( ( ( float ) iX ) / vecResolution.fX, - ( ( float ) iY ) / vecResolution.fY ); - */ - - CVector2D vecCursorPosition((float)iX, (float)iY); - - CVector vecOrigin, vecTarget, vecScreen((float)iX, (float)iY, 300.0f); - g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); - - // Grab the camera position - CCamera* pCamera = g_pGame->GetCamera(); - CCam* pCam = pCamera->GetCam(pCamera->GetActiveCam()); - CMatrix matCamera; - pCamera->GetMatrix(&matCamera); - vecOrigin = matCamera.vPos; - - CColPoint* pColPoint = NULL; - CEntity* pGameEntity = NULL; - - // Grab the collision point/entity - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pGameEntity); - - CVector vecCollision; - ElementID CollisionEntityID = INVALID_ELEMENT_ID; - CClientEntity* pCollisionEntity = NULL; - if (bCollision && pColPoint) - { - vecCollision = pColPoint->GetPosition(); - if (pGameEntity) - { - CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity); - if (pEntity) - { - pCollisionEntity = pEntity; - if (!pEntity->IsLocalEntity()) - CollisionEntityID = pEntity->GetID(); - } - } - } - else - { - vecCollision = vecTarget; - } - - // Destroy the colpoint so we don't get a leak - if (pColPoint) - { - pColPoint->Destroy(); - } - - const char* szButton = NULL; - const char* szState = NULL; - switch (ucButtonHit) - { - case 0: - szButton = "left"; - szState = "down"; - break; - case 1: - szButton = "left"; - szState = "up"; - break; - case 2: - szButton = "middle"; - szState = "down"; - break; - case 3: - szButton = "middle"; - szState = "up"; - break; - case 4: - szButton = "right"; - szState = "down"; - break; - case 5: - szButton = "right"; - szState = "up"; - break; - } - if (szButton && szState) - { - if (std::isnan(vecCollision.fX)) - vecCollision.fX = 0; - if (std::isnan(vecCollision.fY)) - vecCollision.fY = 0; - if (std::isnan(vecCollision.fZ)) - vecCollision.fZ = 0; - - // Call the event for the client - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(vecCursorPosition.fX); - Arguments.PushNumber(vecCursorPosition.fY); - Arguments.PushNumber(vecCollision.fX); - Arguments.PushNumber(vecCollision.fY); - Arguments.PushNumber(vecCollision.fZ); - if (pCollisionEntity) - Arguments.PushElement(pCollisionEntity); - else - Arguments.PushBoolean(false); - m_pRootEntity->CallEvent("onClientClick", Arguments, false); - - // Send the button, cursor position, 3d position and the entity collided with - CBitStream bitStream; - - SMouseButtonSync button; - button.data.ucButton = ucButtonHit; - bitStream.pBitStream->Write(&button); - - bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fX)); - bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fY)); - - SPositionSync position(false); - position.data.vecPosition = vecCollision; - bitStream.pBitStream->Write(&position); - - if (CollisionEntityID != INVALID_ELEMENT_ID) - { - bitStream.pBitStream->WriteBit(true); - bitStream.pBitStream->Write(CollisionEntityID); - } - else - bitStream.pBitStream->WriteBit(false); - - m_pNetAPI->RPC(CURSOR_EVENT, bitStream.pBitStream); - - if (strcmp(szState, "down") == 0) - { - CVector2D vecDelta = m_vecLastCursorPosition - vecCursorPosition; - - if ((GetTickCount32() - m_ulLastClickTick) < DOUBLECLICK_TIMEOUT && vecDelta.Length() <= DOUBLECLICK_MOVE_THRESHOLD) - { - // Call the event for the client - CLuaArguments DoubleClickArguments; - DoubleClickArguments.PushString(szButton); - DoubleClickArguments.PushNumber(vecCursorPosition.fX); - DoubleClickArguments.PushNumber(vecCursorPosition.fY); - DoubleClickArguments.PushNumber(vecCollision.fX); - DoubleClickArguments.PushNumber(vecCollision.fY); - DoubleClickArguments.PushNumber(vecCollision.fZ); - if (pCollisionEntity) - DoubleClickArguments.PushElement(pCollisionEntity); - else - DoubleClickArguments.PushBoolean(false); - m_pRootEntity->CallEvent("onClientDoubleClick", DoubleClickArguments, false); - } - - m_ulLastClickTick = GetTickCount32(); - m_vecLastCursorPosition = vecCursorPosition; - } - - return true; - } - } - } - } - } - switch (uMsg) - { - case WM_MOUSEMOVE: - { - int iX = LOWORD(lParam), iY = HIWORD(lParam); - static int iPreviousX = 0, iPreviousY = 0; - if (iX != iPreviousX || iY != iPreviousY) - { - iPreviousX = iX, iPreviousY = iY; - - CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); - CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); - - CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); - g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); - - // Call the onClientCursorMove event - CLuaArguments Arguments; - Arguments.PushNumber((double)vecCursorPosition.fX); - Arguments.PushNumber((double)vecCursorPosition.fY); - Arguments.PushNumber((double)iX); - Arguments.PushNumber((double)iY); - Arguments.PushNumber((double)vecTarget.fX); - Arguments.PushNumber((double)vecTarget.fY); - Arguments.PushNumber((double)vecTarget.fZ); - m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); - } - break; - } - } - return false; -} - -CClientPlayer* CClientGame::GetClosestRemotePlayer(const CVector& vecPosition, float fMaxDistance) -{ - CClientPlayer* pClosest = NULL; - float fDistance = 0.0f, fTemp; - CVector vecTemp; - CClientPlayer* pPlayer; - vector::const_iterator iter = m_pPlayerManager->IterBegin(); - for (; iter != m_pPlayerManager->IterEnd(); ++iter) - { - pPlayer = *iter; - if (!pPlayer->IsLocalPlayer() && !pPlayer->IsDeadOnNetwork() && pPlayer->GetHealth() > 0) - { - // Ensure remote player is alive and sending position updates - ulong ulTimeSinceLastPuresync = CClientTime::GetTime() - pPlayer->GetLastPuresyncTime(); - if (ulTimeSinceLastPuresync < static_cast(g_TickRateSettings.iPureSync) * 2) - { - pPlayer->GetPosition(vecTemp); - fTemp = DistanceBetweenPoints3D(vecPosition, vecTemp); - if (fTemp < fMaxDistance) - { - if (!pClosest || fTemp < fDistance) - { - pClosest = pPlayer; - fDistance = fTemp; - } - } - } - } - } - return pClosest; -} - -void CClientGame::SetGameSpeed(float fSpeed) -{ - g_pGame->SetGameSpeed(fSpeed); - m_fGameSpeed = fSpeed; -} - -void CClientGame::SetMinuteDuration(unsigned long ulDelay) -{ - g_pGame->SetMinuteDuration(ulDelay); - m_ulMinuteDuration = ulDelay; -} - -void CClientGame::SetMoney(long lMoney, bool bInstant) -{ - g_pGame->GetPlayerInfo()->SetPlayerMoney(lMoney, bInstant); - m_lMoney = lMoney; -} - -void CClientGame::SetWanted(DWORD dwWanted) -{ - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(dwWanted); - m_dwWanted = dwWanted; -} - -void CClientGame::AddBuiltInEvents(void) -{ - // Resource events - m_Events.AddEvent("onClientResourceStart", "resource", NULL, false); - m_Events.AddEvent("onClientResourceStop", "resource", NULL, false); - - // Element events - m_Events.AddEvent("onClientElementDataChange", "name", NULL, false); - m_Events.AddEvent("onClientElementStreamIn", "", NULL, false); - m_Events.AddEvent("onClientElementStreamOut", "", NULL, false); - m_Events.AddEvent("onClientElementDestroy", "", NULL, false); - - // Player events - m_Events.AddEvent("onClientPlayerJoin", "", NULL, false); - m_Events.AddEvent("onClientPlayerQuit", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerTarget", "target", NULL, false); - m_Events.AddEvent("onClientPlayerSpawn", "team", NULL, false); - m_Events.AddEvent("onClientPlayerChangeNick", "oldNick", NULL, false); - m_Events.AddEvent("onClientPlayerVehicleEnter", "vehicle, seat", NULL, false); - m_Events.AddEvent("onClientPlayerVehicleExit", "vehicle, seat", NULL, false); - m_Events.AddEvent("onClientPlayerTask", "priority, slot, name", NULL, false); - m_Events.AddEvent("onClientPlayerWeaponSwitch", "previous, current", NULL, false); - m_Events.AddEvent("onClientPlayerStuntStart", "type", NULL, false); - m_Events.AddEvent("onClientPlayerStuntFinish", "type, time, distance", NULL, false); - m_Events.AddEvent("onClientPlayerRadioSwitch", "", NULL, false); - m_Events.AddEvent("onClientPlayerDamage", "attacker, weapon, bodypart", NULL, false); - m_Events.AddEvent("onClientPlayerWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); - m_Events.AddEvent("onClientPlayerWasted", "", NULL, false); - m_Events.AddEvent("onClientPlayerChoke", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceStart", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceStop", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoicePause", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceResumed", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerStealthKill", "target", NULL, false); - m_Events.AddEvent("onClientPlayerHitByWaterCannon", "vehicle", NULL, false); - m_Events.AddEvent("onClientPlayerHeliKilled", "heli", NULL, false); - m_Events.AddEvent("onClientPlayerPickupHit", "pickup, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPlayerPickupLeave", "pickup, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPlayerNetworkStatus", "type, ticks", NULL, false); - - // Ped events - m_Events.AddEvent("onClientPedDamage", "attacker, weapon, bodypart", NULL, false); - m_Events.AddEvent("onClientPedWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); - m_Events.AddEvent("onClientPedWasted", "", NULL, false); - m_Events.AddEvent("onClientPedChoke", "", NULL, false); - m_Events.AddEvent("onClientPedHeliKilled", "heli", NULL, false); - m_Events.AddEvent("onClientPedHitByWaterCannon", "vehicle", NULL, false); - - // Vehicle events - m_Events.AddEvent("onClientVehicleRespawn", "", NULL, false); - m_Events.AddEvent("onClientVehicleEnter", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleExit", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleStartEnter", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleStartExit", "player, seat", NULL, false); - m_Events.AddEvent("onClientTrailerAttach", "towedBy", NULL, false); - m_Events.AddEvent("onClientTrailerDetach", "towedBy", NULL, false); - m_Events.AddEvent("onClientVehicleExplode", "", NULL, false); - m_Events.AddEvent("onClientVehicleCollision", "collidedelement, damageImpulseMag, bodypart, x, y, z, velX, velY, velZ", NULL, false); - m_Events.AddEvent("onClientVehicleDamage", "attacker, weapon, loss, x, y, z, tyre", NULL, false); - m_Events.AddEvent("onClientVehicleNitroStateChange", "activated", NULL, false); - - // GUI events - m_Events.AddEvent("onClientGUIClick", "button, state, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIDoubleClick", "button, state, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIMouseDown", "button, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIMouseUp", "button, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIScroll", "element", NULL, false); - m_Events.AddEvent("onClientGUIChanged", "element", NULL, false); - m_Events.AddEvent("onClientGUIAccepted", "element", NULL, false); - // m_Events.AddEvent ( "onClientGUIClose", "element", NULL, false ); - // m_Events.AddEvent ( "onClientGUIKeyDown", "element", NULL, false ); - m_Events.AddEvent("onClientGUITabSwitched", "element", NULL, false); - m_Events.AddEvent("onClientGUIComboBoxAccepted", "element", NULL, false); - - // Input events - m_Events.AddEvent("onClientDoubleClick", "button, screenX, screenY, worldX, worldY, worldZ, element", NULL, false); - m_Events.AddEvent("onClientMouseMove", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseEnter", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseLeave", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseWheel", "", NULL, false); - m_Events.AddEvent("onClientGUIMove", "", NULL, false); - m_Events.AddEvent("onClientGUISize", "", NULL, false); - m_Events.AddEvent("onClientGUIFocus", "", NULL, false); - m_Events.AddEvent("onClientGUIBlur", "", NULL, false); - m_Events.AddEvent("onClientKey", "key, state", NULL, false); - m_Events.AddEvent("onClientCharacter", "character", NULL, false); - - // Console events - m_Events.AddEvent("onClientConsole", "text", NULL, false); - - // Chat events - m_Events.AddEvent("onClientChatMessage", "test, r, g, b", NULL, false); - - // Debug events - m_Events.AddEvent("onClientDebugMessage", "message, level, file, line", NULL, false); - - // Game events - m_Events.AddEvent("onClientPreRender", "", NULL, false); - m_Events.AddEvent("onClientHUDRender", "", NULL, false); - m_Events.AddEvent("onClientRender", "", NULL, false); - m_Events.AddEvent("onClientMinimize", "", NULL, false); - m_Events.AddEvent("onClientRestore", "", NULL, false); - - // Cursor events - m_Events.AddEvent("onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false); - m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); - - // Transfer box event - m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); - - // Marker events - m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); - - // Marker events - m_Events.AddEvent("onClientPickupHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPickupLeave", "entity, matchingDimension", NULL, false); - - // Col-shape events - m_Events.AddEvent("onClientColShapeHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientColShapeLeave", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientElementColShapeHit", "colShape, matchingDimension", NULL, false); - m_Events.AddEvent("onClientElementColShapeLeave", "colShape, matchingDimension", NULL, false); - - // Explosion events - m_Events.AddEvent("onClientExplosion", "x, y, z, type", NULL, false); - - // Projectile events - m_Events.AddEvent("onClientProjectileCreation", "creator", NULL, false); - - // Sound events - m_Events.AddEvent("onClientSoundStream", "success, length, streamName, error", NULL, false); - m_Events.AddEvent("onClientSoundFinishedDownload", "length", NULL, false); - m_Events.AddEvent("onClientSoundChangedMeta", "streamTitle", NULL, false); - m_Events.AddEvent("onClientSoundStarted", "reason", NULL, false); - m_Events.AddEvent("onClientSoundStopped", "reason", NULL, false); - m_Events.AddEvent("onClientSoundBeat", "time", NULL, false); - - // Object events - m_Events.AddEvent("onClientObjectDamage", "loss, attacker", NULL, false); - m_Events.AddEvent("onClientObjectBreak", "attacker", NULL, false); - - // Web events - m_Events.AddEvent("onClientBrowserWhitelistChange", "newPages", NULL, false); - m_Events.AddEvent("onClientBrowserCreated", "", NULL, false); - m_Events.AddEvent("onClientBrowserLoadingStart", "url, mainframe", NULL, false); - m_Events.AddEvent("onClientBrowserDocumentReady", "url", NULL, false); - m_Events.AddEvent("onClientBrowserLoadingFailed", "url, errorcode, errordescription", NULL, false); - m_Events.AddEvent("onClientBrowserNavigate", "url, isblocked", NULL, false); - m_Events.AddEvent("onClientBrowserPopup", "targeturl, openerurl, ispopup", NULL, false); - m_Events.AddEvent("onClientBrowserCursorChange", "cursor", NULL, false); - m_Events.AddEvent("onClientBrowserTooltip", "text", NULL, false); - m_Events.AddEvent("onClientBrowserInputFocusChanged", "gainedfocus", NULL, false); - m_Events.AddEvent("onClientBrowserResourceBlocked", "url, domain, reason", NULL, false); - - // Misc events - m_Events.AddEvent("onClientFileDownloadComplete", "fileName, success", NULL, false); - - m_Events.AddEvent("onClientWeaponFire", "ped, x, y, z", NULL, false); -} - -void CClientGame::DrawFPS(void) -{ - // Draw the background - float fResWidth = static_cast(g_pCore->GetGraphics()->GetViewportWidth()); - float fResHeight = static_cast(g_pCore->GetGraphics()->GetViewportHeight()); - g_pCore->GetGraphics()->DrawRectangle(0.75f * fResWidth, 0.22f * fResHeight, 0.25f * fResWidth, 0.04f * fResHeight, 0x78000000); - - static char x = 0; - static float fDisp = 0.0f; - if (x == 20) - { - x = 0; - fDisp = g_pGame->GetFPS(); - } - else - x++; - SString strBuffer("FrameRate: %4.2f\n", fDisp); - - // Print it - m_pDisplayManager->DrawText2D(strBuffer, CVector(0.76f, 0.23f, 0), 1.0f, 0xFFFFFFFF); -} - -#ifdef MTA_DEBUG - -void CClientGame::DrawTasks(CClientPlayer* pPlayer) -{ - CTask* pTask = NULL; - CTask* pSubTask = NULL; - - // Got a local player model - if (pPlayer) - { - CTaskManager* man = pPlayer->GetTaskManager(); - if (man == NULL) - return; - if ((unsigned long)man == 0xDDDDDDDD) - { - m_pDisplayManager->DrawText2D("HELP! MANAGER FUCKED", CVector(0.05f, 0.5f, 0), 1.0f); - return; - } - - // Grab the current task - SString strOutput; - SString strSubOutput; - - pTask = man->GetTask(TASK_PRIORITY_PHYSICAL_RESPONSE); - strOutput += SString("Physical Response: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_TEMP); - strOutput += SString("Event Response Temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_NONTEMP); - strOutput += SString("Event Response Non-temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_PRIMARY); - strOutput += SString("Primary: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_DEFAULT); - strOutput += SString("Default: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_ATTACK); - strOutput += SString("Secondary Attack: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_DUCK); - strOutput += SString("Secondary Duck: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_SAY); - strOutput += SString("Secondary Say: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX); - strOutput += SString("Secondary Facial Complex: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM); - strOutput += SString("Secondary Partial Anim: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_IK); - strOutput += SString("Secondary IK: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - m_pDisplayManager->DrawText2D(strOutput, CVector(0.05f, 0.5f, 0), 1.0f); - m_pDisplayManager->DrawText2D(strSubOutput, CVector(0.5f, 0.5f, 0), 1.0f); - } -} - -int iPlayerTask = 0; -void CClientGame::DrawPlayerDetails(CClientPlayer* pPlayer) -{ - // Get the info - CControllerState cs; - - pPlayer->GetControllerState(cs); - - CVector vecPosition; - pPlayer->GetPosition(vecPosition); - - float fRotation = pPlayer->GetCurrentRotation(); - float fCameraRotation = pPlayer->GetCameraRotation(); - float fHealth = pPlayer->GetHealth(); - bool bIsDucked = pPlayer->IsDucked(); - bool bWearingGoggles = pPlayer->IsWearingGoggles(); - bool bInVehicle = pPlayer->GetOccupiedVehicle() != NULL; - float fWeaponRange = 0.0f; - - unsigned char ucWeapon = 0; - unsigned char ucWeaponState = 0; - unsigned short usWeaponAmmo = 0; - CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); - if (pWeapon) - { - ucWeapon = static_cast(pWeapon->GetType()); - ucWeaponState = static_cast(pWeapon->GetState()); - usWeaponAmmo = static_cast(pWeapon->GetAmmoInClip()); - float fSkill = pPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(pWeapon->GetType())); - CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(pWeapon->GetType(), fSkill); - fWeaponRange = pWeaponInfo->GetWeaponRange(); - } - - float fAimX, fAimY; - pPlayer->GetAim(fAimX, fAimY); - const CVector& vecAimSource = pPlayer->GetAimSource(); - const CVector& vecAimTarget = pPlayer->GetAimTarget(); - unsigned char ucDrivebyAim = pPlayer->GetVehicleAimAnim(); - - g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x10DE1212, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x90DE1212, false); - - CTask* pPrimaryTask = pPlayer->GetCurrentPrimaryTask(); - int iPrimaryTask = pPrimaryTask ? pPrimaryTask->GetTaskType() : -1; - - // Copy the stuff - SString strBuffer( - "Orient:\n" - "Position: %f %f %f\n" - "Rotation/camera: %f %f\n" - "Health: %f\n" - "\n" - "Keys:\n" - "LeftShoulder1: %hi\n" - "RightShoulder1: %hi\n" - "ButtonSquare: %hi\n" - "ButtonCross: %hi\n" - "ButtonCircle: %hi\n" - "ShockButtonL: %hi\n" - "PedWalk: %hi\n" - "VehicleMouseLook: %hi\n" - "LeftStickX: %hi\n" - "LeftStickY: %hi\n" - "\n" - "Misc:\n" - "Primary task: %d\n" - "Ducked: %u\n" - "Goggles: %u\n" - "In vehicle: %u\n" - "Weapon: %u\n" - "Weapon state: %u\n" - "Weapon ammo: %u\n" - "Weapon range: %f\n" - "Aim: %f %f\n" - "Aim source: %f %f %f\n" - "Aim target: %f %f %f\n" - "Driveby aim: %u\n" - "Frozen: %u\n", - vecPosition.fX, vecPosition.fY, vecPosition.fZ, fRotation, fCameraRotation, fHealth, cs.LeftShoulder1, cs.RightShoulder1, cs.ButtonSquare, - cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.m_bPedWalk, cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, iPrimaryTask, bIsDucked, - bWearingGoggles, bInVehicle, ucWeapon, ucWeaponState, usWeaponAmmo, fWeaponRange, fAimX, fAimY, vecAimSource.fX, vecAimSource.fY, vecAimSource.fZ, - vecAimTarget.fX, vecAimTarget.fY, vecAimTarget.fZ, ucDrivebyAim, pPlayer->IsFrozen()); - - // Draw it - m_pDisplayManager->DrawText2D(strBuffer, CVector(0.45f, 0.05f, 0), 1.0f, 0xFFFFFFFF); -} - -void CClientGame::DrawWeaponsyncData(CClientPlayer* pPlayer) -{ - CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); - - if (pWeapon) - { - CVector vecSource; - CVector vecTarget; - - // red line: Draw their synced aim line - pPlayer->GetShotData(&vecSource, &vecTarget); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x10DE1212, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x90DE1212, false); - - // green line: Set muzzle as origin and perform a collision test for the target - CColPoint* pCollision; - CVector vecTemp; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecSource, &vecTarget, &pCollision, NULL); - if (pCollision) - { - if (bCollision) - { - CVector vecBullet = pCollision->GetPosition() - vecSource; - vecBullet.Normalize(); - CVector vecTarget = vecSource + (vecBullet * 200); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x1012DE12, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x9012DE12, false); - } - pCollision->Destroy(); - } - - if (m_pLocalPlayer != pPlayer) - { - // Draw information about their weapon state, total ammo and ammo in clip - CVector vecScreenPosition; - CVector vecPosition; - - pPlayer->GetPosition(vecPosition); - - vecPosition.fZ += 1.0f; - g_pCore->GetGraphics()->CalcScreenCoors(&vecPosition, &vecScreenPosition); - - SString strTemp; - int yoffset; - - yoffset = 0; - strTemp.Format("Ammo in clip: %d", pWeapon->GetAmmoInClip()); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); - - yoffset = 15; - strTemp.Format("State: %d", pWeapon->GetState()); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); - } - } -} - -void CClientGame::UpdateMimics(void) -{ - // Got a local player? - if (m_pLocalPlayer) - { - unsigned char ucWeaponType = 0; - unsigned char ucWeaponState = 0; - unsigned long ulWeaponAmmoInClip = 0; - eWeaponSlot weaponSlot = WEAPONSLOT_TYPE_UNARMED; - - CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(m_pLocalPlayer->GetCurrentWeaponSlot()); - if (pPlayerWeapon) - { - ucWeaponType = static_cast(pPlayerWeapon->GetType()); - ucWeaponState = static_cast(pPlayerWeapon->GetState()); - weaponSlot = pPlayerWeapon->GetSlot(); - ulWeaponAmmoInClip = pPlayerWeapon->GetAmmoInClip(); - } - - // Simulate lag (or not) - if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) - { - m_ulLastMimicLag = CClientTime::GetTime(); - - // Grab the local data - CControllerState Controller; - m_pLocalPlayer->GetControllerState(Controller); - CVector vecPosition; - m_pLocalPlayer->GetPosition(vecPosition); - float fRotation = m_pLocalPlayer->GetCurrentRotation(); - CVector vecMoveSpeed; - m_pLocalPlayer->GetMoveSpeed(vecMoveSpeed); - float fHealth = m_pLocalPlayer->GetHealth(); - float fArmor = m_pLocalPlayer->GetArmor(); - float fCameraRotation = g_pGame->GetCamera()->GetCameraRotation(); - bool bDucked = m_pLocalPlayer->IsDucked(); - bool bWearingGoggles = m_pLocalPlayer->IsWearingGoggles(true); - bool bHasJetpack = m_pLocalPlayer->HasJetPack(); - bool bChoking = m_pLocalPlayer->IsChoking(); - bool bSunbathing = m_pLocalPlayer->IsSunbathing(); - bool bDoingDriveby = m_pLocalPlayer->IsDoingGangDriveby(); - bool bStealthAiming = m_pLocalPlayer->IsStealthAiming(); - - // Is the current weapon goggles (44 or 45) or a camera (43), or a detonator (40), don't apply the fire key - if (weaponSlot == 11 || weaponSlot == 12 || ucWeaponType == 43) - Controller.ButtonCircle = 0; - - CClientVehicle* pVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - unsigned int uiSeat = m_pLocalPlayer->GetOccupiedVehicleSeat(); - - CShotSyncData* pShotSync = g_pMultiplayer->GetLocalShotSyncData(); - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - float fAimX = pShotSync->m_fArmDirectionX; - float fAimY = pShotSync->m_fArmDirectionY; - char cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; - bool bAkimboUp = g_pMultiplayer->GetAkimboTargetUp(); - - /* - static CClientMarker *pOriginCorona = NULL, *pTargetCorona = NULL; - if ( pOriginCorona == NULL ) - { - pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); - pOriginCorona->SetColor ( 0, 255, 0, 255 ); - pOriginCorona->SetSize ( 0.5f ); - } - else - pOriginCorona->SetPosition ( vecOrigin ); - - if ( pTargetCorona == NULL ) - { - pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); - pTargetCorona->SetColor ( 255, 0, 0, 255 ); - pTargetCorona->SetSize ( 0.5f ); - } - else - pTargetCorona->SetPosition ( vecTarget );*/ - - // Apply this to each of our mimic players - unsigned int uiMimicIndex = 0; - list::const_iterator iterMimics = m_Mimics.begin(); - for (; iterMimics != m_Mimics.end(); ++iterMimics, ++uiMimicIndex) - { - vecPosition.fX += 4.0f; - vecOrigin.fX += 4.0f; - vecTarget.fX += 4.0f; - - CClientPlayer* pMimic = *iterMimics; - - pMimic->SetHealth(fHealth); - pMimic->LockHealth(fHealth); - pMimic->SetArmor(fArmor); - pMimic->LockArmor(fArmor); - pMimic->SetWearingGoggles(bWearingGoggles); - pMimic->SetHasJetPack(bHasJetpack); - pMimic->SetChoking(bChoking); - pMimic->SetSunbathing(bSunbathing); - pMimic->SetDoingGangDriveby(bDoingDriveby); - pMimic->SetStealthAiming(bStealthAiming); - - Controller.ShockButtonL = 0; - - if (m_bMimicLag) - { - pMimic->SetTargetPosition(vecPosition, TICK_RATE); - pMimic->SetMoveSpeed(vecMoveSpeed); - pMimic->SetControllerState(Controller); - pMimic->SetTargetRotation(fRotation); - pMimic->SetCameraRotation(fCameraRotation); - pMimic->Duck(bDucked); - } - else - { - pMimic->SetPosition(vecPosition); - pMimic->SetMoveSpeed(vecMoveSpeed); - pMimic->SetTargetRotation(fRotation); - pMimic->SetCameraRotation(fCameraRotation); - pMimic->SetControllerState(Controller); - pMimic->Duck(bDucked); - } - - if (ucWeaponType != 0) - { - if (ucWeaponType == 44 || ucWeaponType == 45) - { - Controller.ButtonCircle = 0; - } - - if (m_bMimicLag) - { - pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); - pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); - - pMimic->AddChangeWeapon(TICK_RATE, weaponSlot, (unsigned char)ulWeaponAmmoInClip); - } - else - { - CWeapon* pPlayerWeapon = pMimic->GetWeapon(); - eWeaponType eCurrentWeapon = static_cast(ucWeaponType); - if ((pPlayerWeapon && pPlayerWeapon->GetType() != eCurrentWeapon) || !pPlayerWeapon) - { - pPlayerWeapon = pMimic->GiveWeapon(eCurrentWeapon, ulWeaponAmmoInClip); - if (pPlayerWeapon) - { - pPlayerWeapon->SetAsCurrentWeapon(); - } - } - - if (pPlayerWeapon) - { - pPlayerWeapon->SetAmmoTotal(9999); - pPlayerWeapon->SetAmmoInClip(ulWeaponAmmoInClip); - pPlayerWeapon->SetState(static_cast(ucWeaponState)); - } - pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); - pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); - } - } - else - { - pMimic->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); - } - - CClientVehicle* pMimicVehicle = pMimic->GetOccupiedVehicle(); - if (pVehicle) - { - unsigned int uiModel; - CVector vecPosition, vecRotationDegrees; - CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; - float fHealth; - - uiModel = pVehicle->GetModel(); - pVehicle->GetPosition(vecPosition); - pVehicle->GetRotationDegrees(vecRotationDegrees); - pVehicle->GetMoveSpeed(vecMoveSpeed); - pVehicle->GetTurnSpeed(vecTurnSpeed); - fHealth = pVehicle->GetHealth(); - - if (pMimicVehicle && pMimicVehicle->GetModel() != uiModel) - { - delete pMimicVehicle; - pMimicVehicle = NULL; - } - - vecPosition.fX += ((float)(uiMimicIndex + 1) * 10.0f); - - if (pMimicVehicle == NULL) - { - pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, uiModel, 0, 0); - pMimicVehicle->SetPosition(vecPosition); - - const SSlotStates& usUpgrades = pVehicle->GetUpgrades()->GetSlotStates(); - for (unsigned char uc = 0; uc < VEHICLE_UPGRADE_SLOTS; uc++) - { - if (usUpgrades[uc]) - { - pMimicVehicle->GetUpgrades()->AddUpgrade(usUpgrades[uc], true); - } - } - - m_vecLastMimicPos = vecPosition; - } - - if (m_bMimicLag) - { - pMimicVehicle->SetTargetPosition(vecPosition, TICK_RATE); - pMimicVehicle->SetTargetRotation(vecRotationDegrees, TICK_RATE); - pMimicVehicle->SetMoveSpeed(vecMoveSpeed); - pMimicVehicle->SetTurnSpeed(vecTurnSpeed); - } - else - { - pMimicVehicle->SetPosition(vecPosition); - pMimicVehicle->SetRotationDegrees(vecRotationDegrees); - pMimicVehicle->SetMoveSpeed(vecMoveSpeed); - pMimicVehicle->SetTurnSpeed(vecTurnSpeed); - } - pMimicVehicle->SetHealth(fHealth); - if (pMimic->GetOccupiedVehicle() != pMimicVehicle) - pMimic->WarpIntoVehicle(pMimicVehicle, uiSeat); - - unsigned int uiTrailerLoop = 0; - CClientVehicle* pTrailer = pVehicle->GetTowedVehicle(); - CClientVehicle* pMimicTrailer = NULL; - while (pTrailer) - { - uiModel = pTrailer->GetModel(); - pTrailer->GetPosition(vecPosition); - pTrailer->GetRotationDegrees(vecRotationDegrees); - pTrailer->GetMoveSpeed(vecMoveSpeed); - pTrailer->GetTurnSpeed(vecTurnSpeed); - fHealth = pTrailer->GetHealth(); - - pMimicTrailer = DynamicCast(CElementIDs::GetElement(static_cast(450 + uiMimicIndex + uiTrailerLoop))); - - if (pMimicTrailer && pMimicTrailer->GetModel() != uiModel) - { - delete pMimicTrailer; - pMimicTrailer = NULL; - } - - if (!pMimicTrailer) - { - pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, - static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); - pMimicVehicle->SetTowedVehicle(pMimicTrailer); - } - - pTrailer = pTrailer->GetTowedVehicle(); - pMimicTrailer = pMimicTrailer->GetTowedVehicle(); - uiTrailerLoop++; - } - if (pMimicTrailer) - { - if (pMimicTrailer->GetTowedByVehicle()) - { - pMimicTrailer->GetTowedByVehicle()->SetTowedVehicle(NULL); - } - } - } - else if (pMimicVehicle) - { - pMimic->RemoveFromVehicle(); - delete pMimicVehicle; - } - } - } - } -} - -void CClientGame::DoPaintballs(void) -{ - if (m_pLocalPlayer) - { - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - - CColPoint* pCollision = NULL; - CEntity* pCollisionEntity = NULL; - m_pLocalPlayer->WorldIgnore(true); - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionEntity); - m_pLocalPlayer->WorldIgnore(false); - - static list paintBalls; - if (paintBalls.size() >= 5) - { - CClientMarker* pCorona = paintBalls.back(); - delete pCorona; - paintBalls.pop_back(); - } - - CClientMarker* pCorona = new CClientMarker(m_pManager, INVALID_ELEMENT_ID, CClientMarker::MARKER_CORONA); - paintBalls.push_front(pCorona); - pCorona->SetSize(0.2f); - if (bCollision && pCollision) - { - pCorona->SetPosition(pCollision->GetPosition()); - pCorona->SetColor(SColorRGBA(255, 0, 0, 255)); - } - else - { - pCorona->SetPosition(vecTarget); - pCorona->SetColor(SColorRGBA(255, 255, 0, 255)); - } - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - } -} - -#endif - -void CClientGame::QuitPlayer(CClientPlayer* pPlayer, eQuitReason Reason) -{ - // Get the nick pointer and echo the quit message to the chat - const char* szNick = pPlayer->GetNick(); - const char* szReason = "Unknown"; - switch (Reason) - { - case QUIT_QUIT: - szReason = "Quit"; - break; - case QUIT_KICK: - szReason = "Kicked"; - break; - case QUIT_BAN: - szReason = "Banned"; - break; - case QUIT_CONNECTION_DESYNC: - szReason = "Bad Connection"; - break; - case QUIT_TIMEOUT: - szReason = "Timed Out"; - break; - } - - // In debug, make sure we don't look at this player's details -#ifdef MTA_DEBUG - if (m_pShowPlayer == pPlayer) - { - m_pShowPlayer = NULL; - } -#endif - - // Call our onClientPlayerQuit event - CLuaArguments Arguments; - Arguments.PushString(szReason); - pPlayer->CallEvent("onClientPlayerQuit", Arguments, true); - - // Detach the camera from this player if we're watching them - m_pManager->GetCamera()->UnreferencePlayer(pPlayer); - - // Was this player jacking us? - if (m_bIsGettingJacked && m_pGettingJackedBy == pPlayer) - { - ResetVehicleInOut(); - m_pLocalPlayer->RemoveFromVehicle(false); - m_pLocalPlayer->SetVehicleInOutState(VEHICLE_INOUT_NONE); - } - - // Delete the player - delete pPlayer; -} - -void CClientGame::Event_OnIngame(void) -{ - // Unpause the game - g_pGame->Pause(false); - - // Disable parts of the Hud - CHud* pHud = g_pGame->GetHud(); - pHud->SetComponentVisible(HUD_HELP_TEXT, false); - pHud->SetComponentVisible(HUD_VITAL_STATS, false); - pHud->SetComponentVisible(HUD_AREA_NAME, false); - - g_pMultiplayer->DeleteAndDisableGangTags(); - - // Switch off peds and traffic - SFixedArray vecs = {CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), - CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0)}; - g_pGame->GetPathFind()->SwitchRoadsOffInArea(&vecs[0], &vecs[1]); - g_pGame->GetPathFind()->SwitchPedRoadsOffInArea(&vecs[2], &vecs[3]); - g_pGame->GetPathFind()->SetPedDensity(0.0f); - g_pGame->GetPathFind()->SetVehicleDensity(0.0f); - - g_pGame->GetWorld()->ClearRemovedBuildingLists(); - g_pGame->GetWorld()->SetOcclusionsEnabled(true); - - g_pGame->ResetModelLodDistances(); - g_pGame->ResetAlphaTransparencies(); - - // Make sure we can access all areas - g_pGame->GetStats()->ModifyStat(CITIES_PASSED, 2.0); - - // This is to prevent the 'white arrows in checkpoints' bug (#274) - g_pGame->Get3DMarkers()->CreateMarker(87654, (e3DMarkerType)5, &vecs[4], 1, 0.2f, 0, 0, 0, 0); - - // Stop us getting 4 stars if we visit the SF or LV - // g_pGame->GetPlayerInfo()->GetWanted()->SetMaximumWantedLevel ( 0 ); - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(0); - - // Reset anything from last game - ResetMapInfo(); - g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level - g_pGame->GetWaterManager()->SetWaterDrawnLast(true); - m_pCamera->SetCameraClip(true, true); - - // Create a local player for us - m_pLocalPlayer = new CClientPlayer(m_pManager, m_LocalID, true); - if (m_pLocalPlayer) - { - // Set our parent the root entity - m_pLocalPlayer->SetParent(m_pRootEntity); - - // Give the local player our nickname - m_pLocalPlayer->SetNick(m_strLocalNick); - - // Freeze the player at some location we won't see - m_pLocalPlayer->SetHealth(100); - m_pLocalPlayer->SetPosition(CVector(0, 0, 0)); - m_pLocalPlayer->SetFrozen(true); - m_pLocalPlayer->ResetInterpolation(); - - // Reset him - m_pLocalPlayer->ResetStats(); - } - else - { - RaiseFatalError(2); - } - - // Make sure we never get tired - g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true); - - // Tell doggy we got the game running - WatchDogCompletedSection("L1"); -} - -void CClientGame::Event_OnIngameAndConnected(void) -{ - m_ulVerifyTimeStart = CClientTime::GetTime(); - - // Keep criminal records of how many times they've connected to servers - SetApplicationSettingInt("times-connected", GetApplicationSettingInt("times-connected") + 1); - if (m_ServerType == SERVER_TYPE_EDITOR) - SetApplicationSettingInt("times-connected-editor", GetApplicationSettingInt("times-connected-editor") + 1); - - // Notify the server telling we're ingame - m_pNetAPI->RPC(PLAYER_INGAME_NOTICE); -} - -bool CClientGame::StaticBreakTowLinkHandler(CVehicle* pTowingVehicle) -{ - return g_pClientGame->BreakTowLinkHandler(pTowingVehicle); -} - -void CClientGame::StaticDrawRadarAreasHandler(void) -{ - g_pClientGame->DrawRadarAreasHandler(); -} - -bool CClientGame::StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent) -{ - return g_pClientGame->DamageHandler(pDamagePed, pEvent); -} - -void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart) -{ - g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart); -} - -void CClientGame::StaticFireHandler(CFire* pFire) -{ - g_pClientGame->FireHandler(pFire); -} - -void CClientGame::StaticRender3DStuffHandler(void) -{ - g_pClientGame->Render3DStuffHandler(); -} - -void CClientGame::StaticPreRenderSkyHandler(void) -{ - g_pClientGame->PreRenderSkyHandler(); -} - -void CClientGame::StaticRenderHeliLightHandler() -{ - g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); -} - -bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) -{ - return g_pClientGame->ChokingHandler(ucWeaponType); -} - -void CClientGame::StaticCAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) -{ - g_pClientGame->CAnimBlendAssocDestructorHandler(pThis); -} - -CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) -{ - return g_pClientGame->AddAnimationHandler(pClump, animGroup, animID); -} - -CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) -{ - return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); -} - -bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) -{ - return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); -} - -bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, - int* pFlags, RpClump* pClump) -{ - return g_pClientGame->BlendAnimationHierarchyHandler(pAnimAssoc, pOutAnimHierarchy, pFlags, pClump); -} - -void CClientGame::StaticPreWorldProcessHandler(void) -{ - g_pClientGame->PreWorldProcessHandler(); -} - -void CClientGame::StaticPostWorldProcessHandler(void) -{ - g_pClientGame->PostWorldProcessHandler(); -} - -void CClientGame::StaticPreFxRenderHandler(void) -{ - g_pCore->OnPreFxRender(); -} - -void CClientGame::StaticPreHudRenderHandler(void) -{ - g_pCore->OnPreHUDRender(); -} - -bool CClientGame::StaticProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) -{ - return g_pClientGame->ProcessCollisionHandler(pThisInterface, pOtherInterface); -} - -bool CClientGame::StaticVehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, - float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, - CVector vecCollisionVelocity) -{ - return g_pClientGame->VehicleCollisionHandler(pCollidingVehicle, pCollidedVehicle, iModelIndex, fDamageImpulseMag, fCollidingDamageImpulseMag, usPieceType, - vecCollisionPos, vecCollisionVelocity); -} - -bool CClientGame::StaticVehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) -{ - return g_pClientGame->VehicleDamageHandler(pVehicleInterface, fLoss, pAttackerInterface, weaponType, vecDamagePos, ucTyre); -} - -bool CClientGame::StaticHeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) -{ - return g_pClientGame->HeliKillHandler(pHeliInterface, pHitInterface); -} - -bool CClientGame::StaticObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) -{ - return g_pClientGame->ObjectDamageHandler(pObjectInterface, fLoss, pAttackerInterface); -} - -bool CClientGame::StaticObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) -{ - return g_pClientGame->ObjectBreakHandler(pObjectInterface, pAttackerInterface); -} - -bool CClientGame::StaticWaterCannonHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) -{ - return g_pClientGame->WaterCannonHitHandler(pCannonVehicle, pHitPed); -} - -bool CClientGame::StaticVehicleFellThroughMapHandler(CVehicleSAInterface* pVehicle) -{ - return g_pClientGame->VehicleFellThroughMapHandler(pVehicle); -} - -void CClientGame::StaticGameObjectDestructHandler(CEntitySAInterface* pObject) -{ - g_pClientGame->GameObjectDestructHandler(pObject); -} - -void CClientGame::StaticGameVehicleDestructHandler(CEntitySAInterface* pVehicle) -{ - g_pClientGame->GameVehicleDestructHandler(pVehicle); -} - -void CClientGame::StaticGamePlayerDestructHandler(CEntitySAInterface* pPlayer) -{ - g_pClientGame->GamePlayerDestructHandler(pPlayer); -} - -void CClientGame::StaticGameProjectileDestructHandler(CEntitySAInterface* pProjectile) -{ - g_pClientGame->GameProjectileDestructHandler(pProjectile); -} - -void CClientGame::StaticGameModelRemoveHandler(ushort usModelId) -{ - g_pClientGame->GameModelRemoveHandler(usModelId); -} - -void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) -{ - if (pGameEntity) - { - // Map to client entity and pass to the texture replacer - CClientEntity* pClientEntity = g_pClientGame->GetGameEntityXRefManager()->FindClientEntity(pGameEntity); - if (pClientEntity) - { - int iTypeMask; - ushort usModelId = 0xFFFF; - switch (pClientEntity->GetType()) - { - case CCLIENTPED: - case CCLIENTPLAYER: - iTypeMask = TYPE_MASK_PED; - usModelId = (ushort) static_cast(pClientEntity)->GetModel(); - break; - case CCLIENTVEHICLE: - iTypeMask = TYPE_MASK_VEHICLE; - break; - case CCLIENTOBJECT: - iTypeMask = TYPE_MASK_OBJECT; - break; - default: - iTypeMask = TYPE_MASK_OTHER; - break; - } - g_pGame->GetRenderWare()->SetRenderingClientEntity(pClientEntity, usModelId, iTypeMask); - return; - } - } - - g_pGame->GetRenderWare()->SetRenderingClientEntity(NULL, 0xFFFF, TYPE_MASK_WORLD); -} - -void CClientGame::StaticTaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) -{ - g_pClientGame->TaskSimpleBeHitHandler(pPedAttacker, hitBodyPart, hitBodySide, weaponId); -} - -void CClientGame::StaticFxSystemDestructionHandler(void* pFxSAInterface) -{ - g_pClientGame->GetManager()->GetEffectManager()->SAEffectDestroyed(pFxSAInterface); -} - -AnimationId CClientGame::StaticDrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId) -{ - return g_pClientGame->DrivebyAnimationHandler(animGroup, animId); -} - -void CClientGame::DrawRadarAreasHandler(void) -{ - m_pRadarAreaManager->DoPulse(); -} - -bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle) -{ - CClientVehicle* pVehicle = m_pVehicleManager->Get(pTowedVehicle, false); - if (pVehicle) - { - // Check if this is a legal break - bool bLegal = ((pVehicle->GetControllingPlayer() == m_pLocalPlayer) || (m_pUnoccupiedVehicleSync->Exists(static_cast(pVehicle)))); - - // Not a legal break? - if (!bLegal) - { - // Save the time it broke (used in UpdateTrailers) - pVehicle->SetIllegalTowBreakTime(GetTickCount32()); - } - } - - // Allow it to break - return true; -} - -void CClientGame::FireHandler(CFire* pFire) -{ - // Disable spreading fires - pFire->SetNumGenerationsAllowed(0); -} - -void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) -{ - if (pProjectile->IsLocal()) - { - // Did the local player create this projectile? - if (m_pLocalPlayer && pProjectile->GetCreator() == m_pLocalPlayer) - { - // Physics says our projectile should start off at our velocity - CVector vecVelocity, vecPlayerVelocity; - pProjectile->GetVelocity(vecVelocity); - m_pLocalPlayer->GetMoveSpeed(vecPlayerVelocity); - vecVelocity += vecPlayerVelocity; - pProjectile->SetVelocity(vecVelocity); - } - - SendProjectileSync(pProjectile); - } - - // Renew the interior and dimension - if (pProjectile->GetCreator()) - { - pProjectile->SetInterior(pProjectile->GetCreator()->GetInterior()); - pProjectile->SetDimension(pProjectile->GetCreator()->GetDimension()); - } - - // Validate the projectile for our element tree - pProjectile->SetParent(m_pRootEntity); - - // Call our creation event - CLuaArguments Arguments; - Arguments.PushElement(pProjectile->GetCreator()); - pProjectile->CallEvent("onClientProjectileCreation", Arguments, true); -} - -void CClientGame::Render3DStuffHandler(void) -{ -} - -void CClientGame::PreRenderSkyHandler(void) -{ - g_pCore->GetGraphics()->GetRenderItemManager()->PreDrawWorld(); -} - -void CClientGame::PreWorldProcessHandler(void) -{ -} - -void CClientGame::PostWorldProcessHandler(void) -{ - m_pManager->GetMarkerManager()->DoPulse(); - m_pManager->GetPointLightsManager()->DoPulse(); - m_pManager->GetObjectManager()->DoPulse(); - - // Update frame time slice - uint uiCurrentTick = GetTickCount32(); - if (m_uiLastFrameTick) - { - m_uiFrameTimeSlice = uiCurrentTick - m_uiLastFrameTick; - m_uiFrameCount++; - - // Call onClientPreRender LUA event - CLuaArguments Arguments; - Arguments.PushNumber(m_uiFrameTimeSlice); - m_pRootEntity->CallEvent("onClientPreRender", Arguments, false); - } - m_uiLastFrameTick = uiCurrentTick; -} - -void CClientGame::IdleHandler(void) -{ - // If we are minimized we do the pulsing here - if (g_pCore->IsWindowMinimized()) - { - if (!m_bWasMinimized) - { - m_bWasMinimized = true; - // Call onClientMinimize LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); - - bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); - - // Apply mute on minimize options - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) - g_pGame->GetAudio()->SetMusicMasterVolume(0); - - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) - g_pGame->GetAudio()->SetEffectsMasterVolume(0); - - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) - m_pManager->GetSoundManager()->SetMinimizeMuted(true); - } - } - - // Ensure dummy progress graphic will be displayed when using alt pulse order - g_pCore->SetDummyProgressUpdateAlways(true); - - // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) - DoPulses2(true); - - g_pCore->SetDummyProgressUpdateAlways(false); -} - -bool CClientGame::ChokingHandler(unsigned char ucWeaponType) -{ - if (!m_pLocalPlayer) - return true; - CLuaArguments Arguments; - Arguments.PushNumber(ucWeaponType); - return m_pLocalPlayer->CallEvent("onClientPlayerChoke", Arguments, true); -} - -void CClientGame::CAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) -{ - // printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID); - RemoveAnimationAssociationFromMap(pThis); -} - -CAnimBlendAssociationSAInterface* CClientGame::AddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) -{ - // printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); - return nullptr; -} - -CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) -{ - // printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); - return nullptr; -} - -bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) -{ - bool isCustomAnimationToPlay = false; - CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); - auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); - auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); - auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); - auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); - - CClientPed* pClientPed = GetClientPedByClump(*pClump); - if (pClientPed != nullptr) - { - auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); - if (pReplacedAnimation != nullptr) - { - std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); - - // Play our custom animation instead of default - auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); - pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); - pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); - pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); - isCustomAnimationToPlay = true; - } - } - - if (!isCustomAnimationToPlay) - { - auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); - - // Play default internal animation - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); - } - return isCustomAnimationToPlay; -} - -bool CClientGame::BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags, - RpClump* pClump) -{ - bool isCustomAnimationToPlay = false; - CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); - CClientPed* pClientPed = GetClientPedByClump(*pClump); - if (pClientPed != nullptr) - { - if (pClientPed->IsNextAnimationCustom()) - { - std::shared_ptr pIFP = pClientPed->GetCustomAnimationIFP(); - if (pIFP) - { - const SString& strAnimationName = pClientPed->GetNextAnimationCustomName(); - auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy(strAnimationName); - if (pCustomAnimBlendHierarchy != nullptr) - { - std::shared_ptr pIFPAnimations = pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); - - pClientPed->SetCurrentAnimationCustom(true); - pClientPed->SetNextAnimationNormal(); - - if (pIFP->IsUnloading()) - { - pClientPed->DereferenceCustomAnimationBlock(); - } - *pOutAnimHierarchy = pCustomAnimBlendHierarchy; - isCustomAnimationToPlay = true; - return isCustomAnimationToPlay; - } - } - } - - pClientPed->SetCurrentAnimationCustom(false); - pClientPed->SetNextAnimationNormal(); - } - return isCustomAnimationToPlay; -} - -bool CClientGame::ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) -{ - if (pThisInterface == pOtherInterface) - return true; - - if (!m_BuiltCollisionMapThisFrame) - { - // Build a map of CPhysicalSAInterface*/CClientEntity*'s that have collision disabled - m_BuiltCollisionMapThisFrame = true; - m_CachedCollisionMap.clear(); - - std::map::iterator iter = m_AllDisabledCollisions.begin(); - for (; iter != m_AllDisabledCollisions.end(); ++iter) - { - CClientEntity* pEntity = iter->first; - CEntity* pGameEntity = pEntity->GetGameEntity(); - CEntitySAInterface* pInterface = pGameEntity ? pGameEntity->GetInterface() : NULL; - - if (pInterface) - m_CachedCollisionMap[pInterface] = pEntity; - } - } - - // Check both elements appear in the cached map before doing extra processing - std::map::iterator iter1 = m_CachedCollisionMap.find((CEntitySAInterface*)pThisInterface); - if (iter1 != m_CachedCollisionMap.end()) - { - std::map::iterator iter2 = m_CachedCollisionMap.find((CEntitySAInterface*)pOtherInterface); - if (iter2 != m_CachedCollisionMap.end()) - { - // Re-get the entity pointers using a safer method - CEntity* pGameEntity = g_pGame->GetPools()->GetEntity((DWORD*)pThisInterface); - CEntity* pGameColEntity = g_pGame->GetPools()->GetEntity((DWORD*)pOtherInterface); - - if (pGameEntity && pGameColEntity) - { - CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity, true); - CClientEntity* pColEntity = m_pManager->FindEntity(pGameColEntity, true); - - if (pEntity && pColEntity) - { - #if MTA_DEBUG - CClientEntity* ppThisEntity2 = iter1->second; - CClientEntity* ppOtherEntity2 = iter2->second; - // These should match, but its not essential. - assert(ppThisEntity2 == pEntity); - assert(ppOtherEntity2 == pColEntity); - #endif - if (!pEntity->IsCollidableWith(pColEntity)) - return false; - } - } - } - } - - return true; -} - -// -// On demand files -// -void CClientGame::DownloadSingularResourceFiles(void) -{ - if (!IsTransferringSingularFiles()) - return; - - if (!g_pNet->IsConnected()) - return; - - CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES); - if (!pHTTP->ProcessQueuedFiles()) - { - // Downloading - } - else - { - // Can't clear list until all files have been processed - if (m_pSingularFileDownloadManager->AllComplete()) - { - SetTransferringSingularFiles(false); - m_pSingularFileDownloadManager->ClearList(); - } - } -} - -// Get relevant death anim for animation purposes during death situation -void GetDeathAnim(CClientPed* pDamagedPed, CEventDamage* pEvent, AssocGroupId& outAnimGroup, AnimationId& outAnimID) -{ - if (pEvent) - { - pEvent->ComputeDeathAnim(pDamagedPed->GetGamePlayer(), false); - outAnimGroup = pEvent->GetAnimGroup(); - outAnimID = pEvent->GetAnimId(); - } - else - { - // Using same numbers as CClientGame::DoWastedCheck defaults - outAnimGroup = 0; - outAnimID = 15; - } -} - -// -// DamageHandler seems to be called 3 times for each bit of damage: -// -// pass 1 - preApplyDamage -// is pass 1 if: fDamage == zero && fCurrentHealth == fPreviousHealth -// returning false stops any damage being inflicted -// returning true applies damage and allows pass 2 -// pass 2 - postApplyDamage/preApplyAnim -// is pass 2 if: fDamage > zero && fCurrentHealth != fPreviousHealth -// returning false stops damage anim -// returning true allows damage anim and allows pass 3 -// pass 3 - postApplyAnim -// is pass 3 if: fDamage > zero && fCurrentHealth == fPreviousHealth -// returning false ?? -// returning true ?? -// -bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) -{ - // CEventDamage::AffectsPed: This is/can be called more than once for each bit of damage (and may not actually take any more health (even if we return - // true)) - - // Grab some data from the event - CEntity* pInflictor = pEvent->GetInflictingEntity(); - eWeaponType weaponUsed = pEvent->GetWeaponUsed(); - ePedPieceTypes hitZone = pEvent->GetPedPieceType(); - CWeaponInfo* pWeaponInfo = g_pGame->GetWeaponInfo(weaponUsed); - float fDamage = pEvent->GetDamageApplied(); - EDamageReasonType damageReason = pEvent->GetDamageReason(); - - /* Causes too much desync right now - // Is this shotgun damage? - if ( weaponUsed == WEAPONTYPE_SHOTGUN || weaponUsed == WEAPONTYPE_SPAS12_SHOTGUN ) - { - // Make the ped fall down - pEvent->MakePedFallDown (); - } */ - - // Grab the damaged ped - CClientPed* pDamagedPed = NULL; - if (pDamagePed) - pDamagedPed = m_pPedManager->Get(dynamic_cast(pDamagePed), true, true); - - // Grab the inflictor - CClientEntity* pInflictingEntity = NULL; - if (pInflictor) - pInflictingEntity = m_pManager->FindEntity(pInflictor, true); - - // If the damage was caused by an explosion - if (weaponUsed == WEAPONTYPE_EXPLOSION) - { - CClientEntity* pLastExplosionCreator = m_pManager->GetExplosionManager()->m_pLastCreator; - - // If we don't have an inflictor, look for the last explosion creator - if (!pInflictor && pLastExplosionCreator) - pInflictingEntity = pLastExplosionCreator; - - // Change the weapon used to whatever created the explosion - weaponUsed = m_pManager->GetExplosionManager()->m_LastWeaponType; - } - - // Do we have a damaged ped? - if (pDamagedPed) - { - /////////////////////////////////////////////////////////////////////////// - // - // Pass 1 stuff - // - // return false to stop any damage being inflicted - // - /////////////////////////////////////////////////////////////////////////// - - // Pass 1 checks for double shots - if (fDamage == 0.0f && damageReason != EDamageReason::PISTOL_WHIP) - { - // Only check for remote players - CClientPlayer* pInflictingPlayer = DynamicCast(pInflictingEntity); - if (pInflictingPlayer && !pInflictingPlayer->IsLocalPlayer()) - { - bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon - bool bBulletSyncWeapon = GetWeaponTypeUsesBulletSync(weaponUsed); - - if (bBulletSyncShot) - { - if (g_iDamageEventLimit == 0) - { - AddReportLog(5501, SString("2nd pass 1 for BulletSyncShot damage. weaponUsed:%d", weaponUsed)); - return false; - } - g_iDamageEventLimit--; - if (!bBulletSyncWeapon) - { - AddReportLog(5502, SString("BulletSyncShot but not bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); - return false; - } - } - else - { - if (bBulletSyncWeapon) - { - AddReportLog(5503, SString("not BulletSyncShot but bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); - return false; - } - } - } - } - - // Is the damaged ped a player? - if (IS_PLAYER(pDamagedPed)) - { - CClientPlayer* pDamagedPlayer = static_cast(pDamagedPed); - - // Do we have an inflicting entity? - if (pInflictingEntity) - { - // Grab the inflicting player - CClientPlayer* pInflictingPlayer = NULL; - - switch (pInflictingEntity->GetType()) - { - case CCLIENTPLAYER: - { - pInflictingPlayer = static_cast(pInflictingEntity); - break; - } - case CCLIENTVEHICLE: - { - CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); - if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) - { - CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); - if (pPed && pPed->GetType() == CCLIENTPLAYER) - pInflictingPlayer = static_cast(pPed); - } - break; - } - default: - break; - } - if (pInflictingPlayer) - { - // Is the damaged player on a team - CClientTeam* pTeam = pDamagedPlayer->GetTeam(); - if (pTeam) - { - // Is this friendly-fire from a team-mate? - if (pDamagedPlayer->IsOnMyTeam(pInflictingPlayer) && !pTeam->GetFriendlyFire() && pDamagedPlayer != pInflictingPlayer) - return false; - } - } - } - } - /////////////////////////////////////////////////////////////////////////// - // Pass 1 end - /////////////////////////////////////////////////////////////////////////// - - return ApplyPedDamageFromGame(weaponUsed, fDamage, hitZone, pDamagedPed, pInflictingEntity, pEvent); - } - - // No damage anim for fire - if (weaponUsed == WEAPONTYPE_FLAMETHROWER) - return false; - - // Allow the damage processing to continue - return true; -} - -// -// Check GTA stored health with our stored health and do stuff -// -bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, uchar hitZone, CClientPed* pDamagedPed, CClientEntity* pInflictingEntity, - CEventDamage* pEvent) -{ - float fPreviousHealth = pDamagedPed->m_fHealth; - float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); - float fPreviousArmor = pDamagedPed->m_fArmor; - float fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); - - // Have we taken any damage here? - if ((fPreviousHealth != fCurrentHealth || fPreviousArmor != fCurrentArmor) && fDamage != 0.0f) - { - /////////////////////////////////////////////////////////////////////////// - /// - // Pass 2 stuff - (GTA has applied the damage) - // - // return false to stop damage anim (incl. death task) - // - /////////////////////////////////////////////////////////////////////////// - - g_fApplyDamageLastAmount = fDamage; - g_ucApplyDamageLastHitZone = hitZone; - g_pApplyDamageLastDamagedPed = pDamagedPed; - - CLuaArguments Arguments; - if (pInflictingEntity) - Arguments.PushElement(pInflictingEntity); - else - Arguments.PushBoolean(false); - Arguments.PushNumber(static_cast(weaponUsed)); - Arguments.PushNumber(static_cast(hitZone)); - Arguments.PushNumber(fDamage); - - // Call our event - if ((IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPlayerDamage", Arguments, true)) || - (!IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPedDamage", Arguments, true))) - { - // Stop here if they cancelEvent it - if (pDamagedPed->IsLocalPlayer()) - { - // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) - fPreviousHealth = pDamagedPed->m_fHealth; - fPreviousArmor = pDamagedPed->m_fArmor; - } - pDamagedPed->GetGamePlayer()->SetHealth(fPreviousHealth); - pDamagedPed->GetGamePlayer()->SetArmor(fPreviousArmor); - return false; - } - - if (pDamagedPed->IsLocalPlayer()) - { - // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) - fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); - fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); - } - - bool bIsBeingShotWhilstAiming = (weaponUsed >= WEAPONTYPE_PISTOL && weaponUsed <= WEAPONTYPE_MINIGUN && pDamagedPed->IsUsingGun()); - bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); - - bool bAllowChoke = true; - // Is this is a remote player? - if (!pDamagedPed->IsLocalPlayer()) - { - // Don't allow GTA to start the choking task - if (weaponUsed == WEAPONTYPE_TEARGAS || weaponUsed == WEAPONTYPE_SPRAYCAN || weaponUsed == WEAPONTYPE_EXTINGUISHER) - bAllowChoke = false; - } - - // Check if their health or armor is locked, and if so prevent applying the damage locally - if (pDamagedPed->IsHealthLocked() || pDamagedPed->IsArmorLocked()) - { - // Restore health+armor - pDamagedPed->GetGamePlayer()->SetHealth(pDamagedPed->GetHealth()); - pDamagedPed->GetGamePlayer()->SetArmor(pDamagedPed->GetArmor()); - - if (bOldBehaviour) - { - // Don't play the animation if it's going to be a death one, or if it's going to interrupt aiming - if (fCurrentHealth == 0.0f || bIsBeingShotWhilstAiming) - return false; - - // Allow animation for remote players (if currently we don't need block choke) - return bAllowChoke; - } - - // No hit animation for remote players - return false; - } - - // Update our stored health/armor - pDamagedPed->m_fHealth = fCurrentHealth; - pDamagedPed->m_fArmor = fCurrentArmor; - - ElementID damagerID = INVALID_ELEMENT_ID; - if (pInflictingEntity && !pInflictingEntity->IsLocalEntity()) - damagerID = pInflictingEntity->GetID(); - - // Is it the local player? - if (pDamagedPed->IsLocalPlayer()) - { - // Update our stored damage stuff - m_ucDamageWeapon = static_cast(weaponUsed); - m_ucDamageBodyPiece = static_cast(hitZone); - m_pDamageEntity = pInflictingEntity; - m_ulDamageTime = CClientTime::GetTime(); - m_DamagerID = damagerID; - m_bDamageSent = false; - } - // Does this damage kill the player? - if (fCurrentHealth == 0.0f) - { - if (pDamagedPed->GetType() == CCLIENTPLAYER) - { - // Is the local player dying? - if (pDamagedPed->IsLocalPlayer() && fPreviousHealth > 0.0f) - { - // Grab our death animation - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - - // Check if we're dead - DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); - } - - // Allow GTA to kill us if we've fell to our death - if (pDamagedPed->IsLocalPlayer() && weaponUsed == WEAPONTYPE_FALL) - return true; - - // Don't let GTA start the death task - return false; - } - else - { - if (pDamagedPed->IsLocalEntity() && fPreviousHealth > 0.0f) - { - // Client-side ped - pDamagedPed->CallEvent("onClientPedWasted", Arguments, true); - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - pDamagedPed->Kill(weaponUsed, hitZone, false, false, animGroup, animID); - return true; - } - if (fPreviousHealth > 0.0f) - { - // Grab our death animation - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - - SendPedWastedPacket(pDamagedPed, damagerID, weaponUsed, hitZone, animGroup, animID); - } - } - } - - // Disallow choke task if it's necessary - if (!bAllowChoke) - return false; - - // Inhibit hit-by-gun animation for local player if required - if (bOldBehaviour) - if (pDamagedPed->IsLocalPlayer() && bIsBeingShotWhilstAiming) - return false; - - /////////////////////////////////////////////////////////////////////////// - // Pass 2 end - /////////////////////////////////////////////////////////////////////////// - } - - // No damage anim for fire - if (weaponUsed == WEAPONTYPE_FLAMETHROWER) - return false; - - // Allow the damage processing to continue - return true; -} - -void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, unsigned char ucBodyPart) -{ - CClientPed* pKilledPed = m_pPedManager->Get(dynamic_cast(pKilledPedSA), true, true); - - if (!pKilledPed) - return; - - // Not required for remote players. Local player is handled in DoPulses->DoWastedCheck - if (IS_PLAYER(pKilledPed)) - return; - - // Set the health to zero (this is safe as GTA will do it anyway in a few ticks) - pKilledPed->SetHealth(0.0f); - - // Call Lua - CLuaArguments Arguments; - Arguments.PushBoolean(false); - Arguments.PushNumber(ucDeathReason); - Arguments.PushNumber(ucBodyPart); - - pKilledPed->CallEvent("onClientPedWasted", Arguments, true); - - // Notify the server - SendPedWastedPacket(pKilledPed, INVALID_ELEMENT_ID, ucDeathReason, ucBodyPart); -} - -bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, - float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) -{ - if (pCollidingVehicle && pCollidedWith) - { - CVehicle* pColliderVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidingVehicle); - CClientEntity* pVehicleClientEntity = m_pManager->FindEntity(pColliderVehicle, true); - if (pVehicleClientEntity) - { - CClientVehicle* pClientVehicle = static_cast(pVehicleClientEntity); - - CEntity* pCollidedWithEntity = g_pGame->GetPools()->GetEntity((DWORD*)pCollidedWith); - CClientEntity* pCollidedWithClientEntity = NULL; - if (pCollidedWithEntity) - { - if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pCollidedWithVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithVehicle, true); - } - else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_OBJECT) - { - CObject* pCollidedWithObject = g_pGame->GetPools()->GetObject((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithObject, true); - } - else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pCollidedWithPed = g_pGame->GetPools()->GetPed((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithPed, true); - } - } - CLuaArguments Arguments; - if (pCollidedWithClientEntity) - { - Arguments.PushElement(pCollidedWithClientEntity); - } - else - { - Arguments.PushNil(); - } - Arguments.PushNumber(fDamageImpulseMag); - Arguments.PushNumber(usPieceType); - Arguments.PushNumber(vecCollisionPos.fX); - Arguments.PushNumber(vecCollisionPos.fY); - Arguments.PushNumber(vecCollisionPos.fZ); - Arguments.PushNumber(vecCollisionVelocity.fX); - Arguments.PushNumber(vecCollisionVelocity.fY); - Arguments.PushNumber(vecCollisionVelocity.fZ); - Arguments.PushNumber(fCollidingDamageImpulseMag); - Arguments.PushNumber(iModelIndex); - - pVehicleClientEntity->CallEvent("onClientVehicleCollision", Arguments, true); - // Alocate a BitStream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - // Make sure it created - if (pBitStream) - { - if (pBitStream->Version() >= 0x028) - { - // Sync Stuff - // if it's not a local vehicle + it collided with the local player - if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) - { - // is it below the anti spam threshold? - if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) - { - // if there is no controlling player - if (!pClientVehicle->GetControllingPlayer()) - { - CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); - // if We aren't already syncing the vehicle - if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) - { - // Write the vehicle ID - pBitStream->Write(pVehicleClientEntity->GetID()); - // Send! - g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, - PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); - // Reset our push time - pClientVehicle->ResetLastPushTime(); - } - } - } - } - } - g_pNet->DeallocateNetBitStream(pBitStream); - } - return true; - } - } - return false; -} - -bool CClientGame::HeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) -{ - if (pHeliInterface && pHitInterface) - { - // Get our heli and client heli - CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); - CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); - if (pHeli && pClientHeli && pClientHeli->AreHeliBladeCollisionsEnabled()) - { - // Get our ped and client ped - CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitInterface); - CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); - // Was our client ped valid - if (pClientPed) - { - // Get our heli and client heli - CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); - CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); - - // Iterate our "stored" cancel state and find the heli in question - std::pair::iterator, std::multimap::iterator> iterators = - m_HeliCollisionsMap.equal_range(pClientHeli); - std::multimap::const_iterator iter = iterators.first; - for (; iter != iterators.second; ++iter) - { - // If the Heli and ped collided within the clear rate return false - if ((*iter).first == pClientHeli && (*iter).second == pClientPed) - return false; - } - - CLuaArguments Arguments; - if (pClientHeli) - { - // Push our heli - Arguments.PushElement(pClientHeli); - } - else - { - Arguments.PushNil(); - } - - // Trigger our event - bool bContinue; - if (IS_PLAYER(pClientPed)) - bContinue = pClientPed->CallEvent("onClientPlayerHeliKilled", Arguments, true); - else - bContinue = pClientPed->CallEvent("onClientPedHeliKilled", Arguments, true); - - // Was our event cancelled - if (!bContinue) - { - // Add our heli and ped pair to the list - std::pair pair = std::pair(pClientHeli, pClientPed); - m_HeliCollisionsMap.insert(pair); - } - // Return if it was cancelled - return bContinue; - } - } - else - { - return false; - } - } - return true; -} - -bool CClientGame::VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) -{ - bool bAllowDamage = true; - CClientVehicle* pClientVehicle = GetGameEntityXRefManager()->FindClientVehicle(pVehicleInterface); - if (pClientVehicle) - { - CClientEntity* pClientAttacker = GetGameEntityXRefManager()->FindClientEntity(pAttackerInterface); - - // Compose arguments - // attacker, weapon, loss, damagepos, tyreIdx - CLuaArguments Arguments; - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - if (weaponType != WEAPONTYPE_INVALID) - Arguments.PushNumber(weaponType); - else - Arguments.PushNil(); - Arguments.PushNumber(fLoss); - Arguments.PushNumber(vecDamagePos.fX); - Arguments.PushNumber(vecDamagePos.fY); - Arguments.PushNumber(vecDamagePos.fZ); - if (ucTyre != UCHAR_INVALID_INDEX) - Arguments.PushNumber(ucTyre); - else - Arguments.PushNil(); - - if (!pClientVehicle->CallEvent("onClientVehicleDamage", Arguments, true)) - { - bAllowDamage = false; - } - } - - return bAllowDamage; -} - -bool CClientGame::ObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) -{ - if (pObjectInterface) - { - // Get our object and client object - CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); - CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); - - // Is our client vehicle valid? - if (pClientObject) - { - CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); - CClientEntity* pClientAttacker = NULL; - if (pAttacker) - { - if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); - } - else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerPed); - } - } - - CLuaArguments Arguments; - Arguments.PushNumber(fLoss); - - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - - return pClientObject->CallEvent("onClientObjectDamage", Arguments, true); - } - } - return true; -} - -bool CClientGame::ObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) -{ - if (pObjectInterface) - { - // Get our object and client object - CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); - CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); - - // Is our client vehicle valid? - if (pClientObject) - { - if (!pClientObject->IsBreakable(false)) - return false; - - // Apply to MTA's "internal storage", too - pClientObject->SetHealth(0.0f); - - CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); - CClientEntity* pClientAttacker = NULL; - if (pAttacker) - { - if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); - } - else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerPed); - } - } - - CLuaArguments Arguments; - - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - - return pClientObject->CallEvent("onClientObjectBreak", Arguments, true); - } - } - return true; -} - -bool CClientGame::WaterCannonHitHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) -{ - if (pCannonVehicle && pHitPed) - { - // Get our vehicle and client vehicle - CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCannonVehicle); - CClientVehicle* pCannonClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); - // Was our client vehicle valid - if (pCannonClientVehicle) - { - // Get our ped and client ped - CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitPed); - CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); - - CLuaArguments Arguments; - if (pClientPed) - { - // Push our ped - Arguments.PushElement(pClientPed); - } - else - { - Arguments.PushNil(); - } - - // Trigger our event - bool bContinue = true; - if (!IS_PLAYER(pClientPed)) - bContinue = pCannonClientVehicle->CallEvent("onClientPedHitByWaterCannon", Arguments, true); - else - bContinue = pCannonClientVehicle->CallEvent("onClientPlayerHitByWaterCannon", Arguments, true); - - // Return if it was cancelled - return bContinue; - } - } - return false; -} - -bool CClientGame::VehicleFellThroughMapHandler(CVehicleSAInterface* pVehicleInterface) -{ - if (pVehicleInterface) - { - // Get our vehicle and client vehicle - CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pVehicleInterface); - CClientVehicle* pClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); - if (pClientVehicle) - { - // handle or don't - return pClientVehicle->OnVehicleFallThroughMap(); - } - } - // unhandled - return false; -} - -// Validate known objects -void CClientGame::GameObjectDestructHandler(CEntitySAInterface* pObject) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pObject); -} - -void CClientGame::GameVehicleDestructHandler(CEntitySAInterface* pVehicle) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pVehicle); -} - -void CClientGame::GamePlayerDestructHandler(CEntitySAInterface* pPlayer) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pPlayer); -} - -void CClientGame::GameProjectileDestructHandler(CEntitySAInterface* pProjectile) -{ - CClientProjectile* pClientProjectile = m_pManager->GetProjectileManager()->Get(pProjectile); - // Happens when destroyElement is called rather than letting the projectile expire - // Normal code path is destruction from CProjectileSAInterface -> CProjectileSA -> CClientProjectile - // destroyElement is CClientProjectile -> CProjectileSA -> CProjectileSAInterface - // which means the CClientProjectile element is deleted when we get here - if (pClientProjectile) - CStaticFunctionDefinitions::DestroyElement(*pClientProjectile); -} - -void CClientGame::GameModelRemoveHandler(ushort usModelId) -{ - m_pGameEntityXRefManager->OnGameModelRemove(usModelId); -} - -void CClientGame::TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) -{ - bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); - if (bOldBehaviour) - return; - - CClientPed* pClientPedAttacker = DynamicCast(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedAttacker)); - - // Make sure cause was networked ped - if (pClientPedAttacker && !pClientPedAttacker->IsLocalEntity()) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write((ushort)TASK_SIMPLE_BE_HIT); - pBitStream->Write(pClientPedAttacker->GetID()); - pBitStream->Write((uchar)hitBodyPart); - pBitStream->Write((uchar)hitBodySide); - pBitStream->Write((uchar)weaponId); - g_pNet->SendPacket(PACKET_ID_PED_TASK, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -bool CClientGame::StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (g_pClientGame) - { - return g_pClientGame->ProcessMessage(hwnd, uMsg, wParam, lParam); - } - - return false; -} - -bool CClientGame::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (ProcessMessageForCursorEvents(hwnd, uMsg, wParam, lParam)) - { - return true; - } - - return false; -} - -void CClientGame::ProcessVehicleInOutKey(bool bPassenger) -{ - // Are we already sending an in/out request or not allowed to create a new in/out? - if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? - || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) - || m_bIsGettingJacked // Make sure we're not currently getting carjacked && - || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... - || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... - || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon - ) - { - return; - } - - // Reset the "is jacking" bit - m_bIsJackingVehicle = false; - - // Got a local player model? - if (!m_pLocalPlayer) - { - // No local player. Stop. - return; - } - - // If the player is in a vehicle we need to leave the vehicle. - CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - if (pOccupiedVehicle) - { - // Only let us leave the vehicle if: - // - we press F (as driver) - // - we press either F or G as a passenger - if (bPassenger && m_pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - // Driver pressed G, so stop. - return; - } - - // We're about to exit a vehicle - // Send an in request - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!pBitStream) - { - return; - } - - // Write the vehicle id to it and that we're requesting to get out of it - pBitStream->Write(pOccupiedVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_REQUEST_OUT); - pBitStream->WriteBits(&ucAction, 4); - - unsigned char ucDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pLocalPlayer->GetGamePlayer(), pOccupiedVehicle->GetGameVehicle()); - if (ucDoor >= 2 && ucDoor <= 5) - { - ucDoor -= 2; - pBitStream->WriteBits(&ucDoor, 2); - } - - // Send and destroy it - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're now exiting a vehicle - m_bIsGettingOutOfVehicle = true; - m_ulLastVehicleInOutTime = CClientTime::GetTime(); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_out"); -#endif - return; - } - - // - // We're going to enter a vehicle - // - - // If the Jump task is playing and we are in water - I know right - // Kill the task. - // - CTask* pTask = m_pLocalPlayer->GetCurrentPrimaryTask(); - if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter - { - CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, nullptr, nullptr, 20.0f); - if (pVehicle && - (pVehicle->IsInWater() || - m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) - { - m_pLocalPlayer->KillTask(3, true); // Kill jump task if we are about to warp in - } - } - - // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle' - // task will replace it and fuck it up! - // - if (m_pLocalPlayer->GetCurrentPrimaryTask()) - { - // We already have a primary task, so stop. - return; - } - - // Are we holding the aim_weapon key? - SBindableGTAControl* pBind = g_pCore->GetKeyBinds()->GetBindableFromControl("aim_weapon"); - if (pBind && pBind->bState) - { - // Stop because the player is probably using rshift + f/g - return; - } - - if (m_pLocalPlayer->IsClimbing() // Make sure we're not currently climbing - || m_pLocalPlayer->HasJetPack() // Make sure we don't have a jetpack - || m_pLocalPlayer->IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway - || m_pLocalPlayer->IsRunningAnimation() // Make sure we aren't running an animation - ) - { - return; - } - - // Grab the closest vehicle - unsigned int uiDoor = 0; - CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, &uiDoor, nullptr, 20.0f); - unsigned int uiSeat = uiDoor; - - if (bPassenger && uiDoor == 0) - { - // We're trying to enter as a passenger, yet our closest door - // is the driver's door. Force an enter for the passenger seat. - uiSeat = 1; - } - else if (!bPassenger) - { - // We want to drive. Force our seat to the driver's seat. - uiSeat = 0; - } - - if (!pVehicle || !pVehicle->IsEnterable()) - { - // Stop if there isn't a vehicle, or the vehicle is not enterable - return; - } - - // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly) - if (pVehicle->GetVehicleType() == CLIENTVEHICLE_BOAT && m_pLocalPlayer->GetContactEntity() != pVehicle) - { - return; - } - - // Call the onClientVehicleStartEnter event for remote players - // Local player triggered before sending packet in CClientGame - CLuaArguments Arguments; - Arguments.PushElement(m_pLocalPlayer); // player - Arguments.PushNumber(uiSeat); // seat - Arguments.PushNumber(uiDoor); // Door - - if (!pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true)) - { - // Event has been cancelled - return; - } - - // Send an in request - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!pBitStream) - { - return; - } - - // Write the vehicle id to it and that we're requesting to get into it - pBitStream->Write(pVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_REQUEST_IN); - unsigned char ucSeat = static_cast(uiSeat); - bool bIsOnWater = pVehicle->IsOnWater(); - unsigned char ucDoor = static_cast(uiDoor); - pBitStream->WriteBits(&ucAction, 4); - pBitStream->WriteBits(&ucSeat, 4); - pBitStream->WriteBit(bIsOnWater); - pBitStream->WriteBits(&ucDoor, 3); - - // Send and destroy it - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're now entering a vehicle - m_bIsGettingIntoVehicle = true; - m_ulLastVehicleInOutTime = CClientTime::GetTime(); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_in"); -#endif -} - -// Shot compensation (Jax): -// Positions the local player where he should of been on the shooting player's screen when he -// fired remotely. (the position we !reported! around the time he shot) -bool bShotCompensation = true; - -// Temporary pointers for pre- and post-functions -CVector vecWeaponFirePosition, vecRemoteWeaponFirePosition; -CPlayerPed* pWeaponFirePed = NULL; - -bool CClientGame::PreWeaponFire(CPlayerPed* pPlayerPed, bool bStopIfUsingBulletSync) -{ - pWeaponFirePed = pPlayerPed; - - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pWeaponFirePed) - { - CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); - - // Get the CClientNetPlayer class with the specified player ped - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(pWeaponFirePed, true); - - // Move both players to where they should be for shot compensation - if (pPlayer && !pPlayer->IsLocalPlayer()) - { - if (bStopIfUsingBulletSync && pPlayer->IsCurrentWeaponUsingBulletSync()) - return false; // Don't apply shot compensation & tell caller to not do bullet trace - - if (bShotCompensation) - { - if (!pVehicle || pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - // Warp back in time to where we were when this player shot (their latency) - - // We don't account for interpolation here, +250ms seems to work better - // ** Changed ajustment to +125ms as the position of this clients player on the firers screen - // has been changed. See CClientPed::UpdateTargetPosition() ** - CVector vecPosition; - unsigned short usLatency = (pPlayer->GetLatency() + 125); - g_pClientGame->m_pNetAPI->GetInterpolation(vecPosition, usLatency); - - // Move the entity back - if (pVehicle) - { - pVehicle->GetPosition(vecWeaponFirePosition); - pVehicle->SetPosition(vecPosition, false, false); - } - else - { - pLocalPlayer->GetPosition(vecWeaponFirePosition); - pLocalPlayer->SetPosition(vecPosition, false, false); - } - } - } - } - } - return true; -} - -void CClientGame::PostWeaponFire(void) -{ - // Send bullet sync with local damage info - if (g_bBulletFireVectorsValid) - { - g_bBulletFireVectorsValid = false; - CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer) - { - eWeaponType weaponType = pLocalPlayer->GetCurrentWeaponType(); - if (g_pClientGame->GetWeaponTypeUsesBulletSync(weaponType)) - { - g_pClientGame->GetNetAPI()->SendBulletSyncFire(weaponType, g_vecBulletFireStartPosition, g_vecBulletFireEndPosition, g_fApplyDamageLastAmount, - g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); - } - } - } - - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pWeaponFirePed) - { - CClientPed* pPed = g_pClientGame->GetPedManager()->Get(pWeaponFirePed, true, true); - if (pPed) - { - if (pPed->GetType() == CCLIENTPLAYER) - { - if (bShotCompensation) - { - // Restore compensated positions - if (!pPed->IsLocalPlayer()) - { - CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); - if (!pVehicle) - { - pLocalPlayer->SetPosition(vecWeaponFirePosition, false, false); - } - else if (pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - pVehicle->SetPosition(vecWeaponFirePosition, false, false); - } - } - } - } - - // Call some events - CWeapon* pWeapon = pPed->GetWeapon(); - if (pWeapon) - { - CVector vecCollision; - CClientEntity* pCollisionEntity = NULL; - - if (pPed->GetBulletImpactData(&pCollisionEntity, &vecCollision) == false) - { - CShotSyncData* pShotsyncData = pPed->m_shotSyncData; - CVector vecOrigin, vecTarget; - pPed->GetShotData(&vecOrigin, &vecTarget); - - CColPoint* pCollision = NULL; - CEntity* pCollisionGameEntity = NULL; - vecCollision = vecTarget; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionGameEntity); - if (bCollision && pCollision) - vecCollision = pCollision->GetPosition(); - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - - if (pCollisionGameEntity) - pCollisionEntity = g_pClientGame->m_pManager->FindEntity(pCollisionGameEntity); - } - else - { - pPed->ClearBulletImpactData(); - } - - // Call our lua event - CLuaArguments Arguments; - Arguments.PushNumber((double)pWeapon->GetType()); - Arguments.PushNumber((double)pWeapon->GetAmmoTotal()); - Arguments.PushNumber((double)pWeapon->GetAmmoInClip()); - Arguments.PushNumber((double)vecCollision.fX); - Arguments.PushNumber((double)vecCollision.fY); - Arguments.PushNumber((double)vecCollision.fZ); - if (pCollisionEntity) - Arguments.PushElement(pCollisionEntity); - else - Arguments.PushNil(); - - if (IS_PLAYER(pPed)) - { - CVector vecOrigin; - pPed->GetShotData(&vecOrigin); - Arguments.PushNumber((double)vecOrigin.fX); - Arguments.PushNumber((double)vecOrigin.fY); - Arguments.PushNumber((double)vecOrigin.fZ); - pPed->CallEvent("onClientPlayerWeaponFire", Arguments, true); - } - else - pPed->CallEvent("onClientPedWeaponFire", Arguments, true); - } - pPed->PostWeaponFire(); -#ifdef MTA_DEBUG - if (pPed->IsLocalPlayer() && g_pClientGame->m_bDoPaintballs) - { - g_pClientGame->DoPaintballs(); - } -#endif - } - } - pWeaponFirePed = NULL; -} - -void CClientGame::BulletImpact(CPed* pInitiator, CEntity* pVictim, const CVector* pStartPosition, const CVector* pEndPosition) -{ - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pInitiator) - { - // Find the client ped that initiated the bullet impact - CClientPed* pInitiatorPed = g_pClientGame->GetPedManager()->Get(dynamic_cast(pInitiator), true, true); - - if (pInitiatorPed) - { - // Calculate the collision of the bullet - CVector vecCollision; - CColPoint* pCollision = NULL; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(pStartPosition, pEndPosition, &pCollision, NULL); - if (bCollision && pCollision) - { - vecCollision = pCollision->GetPosition(); - } - else - { - // If we don't have a collision, use the end of the ray that the bullet is tracing. - vecCollision = *pEndPosition; - } - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - - // Find the client entity for the victim. - CClientEntity* pClientVictim = NULL; - if (pVictim) - { - pClientVictim = g_pClientGame->m_pManager->FindEntity(pVictim); - } - - // Store the data in the bullet fire initiator. - pInitiatorPed->SetBulletImpactData(pClientVictim, vecCollision); - } - } -} - -void CClientGame::BulletFire(CPed* pInitiator, const CVector* pStartPosition, const CVector* pEndPosition) -{ - g_bBulletFireVectorsValid = false; - g_fApplyDamageLastAmount = 0; - g_ucApplyDamageLastHitZone = 0; - g_pApplyDamageLastDamagedPed = NULL; - - // Got a local player model? - CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pLocalPlayer->GetGamePlayer() == pInitiator) - { - g_bBulletFireVectorsValid = true; - g_vecBulletFireStartPosition = *pStartPosition; - g_vecBulletFireEndPosition = *pEndPosition; - } -} - -bool CClientGame::StaticProcessPacket(unsigned char ucPacketID, NetBitStreamInterface& bitStream) -{ - if (g_pClientGame) - { - g_pCore->UpdateDummyProgress(); - g_pClientGame->GetManager()->GetPacketRecorder()->RecordPacket(ucPacketID, bitStream); - return g_pClientGame->m_pPacketHandler->ProcessPacket(ucPacketID, bitStream); - } - - return false; -} - -void CClientGame::SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin) -{ - SPositionSync position(false); - position.data.vecPosition = vecPosition; - - // Create the bitstream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write our origin id - if (pOrigin) - { - pBitStream->WriteBit(true); - pBitStream->Write(pOrigin->GetID()); - - // Convert position - CVector vecTemp; - pOrigin->GetPosition(vecTemp); - position.data.vecPosition -= vecTemp; - } - else - pBitStream->WriteBit(false); - - // Write the position and the type - pBitStream->Write(&position); - - SExplosionTypeSync explosionType; - explosionType.data.uiType = Type; - pBitStream->Write(&explosionType); - - // Destroy it - g_pNet->SendPacket(PACKET_ID_EXPLOSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -void CClientGame::SendFireSync(CFire* pFire) -{ -#ifdef MTA_DEBUG - CVector* vecPos = pFire->GetPosition(); - if (vecPos) - g_pCore->GetConsole()->Printf("we're sending fire: %f %f %f %f", pFire->GetStrength(), vecPos->fX, vecPos->fY, vecPos->fZ); - else - g_pCore->GetConsole()->Printf("we're sending a fire!"); -#endif -} - -void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) -{ - // Create the bitstream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - SPositionSync origin(false); - CClientEntity* pOriginSource = NULL; - eWeaponType weaponType = pProjectile->GetWeaponType(); - CClientEntity* pTarget = pProjectile->GetTargetEntity(); - origin.data.vecPosition = *pProjectile->GetOrigin(); - - // Is this a heatseaking missile with a target? sync it relative to the target - if (weaponType == WEAPONTYPE_ROCKET_HS && pTarget && !pTarget->IsLocalEntity()) - pOriginSource = pTarget; - - // Write the source of the projectile, if it has - if (pOriginSource) - { - CVector vecTemp; - pOriginSource->GetPosition(vecTemp); - origin.data.vecPosition -= vecTemp; - - pBitStream->WriteBit(true); - pBitStream->Write(pOriginSource->GetID()); - } - else - pBitStream->WriteBit(false); - - // Write the origin position - pBitStream->Write(&origin); - - // Write the creator weapon type - SWeaponTypeSync weaponTypeSync; - weaponTypeSync.data.ucWeaponType = static_cast(weaponType); - pBitStream->Write(&weaponTypeSync); - - // Write the projectile's model - if (pBitStream->Version() >= 0x4F) - if (pBitStream->Version() >= 0x52 || pOriginSource) // Fix possible error for 0x51 server - pBitStream->Write(pProjectile->GetModel()); - - switch (weaponType) - { - case WEAPONTYPE_GRENADE: - case WEAPONTYPE_TEARGAS: - case WEAPONTYPE_MOLOTOV: - case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: - { - SFloatSync<7, 17> projectileForce; - projectileForce.data.fValue = pProjectile->GetForce(); - pBitStream->Write(&projectileForce); - - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); - - break; - } - case WEAPONTYPE_ROCKET: - case WEAPONTYPE_ROCKET_HS: - { - if (pTarget) - { - pBitStream->WriteBit(true); - pBitStream->Write(pTarget->GetID()); - } - else - pBitStream->WriteBit(false); - - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); - - SRotationRadiansSync rotation(true); - pProjectile->GetRotationRadians(rotation.data.vecRotation); - pBitStream->Write(&rotation); - - break; - } - case WEAPONTYPE_FLARE: - case WEAPONTYPE_FREEFALL_BOMB: - break; - } - g_pNet->SendPacket(PACKET_ID_PROJECTILE, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - - // Destroy it - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -void CClientGame::ResetAmmoInClip(void) -{ - memset(&m_wasWeaponAmmoInClip[0], 0, sizeof(m_wasWeaponAmmoInClip)); -} - -void CClientGame::ResetMapInfo(void) -{ - // Restore some game stuff - // Keybinds - g_pCore->GetKeyBinds()->SetAllControlsEnabled(true, true, true); - - // Radarmap - m_pRadarMap->SetForcedState(false); - - // Camera - m_pCamera->FadeOut(0.0f, 0, 0, 0); - g_pGame->GetWorld()->SetCurrentArea(0); - m_pCamera->SetFocusToLocalPlayer(); - g_pGame->GetSettings()->ResetFieldOfViewFromScript(); - - // Dimension - SetAllDimensions(0); - - // Hud - g_pGame->GetHud()->SetComponentVisible(HUD_ALL, true); - // Disable area names as they are on load until camera unfades - g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); - g_pGame->GetHud()->SetComponentVisible(HUD_VITAL_STATS, false); - - m_bHudAreaNameDisabled = false; - - // Gravity - g_pMultiplayer->SetLocalPlayerGravity(DEFAULT_GRAVITY); - g_pMultiplayer->SetGlobalGravity(DEFAULT_GRAVITY); - g_pGame->SetGravity(DEFAULT_GRAVITY); - - // Gamespeed - SetGameSpeed(DEFAULT_GAME_SPEED); - - // Game minute duration - SetMinuteDuration(DEFAULT_MINUTE_DURATION); - - // Wanted-level - SetWanted(0); - - // Money - SetMoney(0, true); - - // Weather - m_pBlendedWeather->SetWeather(0); - - // Rain - g_pGame->GetWeather()->ResetAmountOfRain(); - - // Wind - g_pMultiplayer->RestoreWindVelocity(); - - // Far clip distance - g_pMultiplayer->RestoreFarClipDistance(); - - // Near clip distance - g_pMultiplayer->RestoreNearClipDistance(); - - // Fog distance - g_pMultiplayer->RestoreFogDistance(); - - // Vehicles LOD distance - g_pGame->GetSettings()->ResetVehiclesLODDistance(); - - // Peds LOD distance - g_pGame->GetSettings()->ResetPedsLODDistance(); - - // Sun color - g_pMultiplayer->ResetSunColor(); - - // Sun size - g_pMultiplayer->ResetSunSize(); - - // Sky-gradient - g_pMultiplayer->ResetSky(); - - // Heat haze - g_pMultiplayer->ResetHeatHaze(); - - // Water-colour - g_pMultiplayer->ResetWater(); - - // Water - GetManager()->GetWaterManager()->ResetWorldWaterLevel(); - - // Re-enable interior sounds and furniture - g_pMultiplayer->SetInteriorSoundsEnabled(true); - for (int i = 0; i <= 4; ++i) - g_pMultiplayer->SetInteriorFurnitureEnabled(i, true); - - // Clouds - g_pMultiplayer->SetCloudsEnabled(true); - g_pClientGame->SetCloudsEnabled(true); - - // Birds - g_pMultiplayer->DisableBirds(false); - g_pClientGame->SetBirdsEnabled(true); - - // Ambient sounds - g_pGame->GetAudio()->ResetAmbientSounds(); - - // World sounds - g_pGame->GetAudio()->ResetWorldSounds(); - - // Cheats - g_pGame->ResetCheats(); - - // Players - m_pPlayerManager->ResetAll(); - - // Jetpack max height - g_pGame->GetWorld()->SetJetpackMaxHeight(DEFAULT_JETPACK_MAXHEIGHT); - - // Aircraft max height - g_pGame->GetWorld()->SetAircraftMaxHeight(DEFAULT_AIRCRAFT_MAXHEIGHT); - - // Aircraft max velocity - g_pGame->GetWorld()->SetAircraftMaxVelocity(DEFAULT_AIRCRAFT_MAXVELOCITY); - - // Moon size - g_pMultiplayer->ResetMoonSize(); - - // Disable the change of any player stats - g_pMultiplayer->SetLocalStatsStatic(true); - - // Restore blur -#ifdef MTA_DEBUG - g_pGame->SetBlurLevel(0); -#else - g_pGame->SetBlurLevel(DEFAULT_BLUR_LEVEL); -#endif - - // Close all garages - CGarage* pGarage = NULL; - CGarages* pGarages = g_pCore->GetGame()->GetGarages(); - - for (unsigned char i = 0; (pGarage = pGarages->GetGarage(i)) != NULL; i++) - { - pGarage->SetOpen(false); - } - - // Player specific stuff - if (m_pLocalPlayer) - { - // Interior - m_pLocalPlayer->SetInterior(0); - - // Headless state - m_pLocalPlayer->SetHeadless(false); - - // Frozen state - m_pLocalPlayer->SetFrozen(false); - - // Voice - short sVoiceType, sVoiceID; - m_pLocalPlayer->GetModelInfo()->GetVoice(&sVoiceType, &sVoiceID); - m_pLocalPlayer->SetVoice(sVoiceType, sVoiceID); - - m_pLocalPlayer->DestroySatchelCharges(false, true); - // Tell the server we want to destroy our satchels - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - g_pNet->SendPacket(PACKET_ID_DESTROY_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, - AnimationId animID) -{ - if (Ped && Ped->GetHealth() == 0.0f) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write some death info - pBitStream->WriteCompressed(animGroup); - pBitStream->WriteCompressed(animID); - - pBitStream->Write(damagerID); - - SWeaponTypeSync weapon; - weapon.data.ucWeaponType = ucWeapon; - pBitStream->Write(&weapon); - - SBodypartSync bodyPart; - bodyPart.data.uiBodypart = ucBodyPiece; - pBitStream->Write(&bodyPart); - - // Write the position we died in - SPositionSync pos(false); - Ped->GetPosition(pos.data.vecPosition); - pBitStream->Write(&pos); - - pBitStream->Write(Ped->GetID()); - - // The ammo in our weapon and write the ammo total - CWeapon* pPlayerWeapon = Ped->GetWeapon(); - SWeaponAmmoSync ammo(ucWeapon, true, false); - ammo.data.usTotalAmmo = 0; - if (pPlayerWeapon) - ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); - pBitStream->Write(&ammo); - - // Send the packet - g_pNet->SendPacket(PACKET_ID_PED_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, AnimationId animID) -{ - // Are we not already marked as dead? and have we run out of health? - if (!m_pLocalPlayer->IsDeadOnNetwork() && m_pLocalPlayer->GetHealth() == 0.0f) - { - // Send the "i am dead" packet - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - m_pLocalPlayer->SetDeadOnNetwork(true); - - // Call the onClientPlayerWasted event - CClientEntity* pKiller = (damagerID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(damagerID) : NULL; - CLuaArguments Arguments; - if (pKiller) - Arguments.PushElement(pKiller); - else - Arguments.PushBoolean(false); - if (ucWeapon != 0xFF) - Arguments.PushNumber(ucWeapon); - else - Arguments.PushBoolean(false); - if (ucBodyPiece != 0xFF) - Arguments.PushNumber(ucBodyPiece); - else - Arguments.PushBoolean(false); - Arguments.PushBoolean(false); - m_pLocalPlayer->CallEvent("onClientPlayerWasted", Arguments, true); - - // Write some death info - pBitStream->WriteCompressed(animGroup); - pBitStream->WriteCompressed(animID); - - pBitStream->Write(damagerID); - - SWeaponTypeSync weapon; - weapon.data.ucWeaponType = ucWeapon; - pBitStream->Write(&weapon); - - SBodypartSync bodyPart; - bodyPart.data.uiBodypart = ucBodyPiece; - pBitStream->Write(&bodyPart); - - // Write the position we died in - SPositionSync pos(false); - m_pLocalPlayer->GetPosition(pos.data.vecPosition); - pBitStream->Write(&pos); - - // The ammo in our weapon and write the ammo total - CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(); - SWeaponAmmoSync ammo(ucWeapon, true, false); - ammo.data.usTotalAmmo = 0; - if (pPlayerWeapon) - ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); - pBitStream->Write(&ammo); - - // Send the packet - g_pNet->SendPacket(PACKET_ID_PLAYER_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -bool CClientGame::OnKeyDown(CGUIKeyEventArgs Args) -{ - return true; -} - -bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - const char* szState = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIClick", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseDoubleClick(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - const char* szState = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIDoubleClick", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIMouseDown", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseButtonUp(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIMouseUp", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseMove(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseMove", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseEnter(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - if (Args.pSwitchedWindow) - { - CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); - if (GetGUIManager()->Exists(pGUISwitchedElement)) - Arguments.PushElement(pGUISwitchedElement); - } - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseEnter", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseLeave(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - if (Args.pSwitchedWindow) - { - CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); - if (GetGUIManager()->Exists(pGUISwitchedElement)) - Arguments.PushElement(pGUISwitchedElement); - } - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseLeave", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseWheel(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.wheelChange); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseWheel", Arguments, true); - - return true; -} - -bool CClientGame::OnMove(CGUIElement* pElement) -{ - if (!pElement) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); - if (pGUIElement && GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientGUIMove", Arguments, true); - - return true; -} - -bool CClientGame::OnSize(CGUIElement* pElement) -{ - if (!pElement) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientGUISize", Arguments, true); - - return true; -} - -bool CClientGame::OnFocusGain(CGUIFocusEventArgs Args) -{ - if (!Args.pActivatedWindow) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pActivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pActivatedWindow); - - if (Args.pDeactivatedWindow) - { - CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); - if (GetGUIManager()->Exists(pDeactivatedGUIElement)) - pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); - } - - if (GetGUIManager()->Exists(pActivatedGUIElement)) - pActivatedGUIElement->CallEvent("onClientGUIFocus", Arguments, true); - - return true; -} - -bool CClientGame::OnFocusLoss(CGUIFocusEventArgs Args) -{ - if (!Args.pDeactivatedWindow) - return false; - - CLuaArguments Arguments; - - if (Args.pActivatedWindow) - { - // pDeactivatedWindow looses focus but an other window is now gaining it so we let CClientGame::OnFocusGain trigger both events in the right order - return true; - } - - CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); - if (GetGUIManager()->Exists(pDeactivatedGUIElement)) - pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); - - return true; -} - -// -// Display a progress dialog if a big packet is coming in -// -void CClientGame::NotifyBigPacketProgress(unsigned long ulBytesReceived, unsigned long ulTotalSize) -{ - // Should display progress box? - if (ulBytesReceived >= ulTotalSize || ulTotalSize < 50000) - { - if (m_bReceivingBigPacket) - { - // Switch off progress box - m_bReceivingBigPacket = false; - m_pBigPacketTransferBox->Hide(); - } - return; - } - - // Update progress box - if (!m_bReceivingBigPacket || m_ulBigPacketSize != ulTotalSize) - { - m_bReceivingBigPacket = true; - m_ulBigPacketSize = ulTotalSize; - m_pBigPacketTransferBox->Hide(); - m_pBigPacketTransferBox->AddToTotalSize(ulTotalSize); - m_pBigPacketTransferBox->Show(); - } - - m_pBigPacketTransferBox->DoPulse(); - m_pBigPacketTransferBox->SetInfo(std::min(ulTotalSize, ulBytesReceived), CTransferBox::PACKET); -} - -bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled) -{ - if (ucGlitch < NUM_GLITCHES && bEnabled != m_Glitches[ucGlitch]) - { - m_Glitches[ucGlitch] = bEnabled; - if (ucGlitch == GLITCH_QUICKRELOAD) - g_pMultiplayer->DisableQuickReload(!bEnabled); - if (ucGlitch == GLITCH_CLOSEDAMAGE) - g_pMultiplayer->DisableCloseRangeDamage(!bEnabled); - return true; - } - return false; -} - -bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) -{ - return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; -} - -bool CClientGame::SetCloudsEnabled(bool bEnabled) -{ - m_bCloudsEnabled = bEnabled; - return true; -} -bool CClientGame::GetCloudsEnabled(void) -{ - return m_bCloudsEnabled; -} - -bool CClientGame::SetBirdsEnabled(bool bEnabled) -{ - m_bBirdsEnabled = bEnabled; - return true; -} -bool CClientGame::GetBirdsEnabled(void) -{ - return m_bBirdsEnabled; -} - -#pragma code_seg(".text") -bool CClientGame::VerifySADataFiles(int iEnableClientChecks) -{ - int& iCheckStatus = g_pGame->GetCheckStatus(); - - if (!g_pGame->VerifySADataFileNames()) - iCheckStatus |= (1 << 11); - - __declspec(allocate(".text")) static char szVerifyData[][32] = {"data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", - "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", - "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", - "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", - "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", - "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", - "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", - "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", - "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", - "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", - "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", - "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74"}; - - CMD5Hasher hasher; - for (int i = 0; i < NUMELMS(szVerifyData); i += 2) - { - MD5 md5; - if (!hasher.Calculate(szVerifyData[i], md5) || memcmp(md5.data, szVerifyData[i + 1], 0x10)) - { - iCheckStatus |= (1 << i); - } - } - - if (iCheckStatus & iEnableClientChecks) - { - g_pCore->InitiateDataFilesFix(); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - return true; -} - -void CClientGame::InitVoice(bool bEnabled, unsigned int uiServerSampleRate, unsigned char ucQuality, unsigned int uiBitrate) -{ - if (m_pVoiceRecorder) - { - m_pVoiceRecorder->Init(bEnabled, uiServerSampleRate, ucQuality, uiBitrate); - } -} - -// -// If debug render mode is on, allow each element in range to draw some stuff -// -void CClientGame::DebugElementRender(void) -{ - if (!GetDevelopmentMode() || !GetShowCollision()) - return; - - CVector vecCameraPos; - m_pCamera->GetPosition(vecCameraPos); - float fDrawRadius = 200.f; - - // Get all entities within range - CClientEntityResult result; - GetClientSpatialDatabase()->SphereQuery(result, CSphere(vecCameraPos, fDrawRadius)); - - // For each entity found - for (CClientEntityResult::const_iterator it = result.begin(); it != result.end(); ++it) - { - CClientEntity* pEntity = *it; - if (pEntity->GetParent()) - pEntity->DebugRender(vecCameraPos, fDrawRadius); - } -} - -////////////////////////////////////////////////////////////////// -// Click -// -void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString& strTag, uint uiQuality, uint uiMaxBandwidth, uint uiMaxPacketSize, - CResource* pResource, uint uiServerSentTime) -{ - if (!pResource) - return; - - bool bAllowScreenUploadEnabled = 1; - g_pCore->GetCVars()->Get("allow_screen_upload", bAllowScreenUploadEnabled); - bool bWindowMinimized = g_pCore->IsWindowMinimized(); - - if (bWindowMinimized || !bAllowScreenUploadEnabled) - { - // If alt-tabbed or opt-out - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!bAllowScreenUploadEnabled) - pBitStream->Write((uchar)EPlayerScreenShotResult::DISABLED); - else - pBitStream->Write((uchar)EPlayerScreenShotResult::MINIMIZED); - pBitStream->Write(uiServerSentTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); - g_pNet->DeallocateNetBitStream(pBitStream); - } - else - { - // Do grab and send - SScreenShotArgs screenShotArgs; - screenShotArgs.uiMaxBandwidth = uiMaxBandwidth; - screenShotArgs.uiMaxPacketSize = uiMaxPacketSize; - screenShotArgs.usResourceNetId = pResource->GetNetID(); - screenShotArgs.strTag = strTag; - screenShotArgs.uiServerSentTime = uiServerSentTime; - m_ScreenShotArgList.push_back(screenShotArgs); - g_pCore->GetGraphics()->GetScreenGrabber()->QueueScreenShot(uiSizeX, uiSizeY, uiQuality, &CClientGame::StaticGottenPlayerScreenShot); - } -} - -////////////////////////////////////////////////////////////////// -// Callback from TakePlayerScreendsShot -// -void CClientGame::StaticGottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strError) -{ - if (g_pClientGame) - g_pClientGame->GottenPlayerScreenShot(pBuffer, uiTimeSpentInQueue, strError); -} - -////////////////////////////////////////////////////////////////// -// Break data into packets and put into delayed send list -// -void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strInError) -{ - SString strError = strInError; - - // Pop saved args - if (m_ScreenShotArgList.empty()) - return; - - SScreenShotArgs screenShotArgs = m_ScreenShotArgList.front(); - m_ScreenShotArgList.pop_front(); - const uint uiMaxBandwidth = Clamp(100, screenShotArgs.uiMaxBandwidth, 1000000); - const uint uiMaxPacketSize = Clamp(100, screenShotArgs.uiMaxPacketSize, 100000); - const ushort usResourceNetId = screenShotArgs.usResourceNetId; - const SString strTag = screenShotArgs.strTag; - const uint uiServerGrabTime = screenShotArgs.uiServerSentTime + uiTimeSpentInQueue; - - // Silently ignore if resource has been stopped - CResource* pResource = GetResourceManager()->GetResourceFromNetID(usResourceNetId); - if (!pResource) - return; - - // Validate buffer - if (strError.empty()) - { - if (!pBuffer || pBuffer->GetSize() == 0) - strError = "Buffer empty"; - } - - // Handle error - if (!strError.empty()) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write((uchar)EPlayerScreenShotResult::ERROR_); - pBitStream->Write(uiServerGrabTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - if (pBitStream->Version() >= 0x053) - pBitStream->WriteString(strError); - g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); - g_pNet->DeallocateNetBitStream(pBitStream); - return; - } - - // Calc constants stuff - const uint uiSendRate = Clamp(5, uiMaxBandwidth / uiMaxPacketSize, 20); - const long long llPacketInterval = 1000 / uiSendRate; - const uint uiTotalByteSize = pBuffer->GetSize(); - const char* pData = pBuffer->GetData(); - const uint uiBytesPerPart = std::min(std::min(std::max(100U, uiMaxBandwidth / uiSendRate), uiTotalByteSize), 30000U); - const uint uiNumParts = std::max(1U, (uiTotalByteSize + uiBytesPerPart - 1) / uiBytesPerPart); - - // Calc variables stuff - CTickCount tickCount = CTickCount::Now() + CTickCount(llPacketInterval); - uint uiBytesRemaining = uiTotalByteSize; - m_usNextScreenShotId++; - - // Make each packet - for (uint i = 0; i < uiNumParts; i++) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - - ushort usPartNumber = i; - ushort usBytesThisPart = std::min(uiBytesRemaining, uiBytesPerPart); - assert(usBytesThisPart != 0); - - pBitStream->Write((uchar)EPlayerScreenShotResult::SUCCESS); - pBitStream->Write(m_usNextScreenShotId); - pBitStream->Write(usPartNumber); - pBitStream->Write(usBytesThisPart); - pBitStream->Write(pData, usBytesThisPart); - - // Write more info if first part - if (usPartNumber == 0) - { - pBitStream->Write(uiServerGrabTime); - pBitStream->Write(uiTotalByteSize); - pBitStream->Write((ushort)uiNumParts); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - } - - // Add to delay send list - SDelayedPacketInfo delayedPacketInfo; - delayedPacketInfo.useTickCount = tickCount; - delayedPacketInfo.ucPacketID = PACKET_ID_PLAYER_SCREENSHOT; - delayedPacketInfo.pBitStream = pBitStream; - delayedPacketInfo.packetPriority = PACKET_PRIORITY_LOW; - delayedPacketInfo.packetReliability = PACKET_RELIABILITY_RELIABLE_ORDERED; - delayedPacketInfo.packetOrdering = PACKET_ORDERING_DATA_TRANSFER; - m_DelayedSendList.push_back(delayedPacketInfo); - - // Increment stuff - pData += usBytesThisPart; - uiBytesRemaining -= usBytesThisPart; - tickCount += CTickCount(llPacketInterval); - } - - assert(uiBytesRemaining == 0); -} - -////////////////////////////////////////////////////////////////// -// Process delay send list -// -void CClientGame::ProcessDelayedSendList(void) -{ - CTickCount tickCount = CTickCount::Now(); - - while (!m_DelayedSendList.empty()) - { - SDelayedPacketInfo& info = m_DelayedSendList.front(); - if (info.useTickCount > tickCount) - break; - - g_pNet->SendPacket(info.ucPacketID, info.pBitStream, info.packetPriority, info.packetReliability, info.packetOrdering); - g_pNet->DeallocateNetBitStream(info.pBitStream); - m_DelayedSendList.pop_front(); - } -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetWeaponTypesUsingBulletSync -// -// Set whether the local player will send bulletsync messages for the supplied weapon type -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetWeaponTypesUsingBulletSync(const std::set& weaponTypesUsingBulletSync) -{ - m_weaponTypesUsingBulletSync = weaponTypesUsingBulletSync; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::GetWeaponTypeUsesBulletSync -// -// Get whether the local player should send bulletsync messages for the supplied weapon type -// -////////////////////////////////////////////////////////////////// -bool CClientGame::GetWeaponTypeUsesBulletSync(eWeaponType weaponType) -{ - return MapContains(m_weaponTypesUsingBulletSync, weaponType); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetDevelopmentMode -// -// Special mode which enables commands such as showcol and showsound -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetDevelopmentMode(bool bEnable, bool bEnableWeb) -{ - m_bDevelopmentMode = bEnable; - - if (m_bDevelopmentMode) - g_pGame->GetAudio()->SetWorldSoundHandler(CClientGame::StaticWorldSoundHandler); - else - g_pGame->GetAudio()->SetWorldSoundHandler(NULL); - - if (g_pCore->IsWebCoreLoaded()) - g_pCore->GetWebCore()->SetTestModeEnabled(bEnableWeb); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::StaticWorldSoundHandler -// -// Handle callback from CAudioSA when a world sound is played -// -////////////////////////////////////////////////////////////////// -void CClientGame::StaticWorldSoundHandler(uint uiGroup, uint uiIndex) -{ - g_pClientGame->WorldSoundHandler(uiGroup, uiIndex); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::WorldSoundHandler -// -// Handle callback from CAudioSA when a world sound is played -// -////////////////////////////////////////////////////////////////// -void CClientGame::WorldSoundHandler(uint uiGroup, uint uiIndex) -{ - if (m_bShowSound) - m_pScriptDebugging->LogInformation(NULL, "%s - World sound group:%d index:%d", *GetLocalTimeString(false, true), uiGroup, uiIndex); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::IsUsingAlternatePulseOrder -// -// Returns true if should be using alternate pulse order -// -////////////////////////////////////////////////////////////////// -bool CClientGame::IsUsingAlternatePulseOrder(bool bAdvanceDelayCounter) -{ - if (m_MiscGameSettings.bUseAltPulseOrder) - { - // Only actually start using alternate pulse order after 100 frames - if (m_uiAltPulseOrderCounter >= 100) - return true; - else if (bAdvanceDelayCounter) - m_uiAltPulseOrderCounter++; - } - - return false; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::OutputServerInfo -// -// Output info about the connected server for player -// -////////////////////////////////////////////////////////////////// -void CClientGame::OutputServerInfo(void) -{ - SString strTotalOutput; - strTotalOutput += SString("Server info for %s", g_pNet->GetConnectedServer(true)); - strTotalOutput += "\n"; - strTotalOutput += SString("Ver: %s\n", *GetServerVersionSortable()); - strTotalOutput += SString("AC: %s\n", *m_strACInfo); - - { - SString strVoice; - if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) - strVoice += SString("Enabled - Sample rate:%d Quality:%d", m_pVoiceRecorder->GetSampleRate(), m_pVoiceRecorder->GetSampleQuality()); - else - strVoice += "Disabled"; - - strTotalOutput += SString("Voice: %s\n", *strVoice); - } - - { - SString strEnabledGlitches; - const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", - "Bad driveby hitboxes", "Quick stand"}; - for (uint i = 0; i < NUM_GLITCHES; i++) - { - if (IsGlitchEnabled(i)) - { - if (!strEnabledGlitches.empty()) - strEnabledGlitches += ", "; - if (i < NUMELMS(szGlitchNames)) - strEnabledGlitches += szGlitchNames[i]; - else - strEnabledGlitches += SString("Unknown(#%d)", i + 1); - } - } - if (strEnabledGlitches.empty()) - strEnabledGlitches = "None"; - strTotalOutput += SString("Glitches: %s\n", *strEnabledGlitches); - } - - { - SString strEnabledBulletSync; - for (std::set::iterator iter = m_weaponTypesUsingBulletSync.begin(); iter != m_weaponTypesUsingBulletSync.end(); ++iter) - { - eWeaponType weaponType = *iter; - if (!strEnabledBulletSync.empty()) - strEnabledBulletSync += ","; - strEnabledBulletSync += SString("%d", weaponType); - } - if (strEnabledBulletSync.empty()) - strEnabledBulletSync = "None"; - strTotalOutput += SString("Bullet sync weapons: %s\n", *strEnabledBulletSync); - } - - { - SString strVehExtrapolate; - if (m_VehExtrapolateSettings.bEnabled) - strVehExtrapolate += SString("Amount:%d%% (LimitMs:%d)", m_VehExtrapolateSettings.iScalePercent, m_VehExtrapolateSettings.iMaxMs); - else - strVehExtrapolate += "Disabled"; - - strTotalOutput += SString("Vehicle extrapolation: %s\n", *strVehExtrapolate); - } - - { - SString strTickRates; - strTickRates += SString("Plr:%d Cam:%d Ped:%d UnocVeh:%d KeyRot:%d KeyJoy:%d", g_TickRateSettings.iPureSync, g_TickRateSettings.iCamSync, - g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, - g_TickRateSettings.iKeySyncAnalogMove); - - strTotalOutput += SString("Tick rates: %s\n", *strTickRates); - } - - { - SString strSyncerDists; - strSyncerDists += SString("Ped:%d UnoccupiedVehicle:%d ", g_TickRateSettings.iPedSyncerDistance, g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); - - strTotalOutput += SString("Syncer distances: %s\n", *strSyncerDists); - } - - g_pCore->GetConsole()->Print(strTotalOutput); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::TellServerSomethingImportant -// -// Report misc important warnings/errors to the current server -// -////////////////////////////////////////////////////////////////// -void CClientGame::TellServerSomethingImportant(uint uiId, const SString& strMessage, uint uiSendLimitForThisId) -{ - g_pCore->GetConsole()->Print(strMessage); - AddReportLog(3400 + uiId, strMessage + g_pNet->GetConnectedServer(true), 10); - - if (uiSendLimitForThisId) - { - uint& uiCount = MapGet(m_SentMessageIds, uiId); - if (uiCount++ >= uiSendLimitForThisId) - return; - } - - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->WriteString(SString("%d,%s", uiId, *strMessage)); - g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE); - g_pNet->DeallocateNetBitStream(pBitStream); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::ChangeFloatPrecision -// -// Manage the change to high floating point precision -// -////////////////////////////////////////////////////////////////// -void CClientGame::ChangeFloatPrecision(bool bHigh) -{ - if (bHigh) - { - // Switch to 53 bit floating point precision on the first call - if (m_uiPrecisionCallDepth++ == 0) - _controlfp(_PC_53, MCW_PC); - } - else - { - // Even though is should never happen, m_uiPrecisionCallDepth is sometimes zero here - dassert(m_uiPrecisionCallDepth != 0); - if (m_uiPrecisionCallDepth != 0) - m_uiPrecisionCallDepth--; - // Switch back to 24 bit floating point precision on the last call - if (m_uiPrecisionCallDepth == 0) - _controlfp(_PC_24, MCW_PC); - } -} - -bool CClientGame::IsHighFloatPrecision(void) const -{ - return m_uiPrecisionCallDepth != 0; -} - -AnimationId CClientGame::DrivebyAnimationHandler(AnimationId animId, AssocGroupId animGroupId) -{ - // Only apply if all clients support the fix - if (!GetMiscGameSettings().bAllowBadDrivebyHitboxFix) - return animId; - - // If the glitch is enabled, don't apply the fix - if (IsGlitchEnabled(GLITCH_BADDRIVEBYHITBOX)) - return animId; - - // Bad animations are 232 and 236 of assoc group 72 - if (animGroupId != 72) - return animId; - - if (animId == 232) - return 235; - else if (animId == 236) - return 231; - - return animId; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetFileCacheRoot -// -// Figure out which directory to use for the client resource file cache -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetFileCacheRoot(void) -{ - if (g_pCore->GetCVars()->GetValue("share_file_cache") == false) - { - // Not sharing, so use current mod directory - m_strFileCacheRoot = GetModRoot(); - AddReportLog(7410, SString("CClientGame::SetFileCacheRoot - Not shared '%s'", *m_strFileCacheRoot)); - } - else - { - // Get shared directory - SString strFileCachePath = GetCommonRegistryValue("", "File Cache Path"); - // Check exists - if (!strFileCachePath.empty() && DirectoryExists(strFileCachePath)) - { - // Check writable - SString strTestFileName = PathJoin(strFileCachePath, "resources", "_test.tmp"); - if (FileSave(strTestFileName, "x")) - { - FileDelete(strTestFileName); - strTestFileName = PathJoin(strFileCachePath, "priv", "_test.tmp"); - if (FileSave(strTestFileName, "x")) - { - FileDelete(strTestFileName); - // Use shared directory - m_strFileCacheRoot = strFileCachePath; - AddReportLog(7411, SString("CClientGame::SetFileCacheRoot - Is shared '%s'", *m_strFileCacheRoot)); - return; - } - } - } - - // Otherwise set this install mod directory as shared - m_strFileCacheRoot = GetModRoot(); - SetCommonRegistryValue("", "File Cache Path", m_strFileCacheRoot); - - if (strFileCachePath.empty()) - AddReportLog(7412, SString("CClientGame::SetFileCacheRoot - Initial setting '%s'", *m_strFileCacheRoot)); - else - AddReportLog(7413, SString("CClientGame::SetFileCacheRoot - Change shared from '%s' to '%s'", *strFileCachePath, *m_strFileCacheRoot)); - } -} - -bool CClientGame::TriggerBrowserRequestResultEvent(const std::unordered_set& newPages) -{ - CLuaArguments Arguments; - CLuaArguments LuaTable; - int i = 0; - - for (auto& domain : newPages) - { - LuaTable.PushNumber(++i); - LuaTable.PushString(domain); - } - Arguments.PushTable(&LuaTable); - - return GetRootEntity()->CallEvent("onClientBrowserWhitelistChange", Arguments, false); -} - -void CClientGame::RestreamModel(unsigned short usModel) -{ - // Is this a vehicle ID? - if (CClientVehicleManager::IsValidModel(usModel)) - { - // Stream the vehicles of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetVehicleManager()->RestreamVehicles(usModel); - } - - // Is this an object ID? - else if (CClientObjectManager::IsValidModel(usModel)) - { - if (CClientPedManager::IsValidWeaponModel(usModel)) - { - // Stream the weapon of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamWeapon(usModel); - m_pManager->GetPickupManager()->RestreamPickups(usModel); - } - // Stream the objects of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetObjectManager()->RestreamObjects(usModel); - g_pGame->GetModelInfo(usModel)->RestreamIPL(); - } - // Is this an ped ID? - else if (CClientPlayerManager::IsValidModel(usModel)) - { - // Stream the ped of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamPeds(usModel); - } - else - - // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect - if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) - m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); -} - -void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) -{ - m_mapOfIfpPointers[u32BlockNameHash] = pIFP; -} - -std::shared_ptr CClientGame::GetIFPPointerFromMap(const unsigned int u32BlockNameHash) -{ - auto it = m_mapOfIfpPointers.find(u32BlockNameHash); - if (it != m_mapOfIfpPointers.end()) - { - return it->second; - } - return nullptr; -} - -void CClientGame::RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash) -{ - m_mapOfIfpPointers.erase(u32BlockNameHash); -} - -void CClientGame::InsertPedPointerToSet(CClientPed* pPed) -{ - m_setOfPedPointers.insert(pPed); -} - -void CClientGame::RemovePedPointerFromSet(CClientPed* pPed) -{ - m_setOfPedPointers.erase(pPed); -} - -CClientPed* CClientGame::GetClientPedByClump(const RpClump& Clump) -{ - for (auto& pPed : m_setOfPedPointers) - { - CEntity* pEntity = pPed->GetGameEntity(); - if (pEntity != nullptr) - { - if (pEntity->GetRpClump() != nullptr) - { - const RpClump& entityClump = *pEntity->GetRpClump(); - if (std::addressof(entityClump) == std::addressof(Clump)) - { - return pPed; - } - } - } - } - return nullptr; -} - -void CClientGame::OnClientIFPUnload(const std::shared_ptr& IFP) -{ - IFP->MarkAsUnloading(); - for (auto& pPed : m_setOfPedPointers) - { - // Remove IFP animations from replaced animations of peds/players - pPed->RestoreAnimations(IFP); - - // Make sure that streamed in pulses or changing model does not accidently - // play our custom animation. We can do that by making the custom animation - // untriggerable - if (pPed->GetCustomAnimationBlockNameHash() == IFP->GetBlockNameHash()) - { - if (pPed->IsCustomAnimationPlaying()) - { - pPed->SetCustomAnimationUntriggerable(); - } - - // Important! As we are using a shared_ptr, we need to decrement the reference counter - // by setting the shared_ptr to nullptr, this will avoid memory leak - if (!pPed->IsNextAnimationCustom() && pPed->IsCurrentAnimationCustom()) - { - pPed->DereferenceCustomAnimationBlock(); - } - } - } -} - -void CClientGame::InsertAnimationAssociationToMap(CAnimBlendAssociationSAInterface* pAnimAssociation, const std::shared_ptr& pIFPAnimations) -{ - m_mapOfCustomAnimationAssociations[pAnimAssociation] = pIFPAnimations; -} - -void CClientGame::RemoveAnimationAssociationFromMap(CAnimBlendAssociationSAInterface* pAnimAssociation) -{ - m_mapOfCustomAnimationAssociations.erase(pAnimAssociation); -} +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CClientGame.cpp + * PURPOSE: Client game manager + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include +#include "game/CAnimBlendAssocGroup.h" +#include "game/CAnimBlendAssociation.h" +#include "game/CAnimBlendHierarchy.h" + +SString StringZeroPadout(const SString& strInput, uint uiPadoutSize) +{ + SString strResult = strInput; + while (strResult.length() < uiPadoutSize) + strResult += '\0'; + return strResult; +} + +using SharedUtil::CalcMTASAPath; +using std::list; +using std::vector; + +// Hide the "conversion from 'unsigned long' to 'DWORD*' of greater size" warning +#pragma warning(disable:4312) + +// Used within this file by the packet handler to grab the this pointer of CClientGame +extern CClientGame* g_pClientGame; +extern int g_iDamageEventLimit; +float g_fApplyDamageLastAmount; +uchar g_ucApplyDamageLastHitZone; +CClientPed* g_pApplyDamageLastDamagedPed; +bool g_bBulletFireVectorsValid; +CVector g_vecBulletFireStartPosition; +CVector g_vecBulletFireEndPosition; + +#define DEFAULT_GRAVITY 0.008f +#define DEFAULT_GAME_SPEED 1.0f +#define DEFAULT_BLUR_LEVEL 36 +#define DEFAULT_JETPACK_MAXHEIGHT 100 +#define DEFAULT_AIRCRAFT_MAXHEIGHT 800 +#define DEFAULT_AIRCRAFT_MAXVELOCITY 1.5f +#define DEFAULT_MINUTE_DURATION 1000 +#define DOUBLECLICK_TIMEOUT 330 +#define DOUBLECLICK_MOVE_THRESHOLD 10.0f + +CClientGame::CClientGame(bool bLocalPlay) +{ + // Init the global var with ourself + g_pClientGame = this; + + // Packet handler + m_pPacketHandler = new CPacketHandler(); + + // Init + m_bLocalPlay = bLocalPlay; + m_bErrorStartingLocal = false; + m_iLocalConnectAttempts = 0; + m_Status = CClientGame::STATUS_CONNECTING; + m_ulVerifyTimeStart = 0; + m_ulLastClickTick = 0; + m_pLocalPlayer = NULL; + m_LocalID = INVALID_ELEMENT_ID; + m_bShowNametags = true; + m_bWaitingForLocalConnect = false; + m_bShowRadar = false; + m_bGameLoaded = false; + m_bTriggeredIngameAndConnected = false; + m_bGracefulDisconnect = false; + m_ulLastVehicleInOutTime = 0; + m_bIsGettingOutOfVehicle = false; + m_bIsGettingIntoVehicle = false; + m_bIsGettingJacked = false; + m_bIsJackingVehicle = false; + m_VehicleInOutID = INVALID_ELEMENT_ID; + m_pGettingJackedBy = NULL; + m_ucVehicleInOutSeat = 0xFF; + m_pTargetedEntity = NULL; + m_TargetedPlayerID = INVALID_ELEMENT_ID; + m_pDamageEntity = NULL; + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageBodyPiece = 0xFF; + m_ucDamageWeapon = 0xFF; + m_ulDamageTime = 0; + m_bDamageSent = true; + m_bShowNetstat = false; + m_bShowFPS = false; + m_bHudAreaNameDisabled = false; + m_fGameSpeed = 1.0f; + m_lMoney = 0; + m_dwWanted = 0; + m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) + ResetAmmoInClip(); + + m_bNoNewVehicleTask = false; + m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; + + m_bCursorEventsEnabled = false; + m_bInitiallyFadedOut = true; + + m_bIsPlayingBack = false; + m_bFirstPlaybackFrame = false; + + // Setup game glitch defaults ( false = disabled ). Remember to update these serverside if you alter them! + m_Glitches[GLITCH_QUICKRELOAD] = false; + g_pMultiplayer->DisableQuickReload(true); + m_Glitches[GLITCH_FASTFIRE] = false; + m_Glitches[GLITCH_FASTMOVE] = false; + m_Glitches[GLITCH_CROUCHBUG] = false; + m_Glitches[GLITCH_CLOSEDAMAGE] = false; + g_pMultiplayer->DisableCloseRangeDamage(true); + m_Glitches[GLITCH_HITANIM] = false; + m_Glitches[GLITCH_FASTSPRINT] = false; + m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; + m_Glitches[GLITCH_QUICKSTAND] = false; + g_pMultiplayer->DisableBadDrivebyHitboxes(true); + + // Remove Night & Thermal vision view (if enabled). + g_pMultiplayer->SetNightVisionEnabled(false); + g_pMultiplayer->SetThermalVisionEnabled(false); + + m_bCloudsEnabled = true; + + m_bBirdsEnabled = true; + + m_bWasMinimized = false; + + // Grab the mod path + m_strModRoot = g_pCore->GetModInstallRoot("deathmatch"); + + // Figure out which directory to use for the client resource file cache + SetFileCacheRoot(); + + // Override CGUI's global events + g_pCore->GetGUI()->SetKeyDownHandler(INPUT_MOD, GUI_CALLBACK_KEY(&CClientGame::OnKeyDown, this)); + g_pCore->GetGUI()->SetMouseClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseClick, this)); + g_pCore->GetGUI()->SetMouseDoubleClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseDoubleClick, this)); + g_pCore->GetGUI()->SetMouseButtonDownHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonDown, this)); + g_pCore->GetGUI()->SetMouseButtonUpHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonUp, this)); + g_pCore->GetGUI()->SetMouseMoveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseMove, this)); + g_pCore->GetGUI()->SetMouseEnterHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseEnter, this)); + g_pCore->GetGUI()->SetMouseLeaveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseLeave, this)); + g_pCore->GetGUI()->SetMouseWheelHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseWheel, this)); + g_pCore->GetGUI()->SetMovedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnMove, this)); + g_pCore->GetGUI()->SetSizedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnSize, this)); + g_pCore->GetGUI()->SetFocusGainedHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusGain, this)); + g_pCore->GetGUI()->SetFocusLostHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusLoss, this)); + g_pCore->GetGUI()->SelectInputHandlers(INPUT_MOD); + + // Startup "entities from root" optimization for getElementsByType + CClientEntity::StartupEntitiesFromRoot(); + + // Startup game entity tracking manager + m_pGameEntityXRefManager = NewGameEntityXRefManager(); + m_pModelCacheManager = NewClientModelCacheManager(); + + // Initialize our root entity with an invalid id, we dont know the true id until map-start + m_pRootEntity = new CClientDummy(NULL, INVALID_ELEMENT_ID, "root"); + m_pRootEntity->MakeSystemEntity(); + + m_pDebugHookManager = new CDebugHookManager(); + + // Movings objects manager + m_pMovingObjectsManager = new CMovingObjectsManager(); + + // Create the manager and grab the most important pointers + m_pManager = new CClientManager; + m_pCamera = m_pManager->GetCamera(); + m_pMarkerManager = m_pManager->GetMarkerManager(); + m_pObjectManager = m_pManager->GetObjectManager(); + m_pPickupManager = m_pManager->GetPickupManager(); + m_pPlayerManager = m_pManager->GetPlayerManager(); + m_pRadarAreaManager = m_pManager->GetRadarAreaManager(); + m_pDisplayManager = m_pManager->GetDisplayManager(); + m_pVehicleManager = m_pManager->GetVehicleManager(); + m_pRadarMarkerManager = m_pManager->GetRadarMarkerManager(); + m_pPathManager = m_pManager->GetPathManager(); + m_pTeamManager = m_pManager->GetTeamManager(); + m_pPedManager = m_pManager->GetPedManager(); + m_pGUIManager = m_pManager->GetGUIManager(); + m_pResourceManager = m_pManager->GetResourceManager(); + m_pProjectileManager = m_pManager->GetProjectileManager(); + m_pLocalServer = NULL; + + m_pLatentTransferManager = new CLatentTransferManager(); + m_pZoneNames = new CZoneNames; + m_pScriptKeyBinds = new CScriptKeyBinds; + m_pRemoteCalls = new CRemoteCalls(); + m_pResourceFileDownloadManager = new CResourceFileDownloadManager(); + + // Create our net API + m_pNetAPI = new CNetAPI(m_pManager); + m_pNetworkStats = new CNetworkStats(m_pDisplayManager); + m_pSyncDebug = new CSyncDebug(m_pManager); + + // Create our blended weather class + m_pBlendedWeather = new CBlendedWeather; + + // Create our RPC class + m_pRPCFunctions = new CRPCFunctions(this); + + // Our management classes + m_pUnoccupiedVehicleSync = new CUnoccupiedVehicleSync(m_pVehicleManager); + m_pPedSync = new CPedSync(m_pPedManager); +#ifdef WITH_OBJECT_SYNC + m_pObjectSync = new CObjectSync(m_pObjectManager); +#endif + m_pNametags = new CNametags(m_pManager); + m_pRadarMap = new CRadarMap(m_pManager); + + // Set the screenshot path + /* This is now done in CCore, to maintain a global screenshot path + SString strScreenShotPath = SString::Printf ( "%s\\screenshots", m_szModRoot ); + g_pCore->SetScreenShotPath ( strScreenShotPath ); + */ + + // Create the transfer boxes (GUI) + m_pTransferBox = new CTransferBox(); + m_pBigPacketTransferBox = new CTransferBox(); + + // Store the time we started on + if (bLocalPlay) + m_ulTimeStart = 0; + else + m_ulTimeStart = CClientTime::GetTime(); + + // MTA Voice + m_pVoiceRecorder = new CVoiceRecorder(); + + // Singular file download manager + m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); + + // Register the message and the net packet handler + g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); + g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); + g_pMultiplayer->SetBulletImpactHandler(CClientGame::BulletImpact); + g_pMultiplayer->SetBulletFireHandler(CClientGame::BulletFire); + g_pMultiplayer->SetExplosionHandler(CClientExplosionManager::Hook_StaticExplosionCreation); + g_pMultiplayer->SetBreakTowLinkHandler(CClientGame::StaticBreakTowLinkHandler); + g_pMultiplayer->SetDrawRadarAreasHandler(CClientGame::StaticDrawRadarAreasHandler); + g_pMultiplayer->SetDamageHandler(CClientGame::StaticDamageHandler); + g_pMultiplayer->SetDeathHandler(CClientGame::StaticDeathHandler); + g_pMultiplayer->SetFireHandler(CClientGame::StaticFireHandler); + g_pMultiplayer->SetProjectileStopHandler(CClientProjectileManager::Hook_StaticProjectileAllow); + g_pMultiplayer->SetProjectileHandler(CClientProjectileManager::Hook_StaticProjectileCreation); + g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); + g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); + g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); + g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); + g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); + g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); + g_pMultiplayer->SetPreFxRenderHandler(CClientGame::StaticPreFxRenderHandler); + g_pMultiplayer->SetPreHudRenderHandler(CClientGame::StaticPreHudRenderHandler); + g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(CClientGame::StaticCAnimBlendAssocDestructorHandler); + g_pMultiplayer->SetAddAnimationHandler(CClientGame::StaticAddAnimationHandler); + g_pMultiplayer->SetAddAnimationAndSyncHandler(CClientGame::StaticAddAnimationAndSyncHandler); + g_pMultiplayer->SetAssocGroupCopyAnimationHandler(CClientGame::StaticAssocGroupCopyAnimationHandler); + g_pMultiplayer->SetBlendAnimationHierarchyHandler(CClientGame::StaticBlendAnimationHierarchyHandler); + g_pMultiplayer->SetProcessCollisionHandler(CClientGame::StaticProcessCollisionHandler); + g_pMultiplayer->SetVehicleCollisionHandler(CClientGame::StaticVehicleCollisionHandler); + g_pMultiplayer->SetVehicleDamageHandler(CClientGame::StaticVehicleDamageHandler); + g_pMultiplayer->SetHeliKillHandler(CClientGame::StaticHeliKillHandler); + g_pMultiplayer->SetObjectDamageHandler(CClientGame::StaticObjectDamageHandler); + g_pMultiplayer->SetObjectBreakHandler(CClientGame::StaticObjectBreakHandler); + g_pMultiplayer->SetWaterCannonHitHandler(CClientGame::StaticWaterCannonHandler); + g_pMultiplayer->SetVehicleFellThroughMapHandler(CClientGame::StaticVehicleFellThroughMapHandler); + g_pMultiplayer->SetGameObjectDestructHandler(CClientGame::StaticGameObjectDestructHandler); + g_pMultiplayer->SetGameVehicleDestructHandler(CClientGame::StaticGameVehicleDestructHandler); + g_pMultiplayer->SetGamePlayerDestructHandler(CClientGame::StaticGamePlayerDestructHandler); + g_pMultiplayer->SetGameProjectileDestructHandler(CClientGame::StaticGameProjectileDestructHandler); + g_pMultiplayer->SetGameModelRemoveHandler(CClientGame::StaticGameModelRemoveHandler); + g_pMultiplayer->SetGameEntityRenderHandler(CClientGame::StaticGameEntityRenderHandler); + g_pMultiplayer->SetFxSystemDestructionHandler(CClientGame::StaticFxSystemDestructionHandler); + g_pMultiplayer->SetDrivebyAnimationHandler(CClientGame::StaticDrivebyAnimationHandler); + g_pGame->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); + g_pGame->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); + g_pGame->SetTaskSimpleBeHitHandler(CClientGame::StaticTaskSimpleBeHitHandler); + g_pCore->SetMessageProcessor(CClientGame::StaticProcessMessage); + g_pCore->GetKeyBinds()->SetKeyStrokeHandler(CClientGame::StaticKeyStrokeHandler); + g_pCore->GetKeyBinds()->SetCharacterKeyHandler(CClientGame::StaticCharacterKeyHandler); + g_pNet->RegisterPacketHandler(CClientGame::StaticProcessPacket); + + m_pLuaManager = new CLuaManager(this); + m_pScriptDebugging = new CScriptDebugging(m_pLuaManager); + m_pScriptDebugging->SetLogfile(CalcMTASAPath("mta\\logs\\clientscript.log"), 3); + + CStaticFunctionDefinitions(m_pLuaManager, &m_Events, g_pCore, g_pGame, this, m_pManager); + CLuaFunctionDefs::Initialize(m_pLuaManager, m_pScriptDebugging, this); + CLuaDefs::Initialize(this, m_pLuaManager, m_pScriptDebugging); + + // Start async task scheduler + m_pAsyncTaskScheduler = new SharedUtil::CAsyncTaskScheduler(2); + + // Disable the enter/exit vehicle key button (we want to handle this button ourselves) + g_pMultiplayer->DisableEnterExitVehicleKey(true); + + // Disable GTA's pickup processing as we want to confirm the hits with the server + m_pPickupManager->SetPickupProcessingDisabled(true); + + // Key-bind for fire-key (for handling satchels and stealth-kills) + g_pCore->GetKeyBinds()->AddControlFunction("fire", CClientGame::StaticUpdateFireKey, true); + + // Init big packet progress vars + m_bReceivingBigPacket = false; + m_ulBigPacketSize = 0; + m_ulBigPacketBytesReceivedBase = 0; + + m_bBeingDeleted = false; + + #if defined (MTA_DEBUG) || defined (MTA_BETA) + m_bShowSyncingInfo = false; + #endif + + #ifdef MTA_DEBUG + m_pShowPlayer = m_pShowPlayerTasks = NULL; + m_bMimicLag = false; + m_ulLastMimicLag = 0; + m_bDoPaintballs = false; + m_bShowInterpolation = false; + #endif + + // Add our lua events + AddBuiltInEvents(); + + // Init debugger class + m_Foo.Init(this); + + // Load some stuff from the core config + float fScale; + g_pCore->GetCVars()->Get("text_scale", fScale); + CClientTextDisplay::SetGlobalScale(fScale); + + // Reset async loading script settings to default + g_pGame->SetAsyncLoadingFromScript(true, false); + + // Reset test mode script settings to default + g_pCore->GetGraphics()->GetRenderItemManager()->SetTestMode(DX_TEST_MODE_NONE); +} + +CClientGame::~CClientGame(void) +{ + m_bBeingDeleted = true; + // Stop all explosions. Unfortunately this doesn't fix the crash + // if a vehicle is destroyed while it explodes. + g_pGame->GetExplosionManager()->RemoveAllExplosions(); + + // Reset camera shaking + g_pGame->GetCamera()->SetShakeForce(0.0f); + + // Stop playing the continious sounds + // if the game was loaded. This is done by + // playing these special IDS. + if (m_bGameLoaded) + { + g_pGame->GetAudio()->PlayFrontEndSound(35); + g_pGame->GetAudio()->PlayFrontEndSound(48); + } + + // Reset the GUI input mode + g_pCore->GetGUI()->SetGUIInputMode(INPUTMODE_NO_BINDS_ON_EDIT); + + // Reset CGUI's global events + g_pCore->GetGUI()->ClearInputHandlers(INPUT_MOD); + + // Destroy mimics + #ifdef MTA_DEBUG + list::const_iterator iterMimics = m_Mimics.begin(); + for (; iterMimics != m_Mimics.end(); iterMimics++) + { + CClientPlayer* pPlayer = *iterMimics; + CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); + if (pVehicle) + delete pVehicle; + + delete pPlayer; + } + #endif + + // Hide the transfer box incase it is showing + m_pTransferBox->Hide(); + m_pBigPacketTransferBox->Hide(); + + // Stop async task scheduler + SAFE_DELETE(m_pAsyncTaskScheduler); + + SAFE_DELETE(m_pVoiceRecorder); + + // Singular file download manager + SAFE_DELETE(m_pSingularFileDownloadManager); + + // NULL the message/net stuff + g_pMultiplayer->SetPreContextSwitchHandler(NULL); + g_pMultiplayer->SetPostContextSwitchHandler(NULL); + g_pMultiplayer->SetPreWeaponFireHandler(NULL); + g_pMultiplayer->SetPostWeaponFireHandler(NULL); + g_pMultiplayer->SetBulletImpactHandler(NULL); + g_pMultiplayer->SetBulletFireHandler(NULL); + g_pMultiplayer->SetExplosionHandler(NULL); + g_pMultiplayer->SetBreakTowLinkHandler(NULL); + g_pMultiplayer->SetDrawRadarAreasHandler(NULL); + g_pMultiplayer->SetDamageHandler(NULL); + g_pMultiplayer->SetFireHandler(NULL); + g_pMultiplayer->SetProjectileStopHandler(NULL); + g_pMultiplayer->SetProjectileHandler(NULL); + g_pMultiplayer->SetProcessCamHandler(nullptr); + g_pMultiplayer->SetRender3DStuffHandler(NULL); + g_pMultiplayer->SetPreRenderSkyHandler(NULL); + g_pMultiplayer->SetRenderHeliLightHandler(nullptr); + g_pMultiplayer->SetChokingHandler(NULL); + g_pMultiplayer->SetPreWorldProcessHandler(NULL); + g_pMultiplayer->SetPostWorldProcessHandler(NULL); + g_pMultiplayer->SetPreFxRenderHandler(NULL); + g_pMultiplayer->SetPreHudRenderHandler(NULL); + g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(NULL); + g_pMultiplayer->SetAddAnimationHandler(NULL); + g_pMultiplayer->SetAddAnimationAndSyncHandler(NULL); + g_pMultiplayer->SetAssocGroupCopyAnimationHandler(NULL); + g_pMultiplayer->SetBlendAnimationHierarchyHandler(NULL); + g_pMultiplayer->SetProcessCollisionHandler(NULL); + g_pMultiplayer->SetVehicleCollisionHandler(NULL); + g_pMultiplayer->SetVehicleDamageHandler(NULL); + g_pMultiplayer->SetHeliKillHandler(NULL); + g_pMultiplayer->SetObjectDamageHandler(NULL); + g_pMultiplayer->SetObjectBreakHandler(NULL); + g_pMultiplayer->SetWaterCannonHitHandler(NULL); + g_pMultiplayer->SetGameObjectDestructHandler(NULL); + g_pMultiplayer->SetGameVehicleDestructHandler(NULL); + g_pMultiplayer->SetGamePlayerDestructHandler(NULL); + g_pMultiplayer->SetGameProjectileDestructHandler(NULL); + g_pMultiplayer->SetGameModelRemoveHandler(NULL); + g_pMultiplayer->SetGameEntityRenderHandler(NULL); + g_pMultiplayer->SetDrivebyAnimationHandler(nullptr); + g_pGame->SetPreWeaponFireHandler(NULL); + g_pGame->SetPostWeaponFireHandler(NULL); + g_pGame->SetTaskSimpleBeHitHandler(NULL); + g_pGame->GetAudio()->SetWorldSoundHandler(NULL); + g_pCore->SetMessageProcessor(NULL); + g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); + g_pCore->GetKeyBinds()->SetCharacterKeyHandler(NULL); + g_pNet->StopNetwork(); + g_pNet->RegisterPacketHandler(NULL); + CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); + pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessClientKeyBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessClientControlBind); + pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessServerKeyBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessServerControlBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticUpdateFireKey); + pKeyBinds->SetAllControlsEnabled(true, true, true); + g_pCore->ForceCursorVisible(false); + SetCursorEventsEnabled(false); + + // Destroy our stuff + SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop + SAFE_DELETE(m_pNametags); + SAFE_DELETE(m_pSyncDebug); + SAFE_DELETE(m_pNetworkStats); + SAFE_DELETE(m_pNetAPI); + SAFE_DELETE(m_pRPCFunctions); + SAFE_DELETE(m_pUnoccupiedVehicleSync); + SAFE_DELETE(m_pPedSync); +#ifdef WITH_OBJECT_SYNC + SAFE_DELETE(m_pObjectSync); +#endif + SAFE_DELETE(m_pBlendedWeather); + SAFE_DELETE(m_pMovingObjectsManager); + SAFE_DELETE(m_pRadarMap); + SAFE_DELETE(m_pRemoteCalls); + SAFE_DELETE(m_pLuaManager); + SAFE_DELETE(m_pLatentTransferManager); + SAFE_DELETE(m_pResourceFileDownloadManager); + + SAFE_DELETE(m_pRootEntity); + + SAFE_DELETE(m_pModelCacheManager); + SAFE_DELETE(m_pGameEntityXRefManager); + SAFE_DELETE(m_pZoneNames); + SAFE_DELETE(m_pScriptKeyBinds); + + // Delete the scriptdebugger + SAFE_DELETE(m_pScriptDebugging); + + // Delete the transfer boxes + SAFE_DELETE(m_pTransferBox); + SAFE_DELETE(m_pBigPacketTransferBox); + + SAFE_DELETE(m_pLocalServer); + SAFE_DELETE(m_pDebugHookManager); + + // Packet handler + SAFE_DELETE(m_pPacketHandler); + + // Delete PerfStatManager + delete CClientPerfStatManager::GetSingleton(); + + // NULL the global CClientGame var + g_pClientGame = NULL; + m_bBeingDeleted = false; +} + +/* +bool CClientGame::StartGame ( void ) // for an offline game (e.g. editor) +{ + m_Status = STATUS_OFFLINE; + g_pCore->SetOfflineMod ( true ); // hide chatbox etc + g_pCore->SetConnected ( true ); // not sure, but its required :) + g_pCore->HideMainMenu (); // duh + + // If the game isn't started, start it + if ( g_pGame->GetSystemState () == 7 ) + { + g_pGame->StartGame (); + } + return true; +} +*/ + +#include +//#define _CRTDBG_CHECK_EVERY_16_DF 0x00100000 /* check heap every 16 heap ops */ +//#define _CRTDBG_CHECK_EVERY_128_DF 0x00800000 /* check heap every 128 heap ops */ +//#define _CRTDBG_CHECK_EVERY_1024_DF 0x04000000 /* check heap every 1024 heap ops */ + +void CClientGame::EnablePacketRecorder(const char* szFilename) +{ + m_pManager->GetPacketRecorder()->StartRecord(szFilename, true); +} + +void CClientGame::StartPlayback(void) +{ + // strcpy ( m_szNick, "Playback" ); + + m_bIsPlayingBack = true; + m_bFirstPlaybackFrame = true; + m_pManager->GetPacketRecorder()->SetPacketHandler(CClientGame::StaticProcessPacket); + + if (!m_pManager->IsGameLoaded()) + { + g_pGame->StartGame(); + } +} + +bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerType Type) +{ + m_ServerType = Type; + // int dbg = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ); + // dbg |= _CRTDBG_ALLOC_MEM_DF; + // dbg |= _CRTDBG_CHECK_ALWAYS_DF; + // dbg |= _CRTDBG_DELAY_FREE_MEM_DF; + // dbg |= _CRTDBG_LEAK_CHECK_DF; + //_CrtSetDbgFlag(dbg); + + // Verify that the nickname is valid + if (!IsNickValid(szNick)) + { + g_pCore->ShowMessageBox(_("Error") + _E("CD01"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + // Store our nickname + m_strLocalNick.AssignLeft(szNick, MAX_PLAYER_NICK_LENGTH); + + // Are we connected? + if (g_pNet->IsConnected() || m_bIsPlayingBack) + { + // Hide the console when connecting.. + if (g_pCore->GetConsole()->IsVisible()) + g_pCore->GetConsole()->SetVisible(false); + + // Display the status box + g_pCore->ShowMessageBox(_("CONNECTING"), _("Entering the game ..."), MB_ICON_INFO); + + // Send the initial data to the server + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Hash the password if neccessary + MD5 Password; + memset(Password.data, 0, sizeof(MD5)); + if (szPassword) + { + // Is it long enough? + size_t sizePassword = strlen(szPassword); + if (sizePassword > 0) + { + // Hash the password and put it in the struct + CMD5Hasher Hasher; + Hasher.Calculate(szPassword, sizePassword, Password); + } + } + + // Append version information + pBitStream->Write(static_cast(MTA_DM_NETCODE_VERSION)); + pBitStream->Write(static_cast(MTA_DM_VERSION)); + pBitStream->Write(static_cast(MTA_DM_BITSTREAM_VERSION)); + + SString strPlayerVersion("%d.%d.%d-%d.%05d.%d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, + MTASA_VERSION_BUILD, g_pNet->GetNetRev()); + pBitStream->WriteString(strPlayerVersion); + + pBitStream->WriteBit(g_pCore->IsOptionalUpdateInfoRequired(g_pNet->GetConnectedServer(true))); + + pBitStream->Write(static_cast(g_pGame->GetGameVersion())); + + // Append user details + SString strTemp = StringZeroPadout(m_strLocalNick, MAX_PLAYER_NICK_LENGTH); + pBitStream->Write(strTemp.c_str(), MAX_PLAYER_NICK_LENGTH); + pBitStream->Write(reinterpret_cast(Password.data), sizeof(MD5)); + + // Append community information (Removed) + std::string strUser; + pBitStream->Write(strUser.c_str(), MAX_SERIAL_LENGTH); + + // Send the packet as joindata + g_pNet->SendPacket(PACKET_ID_PLAYER_JOINDATA, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + return true; + } + } + else + { + g_pCore->ShowMessageBox(_("Error") + _E("CD02"), _("Not connected; please use Quick Connect or the 'connect' command to connect to a server."), + MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + } + + return false; +} + +void CClientGame::SetupLocalGame(eServerType Type) +{ + SString strConfig = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; + m_bWaitingForLocalConnect = true; + if (!m_pLocalServer) + m_pLocalServer = new CLocalServer(strConfig); +} + +bool CClientGame::StartLocalGame(eServerType Type, const char* szPassword) +{ + // Verify that the nickname is valid + std::string strNick; + g_pCore->GetCVars()->Get("nick", strNick); + + if (!IsNickValid(strNick.c_str())) + { + g_pCore->ShowMessageBox(_("Error") + _E("CD03"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + m_bWaitingForLocalConnect = false; + m_ServerType = Type; + SString strTemp = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; + + SAFE_DELETE(m_pLocalServer); + + // Store our nickname + m_strLocalNick.AssignLeft(strNick.c_str(), MAX_PLAYER_NICK_LENGTH); + + // Got a server? + if (m_bLocalPlay) + { + // Start the server locally + if (!m_Server.Start(strTemp)) + { + m_bWaitingForLocalConnect = true; + m_bErrorStartingLocal = true; + g_pCore->ShowMessageBox(_("Error") + _E("CD04"), _("The server is not installed"), MB_ICON_ERROR | MB_BUTTON_OK); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + if (szPassword) + m_Server.SetPassword(szPassword); + + // Display the status box<<<<< + m_OnCancelLocalGameClick = GUI_CALLBACK(&CClientGame::OnCancelLocalGameClick, this); + g_pCore->ShowMessageBox(_("Local Server"), _("Starting local server ..."), MB_BUTTON_CANCEL | MB_ICON_INFO, &m_OnCancelLocalGameClick); + } + else + { + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + // We're waiting for connection + m_bWaitingForLocalConnect = true; + return true; +} + +bool CClientGame::OnCancelLocalGameClick(CGUIElement* pElement) +{ + if (m_bLocalPlay && m_bWaitingForLocalConnect) + { + g_pCore->RemoveMessageBox(); + g_pCore->GetModManager()->RequestUnload(); + return true; + } + return false; +} + +void CClientGame::DoPulsePreFrame(void) +{ + if (m_Status == CClientGame::STATUS_JOINED) + { + if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) + { + m_pVoiceRecorder->DoPulse(); + } + } +} + +void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRenderTargets) +{ + // Allow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); + + // If appropriate, call onClientRestore + if (bDidUnminimize) + { + CLuaArguments Arguments; + Arguments.PushBoolean(bDidRecreateRenderTargets); + m_pRootEntity->CallEvent("onClientRestore", Arguments, false); + m_bWasMinimized = false; + + // Reverse any mute on minimize effects + g_pGame->GetAudio()->SetEffectsMasterVolume(g_pGame->GetSettings()->GetSFXVolume()); + g_pGame->GetAudio()->SetMusicMasterVolume(g_pGame->GetSettings()->GetRadioVolume()); + m_pManager->GetSoundManager()->SetMinimizeMuted(false); + } + + // Call onClientHUDRender LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientHUDRender", Arguments, false); + + // Disallow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); + + // Restore in case script forgets + g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); + + DebugElementRender(); +} + +void CClientGame::DoPulsePostFrame(void) +{ + TIMING_CHECKPOINT("+CClientGame::DoPulsePostFrame"); + #ifdef DEBUG_KEYSTATES + // Get the controller state + CControllerState cs; + g_pGame->GetPad()->GetCurrentControllerState(&cs); + + SString strBuffer; + strBuffer = SString::Printf( + "LeftShoulder1: %u\n" + "LeftShoulder2: %u\n" + "RightShoulder1: %u\n" + "RightShoulder2: %u\n" + "DPadUp: %u\n" + "DPadDown: %u\n" + "DPadLeft: %u\n" + "DPadRight: %u\n" + "Start: %u\n" + "Select: %u\n" + "ButtonSquare: %u\n" + "ButtonTriangle: %u\n" + "ButtonCross: %u\n" + "ButtonCircle: %u\n" + "ShockButtonL: %u\n" + "ShockButtonR: %u\n" + "PedWalk: %u\n", + cs.LeftShoulder1, cs.LeftShoulder2, cs.RightShoulder1, cs.RightShoulder2, cs.DPadUp, cs.DPadDown, cs.DPadLeft, cs.DPadRight, cs.Start, cs.Select, + cs.ButtonSquare, cs.ButtonTriangle, cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.ShockButtonR, cs.m_bPedWalk); + + g_pCore->GetGraphics()->DrawTextTTF(300, 10, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); + + strBuffer = SString::Printf( + "VehicleMouseLook: %u\n" + "LeftStickX: %u\n" + "LeftStickY: %u\n" + "RightStickX: %u\n" + "RightStickY: %u", + cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, cs.RightStickX, cs.RightStickY); + + g_pCore->GetGraphics()->DrawTextTTF(300, 320, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); + #endif + + UpdateModuleTickCount64(); + + if (m_pManager->IsGameLoaded()) + { + // Pulse the nametags before anything that changes player positions, we'll be 1 frame behind, but so is the camera + // If nametags are enabled, pulse the nametag manager + if (m_bShowNametags) + { + m_pNametags->DoPulse(); + } + + // Sync debug + m_pSyncDebug->OnPulse(); + + // Also eventually draw FPS + if (m_bShowFPS) + { + DrawFPS(); + } + + CGraphicsInterface* pGraphics = g_pCore->GetGraphics(); + unsigned int uiHeight = pGraphics->GetViewportHeight(); + unsigned int uiWidth = pGraphics->GetViewportWidth(); + + // Draw a little star in the corner if async is on + if (g_pGame->IsASyncLoadingEnabled(true)) + { + unsigned int uiPosY = g_pGame->IsASyncLoadingEnabled() ? uiHeight - 7 : uiHeight - 12; + pGraphics->DrawString(uiWidth - 5, uiPosY, 0x80ffffff, 1, "*"); + } + + // Draw notice text if dx test mode is enabled + if (g_pCore->GetGraphics()->GetRenderItemManager()->GetTestMode()) + { + unsigned int uiPosY = uiHeight - 30; + pGraphics->DrawString(uiWidth - 155, uiPosY, 0x40ffffff, 1, "dx test mode enabled"); + } + + // Draw notice text if diagnostic mode enabled + EDiagnosticDebugType diagnosticDebug = g_pCore->GetDiagnosticDebug(); + if (diagnosticDebug == EDiagnosticDebug::LOG_TIMING_0000) + { + unsigned int uiPosY = uiHeight - 30; + pGraphics->DrawString(uiWidth - 185, uiPosY, 0xffffff00, 1, "Debug setting: #0000 Log timing"); + } + + // Draw network trouble message if required + if (m_pNetAPI->IsNetworkTrouble()) + { + int iPosX = uiWidth / 2; // Half way across + int iPosY = uiHeight * 45 / 100; // 45/100 down + g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, + DT_NOCLIP | DT_CENTER); + } + + // Adjust the streaming memory limit. + unsigned int uiStreamingMemoryPrev; + g_pCore->GetCVars()->Get("streaming_memory", uiStreamingMemoryPrev); + uint uiStreamingMemory = SharedUtil::Clamp(g_pCore->GetMinStreamingMemory(), uiStreamingMemoryPrev, g_pCore->GetMaxStreamingMemory()); + if (uiStreamingMemory != uiStreamingMemoryPrev) + g_pCore->GetCVars()->Set("streaming_memory", uiStreamingMemory); + + int iStreamingMemoryBytes = static_cast(uiStreamingMemory) * 1024 * 1024; + if (g_pMultiplayer->GetLimits()->GetStreamingMemory() != iStreamingMemoryBytes) + g_pMultiplayer->GetLimits()->SetStreamingMemory(iStreamingMemoryBytes); + + // If we're in debug mode and are supposed to show task data, do it + #ifdef MTA_DEBUG + if (m_pShowPlayerTasks) + { + DrawTasks(m_pShowPlayerTasks); + } + + if (m_pShowPlayer) + { + DrawPlayerDetails(m_pShowPlayer); + } + + std::vector::const_iterator iter = m_pPlayerManager->IterBegin(); + for (; iter != m_pPlayerManager->IterEnd(); ++iter) + { + CClientPlayer* pPlayer = *iter; + if (pPlayer->IsStreamedIn() && pPlayer->IsShowingWepdata()) + DrawWeaponsyncData(pPlayer); + } + #endif + + #if defined (MTA_DEBUG) || defined (MTA_BETA) + if (m_bShowSyncingInfo) + { + // Draw the header boxz + CVector vecPosition = CVector(0.05f, 0.32f, 0); + m_pDisplayManager->DrawText2D("Syncing vehicles:", vecPosition, 1.0f, 0xFFFFFFFF); + + // Print each vehicle we're syncing + CDeathmatchVehicle* pVehicle; + list::const_iterator iter = m_pUnoccupiedVehicleSync->IterBegin(); + for (; iter != m_pUnoccupiedVehicleSync->IterEnd(); iter++) + { + vecPosition.fY += 0.03f; + pVehicle = *iter; + + SString strBuffer("ID: %u (%s)", pVehicle->GetID(), pVehicle->GetNamePointer()); + + m_pDisplayManager->DrawText2D(strBuffer, vecPosition, 1.0f, 0xFFFFFFFF); + } + } + #endif + // Heli Clear time + if (m_LastClearTime.Get() > HeliKill_List_Clear_Rate) + { + // Clear our list now + m_HeliCollisionsMap.clear(); + m_LastClearTime.Reset(); + } + + CClientPerfStatManager::GetSingleton()->DoPulse(); + } + + m_pRadarMap->DoRender(); + m_pManager->DoRender(); + DoPulses(); + + // If we're supposed to show netstat, draw them infront of everything else + if (m_bShowNetstat) + { + m_pNetworkStats->Draw(); + } +} + +void CClientGame::DoPulses(void) +{ + TIMING_CHECKPOINT("-CClientGame::DoPulsePostFrame"); + + g_pCore->ApplyFrameRateLimit(); + + TIMING_CHECKPOINT("+CClientGame::DoPulses"); + + m_BuiltCollisionMapThisFrame = false; + + if (m_bIsPlayingBack && m_bFirstPlaybackFrame && m_pManager->IsGameLoaded()) + { + g_pCore->GetConsole()->Printf("First playback frame, starting"); + m_pManager->GetPacketRecorder()->StartPlayback("log.rec", false); + m_bFirstPlaybackFrame = false; + } + + // Call debug code if debug mode + m_Foo.DoPulse(); + + // Output stuff from our internal server eventually + m_Server.DoPulse(); + + if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED && GetTickCount64_() - m_llLastTransgressionTime > 60000) + { + uint uiLevel = 0; + uint uiInform = 0; + SString strMessage; + + // Is the player a cheater? + if (!m_pManager->GetAntiCheat().PerformChecks()) + { + uiLevel = 1; + uiInform = 2; + } + else + { + strMessage = g_pNet->GetNextBuffer(); + if (strMessage.length()) + { + uiLevel = atoi(strMessage.SplitLeft(":", &strMessage)); + uiInform = atoi(strMessage.SplitLeft(":", &strMessage)); + } + } + + // Send message to the server + if (uiLevel) + { + SString strPrefix = (uiInform == 2) ? "AC" : (uiInform == 1) ? "VF" : "SD"; + SString strMessageCombo = SString("%s #%d %s", *strPrefix, uiLevel, strMessage.c_str()).TrimEnd(" "); + m_llLastTransgressionTime = GetTickCount64_(); + AddReportLog(3100, strMessageCombo + SString(" (%d)", uiInform)); + + if (uiInform > 0) + { + // The server will use the whole message as supplied here + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write(uiLevel); + pBitStream->WriteString(strMessageCombo); + g_pNet->SendPacket(PACKET_ID_PLAYER_TRANSGRESSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + else + { + // Otherwise, disconnect here + AddReportLog(7105, SString("Core - Kicked (%s)", *strMessageCombo)); + g_pCore->ShowMessageBox(_("Error") + _E("CD05"), SString(_("You were kicked from the game ( %s )"), *strMessageCombo), + MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + } + + // Send diagnostic info + if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED) + { + // Retrieve data + SString strMessage = g_pNet->GetDiagnosticStatus(); + + // Send to the server if changed + if (strMessage != m_strLastDiagnosticStatus) + { + m_strLastDiagnosticStatus = strMessage; + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->WriteString(strMessage); + g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } + + // Pulse the network interface + + // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) + DoPulses2(false); + + m_pUnoccupiedVehicleSync->DoPulse(); + m_pPedSync->DoPulse(); +#ifdef WITH_OBJECT_SYNC + m_pObjectSync->DoPulse(); +#endif + m_pLatentTransferManager->DoPulse(); + m_pLuaManager->DoPulse(); + m_pScriptDebugging->UpdateLogOutput(); + + GetModelCacheManager()->DoPulse(); + + #ifdef MTA_DEBUG + UpdateMimics(); + #endif + + // Grab the current time + unsigned long ulCurrentTime = CClientTime::GetTime(); + + // Waiting for a connect? + if (m_bWaitingForLocalConnect) + { + // Connected? + if (g_pNet->IsConnected()) + { + // No longer waiting for connect + m_bWaitingForLocalConnect = false; + + // Assume local server has the same bitstream version + g_pNet->SetServerBitStreamVersion(MTA_DM_BITSTREAM_VERSION); + + // Run the game normally. + StartGame(m_strLocalNick, m_Server.GetPassword().c_str(), m_ServerType); + } + else + { + // Going to try connecting? Do this when the internal server has booted + // and we haven't started the connecting. + if (m_Server.IsReady() && m_iLocalConnectAttempts == 0) + { + g_pCore->ShowMessageBox(_("Local Server"), _("Connecting to local server..."), MB_ICON_INFO); + + // Connect + if (g_pNet->StartNetwork("localhost", 22010)) + { + // We're waiting for connection + m_iLocalConnectAttempts = 1; + m_ulTimeStart = CClientTime::GetTime(); + } + else + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD06"), _("Error connecting to server.")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + + // Timeout? + if (m_ulTimeStart != 0 && CClientTime::GetTime() >= m_ulTimeStart + 5000) + { + // Show timeout message and disconnect + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD07"), _("Connecting to local server timed out. See console for details.")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + } + + // If the game is loaded ... + if (m_pManager->IsGameLoaded()) + { + // Pulse the blended weather manager + m_pBlendedWeather->DoPulse(); + + // If we weren't ingame last frame; call the on ingame event + if (!m_bGameLoaded) + { + // Fix for gta not being focused sometimes + SetActiveWindow(g_pCore->GetHookedWindow()); + SetFocus(g_pCore->GetHookedWindow()); + + m_bGameLoaded = true; + Event_OnIngame(); + } + + // Check if the player is hitting the enter vehicle button + DoVehicleInKeyCheck(); + + // Pulse some stuff + m_pMovingObjectsManager->DoPulse(); + + // Get rid of our deleted elements + m_ElementDeleter.DoDeleteAll(); + m_pLuaManager->ProcessPendingDeleteList(); + + // Get rid of deleted GUI elements + g_pCore->GetGUI()->CleanDeadPool(); + + // Allow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); + + // Call onClientRender LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientRender", Arguments, false); + + // Disallow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); + + // Restore in case script forgets + g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); + + // Ensure replaced/restored textures for models in the GTA map are correct + g_pGame->FlushPendingRestreamIPL(); + + // Respawn objects in respawn pool + m_ObjectRespawner.DoRespawnAll(); + } + + // Are we connecting? + if (m_Status == CClientGame::STATUS_CONNECTING) + { + if (m_bErrorStartingLocal) + { + g_pCore->GetModManager()->RequestUnload(); + return; + } + + // Timed out? + if (!m_bWaitingForLocalConnect && ulCurrentTime >= m_ulTimeStart + NET_CONNECT_TIMEOUT) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD08"), _("Connection timed out"), "connect-timed-out", true); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + else if (m_Status == CClientGame::STATUS_JOINED) + { + // Pulse DownloadFiles if we're transferring stuff + GetResourceFileDownloadManager()->DoPulse(); + DownloadSingularResourceFiles(); + GetRemoteCalls()->ProcessQueuedFiles(); + } + + // Not waiting for local connect? + if (!m_bWaitingForLocalConnect) + { + // Trigger the ingame and connected event + if (!m_bTriggeredIngameAndConnected && m_pManager->IsGameLoaded() && g_pCore->IsConnected()) + { + m_bTriggeredIngameAndConnected = true; + Event_OnIngameAndConnected(); + + // Initialize the game + g_pCore->GetGame()->Initialize(); + } + + unsigned char ucError = g_pNet->GetConnectionError(); + + // Lost connection? + if (!g_pNet->IsConnected() && !m_bGracefulDisconnect && !m_bIsPlayingBack) + { + // See if we can figure out what specifically it was + if (ucError == 0) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD09"), _("Connection with the server was lost")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + else + { + SString strError; + SString strErrorCode; + switch (ucError) + { + case RID_RSA_PUBLIC_KEY_MISMATCH: + strError = _("Disconnected: unknown protocol error"); + strErrorCode = _E("CD10"); // encryption key mismatch + break; + case RID_REMOTE_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected remotely"); + strErrorCode = _E("CD11"); + break; + case RID_REMOTE_CONNECTION_LOST: + strError = _("Disconnected: connection lost remotely"); + strErrorCode = _E("CD12"); + break; + case RID_CONNECTION_BANNED: + strError = _("Disconnected: you are banned from this server"); + strErrorCode = _E("CD13"); + break; + case RID_NO_FREE_INCOMING_CONNECTIONS: + strError = _("Disconnected: the server is currently full"); + strErrorCode = _E("CD14"); + break; + case RID_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected from the server"); + strErrorCode = _E("CD15"); + break; + case RID_CONNECTION_LOST: + strError = _("Disconnected: connection to the server was lost"); + strErrorCode = _E("CD16"); + break; + case RID_INVALID_PASSWORD: + strError = _("Disconnected: invalid password specified"); + strErrorCode = _E("CD17"); + break; + default: + strError = _("Disconnected: connection was refused"); + strErrorCode = _E("CD18"); + break; + } + + // Display an error, reset the error status and exit + g_pCore->ShowNetErrorMessageBox(_("Error") + strErrorCode, strError); + g_pNet->SetConnectionError(0); + g_pCore->GetModManager()->RequestUnload(); + } + } + + // If we're in the verificating status + if (m_Status == CClientGame::STATUS_JOINING) + { + // Time out the verification if it takes too long + if (m_ulVerifyTimeStart != 0 && ulCurrentTime >= m_ulVerifyTimeStart + CLIENT_VERIFICATION_TIMEOUT) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD19"), _("MTA Client verification failed!")); + g_pCore->GetModManager()->RequestUnload(); + } + } + } + + // Check for radar input + m_pRadarMap->DoPulse(); + g_pCore->GetGraphics()->SetAspectRatioAdjustmentSuspended(m_pRadarMap->IsRadarShowing()); + + // Got a local player? + if (m_pLocalPlayer) + { + // Network updates + UpdateVehicleInOut(); + UpdatePlayerTarget(); + UpdatePlayerWeapons(); + // UpdateTrailers (); // Test: Does it always work without this check? + UpdateStunts(); + // Clear last damager if more than 2 seconds old + if (CClientTime::GetTime() - m_ulDamageTime > 2000) + { + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageWeapon = 0xFF; + m_ucDamageBodyPiece = 0xFF; + } + DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); + } + + // Game hacks, restore certain variables + // game-speed changes after spawning + g_pGame->SetGameSpeed(m_fGameSpeed); + // money changes on death/getting into taxis + g_pGame->GetPlayerInfo()->SetPlayerMoney(m_lMoney); + // wanted to stop it changing on skin change etc + if (m_pLocalPlayer) + { + if (m_dwWanted != g_pGame->GetPlayerInfo()->GetWanted()->GetWantedLevel()) + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevelNoFlash(m_dwWanted); + } + // stop players dying from starvation + g_pGame->GetPlayerInfo()->SetLastTimeEaten(0); + // reset weapon logs (for preventing quickreload) + + // Update streaming + m_pManager->UpdateStreamers(); + + // Send screen shot data + ProcessDelayedSendList(); + + // Collect async task scheduler results + m_pAsyncTaskScheduler->CollectResults(); + + TIMING_CHECKPOINT("-CClientGame::DoPulses"); +} + +// Extrapolation test +void CClientGame::DoPulses2(bool bCalledFromIdle) +{ + bool bIsUsingAlternatePulseOrder = IsUsingAlternatePulseOrder(!bCalledFromIdle); + + // Figure out which pulses to do + bool bDoStandardPulses; + bool bDoVehicleManagerPulse; + + if (!bIsUsingAlternatePulseOrder) + { + // With std pulse order, do pulses when not called from idle + bDoStandardPulses = !bCalledFromIdle; + bDoVehicleManagerPulse = !bCalledFromIdle; + } + else + { + // With alt pulse order, do pulses when called from idle + bDoStandardPulses = bCalledFromIdle; + bDoVehicleManagerPulse = bCalledFromIdle; + + // Except when watching a remote synced vehicle + if (CClientVehicle* pTargetVehicle = DynamicCast(m_pCamera->GetTargetEntity())) + if (pTargetVehicle->GetControllingPlayer() != m_pPlayerManager->GetLocalPlayer()) + bDoVehicleManagerPulse = !bDoVehicleManagerPulse; + } + + if (bDoStandardPulses) + { + // Change to high precision so arguments in element data and events can + // be rounded to look more like what is expected + ChangeFloatPrecision(true); + + // Pulse the network interface + TIMING_CHECKPOINT("+NetPulse"); + g_pNet->DoPulse(); + TIMING_CHECKPOINT("-NetPulse"); + + // Change precision back, and check we are in low precision mode 4 sure + ChangeFloatPrecision(false); + assert(!IsHighFloatPrecision()); + } + + m_pManager->DoPulse(bDoStandardPulses, bDoVehicleManagerPulse); + + if (bDoStandardPulses) + { + m_pNetAPI->DoPulse(); + } +} + +void CClientGame::HandleException(CExceptionInformation* pExceptionInformation) +{ +} + +void CClientGame::HandleRadioNext(CControlFunctionBind*) +{ + if (g_pClientGame) + { + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); + if (pPlayer) + { + pPlayer->NextRadioChannel(); + } + } +} + +void CClientGame::HandleRadioPrevious(CControlFunctionBind*) +{ + if (g_pClientGame) + { + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); + if (pPlayer) + { + pPlayer->PreviousRadioChannel(); + } + } +} +bool CClientGame::IsNametagValid(const char* szNick) +{ + // Grab the size of the nametag. Check that it's not to long or short + size_t sizeNick = MbUTF8ToUTF16(szNick).size(); + if (sizeNick < MIN_PLAYER_NAMETAG_LENGTH || sizeNick > MAX_PLAYER_NAMETAG_LENGTH) + { + return false; + } + + // Check that each character is valid (Anything above 32) + unsigned char ucTemp; + for (size_t i = 0; i < sizeNick; i++) + { + ucTemp = szNick[i]; + if (ucTemp < 32) + { + return false; + } + } + + // nametag is valid, return true + return true; +} + +bool CClientGame::IsNickValid(const char* szNick) +{ + // Grab the size of the nick. Check that it's within the player + size_t sizeNick = strlen(szNick); + if (sizeNick < MIN_PLAYER_NICK_LENGTH || sizeNick > MAX_PLAYER_NICK_LENGTH) + { + return false; + } + + // Check that each character is valid (visible characters exluding space) + unsigned char ucTemp; + for (size_t i = 0; i < sizeNick; i++) + { + ucTemp = szNick[i]; + if (ucTemp < 33 || ucTemp > 126) + { + return false; + } + } + + // Nickname is valid, return true + return true; +} + +void CClientGame::ShowNetstat(int iCmd) +{ + bool bShow = (iCmd == 1) ? true : (iCmd == 0) ? false : !m_bShowNetstat; + + if (bShow && !m_bShowNetstat) + { + m_pNetworkStats->Reset(); + } + m_bShowNetstat = bShow; +} + +void CClientGame::ShowEaeg(bool) +{ + if (m_pLocalPlayer) + m_pLocalPlayer->SetStat(0x2329, 1.0f); +} + +#ifdef MTA_WEPSYNCDBG +void CClientGame::ShowWepdata(const char* szNick) +{ + CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); + if (pPlayer) + { + pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); + } +} +#endif + +#ifdef MTA_DEBUG + +void CClientGame::ShowWepdata(const char* szNick) +{ + CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); + if (pPlayer) + { + pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); + } +} + +void CClientGame::ShowPlayer(const char* szNick) +{ + m_pShowPlayer = m_pPlayerManager->Get(szNick); +} + +void CClientGame::ShowTasks(const char* szNick) +{ + m_pShowPlayerTasks = m_pPlayerManager->Get(szNick); +} + +void CClientGame::SetMimic(unsigned int uiMimicCount) +{ + // Check if we're within the max mimics boundary + if (uiMimicCount > MAX_MIMICS) + return; + + // Create neccessary players + while (m_Mimics.size() < uiMimicCount) + { + CClientPlayer* pPlayer = new CClientPlayer(m_pManager, static_cast(MAX_NET_PLAYERS_REAL + (int)m_Mimics.size())); + pPlayer->SetNick("Mimic"); + m_Mimics.push_back(pPlayer); + } + + // Destroy neccessary players + while (m_Mimics.size() > uiMimicCount) + { + CClientPlayer* pPlayer = m_Mimics.back(); + CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); + if (pVehicle) + delete pVehicle; + + delete pPlayer; + m_Mimics.pop_back(); + } +} + +#endif + +void CClientGame::DoVehicleInKeyCheck(void) +{ + // Grab the controller state + CControllerState cs; + g_pGame->GetPad()->GetCurrentControllerState(&cs); + static bool bButtonTriangleWasDown = false; + if (cs.ButtonTriangle) + { + if (!bButtonTriangleWasDown) + { + bButtonTriangleWasDown = true; + + // Process the hit + ProcessVehicleInOutKey(false); + } + } + else + { + bButtonTriangleWasDown = false; + } +} + +void CClientGame::UpdateVehicleInOut(void) +{ + // We got told by the server to animate into a certain vehicle? + if (m_VehicleInOutID != INVALID_ELEMENT_ID) + { + // Grab the vehicle we're getting in/out of + CDeathmatchVehicle* pInOutVehicle = static_cast(m_pVehicleManager->Get(m_VehicleInOutID)); + + // In or out? + if (m_bIsGettingOutOfVehicle) + { + // If we aren't working on leaving the car (he's eiter finished or cancelled/failed leaving) + if (!m_pLocalPlayer->IsLeavingVehicle()) + { + // Are we outside the car? + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + if (!pVehicle) + { + // Tell the server that we successfully left the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction = VEHICLE_NOTIFY_OUT; + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself out (so we're sure the records are correct) + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it, and damagable if we're syncing it + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + }*/ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + + // Reset the vehicle in out stuff so we're ready for another car entry/leave. + // Don't allow a new entry/leave until we've gotten the notify return packet + ElementID ReasonVehicleID = m_VehicleInOutID; + g_pClientGame->ResetVehicleInOut(); + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = ReasonVehicleID; + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_out"); +#endif + } + // Are we still inside the car? + else + { + // Warp us out now to keep in sync with the server + m_pLocalPlayer->RemoveFromVehicle(); + } + } + } + + // Are we getting into a vehicle? + else if (m_bIsGettingIntoVehicle) + { + // If we aren't working on entering the car (he's either finished or cancelled) + if (!m_pLocalPlayer->IsEnteringVehicle()) + { + // Is he in a vehicle now? + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + if (pVehicle) + { + // Tell the server that we successfully entered the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction; + + if (m_bIsJackingVehicle) + { + ucAction = static_cast(VEHICLE_NOTIFY_JACK); +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack"); +#endif + } + else + { + ucAction = static_cast(VEHICLE_NOTIFY_IN); +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in"); +#endif + } + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself in (so we're sure the records are correct) + pVehicle->AllowDoorRatioSetting(m_pLocalPlayer->m_ucEnteringDoor, true); + m_pLocalPlayer->WarpIntoVehicle(pVehicle, m_ucVehicleInOutSeat); + + /* + // Make it damagable + if ( pInOutVehicle ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + */ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + } + else + { + // Tell the server that we aborted entered the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction; + if (m_bIsJackingVehicle) + { + ucAction = static_cast(VEHICLE_NOTIFY_JACK_ABORT); + pBitStream->WriteBits(&ucAction, 4); + + // Did we start jacking them? + bool bAlreadyStartedJacking = false; + CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); + if (pVehicle) + { + CClientPed* pJackedPlayer = pVehicle->GetOccupant(); + if (pJackedPlayer) + { + // Jax: have we already started to jack the other player? + if (pJackedPlayer->IsGettingJacked()) + { + bAlreadyStartedJacking = true; + } + } + unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; + pBitStream->WriteBits(&ucDoor, 3); + SDoorOpenRatioSync door; + door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); + pBitStream->Write(&door); + } + pBitStream->WriteBit(bAlreadyStartedJacking); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack_abort"); +#endif + } + else + { + ucAction = static_cast(VEHICLE_NOTIFY_IN_ABORT); + pBitStream->WriteBits(&ucAction, 4); + CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); + if (pVehicle) + { + unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; + pBitStream->WriteBits(&ucDoor, 3); + SDoorOpenRatioSync door; + door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); + pBitStream->Write(&door); + } + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in_abort"); +#endif + } + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself out again (so we're sure the records are correct) + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it, and damagable if we're syncing it + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + } + */ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + } + + // Reset + // Don't allow a new entry/leave until we've gotten the notify return packet + ElementID ReasonID = m_VehicleInOutID; + ResetVehicleInOut(); + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = ReasonID; + } + } + } + else + { + // If we aren't getting jacked + if (!m_bIsGettingJacked) + { + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + + // Jax: this was commented, re-comment if it was there for a reason (..and give the reason!) + // Are we in a vehicle we aren't supposed to be in? + if (pVehicle && !pOccupiedVehicle) + { + g_pCore->GetConsole()->Print("You shouldn't be in this vehicle"); + m_pLocalPlayer->RemoveFromVehicle(); + } + + // Are we supposed to be in a vehicle? But aren't? + if (pOccupiedVehicle && !pVehicle) + { + // Jax: this happens when we try to warp into a streamed out vehicle, including when we use CClientVehicle::StreamInNow + // ..maybe we need a different way to detect bike falls? + + // Tell the server + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Vehicle id + pBitStream->Write(pOccupiedVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_NOTIFY_FELL_OFF); + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're not allowed to enter any vehicle before we get a confirm + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = pOccupiedVehicle->GetID(); + + // Remove him from the vehicle + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it + CDeathmatchVehicle* pInOutVehicle = static_cast < CDeathmatchVehicle* > ( pOccupiedVehicle ); + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + } + */ + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_fell_off"); +#endif + } + } + } + } +} + +void CClientGame::UpdatePlayerTarget(void) +{ + CControllerState ControllerState; + m_pLocalPlayer->GetControllerState(ControllerState); + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + + // Ignore the local player so we don't get hit + m_pLocalPlayer->WorldIgnore(true); + + // Run a process line of sight and look for an entity we target + CEntity* pColEntity = NULL; + CColPoint* pColPoint = NULL; + g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pColEntity); + + // Unignore the local player again + m_pLocalPlayer->WorldIgnore(false); + + // Kill the colpoint or we get a severe memoryleak + if (pColPoint) + pColPoint->Destroy(); + + if (pColEntity != m_pTargetedGameEntity) + { + m_pTargetedGameEntity = pColEntity; + + if (pColEntity) + { + m_pTargetedEntity = m_pManager->FindEntity(pColEntity); + } + else + m_pTargetedEntity = NULL; + + // Store the last targeted player's id + if (m_pTargetedEntity && m_pTargetedEntity->GetType() == CCLIENTPLAYER) + { + m_TargetedPlayerID = m_pTargetedEntity->GetID(); + } + else + m_TargetedPlayerID = INVALID_ELEMENT_ID; + + // Send the target + ElementID TargetID = INVALID_ELEMENT_ID; + if (m_pTargetedEntity && !m_pTargetedEntity->IsLocalEntity()) + { + TargetID = m_pTargetedEntity->GetID(); + } + + CBitStream bitStream; + bitStream.pBitStream->Write(TargetID); + m_pNetAPI->RPC(PLAYER_TARGET, bitStream.pBitStream); + + // Call our onClientPlayerTarget event + CLuaArguments Arguments; + if (m_pTargetedEntity) + Arguments.PushElement(m_pTargetedEntity); + else + Arguments.PushBoolean(false); + m_pLocalPlayer->CallEvent("onClientPlayerTarget", Arguments, true); + } +} + +void CClientGame::UpdatePlayerWeapons(void) +{ + // Check whether we changed weapon slots + eWeaponSlot currentSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + if (currentSlot != m_lastWeaponSlot) + { + CLuaArguments Arguments; + Arguments.PushNumber(m_lastWeaponSlot); + Arguments.PushNumber(currentSlot); + bool bCancelled = !m_pLocalPlayer->CallEvent("onClientPlayerWeaponSwitch", Arguments, true); + + if (bCancelled) + { + // Save the current ammo in clip + unsigned short usAmmoInClip = 0; + CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); + if (pWeapon) + usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); + + // Force it back to the old slot + m_pLocalPlayer->SetCurrentWeaponSlot(m_lastWeaponSlot); + + // Restore the ammo in clip that there was in that slot + if (usAmmoInClip > 0) + m_pLocalPlayer->GetWeapon()->SetAmmoInClip(usAmmoInClip); + } + else + { + CBitStream bitStream; + CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(); + NetBitStreamInterface& BitStream = *(bitStream.pBitStream); + SWeaponSlotSync slot; + + // Always send bit in case server is not in sync + if ((BitStream.Version() >= 0x44 && m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN) || BitStream.Version() >= 0x4D) + { + CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); + if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && + (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || + (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) + BitStream.WriteBit(true); + else + BitStream.WriteBit(false); + } + + if (pWeapon) + { + /* Send a packet to the server with info about the new weapon, + so the server stays in sync reliably */ + unsigned int uiSlot = static_cast(pWeapon->GetSlot()); + slot.data.uiSlot = uiSlot; + BitStream.Write(&slot); + + if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) + { + SWeaponAmmoSync ammo(pWeapon->GetType(), true, true); + ammo.data.usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); + ammo.data.usTotalAmmo = static_cast(pWeapon->GetAmmoTotal()); + BitStream.Write(&ammo); + } + } + else + { + slot.data.uiSlot = 0; + BitStream.Write(&slot); + } + + m_pNetAPI->RPC(PLAYER_WEAPON, bitStream.pBitStream); + m_lastWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + } + } +} + +void CClientGame::UpdateTrailers(void) +{ + // This function is here to re-attach trailers if they fall off + + unsigned long ulCurrentTime = GetTickCount32(); + + CClientVehicle * pVehicle = NULL, *pTrailer = NULL; + CVehicle * pGameVehicle = NULL, *pGameTrailer = NULL; + unsigned long ulIllegalTowBreakTime; + vector::const_iterator iterVehicles = m_pVehicleManager->StreamedBegin(); + for (; iterVehicles != m_pVehicleManager->StreamedEnd(); iterVehicles++) + { + pVehicle = *iterVehicles; + ulIllegalTowBreakTime = pVehicle->GetIllegalTowBreakTime(); + + // Do we have an illegal break? + if (ulIllegalTowBreakTime != 0) + { + // Has it been atleast 1 second since the break + if (ulCurrentTime > (ulIllegalTowBreakTime + 1000)) + { + // Try to re-attach them + CClientVehicle* pTowedBy = pVehicle->GetTowedByVehicle(); + if (pTowedBy) + { + // Little hack to keep illegaly detached trailers close to their tower + CVector vecPosition; + pVehicle->GetPosition(vecPosition); + pVehicle->SetPosition(vecPosition); + + pGameVehicle = pTowedBy->GetGameVehicle(); + pGameTrailer = pVehicle->GetGameVehicle(); + if (pGameVehicle && pGameTrailer) + { + // pGameTrailer->SetTowLink ( pGameVehicle ); + CVector vecRotation; + pTowedBy->GetRotationRadians(vecRotation); + pVehicle->SetRotationRadians(vecRotation); + pTowedBy->InternalSetTowLink(pVehicle); + } + } + + // Reset the break time, even if we couldnt re-attach it + pVehicle->SetIllegalTowBreakTime(0); + } + } + } +} + +void CClientGame::UpdateFireKey(void) +{ + if (m_pLocalPlayer) + { + SBindableGTAControl* pControl = g_pCore->GetKeyBinds()->GetBindableFromControl("fire"); + + // Is our 'fire' control enabled? + if (pControl->bEnabled) + { + // ** Satchel charge detonation ** + { + // Do we have a detonator in our hand? + if (m_pLocalPlayer->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_DETONATOR) + { + // Planted any satchels? + if (m_pLocalPlayer->CountProjectiles(WEAPONTYPE_REMOTE_SATCHEL_CHARGE) > 0) + { + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + + // Tell the server we want to detonate our satchels + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + g_pNet->SendPacket(PACKET_ID_DETONATE_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } + // Remove the detonator if we dont have any satchels planted + else + { + m_pLocalPlayer->RemoveWeapon(WEAPONTYPE_DETONATOR); + } + } + } + + // Has our control state been cut short? + if (!pControl->bState) + return; + + // ** Stealth kill ** + { + if (m_pLocalPlayer->IsStealthAiming()) + { + // Do we have a target ped? + CClientPed* pTargetPed = m_pLocalPlayer->GetTargetedPed(); + if (pTargetPed) + { + // Do we have a target player? + if (IS_PLAYER(pTargetPed)) + { + CClientPlayer* pTargetPlayer = static_cast(pTargetPed); + + // Is the targetted player on a team + CClientTeam* pTeam = pTargetPlayer->GetTeam(); + if (pTeam) + { + // Is this friendly-fire? + if (pTargetPlayer->IsOnMyTeam(m_pLocalPlayer) && !pTeam->GetFriendlyFire()) + { + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + return; + } + } + } + CPlayerPed* pGameTarget = static_cast(pTargetPed)->GetGamePlayer(); + if (pGameTarget) + { + // Would GTA let us stealth kill now? + if (m_pLocalPlayer->GetGamePlayer()->GetPedIntelligence()->TestForStealthKill(pGameTarget, false)) + { + // Grab our local position + CVector vecLocalPosition; + m_pLocalPlayer->GetPosition(vecLocalPosition); + + // Grab the target's position + CVector vecTargetPosition; + pTargetPed->GetPosition(vecTargetPosition); + + // Work out an angle between the players, and set this as we initiate our knife kill + float fAngle = AngleBetweenPoints2D(vecLocalPosition, vecTargetPosition); + m_pLocalPlayer->SetCurrentRotation(fAngle); + + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + CLuaArguments Arguments; + Arguments.PushElement(pTargetPed); + if (m_pLocalPlayer->CallEvent("onClientPlayerStealthKill", Arguments, false)) + { + if (pTargetPed->IsLocalEntity()) + { + CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, 4 /*WEAPONTYPE_KNIFE*/, 9 /*BODYPART_HEAD*/, true); + return; + } + + // Lets request a stealth kill + CBitStream bitStream; + bitStream.pBitStream->Write(pTargetPed->GetID()); + m_pNetAPI->RPC(REQUEST_STEALTH_KILL, bitStream.pBitStream); + } + else + { + return; + } + } + } + } + } + } + } + } +} + +void CClientGame::UpdateStunts(void) +{ + // * Two wheeler * + static unsigned long ulLastCarTwoWheelCounter = 0; + static float fLastCarTwoWheelDist = 0.0f; + unsigned long ulTemp = g_pGame->GetPlayerInfo()->GetCarTwoWheelCounter(); + // Did we start a stunt? + if (ulLastCarTwoWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("2wheeler"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastCarTwoWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("2wheeler"); + Arguments.PushNumber(ulLastCarTwoWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastCarTwoWheelCounter = ulTemp; + fLastCarTwoWheelDist = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); + + // * Wheelie * + static unsigned long ulLastBikeRearWheelCounter = 0; + static float fLastBikeRearWheelDist = 0.0f; + ulTemp = g_pGame->GetPlayerInfo()->GetBikeRearWheelCounter(); + // Did we start a stunt? + if (ulLastBikeRearWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("wheelie"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastBikeRearWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("wheelie"); + Arguments.PushNumber(ulLastBikeRearWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastBikeRearWheelCounter = ulTemp; + fLastBikeRearWheelDist = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); + + // * Stoppie * + static unsigned long ulLastBikeFrontWheelCounter = 0; + static float fLastBikeFrontWheelDist = 0.0f; + ulTemp = g_pGame->GetPlayerInfo()->GetBikeFrontWheelCounter(); + // Did we start a stunt? + if (ulLastBikeFrontWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("stoppie"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastBikeFrontWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("stoppie"); + Arguments.PushNumber(ulLastBikeFrontWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastBikeFrontWheelCounter = ulTemp; + fLastBikeFrontWheelDist = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); +} + +void CClientGame::StaticUpdateFireKey(CControlFunctionBind* pBind) +{ + g_pClientGame->UpdateFireKey(); +} + +void CClientGame::ChangeVehicleWeapon(bool bNext) +{ + if (m_pLocalPlayer && m_pLocalPlayer->GetRealOccupiedVehicle()) + { + eWeaponSlot currentWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + eWeaponSlot weaponSlot = currentWeaponSlot; + CWeapon* pWeapon = NULL; + while (!pWeapon || pWeapon->GetType() == WEAPONTYPE_UNARMED) + { + if (bNext) + { + if (weaponSlot == WEAPONSLOT_TYPE_DETONATOR) + { + weaponSlot = WEAPONSLOT_TYPE_UNARMED; + break; + } + + weaponSlot = (eWeaponSlot)(weaponSlot + 1); + + if (weaponSlot == currentWeaponSlot) + break; + + pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); + } + else + { + if (weaponSlot == WEAPONSLOT_TYPE_UNARMED) + { + if (weaponSlot != currentWeaponSlot) + break; + weaponSlot = WEAPONSLOT_TYPE_DETONATOR; + } + + weaponSlot = (eWeaponSlot)(weaponSlot - 1); + + if (weaponSlot == currentWeaponSlot) + break; + + pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); + } + } + if (pWeapon || weaponSlot == WEAPONSLOT_TYPE_UNARMED) + { + m_pLocalPlayer->SetCurrentWeaponSlot(weaponSlot); + } + } +} + +void CClientGame::ResetVehicleInOut(void) +{ + m_ulLastVehicleInOutTime = 0; + m_bIsGettingOutOfVehicle = false; + m_bIsGettingIntoVehicle = false; + m_bIsJackingVehicle = false; + m_bIsGettingJacked = false; + m_VehicleInOutID = INVALID_ELEMENT_ID; + m_ucVehicleInOutSeat = 0xFF; + m_bNoNewVehicleTask = false; + m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; + m_pGettingJackedBy = NULL; +} + +void CClientGame::SetAllDimensions(unsigned short usDimension) +{ + m_pManager->GetMarkerStreamer()->SetDimension(usDimension); + m_pManager->GetObjectStreamer()->SetDimension(usDimension); + m_pManager->GetObjectLodStreamer()->SetDimension(usDimension); + m_pManager->GetPickupStreamer()->SetDimension(usDimension); + m_pManager->GetPlayerStreamer()->SetDimension(usDimension); + m_pManager->GetRadarAreaManager()->SetDimension(usDimension); + m_pManager->GetVehicleStreamer()->SetDimension(usDimension); + m_pManager->GetRadarMarkerManager()->SetDimension(usDimension); + m_pManager->GetSoundManager()->SetDimension(usDimension); + m_pManager->GetPointLightsManager()->SetDimension(usDimension); + m_pManager->GetWaterManager()->SetDimension(usDimension); + m_pNametags->SetDimension(usDimension); + m_pCamera->SetDimension(usDimension); +} + +bool CClientGame::StaticKeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) +{ + return g_pClientGame->KeyStrokeHandler(strKey, bState, bIsConsoleInputKey); +} + +bool CClientGame::KeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) +{ + // Do we have a root yet? + if (m_pRootEntity) + { + // Ignore keydown/up pair if main menu is displayed, or console input will use the character + bool bIgnore = false; + if (bState) + { + auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; + bool isMouseKey = strKey.substr(0, 5) == "mouse"; + + if (g_pCore->IsMenuVisible() || (g_pCore->GetConsole()->IsInputActive() && bIsConsoleInputKey) || + (pFocusedBrowser && !pFocusedBrowser->IsLocal() && !isMouseKey)) + + bIgnore = true; // Ignore this keydown and the matching keyup + else + MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup + } + else + { + if (!MapContains(m_AllowKeyUpMap, strKey)) + bIgnore = true; // Ignore this keyup + else + MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup + } + + if (!bIgnore) + { + bool bAllow = true; + // Call our key-stroke event + CLuaArguments Arguments; + Arguments.PushString(strKey); + Arguments.PushBoolean(bState); + bAllow = m_pRootEntity->CallEvent("onClientKey", Arguments, false); + if (bState == true) + { + if (bAllow == false && strKey == "escape") + { + if (m_bLastKeyWasEscapeCancelled) + { + // Escape cannot be skipped twice + bAllow = true; + m_bLastKeyWasEscapeCancelled = false; + } + else + m_bLastKeyWasEscapeCancelled = true; + } + else + m_bLastKeyWasEscapeCancelled = false; + } + return bAllow; + } + } + m_bLastKeyWasEscapeCancelled = false; + return true; +} + +bool CClientGame::StaticCharacterKeyHandler(WPARAM wChar) +{ + return g_pClientGame->CharacterKeyHandler(wChar); +} + +bool CClientGame::CharacterKeyHandler(WPARAM wChar) +{ + // Do we have a root yet? + if (m_pRootEntity && g_pCore->IsMenuVisible() == false && g_pCore->GetConsole()->IsInputActive() == false) + { + // Cancel event if remote browser is focused + auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; + if (pFocusedBrowser && !pFocusedBrowser->IsLocal()) + return false; + + // Safe character? + if (wChar >= 32) + { + // Generate a null-terminating string for our character + wchar_t wUNICODE[2] = {wChar, '\0'}; + + // Convert our UTF character into an ANSI string + SString strANSI = UTF16ToMbUTF8(wUNICODE); + + // Call our character event + CLuaArguments Arguments; + Arguments.PushString(strANSI); + m_pRootEntity->CallEvent("onClientCharacter", Arguments, false); + } + } + + return false; +} + +void CClientGame::StaticProcessClientKeyBind(CKeyFunctionBind* pBind) +{ + g_pClientGame->ProcessClientKeyBind(pBind); +} + +void CClientGame::ProcessClientKeyBind(CKeyFunctionBind* pBind) +{ + m_pScriptKeyBinds->ProcessKey(pBind->boundKey->szKey, pBind->bHitState, SCRIPT_KEY_BIND_FUNCTION); +} + +void CClientGame::StaticProcessClientControlBind(CControlFunctionBind* pBind) +{ + g_pClientGame->ProcessClientControlBind(pBind); +} + +void CClientGame::ProcessClientControlBind(CControlFunctionBind* pBind) +{ + m_pScriptKeyBinds->ProcessKey(pBind->control->szControl, pBind->bHitState, SCRIPT_KEY_BIND_CONTROL_FUNCTION); +} + +void CClientGame::StaticProcessServerKeyBind(CKeyFunctionBind* pBind) +{ + g_pClientGame->ProcessServerKeyBind(pBind); +} + +void CClientGame::ProcessServerKeyBind(CKeyFunctionBind* pBind) +{ + const char* szName = pBind->boundKey->szKey; + unsigned char ucNameLength = (unsigned char)strlen(szName); + CBitStream bitStream; + bitStream.pBitStream->WriteBit(false); + bitStream.pBitStream->WriteBit(pBind->bHitState); + bitStream.pBitStream->Write(szName, ucNameLength); + m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); +} + +void CClientGame::StaticProcessServerControlBind(CControlFunctionBind* pBind) +{ + g_pClientGame->ProcessServerControlBind(pBind); +} + +void CClientGame::ProcessServerControlBind(CControlFunctionBind* pBind) +{ + const char* szName = pBind->control->szControl; + unsigned char ucNameLength = (unsigned char)strlen(szName); + CBitStream bitStream; + bitStream.pBitStream->WriteBit(true); + bitStream.pBitStream->WriteBit(pBind->bHitState); + bitStream.pBitStream->Write(szName, ucNameLength); + m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); +} + +bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + bool bCursorForcedVisible = g_pCore->IsCursorForcedVisible(); + bool bMenuVisible = g_pCore->IsMenuVisible(); + bool bConsoleVisible = g_pCore->GetConsole()->IsVisible(); + + if (bCursorForcedVisible) + { + if (!bMenuVisible && !bConsoleVisible) + { + if (m_bCursorEventsEnabled) + { + unsigned char ucButtonHit = 0xFF; + switch (uMsg) + { + case WM_LBUTTONDOWN: + ucButtonHit = 0; + break; + case WM_LBUTTONUP: + ucButtonHit = 1; + break; + case WM_MBUTTONDOWN: + ucButtonHit = 2; + break; + case WM_MBUTTONUP: + ucButtonHit = 3; + break; + case WM_RBUTTONDOWN: + ucButtonHit = 4; + break; + case WM_RBUTTONUP: + ucButtonHit = 5; + break; + } + if (ucButtonHit != 0xFF) + { + int iX = LOWORD(lParam); + int iY = HIWORD(lParam); + + CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); + + /* + // (IJs) why are these relative? it doesn't make sense + CVector2D vecCursorPosition ( ( ( float ) iX ) / vecResolution.fX, + ( ( float ) iY ) / vecResolution.fY ); + */ + + CVector2D vecCursorPosition((float)iX, (float)iY); + + CVector vecOrigin, vecTarget, vecScreen((float)iX, (float)iY, 300.0f); + g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); + + // Grab the camera position + CCamera* pCamera = g_pGame->GetCamera(); + CCam* pCam = pCamera->GetCam(pCamera->GetActiveCam()); + CMatrix matCamera; + pCamera->GetMatrix(&matCamera); + vecOrigin = matCamera.vPos; + + CColPoint* pColPoint = NULL; + CEntity* pGameEntity = NULL; + + // Grab the collision point/entity + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pGameEntity); + + CVector vecCollision; + ElementID CollisionEntityID = INVALID_ELEMENT_ID; + CClientEntity* pCollisionEntity = NULL; + if (bCollision && pColPoint) + { + vecCollision = pColPoint->GetPosition(); + if (pGameEntity) + { + CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity); + if (pEntity) + { + pCollisionEntity = pEntity; + if (!pEntity->IsLocalEntity()) + CollisionEntityID = pEntity->GetID(); + } + } + } + else + { + vecCollision = vecTarget; + } + + // Destroy the colpoint so we don't get a leak + if (pColPoint) + { + pColPoint->Destroy(); + } + + const char* szButton = NULL; + const char* szState = NULL; + switch (ucButtonHit) + { + case 0: + szButton = "left"; + szState = "down"; + break; + case 1: + szButton = "left"; + szState = "up"; + break; + case 2: + szButton = "middle"; + szState = "down"; + break; + case 3: + szButton = "middle"; + szState = "up"; + break; + case 4: + szButton = "right"; + szState = "down"; + break; + case 5: + szButton = "right"; + szState = "up"; + break; + } + if (szButton && szState) + { + if (std::isnan(vecCollision.fX)) + vecCollision.fX = 0; + if (std::isnan(vecCollision.fY)) + vecCollision.fY = 0; + if (std::isnan(vecCollision.fZ)) + vecCollision.fZ = 0; + + // Call the event for the client + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(vecCursorPosition.fX); + Arguments.PushNumber(vecCursorPosition.fY); + Arguments.PushNumber(vecCollision.fX); + Arguments.PushNumber(vecCollision.fY); + Arguments.PushNumber(vecCollision.fZ); + if (pCollisionEntity) + Arguments.PushElement(pCollisionEntity); + else + Arguments.PushBoolean(false); + m_pRootEntity->CallEvent("onClientClick", Arguments, false); + + // Send the button, cursor position, 3d position and the entity collided with + CBitStream bitStream; + + SMouseButtonSync button; + button.data.ucButton = ucButtonHit; + bitStream.pBitStream->Write(&button); + + bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fX)); + bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fY)); + + SPositionSync position(false); + position.data.vecPosition = vecCollision; + bitStream.pBitStream->Write(&position); + + if (CollisionEntityID != INVALID_ELEMENT_ID) + { + bitStream.pBitStream->WriteBit(true); + bitStream.pBitStream->Write(CollisionEntityID); + } + else + bitStream.pBitStream->WriteBit(false); + + m_pNetAPI->RPC(CURSOR_EVENT, bitStream.pBitStream); + + if (strcmp(szState, "down") == 0) + { + CVector2D vecDelta = m_vecLastCursorPosition - vecCursorPosition; + + if ((GetTickCount32() - m_ulLastClickTick) < DOUBLECLICK_TIMEOUT && vecDelta.Length() <= DOUBLECLICK_MOVE_THRESHOLD) + { + // Call the event for the client + CLuaArguments DoubleClickArguments; + DoubleClickArguments.PushString(szButton); + DoubleClickArguments.PushNumber(vecCursorPosition.fX); + DoubleClickArguments.PushNumber(vecCursorPosition.fY); + DoubleClickArguments.PushNumber(vecCollision.fX); + DoubleClickArguments.PushNumber(vecCollision.fY); + DoubleClickArguments.PushNumber(vecCollision.fZ); + if (pCollisionEntity) + DoubleClickArguments.PushElement(pCollisionEntity); + else + DoubleClickArguments.PushBoolean(false); + m_pRootEntity->CallEvent("onClientDoubleClick", DoubleClickArguments, false); + } + + m_ulLastClickTick = GetTickCount32(); + m_vecLastCursorPosition = vecCursorPosition; + } + + return true; + } + } + } + } + } + switch (uMsg) + { + case WM_MOUSEMOVE: + { + int iX = LOWORD(lParam), iY = HIWORD(lParam); + static int iPreviousX = 0, iPreviousY = 0; + if (iX != iPreviousX || iY != iPreviousY) + { + iPreviousX = iX, iPreviousY = iY; + + CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); + CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); + + CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); + g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); + + // Call the onClientCursorMove event + CLuaArguments Arguments; + Arguments.PushNumber((double)vecCursorPosition.fX); + Arguments.PushNumber((double)vecCursorPosition.fY); + Arguments.PushNumber((double)iX); + Arguments.PushNumber((double)iY); + Arguments.PushNumber((double)vecTarget.fX); + Arguments.PushNumber((double)vecTarget.fY); + Arguments.PushNumber((double)vecTarget.fZ); + m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); + } + break; + } + } + return false; +} + +CClientPlayer* CClientGame::GetClosestRemotePlayer(const CVector& vecPosition, float fMaxDistance) +{ + CClientPlayer* pClosest = NULL; + float fDistance = 0.0f, fTemp; + CVector vecTemp; + CClientPlayer* pPlayer; + vector::const_iterator iter = m_pPlayerManager->IterBegin(); + for (; iter != m_pPlayerManager->IterEnd(); ++iter) + { + pPlayer = *iter; + if (!pPlayer->IsLocalPlayer() && !pPlayer->IsDeadOnNetwork() && pPlayer->GetHealth() > 0) + { + // Ensure remote player is alive and sending position updates + ulong ulTimeSinceLastPuresync = CClientTime::GetTime() - pPlayer->GetLastPuresyncTime(); + if (ulTimeSinceLastPuresync < static_cast(g_TickRateSettings.iPureSync) * 2) + { + pPlayer->GetPosition(vecTemp); + fTemp = DistanceBetweenPoints3D(vecPosition, vecTemp); + if (fTemp < fMaxDistance) + { + if (!pClosest || fTemp < fDistance) + { + pClosest = pPlayer; + fDistance = fTemp; + } + } + } + } + } + return pClosest; +} + +void CClientGame::SetGameSpeed(float fSpeed) +{ + g_pGame->SetGameSpeed(fSpeed); + m_fGameSpeed = fSpeed; +} + +void CClientGame::SetMinuteDuration(unsigned long ulDelay) +{ + g_pGame->SetMinuteDuration(ulDelay); + m_ulMinuteDuration = ulDelay; +} + +void CClientGame::SetMoney(long lMoney, bool bInstant) +{ + g_pGame->GetPlayerInfo()->SetPlayerMoney(lMoney, bInstant); + m_lMoney = lMoney; +} + +void CClientGame::SetWanted(DWORD dwWanted) +{ + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(dwWanted); + m_dwWanted = dwWanted; +} + +void CClientGame::AddBuiltInEvents(void) +{ + // Resource events + m_Events.AddEvent("onClientResourceStart", "resource", NULL, false); + m_Events.AddEvent("onClientResourceStop", "resource", NULL, false); + + // Element events + m_Events.AddEvent("onClientElementDataChange", "name", NULL, false); + m_Events.AddEvent("onClientElementStreamIn", "", NULL, false); + m_Events.AddEvent("onClientElementStreamOut", "", NULL, false); + m_Events.AddEvent("onClientElementDestroy", "", NULL, false); + + // Player events + m_Events.AddEvent("onClientPlayerJoin", "", NULL, false); + m_Events.AddEvent("onClientPlayerQuit", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerTarget", "target", NULL, false); + m_Events.AddEvent("onClientPlayerSpawn", "team", NULL, false); + m_Events.AddEvent("onClientPlayerChangeNick", "oldNick", NULL, false); + m_Events.AddEvent("onClientPlayerVehicleEnter", "vehicle, seat", NULL, false); + m_Events.AddEvent("onClientPlayerVehicleExit", "vehicle, seat", NULL, false); + m_Events.AddEvent("onClientPlayerTask", "priority, slot, name", NULL, false); + m_Events.AddEvent("onClientPlayerWeaponSwitch", "previous, current", NULL, false); + m_Events.AddEvent("onClientPlayerStuntStart", "type", NULL, false); + m_Events.AddEvent("onClientPlayerStuntFinish", "type, time, distance", NULL, false); + m_Events.AddEvent("onClientPlayerRadioSwitch", "", NULL, false); + m_Events.AddEvent("onClientPlayerDamage", "attacker, weapon, bodypart", NULL, false); + m_Events.AddEvent("onClientPlayerWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPlayerWasted", "", NULL, false); + m_Events.AddEvent("onClientPlayerChoke", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceStart", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceStop", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoicePause", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceResumed", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerStealthKill", "target", NULL, false); + m_Events.AddEvent("onClientPlayerHitByWaterCannon", "vehicle", NULL, false); + m_Events.AddEvent("onClientPlayerHeliKilled", "heli", NULL, false); + m_Events.AddEvent("onClientPlayerPickupHit", "pickup, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPlayerPickupLeave", "pickup, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPlayerNetworkStatus", "type, ticks", NULL, false); + + // Ped events + m_Events.AddEvent("onClientPedDamage", "attacker, weapon, bodypart", NULL, false); + m_Events.AddEvent("onClientPedWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPedWasted", "", NULL, false); + m_Events.AddEvent("onClientPedChoke", "", NULL, false); + m_Events.AddEvent("onClientPedHeliKilled", "heli", NULL, false); + m_Events.AddEvent("onClientPedHitByWaterCannon", "vehicle", NULL, false); + + // Vehicle events + m_Events.AddEvent("onClientVehicleRespawn", "", NULL, false); + m_Events.AddEvent("onClientVehicleEnter", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleExit", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleStartEnter", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleStartExit", "player, seat", NULL, false); + m_Events.AddEvent("onClientTrailerAttach", "towedBy", NULL, false); + m_Events.AddEvent("onClientTrailerDetach", "towedBy", NULL, false); + m_Events.AddEvent("onClientVehicleExplode", "", NULL, false); + m_Events.AddEvent("onClientVehicleCollision", "collidedelement, damageImpulseMag, bodypart, x, y, z, velX, velY, velZ", NULL, false); + m_Events.AddEvent("onClientVehicleDamage", "attacker, weapon, loss, x, y, z, tyre", NULL, false); + m_Events.AddEvent("onClientVehicleNitroStateChange", "activated", NULL, false); + + // GUI events + m_Events.AddEvent("onClientGUIClick", "button, state, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIDoubleClick", "button, state, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIMouseDown", "button, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIMouseUp", "button, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIScroll", "element", NULL, false); + m_Events.AddEvent("onClientGUIChanged", "element", NULL, false); + m_Events.AddEvent("onClientGUIAccepted", "element", NULL, false); + // m_Events.AddEvent ( "onClientGUIClose", "element", NULL, false ); + // m_Events.AddEvent ( "onClientGUIKeyDown", "element", NULL, false ); + m_Events.AddEvent("onClientGUITabSwitched", "element", NULL, false); + m_Events.AddEvent("onClientGUIComboBoxAccepted", "element", NULL, false); + + // Input events + m_Events.AddEvent("onClientDoubleClick", "button, screenX, screenY, worldX, worldY, worldZ, element", NULL, false); + m_Events.AddEvent("onClientMouseMove", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseEnter", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseLeave", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseWheel", "", NULL, false); + m_Events.AddEvent("onClientGUIMove", "", NULL, false); + m_Events.AddEvent("onClientGUISize", "", NULL, false); + m_Events.AddEvent("onClientGUIFocus", "", NULL, false); + m_Events.AddEvent("onClientGUIBlur", "", NULL, false); + m_Events.AddEvent("onClientKey", "key, state", NULL, false); + m_Events.AddEvent("onClientCharacter", "character", NULL, false); + + // Console events + m_Events.AddEvent("onClientConsole", "text", NULL, false); + + // Chat events + m_Events.AddEvent("onClientChatMessage", "test, r, g, b", NULL, false); + + // Debug events + m_Events.AddEvent("onClientDebugMessage", "message, level, file, line", NULL, false); + + // Game events + m_Events.AddEvent("onClientPreRender", "", NULL, false); + m_Events.AddEvent("onClientHUDRender", "", NULL, false); + m_Events.AddEvent("onClientRender", "", NULL, false); + m_Events.AddEvent("onClientMinimize", "", NULL, false); + m_Events.AddEvent("onClientRestore", "", NULL, false); + + // Cursor events + m_Events.AddEvent("onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false); + m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); + + // Transfer box event + m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); + + // Marker events + m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); + + // Marker events + m_Events.AddEvent("onClientPickupHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPickupLeave", "entity, matchingDimension", NULL, false); + + // Col-shape events + m_Events.AddEvent("onClientColShapeHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientColShapeLeave", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientElementColShapeHit", "colShape, matchingDimension", NULL, false); + m_Events.AddEvent("onClientElementColShapeLeave", "colShape, matchingDimension", NULL, false); + + // Explosion events + m_Events.AddEvent("onClientExplosion", "x, y, z, type", NULL, false); + + // Projectile events + m_Events.AddEvent("onClientProjectileCreation", "creator", NULL, false); + + // Sound events + m_Events.AddEvent("onClientSoundStream", "success, length, streamName, error", NULL, false); + m_Events.AddEvent("onClientSoundFinishedDownload", "length", NULL, false); + m_Events.AddEvent("onClientSoundChangedMeta", "streamTitle", NULL, false); + m_Events.AddEvent("onClientSoundStarted", "reason", NULL, false); + m_Events.AddEvent("onClientSoundStopped", "reason", NULL, false); + m_Events.AddEvent("onClientSoundBeat", "time", NULL, false); + + // Object events + m_Events.AddEvent("onClientObjectDamage", "loss, attacker", NULL, false); + m_Events.AddEvent("onClientObjectBreak", "attacker", NULL, false); + + // Web events + m_Events.AddEvent("onClientBrowserWhitelistChange", "newPages", NULL, false); + m_Events.AddEvent("onClientBrowserCreated", "", NULL, false); + m_Events.AddEvent("onClientBrowserLoadingStart", "url, mainframe", NULL, false); + m_Events.AddEvent("onClientBrowserDocumentReady", "url", NULL, false); + m_Events.AddEvent("onClientBrowserLoadingFailed", "url, errorcode, errordescription", NULL, false); + m_Events.AddEvent("onClientBrowserNavigate", "url, isblocked", NULL, false); + m_Events.AddEvent("onClientBrowserPopup", "targeturl, openerurl, ispopup", NULL, false); + m_Events.AddEvent("onClientBrowserCursorChange", "cursor", NULL, false); + m_Events.AddEvent("onClientBrowserTooltip", "text", NULL, false); + m_Events.AddEvent("onClientBrowserInputFocusChanged", "gainedfocus", NULL, false); + m_Events.AddEvent("onClientBrowserResourceBlocked", "url, domain, reason", NULL, false); + + // Misc events + m_Events.AddEvent("onClientFileDownloadComplete", "fileName, success", NULL, false); + + m_Events.AddEvent("onClientWeaponFire", "ped, x, y, z", NULL, false); +} + +void CClientGame::DrawFPS(void) +{ + // Draw the background + float fResWidth = static_cast(g_pCore->GetGraphics()->GetViewportWidth()); + float fResHeight = static_cast(g_pCore->GetGraphics()->GetViewportHeight()); + g_pCore->GetGraphics()->DrawRectangle(0.75f * fResWidth, 0.22f * fResHeight, 0.25f * fResWidth, 0.04f * fResHeight, 0x78000000); + + static char x = 0; + static float fDisp = 0.0f; + if (x == 20) + { + x = 0; + fDisp = g_pGame->GetFPS(); + } + else + x++; + SString strBuffer("FrameRate: %4.2f\n", fDisp); + + // Print it + m_pDisplayManager->DrawText2D(strBuffer, CVector(0.76f, 0.23f, 0), 1.0f, 0xFFFFFFFF); +} + +#ifdef MTA_DEBUG + +void CClientGame::DrawTasks(CClientPlayer* pPlayer) +{ + CTask* pTask = NULL; + CTask* pSubTask = NULL; + + // Got a local player model + if (pPlayer) + { + CTaskManager* man = pPlayer->GetTaskManager(); + if (man == NULL) + return; + if ((unsigned long)man == 0xDDDDDDDD) + { + m_pDisplayManager->DrawText2D("HELP! MANAGER FUCKED", CVector(0.05f, 0.5f, 0), 1.0f); + return; + } + + // Grab the current task + SString strOutput; + SString strSubOutput; + + pTask = man->GetTask(TASK_PRIORITY_PHYSICAL_RESPONSE); + strOutput += SString("Physical Response: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_TEMP); + strOutput += SString("Event Response Temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_NONTEMP); + strOutput += SString("Event Response Non-temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_PRIMARY); + strOutput += SString("Primary: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_DEFAULT); + strOutput += SString("Default: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_ATTACK); + strOutput += SString("Secondary Attack: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_DUCK); + strOutput += SString("Secondary Duck: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_SAY); + strOutput += SString("Secondary Say: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX); + strOutput += SString("Secondary Facial Complex: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM); + strOutput += SString("Secondary Partial Anim: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_IK); + strOutput += SString("Secondary IK: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + m_pDisplayManager->DrawText2D(strOutput, CVector(0.05f, 0.5f, 0), 1.0f); + m_pDisplayManager->DrawText2D(strSubOutput, CVector(0.5f, 0.5f, 0), 1.0f); + } +} + +int iPlayerTask = 0; +void CClientGame::DrawPlayerDetails(CClientPlayer* pPlayer) +{ + // Get the info + CControllerState cs; + + pPlayer->GetControllerState(cs); + + CVector vecPosition; + pPlayer->GetPosition(vecPosition); + + float fRotation = pPlayer->GetCurrentRotation(); + float fCameraRotation = pPlayer->GetCameraRotation(); + float fHealth = pPlayer->GetHealth(); + bool bIsDucked = pPlayer->IsDucked(); + bool bWearingGoggles = pPlayer->IsWearingGoggles(); + bool bInVehicle = pPlayer->GetOccupiedVehicle() != NULL; + float fWeaponRange = 0.0f; + + unsigned char ucWeapon = 0; + unsigned char ucWeaponState = 0; + unsigned short usWeaponAmmo = 0; + CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); + if (pWeapon) + { + ucWeapon = static_cast(pWeapon->GetType()); + ucWeaponState = static_cast(pWeapon->GetState()); + usWeaponAmmo = static_cast(pWeapon->GetAmmoInClip()); + float fSkill = pPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(pWeapon->GetType())); + CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(pWeapon->GetType(), fSkill); + fWeaponRange = pWeaponInfo->GetWeaponRange(); + } + + float fAimX, fAimY; + pPlayer->GetAim(fAimX, fAimY); + const CVector& vecAimSource = pPlayer->GetAimSource(); + const CVector& vecAimTarget = pPlayer->GetAimTarget(); + unsigned char ucDrivebyAim = pPlayer->GetVehicleAimAnim(); + + g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x10DE1212, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x90DE1212, false); + + CTask* pPrimaryTask = pPlayer->GetCurrentPrimaryTask(); + int iPrimaryTask = pPrimaryTask ? pPrimaryTask->GetTaskType() : -1; + + // Copy the stuff + SString strBuffer( + "Orient:\n" + "Position: %f %f %f\n" + "Rotation/camera: %f %f\n" + "Health: %f\n" + "\n" + "Keys:\n" + "LeftShoulder1: %hi\n" + "RightShoulder1: %hi\n" + "ButtonSquare: %hi\n" + "ButtonCross: %hi\n" + "ButtonCircle: %hi\n" + "ShockButtonL: %hi\n" + "PedWalk: %hi\n" + "VehicleMouseLook: %hi\n" + "LeftStickX: %hi\n" + "LeftStickY: %hi\n" + "\n" + "Misc:\n" + "Primary task: %d\n" + "Ducked: %u\n" + "Goggles: %u\n" + "In vehicle: %u\n" + "Weapon: %u\n" + "Weapon state: %u\n" + "Weapon ammo: %u\n" + "Weapon range: %f\n" + "Aim: %f %f\n" + "Aim source: %f %f %f\n" + "Aim target: %f %f %f\n" + "Driveby aim: %u\n" + "Frozen: %u\n", + vecPosition.fX, vecPosition.fY, vecPosition.fZ, fRotation, fCameraRotation, fHealth, cs.LeftShoulder1, cs.RightShoulder1, cs.ButtonSquare, + cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.m_bPedWalk, cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, iPrimaryTask, bIsDucked, + bWearingGoggles, bInVehicle, ucWeapon, ucWeaponState, usWeaponAmmo, fWeaponRange, fAimX, fAimY, vecAimSource.fX, vecAimSource.fY, vecAimSource.fZ, + vecAimTarget.fX, vecAimTarget.fY, vecAimTarget.fZ, ucDrivebyAim, pPlayer->IsFrozen()); + + // Draw it + m_pDisplayManager->DrawText2D(strBuffer, CVector(0.45f, 0.05f, 0), 1.0f, 0xFFFFFFFF); +} + +void CClientGame::DrawWeaponsyncData(CClientPlayer* pPlayer) +{ + CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); + + if (pWeapon) + { + CVector vecSource; + CVector vecTarget; + + // red line: Draw their synced aim line + pPlayer->GetShotData(&vecSource, &vecTarget); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x10DE1212, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x90DE1212, false); + + // green line: Set muzzle as origin and perform a collision test for the target + CColPoint* pCollision; + CVector vecTemp; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecSource, &vecTarget, &pCollision, NULL); + if (pCollision) + { + if (bCollision) + { + CVector vecBullet = pCollision->GetPosition() - vecSource; + vecBullet.Normalize(); + CVector vecTarget = vecSource + (vecBullet * 200); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x1012DE12, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x9012DE12, false); + } + pCollision->Destroy(); + } + + if (m_pLocalPlayer != pPlayer) + { + // Draw information about their weapon state, total ammo and ammo in clip + CVector vecScreenPosition; + CVector vecPosition; + + pPlayer->GetPosition(vecPosition); + + vecPosition.fZ += 1.0f; + g_pCore->GetGraphics()->CalcScreenCoors(&vecPosition, &vecScreenPosition); + + SString strTemp; + int yoffset; + + yoffset = 0; + strTemp.Format("Ammo in clip: %d", pWeapon->GetAmmoInClip()); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + + yoffset = 15; + strTemp.Format("State: %d", pWeapon->GetState()); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + } + } +} + +void CClientGame::UpdateMimics(void) +{ + // Got a local player? + if (m_pLocalPlayer) + { + unsigned char ucWeaponType = 0; + unsigned char ucWeaponState = 0; + unsigned long ulWeaponAmmoInClip = 0; + eWeaponSlot weaponSlot = WEAPONSLOT_TYPE_UNARMED; + + CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(m_pLocalPlayer->GetCurrentWeaponSlot()); + if (pPlayerWeapon) + { + ucWeaponType = static_cast(pPlayerWeapon->GetType()); + ucWeaponState = static_cast(pPlayerWeapon->GetState()); + weaponSlot = pPlayerWeapon->GetSlot(); + ulWeaponAmmoInClip = pPlayerWeapon->GetAmmoInClip(); + } + + // Simulate lag (or not) + if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) + { + m_ulLastMimicLag = CClientTime::GetTime(); + + // Grab the local data + CControllerState Controller; + m_pLocalPlayer->GetControllerState(Controller); + CVector vecPosition; + m_pLocalPlayer->GetPosition(vecPosition); + float fRotation = m_pLocalPlayer->GetCurrentRotation(); + CVector vecMoveSpeed; + m_pLocalPlayer->GetMoveSpeed(vecMoveSpeed); + float fHealth = m_pLocalPlayer->GetHealth(); + float fArmor = m_pLocalPlayer->GetArmor(); + float fCameraRotation = g_pGame->GetCamera()->GetCameraRotation(); + bool bDucked = m_pLocalPlayer->IsDucked(); + bool bWearingGoggles = m_pLocalPlayer->IsWearingGoggles(true); + bool bHasJetpack = m_pLocalPlayer->HasJetPack(); + bool bChoking = m_pLocalPlayer->IsChoking(); + bool bSunbathing = m_pLocalPlayer->IsSunbathing(); + bool bDoingDriveby = m_pLocalPlayer->IsDoingGangDriveby(); + bool bStealthAiming = m_pLocalPlayer->IsStealthAiming(); + + // Is the current weapon goggles (44 or 45) or a camera (43), or a detonator (40), don't apply the fire key + if (weaponSlot == 11 || weaponSlot == 12 || ucWeaponType == 43) + Controller.ButtonCircle = 0; + + CClientVehicle* pVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + unsigned int uiSeat = m_pLocalPlayer->GetOccupiedVehicleSeat(); + + CShotSyncData* pShotSync = g_pMultiplayer->GetLocalShotSyncData(); + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + float fAimX = pShotSync->m_fArmDirectionX; + float fAimY = pShotSync->m_fArmDirectionY; + char cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; + bool bAkimboUp = g_pMultiplayer->GetAkimboTargetUp(); + + /* + static CClientMarker *pOriginCorona = NULL, *pTargetCorona = NULL; + if ( pOriginCorona == NULL ) + { + pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); + pOriginCorona->SetColor ( 0, 255, 0, 255 ); + pOriginCorona->SetSize ( 0.5f ); + } + else + pOriginCorona->SetPosition ( vecOrigin ); + + if ( pTargetCorona == NULL ) + { + pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); + pTargetCorona->SetColor ( 255, 0, 0, 255 ); + pTargetCorona->SetSize ( 0.5f ); + } + else + pTargetCorona->SetPosition ( vecTarget );*/ + + // Apply this to each of our mimic players + unsigned int uiMimicIndex = 0; + list::const_iterator iterMimics = m_Mimics.begin(); + for (; iterMimics != m_Mimics.end(); ++iterMimics, ++uiMimicIndex) + { + vecPosition.fX += 4.0f; + vecOrigin.fX += 4.0f; + vecTarget.fX += 4.0f; + + CClientPlayer* pMimic = *iterMimics; + + pMimic->SetHealth(fHealth); + pMimic->LockHealth(fHealth); + pMimic->SetArmor(fArmor); + pMimic->LockArmor(fArmor); + pMimic->SetWearingGoggles(bWearingGoggles); + pMimic->SetHasJetPack(bHasJetpack); + pMimic->SetChoking(bChoking); + pMimic->SetSunbathing(bSunbathing); + pMimic->SetDoingGangDriveby(bDoingDriveby); + pMimic->SetStealthAiming(bStealthAiming); + + Controller.ShockButtonL = 0; + + if (m_bMimicLag) + { + pMimic->SetTargetPosition(vecPosition, TICK_RATE); + pMimic->SetMoveSpeed(vecMoveSpeed); + pMimic->SetControllerState(Controller); + pMimic->SetTargetRotation(fRotation); + pMimic->SetCameraRotation(fCameraRotation); + pMimic->Duck(bDucked); + } + else + { + pMimic->SetPosition(vecPosition); + pMimic->SetMoveSpeed(vecMoveSpeed); + pMimic->SetTargetRotation(fRotation); + pMimic->SetCameraRotation(fCameraRotation); + pMimic->SetControllerState(Controller); + pMimic->Duck(bDucked); + } + + if (ucWeaponType != 0) + { + if (ucWeaponType == 44 || ucWeaponType == 45) + { + Controller.ButtonCircle = 0; + } + + if (m_bMimicLag) + { + pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); + pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); + + pMimic->AddChangeWeapon(TICK_RATE, weaponSlot, (unsigned char)ulWeaponAmmoInClip); + } + else + { + CWeapon* pPlayerWeapon = pMimic->GetWeapon(); + eWeaponType eCurrentWeapon = static_cast(ucWeaponType); + if ((pPlayerWeapon && pPlayerWeapon->GetType() != eCurrentWeapon) || !pPlayerWeapon) + { + pPlayerWeapon = pMimic->GiveWeapon(eCurrentWeapon, ulWeaponAmmoInClip); + if (pPlayerWeapon) + { + pPlayerWeapon->SetAsCurrentWeapon(); + } + } + + if (pPlayerWeapon) + { + pPlayerWeapon->SetAmmoTotal(9999); + pPlayerWeapon->SetAmmoInClip(ulWeaponAmmoInClip); + pPlayerWeapon->SetState(static_cast(ucWeaponState)); + } + pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); + pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); + } + } + else + { + pMimic->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); + } + + CClientVehicle* pMimicVehicle = pMimic->GetOccupiedVehicle(); + if (pVehicle) + { + unsigned int uiModel; + CVector vecPosition, vecRotationDegrees; + CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; + float fHealth; + + uiModel = pVehicle->GetModel(); + pVehicle->GetPosition(vecPosition); + pVehicle->GetRotationDegrees(vecRotationDegrees); + pVehicle->GetMoveSpeed(vecMoveSpeed); + pVehicle->GetTurnSpeed(vecTurnSpeed); + fHealth = pVehicle->GetHealth(); + + if (pMimicVehicle && pMimicVehicle->GetModel() != uiModel) + { + delete pMimicVehicle; + pMimicVehicle = NULL; + } + + vecPosition.fX += ((float)(uiMimicIndex + 1) * 10.0f); + + if (pMimicVehicle == NULL) + { + pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, uiModel, 0, 0); + pMimicVehicle->SetPosition(vecPosition); + + const SSlotStates& usUpgrades = pVehicle->GetUpgrades()->GetSlotStates(); + for (unsigned char uc = 0; uc < VEHICLE_UPGRADE_SLOTS; uc++) + { + if (usUpgrades[uc]) + { + pMimicVehicle->GetUpgrades()->AddUpgrade(usUpgrades[uc], true); + } + } + + m_vecLastMimicPos = vecPosition; + } + + if (m_bMimicLag) + { + pMimicVehicle->SetTargetPosition(vecPosition, TICK_RATE); + pMimicVehicle->SetTargetRotation(vecRotationDegrees, TICK_RATE); + pMimicVehicle->SetMoveSpeed(vecMoveSpeed); + pMimicVehicle->SetTurnSpeed(vecTurnSpeed); + } + else + { + pMimicVehicle->SetPosition(vecPosition); + pMimicVehicle->SetRotationDegrees(vecRotationDegrees); + pMimicVehicle->SetMoveSpeed(vecMoveSpeed); + pMimicVehicle->SetTurnSpeed(vecTurnSpeed); + } + pMimicVehicle->SetHealth(fHealth); + if (pMimic->GetOccupiedVehicle() != pMimicVehicle) + pMimic->WarpIntoVehicle(pMimicVehicle, uiSeat); + + unsigned int uiTrailerLoop = 0; + CClientVehicle* pTrailer = pVehicle->GetTowedVehicle(); + CClientVehicle* pMimicTrailer = NULL; + while (pTrailer) + { + uiModel = pTrailer->GetModel(); + pTrailer->GetPosition(vecPosition); + pTrailer->GetRotationDegrees(vecRotationDegrees); + pTrailer->GetMoveSpeed(vecMoveSpeed); + pTrailer->GetTurnSpeed(vecTurnSpeed); + fHealth = pTrailer->GetHealth(); + + pMimicTrailer = DynamicCast(CElementIDs::GetElement(static_cast(450 + uiMimicIndex + uiTrailerLoop))); + + if (pMimicTrailer && pMimicTrailer->GetModel() != uiModel) + { + delete pMimicTrailer; + pMimicTrailer = NULL; + } + + if (!pMimicTrailer) + { + pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, + static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); + pMimicVehicle->SetTowedVehicle(pMimicTrailer); + } + + pTrailer = pTrailer->GetTowedVehicle(); + pMimicTrailer = pMimicTrailer->GetTowedVehicle(); + uiTrailerLoop++; + } + if (pMimicTrailer) + { + if (pMimicTrailer->GetTowedByVehicle()) + { + pMimicTrailer->GetTowedByVehicle()->SetTowedVehicle(NULL); + } + } + } + else if (pMimicVehicle) + { + pMimic->RemoveFromVehicle(); + delete pMimicVehicle; + } + } + } + } +} + +void CClientGame::DoPaintballs(void) +{ + if (m_pLocalPlayer) + { + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + + CColPoint* pCollision = NULL; + CEntity* pCollisionEntity = NULL; + m_pLocalPlayer->WorldIgnore(true); + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionEntity); + m_pLocalPlayer->WorldIgnore(false); + + static list paintBalls; + if (paintBalls.size() >= 5) + { + CClientMarker* pCorona = paintBalls.back(); + delete pCorona; + paintBalls.pop_back(); + } + + CClientMarker* pCorona = new CClientMarker(m_pManager, INVALID_ELEMENT_ID, CClientMarker::MARKER_CORONA); + paintBalls.push_front(pCorona); + pCorona->SetSize(0.2f); + if (bCollision && pCollision) + { + pCorona->SetPosition(pCollision->GetPosition()); + pCorona->SetColor(SColorRGBA(255, 0, 0, 255)); + } + else + { + pCorona->SetPosition(vecTarget); + pCorona->SetColor(SColorRGBA(255, 255, 0, 255)); + } + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + } +} + +#endif + +void CClientGame::QuitPlayer(CClientPlayer* pPlayer, eQuitReason Reason) +{ + // Get the nick pointer and echo the quit message to the chat + const char* szNick = pPlayer->GetNick(); + const char* szReason = "Unknown"; + switch (Reason) + { + case QUIT_QUIT: + szReason = "Quit"; + break; + case QUIT_KICK: + szReason = "Kicked"; + break; + case QUIT_BAN: + szReason = "Banned"; + break; + case QUIT_CONNECTION_DESYNC: + szReason = "Bad Connection"; + break; + case QUIT_TIMEOUT: + szReason = "Timed Out"; + break; + } + + // In debug, make sure we don't look at this player's details +#ifdef MTA_DEBUG + if (m_pShowPlayer == pPlayer) + { + m_pShowPlayer = NULL; + } +#endif + + // Call our onClientPlayerQuit event + CLuaArguments Arguments; + Arguments.PushString(szReason); + pPlayer->CallEvent("onClientPlayerQuit", Arguments, true); + + // Detach the camera from this player if we're watching them + m_pManager->GetCamera()->UnreferencePlayer(pPlayer); + + // Was this player jacking us? + if (m_bIsGettingJacked && m_pGettingJackedBy == pPlayer) + { + ResetVehicleInOut(); + m_pLocalPlayer->RemoveFromVehicle(false); + m_pLocalPlayer->SetVehicleInOutState(VEHICLE_INOUT_NONE); + } + + // Delete the player + delete pPlayer; +} + +void CClientGame::Event_OnIngame(void) +{ + // Unpause the game + g_pGame->Pause(false); + + // Disable parts of the Hud + CHud* pHud = g_pGame->GetHud(); + pHud->SetComponentVisible(HUD_HELP_TEXT, false); + pHud->SetComponentVisible(HUD_VITAL_STATS, false); + pHud->SetComponentVisible(HUD_AREA_NAME, false); + + g_pMultiplayer->DeleteAndDisableGangTags(); + + // Switch off peds and traffic + SFixedArray vecs = {CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), + CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0)}; + g_pGame->GetPathFind()->SwitchRoadsOffInArea(&vecs[0], &vecs[1]); + g_pGame->GetPathFind()->SwitchPedRoadsOffInArea(&vecs[2], &vecs[3]); + g_pGame->GetPathFind()->SetPedDensity(0.0f); + g_pGame->GetPathFind()->SetVehicleDensity(0.0f); + + g_pGame->GetWorld()->ClearRemovedBuildingLists(); + g_pGame->GetWorld()->SetOcclusionsEnabled(true); + + g_pGame->ResetModelLodDistances(); + g_pGame->ResetAlphaTransparencies(); + + // Make sure we can access all areas + g_pGame->GetStats()->ModifyStat(CITIES_PASSED, 2.0); + + // This is to prevent the 'white arrows in checkpoints' bug (#274) + g_pGame->Get3DMarkers()->CreateMarker(87654, (e3DMarkerType)5, &vecs[4], 1, 0.2f, 0, 0, 0, 0); + + // Stop us getting 4 stars if we visit the SF or LV + // g_pGame->GetPlayerInfo()->GetWanted()->SetMaximumWantedLevel ( 0 ); + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(0); + + // Reset anything from last game + ResetMapInfo(); + g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level + g_pGame->GetWaterManager()->SetWaterDrawnLast(true); + m_pCamera->SetCameraClip(true, true); + + // Create a local player for us + m_pLocalPlayer = new CClientPlayer(m_pManager, m_LocalID, true); + if (m_pLocalPlayer) + { + // Set our parent the root entity + m_pLocalPlayer->SetParent(m_pRootEntity); + + // Give the local player our nickname + m_pLocalPlayer->SetNick(m_strLocalNick); + + // Freeze the player at some location we won't see + m_pLocalPlayer->SetHealth(100); + m_pLocalPlayer->SetPosition(CVector(0, 0, 0)); + m_pLocalPlayer->SetFrozen(true); + m_pLocalPlayer->ResetInterpolation(); + + // Reset him + m_pLocalPlayer->ResetStats(); + } + else + { + RaiseFatalError(2); + } + + // Make sure we never get tired + g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true); + + // Tell doggy we got the game running + WatchDogCompletedSection("L1"); +} + +void CClientGame::Event_OnIngameAndConnected(void) +{ + m_ulVerifyTimeStart = CClientTime::GetTime(); + + // Keep criminal records of how many times they've connected to servers + SetApplicationSettingInt("times-connected", GetApplicationSettingInt("times-connected") + 1); + if (m_ServerType == SERVER_TYPE_EDITOR) + SetApplicationSettingInt("times-connected-editor", GetApplicationSettingInt("times-connected-editor") + 1); + + // Notify the server telling we're ingame + m_pNetAPI->RPC(PLAYER_INGAME_NOTICE); +} + +bool CClientGame::StaticBreakTowLinkHandler(CVehicle* pTowingVehicle) +{ + return g_pClientGame->BreakTowLinkHandler(pTowingVehicle); +} + +void CClientGame::StaticDrawRadarAreasHandler(void) +{ + g_pClientGame->DrawRadarAreasHandler(); +} + +bool CClientGame::StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent) +{ + return g_pClientGame->DamageHandler(pDamagePed, pEvent); +} + +void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart) +{ + g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart); +} + +void CClientGame::StaticFireHandler(CFire* pFire) +{ + g_pClientGame->FireHandler(pFire); +} + +void CClientGame::StaticRender3DStuffHandler(void) +{ + g_pClientGame->Render3DStuffHandler(); +} + +void CClientGame::StaticPreRenderSkyHandler(void) +{ + g_pClientGame->PreRenderSkyHandler(); +} + +void CClientGame::StaticRenderHeliLightHandler() +{ + g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); +} + +bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) +{ + return g_pClientGame->ChokingHandler(ucWeaponType); +} + +void CClientGame::StaticCAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) +{ + g_pClientGame->CAnimBlendAssocDestructorHandler(pThis); +} + +CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) +{ + return g_pClientGame->AddAnimationHandler(pClump, animGroup, animID); +} + +CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, + AssocGroupId animGroup, AnimationId animID) +{ + return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); +} + +bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) +{ + return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); +} + +bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, + int* pFlags, RpClump* pClump) +{ + return g_pClientGame->BlendAnimationHierarchyHandler(pAnimAssoc, pOutAnimHierarchy, pFlags, pClump); +} + +void CClientGame::StaticPreWorldProcessHandler(void) +{ + g_pClientGame->PreWorldProcessHandler(); +} + +void CClientGame::StaticPostWorldProcessHandler(void) +{ + g_pClientGame->PostWorldProcessHandler(); +} + +void CClientGame::StaticPreFxRenderHandler(void) +{ + g_pCore->OnPreFxRender(); +} + +void CClientGame::StaticPreHudRenderHandler(void) +{ + g_pCore->OnPreHUDRender(); +} + +bool CClientGame::StaticProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) +{ + return g_pClientGame->ProcessCollisionHandler(pThisInterface, pOtherInterface); +} + +bool CClientGame::StaticVehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, + float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, + CVector vecCollisionVelocity) +{ + return g_pClientGame->VehicleCollisionHandler(pCollidingVehicle, pCollidedVehicle, iModelIndex, fDamageImpulseMag, fCollidingDamageImpulseMag, usPieceType, + vecCollisionPos, vecCollisionVelocity); +} + +bool CClientGame::StaticVehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, + const CVector& vecDamagePos, uchar ucTyre) +{ + return g_pClientGame->VehicleDamageHandler(pVehicleInterface, fLoss, pAttackerInterface, weaponType, vecDamagePos, ucTyre); +} + +bool CClientGame::StaticHeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) +{ + return g_pClientGame->HeliKillHandler(pHeliInterface, pHitInterface); +} + +bool CClientGame::StaticObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) +{ + return g_pClientGame->ObjectDamageHandler(pObjectInterface, fLoss, pAttackerInterface); +} + +bool CClientGame::StaticObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) +{ + return g_pClientGame->ObjectBreakHandler(pObjectInterface, pAttackerInterface); +} + +bool CClientGame::StaticWaterCannonHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) +{ + return g_pClientGame->WaterCannonHitHandler(pCannonVehicle, pHitPed); +} + +bool CClientGame::StaticVehicleFellThroughMapHandler(CVehicleSAInterface* pVehicle) +{ + return g_pClientGame->VehicleFellThroughMapHandler(pVehicle); +} + +void CClientGame::StaticGameObjectDestructHandler(CEntitySAInterface* pObject) +{ + g_pClientGame->GameObjectDestructHandler(pObject); +} + +void CClientGame::StaticGameVehicleDestructHandler(CEntitySAInterface* pVehicle) +{ + g_pClientGame->GameVehicleDestructHandler(pVehicle); +} + +void CClientGame::StaticGamePlayerDestructHandler(CEntitySAInterface* pPlayer) +{ + g_pClientGame->GamePlayerDestructHandler(pPlayer); +} + +void CClientGame::StaticGameProjectileDestructHandler(CEntitySAInterface* pProjectile) +{ + g_pClientGame->GameProjectileDestructHandler(pProjectile); +} + +void CClientGame::StaticGameModelRemoveHandler(ushort usModelId) +{ + g_pClientGame->GameModelRemoveHandler(usModelId); +} + +void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) +{ + if (pGameEntity) + { + // Map to client entity and pass to the texture replacer + CClientEntity* pClientEntity = g_pClientGame->GetGameEntityXRefManager()->FindClientEntity(pGameEntity); + if (pClientEntity) + { + int iTypeMask; + ushort usModelId = 0xFFFF; + switch (pClientEntity->GetType()) + { + case CCLIENTPED: + case CCLIENTPLAYER: + iTypeMask = TYPE_MASK_PED; + usModelId = (ushort) static_cast(pClientEntity)->GetModel(); + break; + case CCLIENTVEHICLE: + iTypeMask = TYPE_MASK_VEHICLE; + break; + case CCLIENTOBJECT: + iTypeMask = TYPE_MASK_OBJECT; + break; + default: + iTypeMask = TYPE_MASK_OTHER; + break; + } + g_pGame->GetRenderWare()->SetRenderingClientEntity(pClientEntity, usModelId, iTypeMask); + return; + } + } + + g_pGame->GetRenderWare()->SetRenderingClientEntity(NULL, 0xFFFF, TYPE_MASK_WORLD); +} + +void CClientGame::StaticTaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) +{ + g_pClientGame->TaskSimpleBeHitHandler(pPedAttacker, hitBodyPart, hitBodySide, weaponId); +} + +void CClientGame::StaticFxSystemDestructionHandler(void* pFxSAInterface) +{ + g_pClientGame->GetManager()->GetEffectManager()->SAEffectDestroyed(pFxSAInterface); +} + +AnimationId CClientGame::StaticDrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId) +{ + return g_pClientGame->DrivebyAnimationHandler(animGroup, animId); +} + +void CClientGame::DrawRadarAreasHandler(void) +{ + m_pRadarAreaManager->DoPulse(); +} + +bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle) +{ + CClientVehicle* pVehicle = m_pVehicleManager->Get(pTowedVehicle, false); + if (pVehicle) + { + // Check if this is a legal break + bool bLegal = ((pVehicle->GetControllingPlayer() == m_pLocalPlayer) || (m_pUnoccupiedVehicleSync->Exists(static_cast(pVehicle)))); + + // Not a legal break? + if (!bLegal) + { + // Save the time it broke (used in UpdateTrailers) + pVehicle->SetIllegalTowBreakTime(GetTickCount32()); + } + } + + // Allow it to break + return true; +} + +void CClientGame::FireHandler(CFire* pFire) +{ + // Disable spreading fires + pFire->SetNumGenerationsAllowed(0); +} + +void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) +{ + if (pProjectile->IsLocal()) + { + // Did the local player create this projectile? + if (m_pLocalPlayer && pProjectile->GetCreator() == m_pLocalPlayer) + { + // Physics says our projectile should start off at our velocity + CVector vecVelocity, vecPlayerVelocity; + pProjectile->GetVelocity(vecVelocity); + m_pLocalPlayer->GetMoveSpeed(vecPlayerVelocity); + vecVelocity += vecPlayerVelocity; + pProjectile->SetVelocity(vecVelocity); + } + + SendProjectileSync(pProjectile); + } + + // Renew the interior and dimension + if (pProjectile->GetCreator()) + { + pProjectile->SetInterior(pProjectile->GetCreator()->GetInterior()); + pProjectile->SetDimension(pProjectile->GetCreator()->GetDimension()); + } + + // Validate the projectile for our element tree + pProjectile->SetParent(m_pRootEntity); + + // Call our creation event + CLuaArguments Arguments; + Arguments.PushElement(pProjectile->GetCreator()); + pProjectile->CallEvent("onClientProjectileCreation", Arguments, true); +} + +void CClientGame::Render3DStuffHandler(void) +{ +} + +void CClientGame::PreRenderSkyHandler(void) +{ + g_pCore->GetGraphics()->GetRenderItemManager()->PreDrawWorld(); +} + +void CClientGame::PreWorldProcessHandler(void) +{ +} + +void CClientGame::PostWorldProcessHandler(void) +{ + m_pManager->GetMarkerManager()->DoPulse(); + m_pManager->GetPointLightsManager()->DoPulse(); + m_pManager->GetObjectManager()->DoPulse(); + + // Update frame time slice + uint uiCurrentTick = GetTickCount32(); + if (m_uiLastFrameTick) + { + m_uiFrameTimeSlice = uiCurrentTick - m_uiLastFrameTick; + m_uiFrameCount++; + + // Call onClientPreRender LUA event + CLuaArguments Arguments; + Arguments.PushNumber(m_uiFrameTimeSlice); + m_pRootEntity->CallEvent("onClientPreRender", Arguments, false); + } + m_uiLastFrameTick = uiCurrentTick; +} + +void CClientGame::IdleHandler(void) +{ + // If we are minimized we do the pulsing here + if (g_pCore->IsWindowMinimized()) + { + if (!m_bWasMinimized) + { + m_bWasMinimized = true; + // Call onClientMinimize LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); + + bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); + + // Apply mute on minimize options + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) + g_pGame->GetAudio()->SetMusicMasterVolume(0); + + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) + g_pGame->GetAudio()->SetEffectsMasterVolume(0); + + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) + m_pManager->GetSoundManager()->SetMinimizeMuted(true); + } + } + + // Ensure dummy progress graphic will be displayed when using alt pulse order + g_pCore->SetDummyProgressUpdateAlways(true); + + // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) + DoPulses2(true); + + g_pCore->SetDummyProgressUpdateAlways(false); +} + +bool CClientGame::ChokingHandler(unsigned char ucWeaponType) +{ + if (!m_pLocalPlayer) + return true; + CLuaArguments Arguments; + Arguments.PushNumber(ucWeaponType); + return m_pLocalPlayer->CallEvent("onClientPlayerChoke", Arguments, true); +} + +void CClientGame::CAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) +{ + // printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID); + RemoveAnimationAssociationFromMap(pThis); +} + +CAnimBlendAssociationSAInterface* CClientGame::AddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) +{ + // printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); + return nullptr; +} + +CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, + AssocGroupId animGroup, AnimationId animID) +{ + // printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); + return nullptr; +} + +bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) +{ + bool isCustomAnimationToPlay = false; + CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); + auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); + auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); + auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); + auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); + + CClientPed* pClientPed = GetClientPedByClump(*pClump); + if (pClientPed != nullptr) + { + auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); + if (pReplacedAnimation != nullptr) + { + std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); + InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); + + // Play our custom animation instead of default + auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); + pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); + pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); + pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); + isCustomAnimationToPlay = true; + } + } + + if (!isCustomAnimationToPlay) + { + auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); + + // Play default internal animation + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); + } + return isCustomAnimationToPlay; +} + +bool CClientGame::BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags, + RpClump* pClump) +{ + bool isCustomAnimationToPlay = false; + CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); + CClientPed* pClientPed = GetClientPedByClump(*pClump); + if (pClientPed != nullptr) + { + if (pClientPed->IsNextAnimationCustom()) + { + std::shared_ptr pIFP = pClientPed->GetCustomAnimationIFP(); + if (pIFP) + { + const SString& strAnimationName = pClientPed->GetNextAnimationCustomName(); + auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy(strAnimationName); + if (pCustomAnimBlendHierarchy != nullptr) + { + std::shared_ptr pIFPAnimations = pIFP->GetIFPAnimationsPointer(); + InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); + + pClientPed->SetCurrentAnimationCustom(true); + pClientPed->SetNextAnimationNormal(); + + if (pIFP->IsUnloading()) + { + pClientPed->DereferenceCustomAnimationBlock(); + } + *pOutAnimHierarchy = pCustomAnimBlendHierarchy; + isCustomAnimationToPlay = true; + return isCustomAnimationToPlay; + } + } + } + + pClientPed->SetCurrentAnimationCustom(false); + pClientPed->SetNextAnimationNormal(); + } + return isCustomAnimationToPlay; +} + +bool CClientGame::ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) +{ + if (pThisInterface == pOtherInterface) + return true; + + if (!m_BuiltCollisionMapThisFrame) + { + // Build a map of CPhysicalSAInterface*/CClientEntity*'s that have collision disabled + m_BuiltCollisionMapThisFrame = true; + m_CachedCollisionMap.clear(); + + std::map::iterator iter = m_AllDisabledCollisions.begin(); + for (; iter != m_AllDisabledCollisions.end(); ++iter) + { + CClientEntity* pEntity = iter->first; + CEntity* pGameEntity = pEntity->GetGameEntity(); + CEntitySAInterface* pInterface = pGameEntity ? pGameEntity->GetInterface() : NULL; + + if (pInterface) + m_CachedCollisionMap[pInterface] = pEntity; + } + } + + // Check both elements appear in the cached map before doing extra processing + std::map::iterator iter1 = m_CachedCollisionMap.find((CEntitySAInterface*)pThisInterface); + if (iter1 != m_CachedCollisionMap.end()) + { + std::map::iterator iter2 = m_CachedCollisionMap.find((CEntitySAInterface*)pOtherInterface); + if (iter2 != m_CachedCollisionMap.end()) + { + // Re-get the entity pointers using a safer method + CEntity* pGameEntity = g_pGame->GetPools()->GetEntity((DWORD*)pThisInterface); + CEntity* pGameColEntity = g_pGame->GetPools()->GetEntity((DWORD*)pOtherInterface); + + if (pGameEntity && pGameColEntity) + { + CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity, true); + CClientEntity* pColEntity = m_pManager->FindEntity(pGameColEntity, true); + + if (pEntity && pColEntity) + { + #if MTA_DEBUG + CClientEntity* ppThisEntity2 = iter1->second; + CClientEntity* ppOtherEntity2 = iter2->second; + // These should match, but its not essential. + assert(ppThisEntity2 == pEntity); + assert(ppOtherEntity2 == pColEntity); + #endif + if (!pEntity->IsCollidableWith(pColEntity)) + return false; + } + } + } + } + + return true; +} + +// +// On demand files +// +void CClientGame::DownloadSingularResourceFiles(void) +{ + if (!IsTransferringSingularFiles()) + return; + + if (!g_pNet->IsConnected()) + return; + + CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES); + if (!pHTTP->ProcessQueuedFiles()) + { + // Downloading + } + else + { + // Can't clear list until all files have been processed + if (m_pSingularFileDownloadManager->AllComplete()) + { + SetTransferringSingularFiles(false); + m_pSingularFileDownloadManager->ClearList(); + } + } +} + +// Get relevant death anim for animation purposes during death situation +void GetDeathAnim(CClientPed* pDamagedPed, CEventDamage* pEvent, AssocGroupId& outAnimGroup, AnimationId& outAnimID) +{ + if (pEvent) + { + pEvent->ComputeDeathAnim(pDamagedPed->GetGamePlayer(), false); + outAnimGroup = pEvent->GetAnimGroup(); + outAnimID = pEvent->GetAnimId(); + } + else + { + // Using same numbers as CClientGame::DoWastedCheck defaults + outAnimGroup = 0; + outAnimID = 15; + } +} + +// +// DamageHandler seems to be called 3 times for each bit of damage: +// +// pass 1 - preApplyDamage +// is pass 1 if: fDamage == zero && fCurrentHealth == fPreviousHealth +// returning false stops any damage being inflicted +// returning true applies damage and allows pass 2 +// pass 2 - postApplyDamage/preApplyAnim +// is pass 2 if: fDamage > zero && fCurrentHealth != fPreviousHealth +// returning false stops damage anim +// returning true allows damage anim and allows pass 3 +// pass 3 - postApplyAnim +// is pass 3 if: fDamage > zero && fCurrentHealth == fPreviousHealth +// returning false ?? +// returning true ?? +// +bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) +{ + // CEventDamage::AffectsPed: This is/can be called more than once for each bit of damage (and may not actually take any more health (even if we return + // true)) + + // Grab some data from the event + CEntity* pInflictor = pEvent->GetInflictingEntity(); + eWeaponType weaponUsed = pEvent->GetWeaponUsed(); + ePedPieceTypes hitZone = pEvent->GetPedPieceType(); + CWeaponInfo* pWeaponInfo = g_pGame->GetWeaponInfo(weaponUsed); + float fDamage = pEvent->GetDamageApplied(); + EDamageReasonType damageReason = pEvent->GetDamageReason(); + + /* Causes too much desync right now + // Is this shotgun damage? + if ( weaponUsed == WEAPONTYPE_SHOTGUN || weaponUsed == WEAPONTYPE_SPAS12_SHOTGUN ) + { + // Make the ped fall down + pEvent->MakePedFallDown (); + } */ + + // Grab the damaged ped + CClientPed* pDamagedPed = NULL; + if (pDamagePed) + pDamagedPed = m_pPedManager->Get(dynamic_cast(pDamagePed), true, true); + + // Grab the inflictor + CClientEntity* pInflictingEntity = NULL; + if (pInflictor) + pInflictingEntity = m_pManager->FindEntity(pInflictor, true); + + // If the damage was caused by an explosion + if (weaponUsed == WEAPONTYPE_EXPLOSION) + { + CClientEntity* pLastExplosionCreator = m_pManager->GetExplosionManager()->m_pLastCreator; + + // If we don't have an inflictor, look for the last explosion creator + if (!pInflictor && pLastExplosionCreator) + pInflictingEntity = pLastExplosionCreator; + + // Change the weapon used to whatever created the explosion + weaponUsed = m_pManager->GetExplosionManager()->m_LastWeaponType; + } + + // Do we have a damaged ped? + if (pDamagedPed) + { + /////////////////////////////////////////////////////////////////////////// + // + // Pass 1 stuff + // + // return false to stop any damage being inflicted + // + /////////////////////////////////////////////////////////////////////////// + + // Pass 1 checks for double shots + if (fDamage == 0.0f && damageReason != EDamageReason::PISTOL_WHIP) + { + // Only check for remote players + CClientPlayer* pInflictingPlayer = DynamicCast(pInflictingEntity); + if (pInflictingPlayer && !pInflictingPlayer->IsLocalPlayer()) + { + bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon + bool bBulletSyncWeapon = GetWeaponTypeUsesBulletSync(weaponUsed); + + if (bBulletSyncShot) + { + if (g_iDamageEventLimit == 0) + { + AddReportLog(5501, SString("2nd pass 1 for BulletSyncShot damage. weaponUsed:%d", weaponUsed)); + return false; + } + g_iDamageEventLimit--; + if (!bBulletSyncWeapon) + { + AddReportLog(5502, SString("BulletSyncShot but not bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); + return false; + } + } + else + { + if (bBulletSyncWeapon) + { + AddReportLog(5503, SString("not BulletSyncShot but bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); + return false; + } + } + } + } + + // Is the damaged ped a player? + if (IS_PLAYER(pDamagedPed)) + { + CClientPlayer* pDamagedPlayer = static_cast(pDamagedPed); + + // Do we have an inflicting entity? + if (pInflictingEntity) + { + // Grab the inflicting player + CClientPlayer* pInflictingPlayer = NULL; + + switch (pInflictingEntity->GetType()) + { + case CCLIENTPLAYER: + { + pInflictingPlayer = static_cast(pInflictingEntity); + break; + } + case CCLIENTVEHICLE: + { + CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); + if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) + { + CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); + if (pPed && pPed->GetType() == CCLIENTPLAYER) + pInflictingPlayer = static_cast(pPed); + } + break; + } + default: + break; + } + if (pInflictingPlayer) + { + // Is the damaged player on a team + CClientTeam* pTeam = pDamagedPlayer->GetTeam(); + if (pTeam) + { + // Is this friendly-fire from a team-mate? + if (pDamagedPlayer->IsOnMyTeam(pInflictingPlayer) && !pTeam->GetFriendlyFire() && pDamagedPlayer != pInflictingPlayer) + return false; + } + } + } + } + /////////////////////////////////////////////////////////////////////////// + // Pass 1 end + /////////////////////////////////////////////////////////////////////////// + + return ApplyPedDamageFromGame(weaponUsed, fDamage, hitZone, pDamagedPed, pInflictingEntity, pEvent); + } + + // No damage anim for fire + if (weaponUsed == WEAPONTYPE_FLAMETHROWER) + return false; + + // Allow the damage processing to continue + return true; +} + +// +// Check GTA stored health with our stored health and do stuff +// +bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, uchar hitZone, CClientPed* pDamagedPed, CClientEntity* pInflictingEntity, + CEventDamage* pEvent) +{ + float fPreviousHealth = pDamagedPed->m_fHealth; + float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); + float fPreviousArmor = pDamagedPed->m_fArmor; + float fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); + + // Have we taken any damage here? + if ((fPreviousHealth != fCurrentHealth || fPreviousArmor != fCurrentArmor) && fDamage != 0.0f) + { + /////////////////////////////////////////////////////////////////////////// + /// + // Pass 2 stuff - (GTA has applied the damage) + // + // return false to stop damage anim (incl. death task) + // + /////////////////////////////////////////////////////////////////////////// + + g_fApplyDamageLastAmount = fDamage; + g_ucApplyDamageLastHitZone = hitZone; + g_pApplyDamageLastDamagedPed = pDamagedPed; + + CLuaArguments Arguments; + if (pInflictingEntity) + Arguments.PushElement(pInflictingEntity); + else + Arguments.PushBoolean(false); + Arguments.PushNumber(static_cast(weaponUsed)); + Arguments.PushNumber(static_cast(hitZone)); + Arguments.PushNumber(fDamage); + + // Call our event + if ((IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPlayerDamage", Arguments, true)) || + (!IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPedDamage", Arguments, true))) + { + // Stop here if they cancelEvent it + if (pDamagedPed->IsLocalPlayer()) + { + // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) + fPreviousHealth = pDamagedPed->m_fHealth; + fPreviousArmor = pDamagedPed->m_fArmor; + } + pDamagedPed->GetGamePlayer()->SetHealth(fPreviousHealth); + pDamagedPed->GetGamePlayer()->SetArmor(fPreviousArmor); + return false; + } + + if (pDamagedPed->IsLocalPlayer()) + { + // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) + fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); + fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); + } + + bool bIsBeingShotWhilstAiming = (weaponUsed >= WEAPONTYPE_PISTOL && weaponUsed <= WEAPONTYPE_MINIGUN && pDamagedPed->IsUsingGun()); + bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); + + bool bAllowChoke = true; + // Is this is a remote player? + if (!pDamagedPed->IsLocalPlayer()) + { + // Don't allow GTA to start the choking task + if (weaponUsed == WEAPONTYPE_TEARGAS || weaponUsed == WEAPONTYPE_SPRAYCAN || weaponUsed == WEAPONTYPE_EXTINGUISHER) + bAllowChoke = false; + } + + // Check if their health or armor is locked, and if so prevent applying the damage locally + if (pDamagedPed->IsHealthLocked() || pDamagedPed->IsArmorLocked()) + { + // Restore health+armor + pDamagedPed->GetGamePlayer()->SetHealth(pDamagedPed->GetHealth()); + pDamagedPed->GetGamePlayer()->SetArmor(pDamagedPed->GetArmor()); + + if (bOldBehaviour) + { + // Don't play the animation if it's going to be a death one, or if it's going to interrupt aiming + if (fCurrentHealth == 0.0f || bIsBeingShotWhilstAiming) + return false; + + // Allow animation for remote players (if currently we don't need block choke) + return bAllowChoke; + } + + // No hit animation for remote players + return false; + } + + // Update our stored health/armor + pDamagedPed->m_fHealth = fCurrentHealth; + pDamagedPed->m_fArmor = fCurrentArmor; + + ElementID damagerID = INVALID_ELEMENT_ID; + if (pInflictingEntity && !pInflictingEntity->IsLocalEntity()) + damagerID = pInflictingEntity->GetID(); + + // Is it the local player? + if (pDamagedPed->IsLocalPlayer()) + { + // Update our stored damage stuff + m_ucDamageWeapon = static_cast(weaponUsed); + m_ucDamageBodyPiece = static_cast(hitZone); + m_pDamageEntity = pInflictingEntity; + m_ulDamageTime = CClientTime::GetTime(); + m_DamagerID = damagerID; + m_bDamageSent = false; + } + // Does this damage kill the player? + if (fCurrentHealth == 0.0f) + { + if (pDamagedPed->GetType() == CCLIENTPLAYER) + { + // Is the local player dying? + if (pDamagedPed->IsLocalPlayer() && fPreviousHealth > 0.0f) + { + // Grab our death animation + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + + // Check if we're dead + DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); + } + + // Allow GTA to kill us if we've fell to our death + if (pDamagedPed->IsLocalPlayer() && weaponUsed == WEAPONTYPE_FALL) + return true; + + // Don't let GTA start the death task + return false; + } + else + { + if (pDamagedPed->IsLocalEntity() && fPreviousHealth > 0.0f) + { + // Client-side ped + pDamagedPed->CallEvent("onClientPedWasted", Arguments, true); + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + pDamagedPed->Kill(weaponUsed, hitZone, false, false, animGroup, animID); + return true; + } + if (fPreviousHealth > 0.0f) + { + // Grab our death animation + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + + SendPedWastedPacket(pDamagedPed, damagerID, weaponUsed, hitZone, animGroup, animID); + } + } + } + + // Disallow choke task if it's necessary + if (!bAllowChoke) + return false; + + // Inhibit hit-by-gun animation for local player if required + if (bOldBehaviour) + if (pDamagedPed->IsLocalPlayer() && bIsBeingShotWhilstAiming) + return false; + + /////////////////////////////////////////////////////////////////////////// + // Pass 2 end + /////////////////////////////////////////////////////////////////////////// + } + + // No damage anim for fire + if (weaponUsed == WEAPONTYPE_FLAMETHROWER) + return false; + + // Allow the damage processing to continue + return true; +} + +void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, unsigned char ucBodyPart) +{ + CClientPed* pKilledPed = m_pPedManager->Get(dynamic_cast(pKilledPedSA), true, true); + + if (!pKilledPed) + return; + + // Not required for remote players. Local player is handled in DoPulses->DoWastedCheck + if (IS_PLAYER(pKilledPed)) + return; + + // Set the health to zero (this is safe as GTA will do it anyway in a few ticks) + pKilledPed->SetHealth(0.0f); + + // Call Lua + CLuaArguments Arguments; + Arguments.PushBoolean(false); + Arguments.PushNumber(ucDeathReason); + Arguments.PushNumber(ucBodyPart); + + pKilledPed->CallEvent("onClientPedWasted", Arguments, true); + + // Notify the server + SendPedWastedPacket(pKilledPed, INVALID_ELEMENT_ID, ucDeathReason, ucBodyPart); +} + +bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, + float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) +{ + if (pCollidingVehicle && pCollidedWith) + { + CVehicle* pColliderVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidingVehicle); + CClientEntity* pVehicleClientEntity = m_pManager->FindEntity(pColliderVehicle, true); + if (pVehicleClientEntity) + { + CClientVehicle* pClientVehicle = static_cast(pVehicleClientEntity); + + CEntity* pCollidedWithEntity = g_pGame->GetPools()->GetEntity((DWORD*)pCollidedWith); + CClientEntity* pCollidedWithClientEntity = NULL; + if (pCollidedWithEntity) + { + if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pCollidedWithVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithVehicle, true); + } + else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_OBJECT) + { + CObject* pCollidedWithObject = g_pGame->GetPools()->GetObject((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithObject, true); + } + else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pCollidedWithPed = g_pGame->GetPools()->GetPed((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithPed, true); + } + } + CLuaArguments Arguments; + if (pCollidedWithClientEntity) + { + Arguments.PushElement(pCollidedWithClientEntity); + } + else + { + Arguments.PushNil(); + } + Arguments.PushNumber(fDamageImpulseMag); + Arguments.PushNumber(usPieceType); + Arguments.PushNumber(vecCollisionPos.fX); + Arguments.PushNumber(vecCollisionPos.fY); + Arguments.PushNumber(vecCollisionPos.fZ); + Arguments.PushNumber(vecCollisionVelocity.fX); + Arguments.PushNumber(vecCollisionVelocity.fY); + Arguments.PushNumber(vecCollisionVelocity.fZ); + Arguments.PushNumber(fCollidingDamageImpulseMag); + Arguments.PushNumber(iModelIndex); + + pVehicleClientEntity->CallEvent("onClientVehicleCollision", Arguments, true); + // Alocate a BitStream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + // Make sure it created + if (pBitStream) + { + if (pBitStream->Version() >= 0x028) + { + // Sync Stuff + // if it's not a local vehicle + it collided with the local player + if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) + { + // is it below the anti spam threshold? + if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) + { + // if there is no controlling player + if (!pClientVehicle->GetControllingPlayer()) + { + CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); + // if We aren't already syncing the vehicle + if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) + { + // Write the vehicle ID + pBitStream->Write(pVehicleClientEntity->GetID()); + // Send! + g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, + PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); + // Reset our push time + pClientVehicle->ResetLastPushTime(); + } + } + } + } + } + g_pNet->DeallocateNetBitStream(pBitStream); + } + return true; + } + } + return false; +} + +bool CClientGame::HeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) +{ + if (pHeliInterface && pHitInterface) + { + // Get our heli and client heli + CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); + CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); + if (pHeli && pClientHeli && pClientHeli->AreHeliBladeCollisionsEnabled()) + { + // Get our ped and client ped + CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitInterface); + CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); + // Was our client ped valid + if (pClientPed) + { + // Get our heli and client heli + CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); + CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); + + // Iterate our "stored" cancel state and find the heli in question + std::pair::iterator, std::multimap::iterator> iterators = + m_HeliCollisionsMap.equal_range(pClientHeli); + std::multimap::const_iterator iter = iterators.first; + for (; iter != iterators.second; ++iter) + { + // If the Heli and ped collided within the clear rate return false + if ((*iter).first == pClientHeli && (*iter).second == pClientPed) + return false; + } + + CLuaArguments Arguments; + if (pClientHeli) + { + // Push our heli + Arguments.PushElement(pClientHeli); + } + else + { + Arguments.PushNil(); + } + + // Trigger our event + bool bContinue; + if (IS_PLAYER(pClientPed)) + bContinue = pClientPed->CallEvent("onClientPlayerHeliKilled", Arguments, true); + else + bContinue = pClientPed->CallEvent("onClientPedHeliKilled", Arguments, true); + + // Was our event cancelled + if (!bContinue) + { + // Add our heli and ped pair to the list + std::pair pair = std::pair(pClientHeli, pClientPed); + m_HeliCollisionsMap.insert(pair); + } + // Return if it was cancelled + return bContinue; + } + } + else + { + return false; + } + } + return true; +} + +bool CClientGame::VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, + const CVector& vecDamagePos, uchar ucTyre) +{ + bool bAllowDamage = true; + CClientVehicle* pClientVehicle = GetGameEntityXRefManager()->FindClientVehicle(pVehicleInterface); + if (pClientVehicle) + { + CClientEntity* pClientAttacker = GetGameEntityXRefManager()->FindClientEntity(pAttackerInterface); + + // Compose arguments + // attacker, weapon, loss, damagepos, tyreIdx + CLuaArguments Arguments; + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + if (weaponType != WEAPONTYPE_INVALID) + Arguments.PushNumber(weaponType); + else + Arguments.PushNil(); + Arguments.PushNumber(fLoss); + Arguments.PushNumber(vecDamagePos.fX); + Arguments.PushNumber(vecDamagePos.fY); + Arguments.PushNumber(vecDamagePos.fZ); + if (ucTyre != UCHAR_INVALID_INDEX) + Arguments.PushNumber(ucTyre); + else + Arguments.PushNil(); + + if (!pClientVehicle->CallEvent("onClientVehicleDamage", Arguments, true)) + { + bAllowDamage = false; + } + } + + return bAllowDamage; +} + +bool CClientGame::ObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) +{ + if (pObjectInterface) + { + // Get our object and client object + CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); + CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); + + // Is our client vehicle valid? + if (pClientObject) + { + CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); + CClientEntity* pClientAttacker = NULL; + if (pAttacker) + { + if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); + } + else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerPed); + } + } + + CLuaArguments Arguments; + Arguments.PushNumber(fLoss); + + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + + return pClientObject->CallEvent("onClientObjectDamage", Arguments, true); + } + } + return true; +} + +bool CClientGame::ObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) +{ + if (pObjectInterface) + { + // Get our object and client object + CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); + CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); + + // Is our client vehicle valid? + if (pClientObject) + { + if (!pClientObject->IsBreakable(false)) + return false; + + // Apply to MTA's "internal storage", too + pClientObject->SetHealth(0.0f); + + CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); + CClientEntity* pClientAttacker = NULL; + if (pAttacker) + { + if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); + } + else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerPed); + } + } + + CLuaArguments Arguments; + + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + + return pClientObject->CallEvent("onClientObjectBreak", Arguments, true); + } + } + return true; +} + +bool CClientGame::WaterCannonHitHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) +{ + if (pCannonVehicle && pHitPed) + { + // Get our vehicle and client vehicle + CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCannonVehicle); + CClientVehicle* pCannonClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); + // Was our client vehicle valid + if (pCannonClientVehicle) + { + // Get our ped and client ped + CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitPed); + CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); + + CLuaArguments Arguments; + if (pClientPed) + { + // Push our ped + Arguments.PushElement(pClientPed); + } + else + { + Arguments.PushNil(); + } + + // Trigger our event + bool bContinue = true; + if (!IS_PLAYER(pClientPed)) + bContinue = pCannonClientVehicle->CallEvent("onClientPedHitByWaterCannon", Arguments, true); + else + bContinue = pCannonClientVehicle->CallEvent("onClientPlayerHitByWaterCannon", Arguments, true); + + // Return if it was cancelled + return bContinue; + } + } + return false; +} + +bool CClientGame::VehicleFellThroughMapHandler(CVehicleSAInterface* pVehicleInterface) +{ + if (pVehicleInterface) + { + // Get our vehicle and client vehicle + CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pVehicleInterface); + CClientVehicle* pClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); + if (pClientVehicle) + { + // handle or don't + return pClientVehicle->OnVehicleFallThroughMap(); + } + } + // unhandled + return false; +} + +// Validate known objects +void CClientGame::GameObjectDestructHandler(CEntitySAInterface* pObject) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pObject); +} + +void CClientGame::GameVehicleDestructHandler(CEntitySAInterface* pVehicle) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pVehicle); +} + +void CClientGame::GamePlayerDestructHandler(CEntitySAInterface* pPlayer) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pPlayer); +} + +void CClientGame::GameProjectileDestructHandler(CEntitySAInterface* pProjectile) +{ + CClientProjectile* pClientProjectile = m_pManager->GetProjectileManager()->Get(pProjectile); + // Happens when destroyElement is called rather than letting the projectile expire + // Normal code path is destruction from CProjectileSAInterface -> CProjectileSA -> CClientProjectile + // destroyElement is CClientProjectile -> CProjectileSA -> CProjectileSAInterface + // which means the CClientProjectile element is deleted when we get here + if (pClientProjectile) + CStaticFunctionDefinitions::DestroyElement(*pClientProjectile); +} + +void CClientGame::GameModelRemoveHandler(ushort usModelId) +{ + m_pGameEntityXRefManager->OnGameModelRemove(usModelId); +} + +void CClientGame::TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) +{ + bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); + if (bOldBehaviour) + return; + + CClientPed* pClientPedAttacker = DynamicCast(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedAttacker)); + + // Make sure cause was networked ped + if (pClientPedAttacker && !pClientPedAttacker->IsLocalEntity()) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write((ushort)TASK_SIMPLE_BE_HIT); + pBitStream->Write(pClientPedAttacker->GetID()); + pBitStream->Write((uchar)hitBodyPart); + pBitStream->Write((uchar)hitBodySide); + pBitStream->Write((uchar)weaponId); + g_pNet->SendPacket(PACKET_ID_PED_TASK, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +bool CClientGame::StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (g_pClientGame) + { + return g_pClientGame->ProcessMessage(hwnd, uMsg, wParam, lParam); + } + + return false; +} + +bool CClientGame::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (ProcessMessageForCursorEvents(hwnd, uMsg, wParam, lParam)) + { + return true; + } + + return false; +} + +void CClientGame::ProcessVehicleInOutKey(bool bPassenger) +{ + // Are we already sending an in/out request or not allowed to create a new in/out? + if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? + || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) + || m_bIsGettingJacked // Make sure we're not currently getting carjacked && + || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... + || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... + || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon + ) + { + return; + } + + // Reset the "is jacking" bit + m_bIsJackingVehicle = false; + + // Got a local player model? + if (!m_pLocalPlayer) + { + // No local player. Stop. + return; + } + + // If the player is in a vehicle we need to leave the vehicle. + CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + if (pOccupiedVehicle) + { + // Only let us leave the vehicle if: + // - we press F (as driver) + // - we press either F or G as a passenger + if (bPassenger && m_pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + // Driver pressed G, so stop. + return; + } + + // We're about to exit a vehicle + // Send an in request + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!pBitStream) + { + return; + } + + // Write the vehicle id to it and that we're requesting to get out of it + pBitStream->Write(pOccupiedVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_REQUEST_OUT); + pBitStream->WriteBits(&ucAction, 4); + + unsigned char ucDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pLocalPlayer->GetGamePlayer(), pOccupiedVehicle->GetGameVehicle()); + if (ucDoor >= 2 && ucDoor <= 5) + { + ucDoor -= 2; + pBitStream->WriteBits(&ucDoor, 2); + } + + // Send and destroy it + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're now exiting a vehicle + m_bIsGettingOutOfVehicle = true; + m_ulLastVehicleInOutTime = CClientTime::GetTime(); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_out"); +#endif + return; + } + + // + // We're going to enter a vehicle + // + + // If the Jump task is playing and we are in water - I know right + // Kill the task. + // + CTask* pTask = m_pLocalPlayer->GetCurrentPrimaryTask(); + if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter + { + CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, nullptr, nullptr, 20.0f); + if (pVehicle && + (pVehicle->IsInWater() || + m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) + { + m_pLocalPlayer->KillTask(3, true); // Kill jump task if we are about to warp in + } + } + + // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle' + // task will replace it and fuck it up! + // + if (m_pLocalPlayer->GetCurrentPrimaryTask()) + { + // We already have a primary task, so stop. + return; + } + + // Are we holding the aim_weapon key? + SBindableGTAControl* pBind = g_pCore->GetKeyBinds()->GetBindableFromControl("aim_weapon"); + if (pBind && pBind->bState) + { + // Stop because the player is probably using rshift + f/g + return; + } + + if (m_pLocalPlayer->IsClimbing() // Make sure we're not currently climbing + || m_pLocalPlayer->HasJetPack() // Make sure we don't have a jetpack + || m_pLocalPlayer->IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway + || m_pLocalPlayer->IsRunningAnimation() // Make sure we aren't running an animation + ) + { + return; + } + + // Grab the closest vehicle + unsigned int uiDoor = 0; + CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, &uiDoor, nullptr, 20.0f); + unsigned int uiSeat = uiDoor; + + if (bPassenger && uiDoor == 0) + { + // We're trying to enter as a passenger, yet our closest door + // is the driver's door. Force an enter for the passenger seat. + uiSeat = 1; + } + else if (!bPassenger) + { + // We want to drive. Force our seat to the driver's seat. + uiSeat = 0; + } + + if (!pVehicle || !pVehicle->IsEnterable()) + { + // Stop if there isn't a vehicle, or the vehicle is not enterable + return; + } + + // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly) + if (pVehicle->GetVehicleType() == CLIENTVEHICLE_BOAT && m_pLocalPlayer->GetContactEntity() != pVehicle) + { + return; + } + + // Call the onClientVehicleStartEnter event for remote players + // Local player triggered before sending packet in CClientGame + CLuaArguments Arguments; + Arguments.PushElement(m_pLocalPlayer); // player + Arguments.PushNumber(uiSeat); // seat + Arguments.PushNumber(uiDoor); // Door + + if (!pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true)) + { + // Event has been cancelled + return; + } + + // Send an in request + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!pBitStream) + { + return; + } + + // Write the vehicle id to it and that we're requesting to get into it + pBitStream->Write(pVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_REQUEST_IN); + unsigned char ucSeat = static_cast(uiSeat); + bool bIsOnWater = pVehicle->IsOnWater(); + unsigned char ucDoor = static_cast(uiDoor); + pBitStream->WriteBits(&ucAction, 4); + pBitStream->WriteBits(&ucSeat, 4); + pBitStream->WriteBit(bIsOnWater); + pBitStream->WriteBits(&ucDoor, 3); + + // Send and destroy it + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're now entering a vehicle + m_bIsGettingIntoVehicle = true; + m_ulLastVehicleInOutTime = CClientTime::GetTime(); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_in"); +#endif +} + +// Shot compensation (Jax): +// Positions the local player where he should of been on the shooting player's screen when he +// fired remotely. (the position we !reported! around the time he shot) +bool bShotCompensation = true; + +// Temporary pointers for pre- and post-functions +CVector vecWeaponFirePosition, vecRemoteWeaponFirePosition; +CPlayerPed* pWeaponFirePed = NULL; + +bool CClientGame::PreWeaponFire(CPlayerPed* pPlayerPed, bool bStopIfUsingBulletSync) +{ + pWeaponFirePed = pPlayerPed; + + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pWeaponFirePed) + { + CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); + + // Get the CClientNetPlayer class with the specified player ped + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(pWeaponFirePed, true); + + // Move both players to where they should be for shot compensation + if (pPlayer && !pPlayer->IsLocalPlayer()) + { + if (bStopIfUsingBulletSync && pPlayer->IsCurrentWeaponUsingBulletSync()) + return false; // Don't apply shot compensation & tell caller to not do bullet trace + + if (bShotCompensation) + { + if (!pVehicle || pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + // Warp back in time to where we were when this player shot (their latency) + + // We don't account for interpolation here, +250ms seems to work better + // ** Changed ajustment to +125ms as the position of this clients player on the firers screen + // has been changed. See CClientPed::UpdateTargetPosition() ** + CVector vecPosition; + unsigned short usLatency = (pPlayer->GetLatency() + 125); + g_pClientGame->m_pNetAPI->GetInterpolation(vecPosition, usLatency); + + // Move the entity back + if (pVehicle) + { + pVehicle->GetPosition(vecWeaponFirePosition); + pVehicle->SetPosition(vecPosition, false, false); + } + else + { + pLocalPlayer->GetPosition(vecWeaponFirePosition); + pLocalPlayer->SetPosition(vecPosition, false, false); + } + } + } + } + } + return true; +} + +void CClientGame::PostWeaponFire(void) +{ + // Send bullet sync with local damage info + if (g_bBulletFireVectorsValid) + { + g_bBulletFireVectorsValid = false; + CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer) + { + eWeaponType weaponType = pLocalPlayer->GetCurrentWeaponType(); + if (g_pClientGame->GetWeaponTypeUsesBulletSync(weaponType)) + { + g_pClientGame->GetNetAPI()->SendBulletSyncFire(weaponType, g_vecBulletFireStartPosition, g_vecBulletFireEndPosition, g_fApplyDamageLastAmount, + g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); + } + } + } + + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pWeaponFirePed) + { + CClientPed* pPed = g_pClientGame->GetPedManager()->Get(pWeaponFirePed, true, true); + if (pPed) + { + if (pPed->GetType() == CCLIENTPLAYER) + { + if (bShotCompensation) + { + // Restore compensated positions + if (!pPed->IsLocalPlayer()) + { + CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); + if (!pVehicle) + { + pLocalPlayer->SetPosition(vecWeaponFirePosition, false, false); + } + else if (pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + pVehicle->SetPosition(vecWeaponFirePosition, false, false); + } + } + } + } + + // Call some events + CWeapon* pWeapon = pPed->GetWeapon(); + if (pWeapon) + { + CVector vecCollision; + CClientEntity* pCollisionEntity = NULL; + + if (pPed->GetBulletImpactData(&pCollisionEntity, &vecCollision) == false) + { + CShotSyncData* pShotsyncData = pPed->m_shotSyncData; + CVector vecOrigin, vecTarget; + pPed->GetShotData(&vecOrigin, &vecTarget); + + CColPoint* pCollision = NULL; + CEntity* pCollisionGameEntity = NULL; + vecCollision = vecTarget; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionGameEntity); + if (bCollision && pCollision) + vecCollision = pCollision->GetPosition(); + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + + if (pCollisionGameEntity) + pCollisionEntity = g_pClientGame->m_pManager->FindEntity(pCollisionGameEntity); + } + else + { + pPed->ClearBulletImpactData(); + } + + // Call our lua event + CLuaArguments Arguments; + Arguments.PushNumber((double)pWeapon->GetType()); + Arguments.PushNumber((double)pWeapon->GetAmmoTotal()); + Arguments.PushNumber((double)pWeapon->GetAmmoInClip()); + Arguments.PushNumber((double)vecCollision.fX); + Arguments.PushNumber((double)vecCollision.fY); + Arguments.PushNumber((double)vecCollision.fZ); + if (pCollisionEntity) + Arguments.PushElement(pCollisionEntity); + else + Arguments.PushNil(); + + if (IS_PLAYER(pPed)) + { + CVector vecOrigin; + pPed->GetShotData(&vecOrigin); + Arguments.PushNumber((double)vecOrigin.fX); + Arguments.PushNumber((double)vecOrigin.fY); + Arguments.PushNumber((double)vecOrigin.fZ); + pPed->CallEvent("onClientPlayerWeaponFire", Arguments, true); + } + else + pPed->CallEvent("onClientPedWeaponFire", Arguments, true); + } + pPed->PostWeaponFire(); +#ifdef MTA_DEBUG + if (pPed->IsLocalPlayer() && g_pClientGame->m_bDoPaintballs) + { + g_pClientGame->DoPaintballs(); + } +#endif + } + } + pWeaponFirePed = NULL; +} + +void CClientGame::BulletImpact(CPed* pInitiator, CEntity* pVictim, const CVector* pStartPosition, const CVector* pEndPosition) +{ + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pInitiator) + { + // Find the client ped that initiated the bullet impact + CClientPed* pInitiatorPed = g_pClientGame->GetPedManager()->Get(dynamic_cast(pInitiator), true, true); + + if (pInitiatorPed) + { + // Calculate the collision of the bullet + CVector vecCollision; + CColPoint* pCollision = NULL; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(pStartPosition, pEndPosition, &pCollision, NULL); + if (bCollision && pCollision) + { + vecCollision = pCollision->GetPosition(); + } + else + { + // If we don't have a collision, use the end of the ray that the bullet is tracing. + vecCollision = *pEndPosition; + } + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + + // Find the client entity for the victim. + CClientEntity* pClientVictim = NULL; + if (pVictim) + { + pClientVictim = g_pClientGame->m_pManager->FindEntity(pVictim); + } + + // Store the data in the bullet fire initiator. + pInitiatorPed->SetBulletImpactData(pClientVictim, vecCollision); + } + } +} + +void CClientGame::BulletFire(CPed* pInitiator, const CVector* pStartPosition, const CVector* pEndPosition) +{ + g_bBulletFireVectorsValid = false; + g_fApplyDamageLastAmount = 0; + g_ucApplyDamageLastHitZone = 0; + g_pApplyDamageLastDamagedPed = NULL; + + // Got a local player model? + CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pLocalPlayer->GetGamePlayer() == pInitiator) + { + g_bBulletFireVectorsValid = true; + g_vecBulletFireStartPosition = *pStartPosition; + g_vecBulletFireEndPosition = *pEndPosition; + } +} + +bool CClientGame::StaticProcessPacket(unsigned char ucPacketID, NetBitStreamInterface& bitStream) +{ + if (g_pClientGame) + { + g_pCore->UpdateDummyProgress(); + g_pClientGame->GetManager()->GetPacketRecorder()->RecordPacket(ucPacketID, bitStream); + return g_pClientGame->m_pPacketHandler->ProcessPacket(ucPacketID, bitStream); + } + + return false; +} + +void CClientGame::SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin) +{ + SPositionSync position(false); + position.data.vecPosition = vecPosition; + + // Create the bitstream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write our origin id + if (pOrigin) + { + pBitStream->WriteBit(true); + pBitStream->Write(pOrigin->GetID()); + + // Convert position + CVector vecTemp; + pOrigin->GetPosition(vecTemp); + position.data.vecPosition -= vecTemp; + } + else + pBitStream->WriteBit(false); + + // Write the position and the type + pBitStream->Write(&position); + + SExplosionTypeSync explosionType; + explosionType.data.uiType = Type; + pBitStream->Write(&explosionType); + + // Destroy it + g_pNet->SendPacket(PACKET_ID_EXPLOSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +void CClientGame::SendFireSync(CFire* pFire) +{ +#ifdef MTA_DEBUG + CVector* vecPos = pFire->GetPosition(); + if (vecPos) + g_pCore->GetConsole()->Printf("we're sending fire: %f %f %f %f", pFire->GetStrength(), vecPos->fX, vecPos->fY, vecPos->fZ); + else + g_pCore->GetConsole()->Printf("we're sending a fire!"); +#endif +} + +void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) +{ + // Create the bitstream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + SPositionSync origin(false); + CClientEntity* pOriginSource = NULL; + eWeaponType weaponType = pProjectile->GetWeaponType(); + CClientEntity* pTarget = pProjectile->GetTargetEntity(); + origin.data.vecPosition = *pProjectile->GetOrigin(); + + // Is this a heatseaking missile with a target? sync it relative to the target + if (weaponType == WEAPONTYPE_ROCKET_HS && pTarget && !pTarget->IsLocalEntity()) + pOriginSource = pTarget; + + // Write the source of the projectile, if it has + if (pOriginSource) + { + CVector vecTemp; + pOriginSource->GetPosition(vecTemp); + origin.data.vecPosition -= vecTemp; + + pBitStream->WriteBit(true); + pBitStream->Write(pOriginSource->GetID()); + } + else + pBitStream->WriteBit(false); + + // Write the origin position + pBitStream->Write(&origin); + + // Write the creator weapon type + SWeaponTypeSync weaponTypeSync; + weaponTypeSync.data.ucWeaponType = static_cast(weaponType); + pBitStream->Write(&weaponTypeSync); + + // Write the projectile's model + if (pBitStream->Version() >= 0x4F) + if (pBitStream->Version() >= 0x52 || pOriginSource) // Fix possible error for 0x51 server + pBitStream->Write(pProjectile->GetModel()); + + switch (weaponType) + { + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_TEARGAS: + case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: + { + SFloatSync<7, 17> projectileForce; + projectileForce.data.fValue = pProjectile->GetForce(); + pBitStream->Write(&projectileForce); + + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); + + break; + } + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKET_HS: + { + if (pTarget) + { + pBitStream->WriteBit(true); + pBitStream->Write(pTarget->GetID()); + } + else + pBitStream->WriteBit(false); + + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); + + SRotationRadiansSync rotation(true); + pProjectile->GetRotationRadians(rotation.data.vecRotation); + pBitStream->Write(&rotation); + + break; + } + case WEAPONTYPE_FLARE: + case WEAPONTYPE_FREEFALL_BOMB: + break; + } + g_pNet->SendPacket(PACKET_ID_PROJECTILE, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + + // Destroy it + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +void CClientGame::ResetAmmoInClip(void) +{ + memset(&m_wasWeaponAmmoInClip[0], 0, sizeof(m_wasWeaponAmmoInClip)); +} + +void CClientGame::ResetMapInfo(void) +{ + // Restore some game stuff + // Keybinds + g_pCore->GetKeyBinds()->SetAllControlsEnabled(true, true, true); + + // Radarmap + m_pRadarMap->SetForcedState(false); + + // Camera + m_pCamera->FadeOut(0.0f, 0, 0, 0); + g_pGame->GetWorld()->SetCurrentArea(0); + m_pCamera->SetFocusToLocalPlayer(); + g_pGame->GetSettings()->ResetFieldOfViewFromScript(); + + // Dimension + SetAllDimensions(0); + + // Hud + g_pGame->GetHud()->SetComponentVisible(HUD_ALL, true); + // Disable area names as they are on load until camera unfades + g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); + g_pGame->GetHud()->SetComponentVisible(HUD_VITAL_STATS, false); + + m_bHudAreaNameDisabled = false; + + // Gravity + g_pMultiplayer->SetLocalPlayerGravity(DEFAULT_GRAVITY); + g_pMultiplayer->SetGlobalGravity(DEFAULT_GRAVITY); + g_pGame->SetGravity(DEFAULT_GRAVITY); + + // Gamespeed + SetGameSpeed(DEFAULT_GAME_SPEED); + + // Game minute duration + SetMinuteDuration(DEFAULT_MINUTE_DURATION); + + // Wanted-level + SetWanted(0); + + // Money + SetMoney(0, true); + + // Weather + m_pBlendedWeather->SetWeather(0); + + // Rain + g_pGame->GetWeather()->ResetAmountOfRain(); + + // Wind + g_pMultiplayer->RestoreWindVelocity(); + + // Far clip distance + g_pMultiplayer->RestoreFarClipDistance(); + + // Near clip distance + g_pMultiplayer->RestoreNearClipDistance(); + + // Fog distance + g_pMultiplayer->RestoreFogDistance(); + + // Vehicles LOD distance + g_pGame->GetSettings()->ResetVehiclesLODDistance(); + + // Peds LOD distance + g_pGame->GetSettings()->ResetPedsLODDistance(); + + // Sun color + g_pMultiplayer->ResetSunColor(); + + // Sun size + g_pMultiplayer->ResetSunSize(); + + // Sky-gradient + g_pMultiplayer->ResetSky(); + + // Heat haze + g_pMultiplayer->ResetHeatHaze(); + + // Water-colour + g_pMultiplayer->ResetWater(); + + // Water + GetManager()->GetWaterManager()->ResetWorldWaterLevel(); + + // Re-enable interior sounds and furniture + g_pMultiplayer->SetInteriorSoundsEnabled(true); + for (int i = 0; i <= 4; ++i) + g_pMultiplayer->SetInteriorFurnitureEnabled(i, true); + + // Clouds + g_pMultiplayer->SetCloudsEnabled(true); + g_pClientGame->SetCloudsEnabled(true); + + // Birds + g_pMultiplayer->DisableBirds(false); + g_pClientGame->SetBirdsEnabled(true); + + // Ambient sounds + g_pGame->GetAudio()->ResetAmbientSounds(); + + // World sounds + g_pGame->GetAudio()->ResetWorldSounds(); + + // Cheats + g_pGame->ResetCheats(); + + // Players + m_pPlayerManager->ResetAll(); + + // Jetpack max height + g_pGame->GetWorld()->SetJetpackMaxHeight(DEFAULT_JETPACK_MAXHEIGHT); + + // Aircraft max height + g_pGame->GetWorld()->SetAircraftMaxHeight(DEFAULT_AIRCRAFT_MAXHEIGHT); + + // Aircraft max velocity + g_pGame->GetWorld()->SetAircraftMaxVelocity(DEFAULT_AIRCRAFT_MAXVELOCITY); + + // Moon size + g_pMultiplayer->ResetMoonSize(); + + // Disable the change of any player stats + g_pMultiplayer->SetLocalStatsStatic(true); + + // Restore blur +#ifdef MTA_DEBUG + g_pGame->SetBlurLevel(0); +#else + g_pGame->SetBlurLevel(DEFAULT_BLUR_LEVEL); +#endif + + // Close all garages + CGarage* pGarage = NULL; + CGarages* pGarages = g_pCore->GetGame()->GetGarages(); + + for (unsigned char i = 0; (pGarage = pGarages->GetGarage(i)) != NULL; i++) + { + pGarage->SetOpen(false); + } + + // Player specific stuff + if (m_pLocalPlayer) + { + // Interior + m_pLocalPlayer->SetInterior(0); + + // Headless state + m_pLocalPlayer->SetHeadless(false); + + // Frozen state + m_pLocalPlayer->SetFrozen(false); + + // Voice + short sVoiceType, sVoiceID; + m_pLocalPlayer->GetModelInfo()->GetVoice(&sVoiceType, &sVoiceID); + m_pLocalPlayer->SetVoice(sVoiceType, sVoiceID); + + m_pLocalPlayer->DestroySatchelCharges(false, true); + // Tell the server we want to destroy our satchels + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + g_pNet->SendPacket(PACKET_ID_DESTROY_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, + AnimationId animID) +{ + if (Ped && Ped->GetHealth() == 0.0f) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write some death info + pBitStream->WriteCompressed(animGroup); + pBitStream->WriteCompressed(animID); + + pBitStream->Write(damagerID); + + SWeaponTypeSync weapon; + weapon.data.ucWeaponType = ucWeapon; + pBitStream->Write(&weapon); + + SBodypartSync bodyPart; + bodyPart.data.uiBodypart = ucBodyPiece; + pBitStream->Write(&bodyPart); + + // Write the position we died in + SPositionSync pos(false); + Ped->GetPosition(pos.data.vecPosition); + pBitStream->Write(&pos); + + pBitStream->Write(Ped->GetID()); + + // The ammo in our weapon and write the ammo total + CWeapon* pPlayerWeapon = Ped->GetWeapon(); + SWeaponAmmoSync ammo(ucWeapon, true, false); + ammo.data.usTotalAmmo = 0; + if (pPlayerWeapon) + ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); + pBitStream->Write(&ammo); + + // Send the packet + g_pNet->SendPacket(PACKET_ID_PED_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, AnimationId animID) +{ + // Are we not already marked as dead? and have we run out of health? + if (!m_pLocalPlayer->IsDeadOnNetwork() && m_pLocalPlayer->GetHealth() == 0.0f) + { + // Send the "i am dead" packet + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + m_pLocalPlayer->SetDeadOnNetwork(true); + + // Call the onClientPlayerWasted event + CClientEntity* pKiller = (damagerID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(damagerID) : NULL; + CLuaArguments Arguments; + if (pKiller) + Arguments.PushElement(pKiller); + else + Arguments.PushBoolean(false); + if (ucWeapon != 0xFF) + Arguments.PushNumber(ucWeapon); + else + Arguments.PushBoolean(false); + if (ucBodyPiece != 0xFF) + Arguments.PushNumber(ucBodyPiece); + else + Arguments.PushBoolean(false); + Arguments.PushBoolean(false); + m_pLocalPlayer->CallEvent("onClientPlayerWasted", Arguments, true); + + // Write some death info + pBitStream->WriteCompressed(animGroup); + pBitStream->WriteCompressed(animID); + + pBitStream->Write(damagerID); + + SWeaponTypeSync weapon; + weapon.data.ucWeaponType = ucWeapon; + pBitStream->Write(&weapon); + + SBodypartSync bodyPart; + bodyPart.data.uiBodypart = ucBodyPiece; + pBitStream->Write(&bodyPart); + + // Write the position we died in + SPositionSync pos(false); + m_pLocalPlayer->GetPosition(pos.data.vecPosition); + pBitStream->Write(&pos); + + // The ammo in our weapon and write the ammo total + CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(); + SWeaponAmmoSync ammo(ucWeapon, true, false); + ammo.data.usTotalAmmo = 0; + if (pPlayerWeapon) + ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); + pBitStream->Write(&ammo); + + // Send the packet + g_pNet->SendPacket(PACKET_ID_PLAYER_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +bool CClientGame::OnKeyDown(CGUIKeyEventArgs Args) +{ + return true; +} + +bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + const char* szState = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIClick", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseDoubleClick(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + const char* szState = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIDoubleClick", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIMouseDown", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseButtonUp(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIMouseUp", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseMove(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseMove", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseEnter(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + if (Args.pSwitchedWindow) + { + CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); + if (GetGUIManager()->Exists(pGUISwitchedElement)) + Arguments.PushElement(pGUISwitchedElement); + } + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseEnter", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseLeave(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + if (Args.pSwitchedWindow) + { + CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); + if (GetGUIManager()->Exists(pGUISwitchedElement)) + Arguments.PushElement(pGUISwitchedElement); + } + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseLeave", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseWheel(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.wheelChange); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseWheel", Arguments, true); + + return true; +} + +bool CClientGame::OnMove(CGUIElement* pElement) +{ + if (!pElement) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); + if (pGUIElement && GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientGUIMove", Arguments, true); + + return true; +} + +bool CClientGame::OnSize(CGUIElement* pElement) +{ + if (!pElement) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientGUISize", Arguments, true); + + return true; +} + +bool CClientGame::OnFocusGain(CGUIFocusEventArgs Args) +{ + if (!Args.pActivatedWindow) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pActivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pActivatedWindow); + + if (Args.pDeactivatedWindow) + { + CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); + if (GetGUIManager()->Exists(pDeactivatedGUIElement)) + pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); + } + + if (GetGUIManager()->Exists(pActivatedGUIElement)) + pActivatedGUIElement->CallEvent("onClientGUIFocus", Arguments, true); + + return true; +} + +bool CClientGame::OnFocusLoss(CGUIFocusEventArgs Args) +{ + if (!Args.pDeactivatedWindow) + return false; + + CLuaArguments Arguments; + + if (Args.pActivatedWindow) + { + // pDeactivatedWindow looses focus but an other window is now gaining it so we let CClientGame::OnFocusGain trigger both events in the right order + return true; + } + + CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); + if (GetGUIManager()->Exists(pDeactivatedGUIElement)) + pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); + + return true; +} + +// +// Display a progress dialog if a big packet is coming in +// +void CClientGame::NotifyBigPacketProgress(unsigned long ulBytesReceived, unsigned long ulTotalSize) +{ + // Should display progress box? + if (ulBytesReceived >= ulTotalSize || ulTotalSize < 50000) + { + if (m_bReceivingBigPacket) + { + // Switch off progress box + m_bReceivingBigPacket = false; + m_pBigPacketTransferBox->Hide(); + } + return; + } + + // Update progress box + if (!m_bReceivingBigPacket || m_ulBigPacketSize != ulTotalSize) + { + m_bReceivingBigPacket = true; + m_ulBigPacketSize = ulTotalSize; + m_pBigPacketTransferBox->Hide(); + m_pBigPacketTransferBox->AddToTotalSize(ulTotalSize); + m_pBigPacketTransferBox->Show(); + } + + m_pBigPacketTransferBox->DoPulse(); + m_pBigPacketTransferBox->SetInfo(std::min(ulTotalSize, ulBytesReceived), CTransferBox::PACKET); +} + +bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled) +{ + if (ucGlitch < NUM_GLITCHES && bEnabled != m_Glitches[ucGlitch]) + { + m_Glitches[ucGlitch] = bEnabled; + if (ucGlitch == GLITCH_QUICKRELOAD) + g_pMultiplayer->DisableQuickReload(!bEnabled); + if (ucGlitch == GLITCH_CLOSEDAMAGE) + g_pMultiplayer->DisableCloseRangeDamage(!bEnabled); + return true; + } + return false; +} + +bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) +{ + return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; +} + +bool CClientGame::SetCloudsEnabled(bool bEnabled) +{ + m_bCloudsEnabled = bEnabled; + return true; +} +bool CClientGame::GetCloudsEnabled(void) +{ + return m_bCloudsEnabled; +} + +bool CClientGame::SetBirdsEnabled(bool bEnabled) +{ + m_bBirdsEnabled = bEnabled; + return true; +} +bool CClientGame::GetBirdsEnabled(void) +{ + return m_bBirdsEnabled; +} + +#pragma code_seg(".text") +bool CClientGame::VerifySADataFiles(int iEnableClientChecks) +{ + int& iCheckStatus = g_pGame->GetCheckStatus(); + + if (!g_pGame->VerifySADataFileNames()) + iCheckStatus |= (1 << 11); + + __declspec(allocate(".text")) static char szVerifyData[][32] = {"data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", + "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", + "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", + "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", + "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", + "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", + "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", + "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", + "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", + "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", + "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", + "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74"}; + + CMD5Hasher hasher; + for (int i = 0; i < NUMELMS(szVerifyData); i += 2) + { + MD5 md5; + if (!hasher.Calculate(szVerifyData[i], md5) || memcmp(md5.data, szVerifyData[i + 1], 0x10)) + { + iCheckStatus |= (1 << i); + } + } + + if (iCheckStatus & iEnableClientChecks) + { + g_pCore->InitiateDataFilesFix(); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + return true; +} + +void CClientGame::InitVoice(bool bEnabled, unsigned int uiServerSampleRate, unsigned char ucQuality, unsigned int uiBitrate) +{ + if (m_pVoiceRecorder) + { + m_pVoiceRecorder->Init(bEnabled, uiServerSampleRate, ucQuality, uiBitrate); + } +} + +// +// If debug render mode is on, allow each element in range to draw some stuff +// +void CClientGame::DebugElementRender(void) +{ + if (!GetDevelopmentMode() || !GetShowCollision()) + return; + + CVector vecCameraPos; + m_pCamera->GetPosition(vecCameraPos); + float fDrawRadius = 200.f; + + // Get all entities within range + CClientEntityResult result; + GetClientSpatialDatabase()->SphereQuery(result, CSphere(vecCameraPos, fDrawRadius)); + + // For each entity found + for (CClientEntityResult::const_iterator it = result.begin(); it != result.end(); ++it) + { + CClientEntity* pEntity = *it; + if (pEntity->GetParent()) + pEntity->DebugRender(vecCameraPos, fDrawRadius); + } +} + +////////////////////////////////////////////////////////////////// +// Click +// +void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString& strTag, uint uiQuality, uint uiMaxBandwidth, uint uiMaxPacketSize, + CResource* pResource, uint uiServerSentTime) +{ + if (!pResource) + return; + + bool bAllowScreenUploadEnabled = 1; + g_pCore->GetCVars()->Get("allow_screen_upload", bAllowScreenUploadEnabled); + bool bWindowMinimized = g_pCore->IsWindowMinimized(); + + if (bWindowMinimized || !bAllowScreenUploadEnabled) + { + // If alt-tabbed or opt-out + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!bAllowScreenUploadEnabled) + pBitStream->Write((uchar)EPlayerScreenShotResult::DISABLED); + else + pBitStream->Write((uchar)EPlayerScreenShotResult::MINIMIZED); + pBitStream->Write(uiServerSentTime); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); + g_pNet->DeallocateNetBitStream(pBitStream); + } + else + { + // Do grab and send + SScreenShotArgs screenShotArgs; + screenShotArgs.uiMaxBandwidth = uiMaxBandwidth; + screenShotArgs.uiMaxPacketSize = uiMaxPacketSize; + screenShotArgs.usResourceNetId = pResource->GetNetID(); + screenShotArgs.strTag = strTag; + screenShotArgs.uiServerSentTime = uiServerSentTime; + m_ScreenShotArgList.push_back(screenShotArgs); + g_pCore->GetGraphics()->GetScreenGrabber()->QueueScreenShot(uiSizeX, uiSizeY, uiQuality, &CClientGame::StaticGottenPlayerScreenShot); + } +} + +////////////////////////////////////////////////////////////////// +// Callback from TakePlayerScreendsShot +// +void CClientGame::StaticGottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strError) +{ + if (g_pClientGame) + g_pClientGame->GottenPlayerScreenShot(pBuffer, uiTimeSpentInQueue, strError); +} + +////////////////////////////////////////////////////////////////// +// Break data into packets and put into delayed send list +// +void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strInError) +{ + SString strError = strInError; + + // Pop saved args + if (m_ScreenShotArgList.empty()) + return; + + SScreenShotArgs screenShotArgs = m_ScreenShotArgList.front(); + m_ScreenShotArgList.pop_front(); + const uint uiMaxBandwidth = Clamp(100, screenShotArgs.uiMaxBandwidth, 1000000); + const uint uiMaxPacketSize = Clamp(100, screenShotArgs.uiMaxPacketSize, 100000); + const ushort usResourceNetId = screenShotArgs.usResourceNetId; + const SString strTag = screenShotArgs.strTag; + const uint uiServerGrabTime = screenShotArgs.uiServerSentTime + uiTimeSpentInQueue; + + // Silently ignore if resource has been stopped + CResource* pResource = GetResourceManager()->GetResourceFromNetID(usResourceNetId); + if (!pResource) + return; + + // Validate buffer + if (strError.empty()) + { + if (!pBuffer || pBuffer->GetSize() == 0) + strError = "Buffer empty"; + } + + // Handle error + if (!strError.empty()) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write((uchar)EPlayerScreenShotResult::ERROR_); + pBitStream->Write(uiServerGrabTime); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + if (pBitStream->Version() >= 0x053) + pBitStream->WriteString(strError); + g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); + g_pNet->DeallocateNetBitStream(pBitStream); + return; + } + + // Calc constants stuff + const uint uiSendRate = Clamp(5, uiMaxBandwidth / uiMaxPacketSize, 20); + const long long llPacketInterval = 1000 / uiSendRate; + const uint uiTotalByteSize = pBuffer->GetSize(); + const char* pData = pBuffer->GetData(); + const uint uiBytesPerPart = std::min(std::min(std::max(100U, uiMaxBandwidth / uiSendRate), uiTotalByteSize), 30000U); + const uint uiNumParts = std::max(1U, (uiTotalByteSize + uiBytesPerPart - 1) / uiBytesPerPart); + + // Calc variables stuff + CTickCount tickCount = CTickCount::Now() + CTickCount(llPacketInterval); + uint uiBytesRemaining = uiTotalByteSize; + m_usNextScreenShotId++; + + // Make each packet + for (uint i = 0; i < uiNumParts; i++) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + + ushort usPartNumber = i; + ushort usBytesThisPart = std::min(uiBytesRemaining, uiBytesPerPart); + assert(usBytesThisPart != 0); + + pBitStream->Write((uchar)EPlayerScreenShotResult::SUCCESS); + pBitStream->Write(m_usNextScreenShotId); + pBitStream->Write(usPartNumber); + pBitStream->Write(usBytesThisPart); + pBitStream->Write(pData, usBytesThisPart); + + // Write more info if first part + if (usPartNumber == 0) + { + pBitStream->Write(uiServerGrabTime); + pBitStream->Write(uiTotalByteSize); + pBitStream->Write((ushort)uiNumParts); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + } + + // Add to delay send list + SDelayedPacketInfo delayedPacketInfo; + delayedPacketInfo.useTickCount = tickCount; + delayedPacketInfo.ucPacketID = PACKET_ID_PLAYER_SCREENSHOT; + delayedPacketInfo.pBitStream = pBitStream; + delayedPacketInfo.packetPriority = PACKET_PRIORITY_LOW; + delayedPacketInfo.packetReliability = PACKET_RELIABILITY_RELIABLE_ORDERED; + delayedPacketInfo.packetOrdering = PACKET_ORDERING_DATA_TRANSFER; + m_DelayedSendList.push_back(delayedPacketInfo); + + // Increment stuff + pData += usBytesThisPart; + uiBytesRemaining -= usBytesThisPart; + tickCount += CTickCount(llPacketInterval); + } + + assert(uiBytesRemaining == 0); +} + +////////////////////////////////////////////////////////////////// +// Process delay send list +// +void CClientGame::ProcessDelayedSendList(void) +{ + CTickCount tickCount = CTickCount::Now(); + + while (!m_DelayedSendList.empty()) + { + SDelayedPacketInfo& info = m_DelayedSendList.front(); + if (info.useTickCount > tickCount) + break; + + g_pNet->SendPacket(info.ucPacketID, info.pBitStream, info.packetPriority, info.packetReliability, info.packetOrdering); + g_pNet->DeallocateNetBitStream(info.pBitStream); + m_DelayedSendList.pop_front(); + } +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetWeaponTypesUsingBulletSync +// +// Set whether the local player will send bulletsync messages for the supplied weapon type +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetWeaponTypesUsingBulletSync(const std::set& weaponTypesUsingBulletSync) +{ + m_weaponTypesUsingBulletSync = weaponTypesUsingBulletSync; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::GetWeaponTypeUsesBulletSync +// +// Get whether the local player should send bulletsync messages for the supplied weapon type +// +////////////////////////////////////////////////////////////////// +bool CClientGame::GetWeaponTypeUsesBulletSync(eWeaponType weaponType) +{ + return MapContains(m_weaponTypesUsingBulletSync, weaponType); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetDevelopmentMode +// +// Special mode which enables commands such as showcol and showsound +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetDevelopmentMode(bool bEnable, bool bEnableWeb) +{ + m_bDevelopmentMode = bEnable; + + if (m_bDevelopmentMode) + g_pGame->GetAudio()->SetWorldSoundHandler(CClientGame::StaticWorldSoundHandler); + else + g_pGame->GetAudio()->SetWorldSoundHandler(NULL); + + if (g_pCore->IsWebCoreLoaded()) + g_pCore->GetWebCore()->SetTestModeEnabled(bEnableWeb); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::StaticWorldSoundHandler +// +// Handle callback from CAudioSA when a world sound is played +// +////////////////////////////////////////////////////////////////// +void CClientGame::StaticWorldSoundHandler(uint uiGroup, uint uiIndex) +{ + g_pClientGame->WorldSoundHandler(uiGroup, uiIndex); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::WorldSoundHandler +// +// Handle callback from CAudioSA when a world sound is played +// +////////////////////////////////////////////////////////////////// +void CClientGame::WorldSoundHandler(uint uiGroup, uint uiIndex) +{ + if (m_bShowSound) + m_pScriptDebugging->LogInformation(NULL, "%s - World sound group:%d index:%d", *GetLocalTimeString(false, true), uiGroup, uiIndex); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::IsUsingAlternatePulseOrder +// +// Returns true if should be using alternate pulse order +// +////////////////////////////////////////////////////////////////// +bool CClientGame::IsUsingAlternatePulseOrder(bool bAdvanceDelayCounter) +{ + if (m_MiscGameSettings.bUseAltPulseOrder) + { + // Only actually start using alternate pulse order after 100 frames + if (m_uiAltPulseOrderCounter >= 100) + return true; + else if (bAdvanceDelayCounter) + m_uiAltPulseOrderCounter++; + } + + return false; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::OutputServerInfo +// +// Output info about the connected server for player +// +////////////////////////////////////////////////////////////////// +void CClientGame::OutputServerInfo(void) +{ + SString strTotalOutput; + strTotalOutput += SString("Server info for %s", g_pNet->GetConnectedServer(true)); + strTotalOutput += "\n"; + strTotalOutput += SString("Ver: %s\n", *GetServerVersionSortable()); + strTotalOutput += SString("AC: %s\n", *m_strACInfo); + + { + SString strVoice; + if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) + strVoice += SString("Enabled - Sample rate:%d Quality:%d", m_pVoiceRecorder->GetSampleRate(), m_pVoiceRecorder->GetSampleQuality()); + else + strVoice += "Disabled"; + + strTotalOutput += SString("Voice: %s\n", *strVoice); + } + + { + SString strEnabledGlitches; + const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", + "Bad driveby hitboxes", "Quick stand"}; + for (uint i = 0; i < NUM_GLITCHES; i++) + { + if (IsGlitchEnabled(i)) + { + if (!strEnabledGlitches.empty()) + strEnabledGlitches += ", "; + if (i < NUMELMS(szGlitchNames)) + strEnabledGlitches += szGlitchNames[i]; + else + strEnabledGlitches += SString("Unknown(#%d)", i + 1); + } + } + if (strEnabledGlitches.empty()) + strEnabledGlitches = "None"; + strTotalOutput += SString("Glitches: %s\n", *strEnabledGlitches); + } + + { + SString strEnabledBulletSync; + for (std::set::iterator iter = m_weaponTypesUsingBulletSync.begin(); iter != m_weaponTypesUsingBulletSync.end(); ++iter) + { + eWeaponType weaponType = *iter; + if (!strEnabledBulletSync.empty()) + strEnabledBulletSync += ","; + strEnabledBulletSync += SString("%d", weaponType); + } + if (strEnabledBulletSync.empty()) + strEnabledBulletSync = "None"; + strTotalOutput += SString("Bullet sync weapons: %s\n", *strEnabledBulletSync); + } + + { + SString strVehExtrapolate; + if (m_VehExtrapolateSettings.bEnabled) + strVehExtrapolate += SString("Amount:%d%% (LimitMs:%d)", m_VehExtrapolateSettings.iScalePercent, m_VehExtrapolateSettings.iMaxMs); + else + strVehExtrapolate += "Disabled"; + + strTotalOutput += SString("Vehicle extrapolation: %s\n", *strVehExtrapolate); + } + + { + SString strTickRates; + strTickRates += SString("Plr:%d Cam:%d Ped:%d UnocVeh:%d KeyRot:%d KeyJoy:%d", g_TickRateSettings.iPureSync, g_TickRateSettings.iCamSync, + g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, + g_TickRateSettings.iKeySyncAnalogMove); + + strTotalOutput += SString("Tick rates: %s\n", *strTickRates); + } + + { + SString strSyncerDists; + strSyncerDists += SString("Ped:%d UnoccupiedVehicle:%d ", g_TickRateSettings.iPedSyncerDistance, g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); + + strTotalOutput += SString("Syncer distances: %s\n", *strSyncerDists); + } + + g_pCore->GetConsole()->Print(strTotalOutput); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::TellServerSomethingImportant +// +// Report misc important warnings/errors to the current server +// +////////////////////////////////////////////////////////////////// +void CClientGame::TellServerSomethingImportant(uint uiId, const SString& strMessage, uint uiSendLimitForThisId) +{ + g_pCore->GetConsole()->Print(strMessage); + AddReportLog(3400 + uiId, strMessage + g_pNet->GetConnectedServer(true), 10); + + if (uiSendLimitForThisId) + { + uint& uiCount = MapGet(m_SentMessageIds, uiId); + if (uiCount++ >= uiSendLimitForThisId) + return; + } + + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->WriteString(SString("%d,%s", uiId, *strMessage)); + g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE); + g_pNet->DeallocateNetBitStream(pBitStream); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::ChangeFloatPrecision +// +// Manage the change to high floating point precision +// +////////////////////////////////////////////////////////////////// +void CClientGame::ChangeFloatPrecision(bool bHigh) +{ + if (bHigh) + { + // Switch to 53 bit floating point precision on the first call + if (m_uiPrecisionCallDepth++ == 0) + _controlfp(_PC_53, MCW_PC); + } + else + { + // Even though is should never happen, m_uiPrecisionCallDepth is sometimes zero here + dassert(m_uiPrecisionCallDepth != 0); + if (m_uiPrecisionCallDepth != 0) + m_uiPrecisionCallDepth--; + // Switch back to 24 bit floating point precision on the last call + if (m_uiPrecisionCallDepth == 0) + _controlfp(_PC_24, MCW_PC); + } +} + +bool CClientGame::IsHighFloatPrecision(void) const +{ + return m_uiPrecisionCallDepth != 0; +} + +AnimationId CClientGame::DrivebyAnimationHandler(AnimationId animId, AssocGroupId animGroupId) +{ + // Only apply if all clients support the fix + if (!GetMiscGameSettings().bAllowBadDrivebyHitboxFix) + return animId; + + // If the glitch is enabled, don't apply the fix + if (IsGlitchEnabled(GLITCH_BADDRIVEBYHITBOX)) + return animId; + + // Bad animations are 232 and 236 of assoc group 72 + if (animGroupId != 72) + return animId; + + if (animId == 232) + return 235; + else if (animId == 236) + return 231; + + return animId; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetFileCacheRoot +// +// Figure out which directory to use for the client resource file cache +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetFileCacheRoot(void) +{ + if (g_pCore->GetCVars()->GetValue("share_file_cache") == false) + { + // Not sharing, so use current mod directory + m_strFileCacheRoot = GetModRoot(); + AddReportLog(7410, SString("CClientGame::SetFileCacheRoot - Not shared '%s'", *m_strFileCacheRoot)); + } + else + { + // Get shared directory + SString strFileCachePath = GetCommonRegistryValue("", "File Cache Path"); + // Check exists + if (!strFileCachePath.empty() && DirectoryExists(strFileCachePath)) + { + // Check writable + SString strTestFileName = PathJoin(strFileCachePath, "resources", "_test.tmp"); + if (FileSave(strTestFileName, "x")) + { + FileDelete(strTestFileName); + strTestFileName = PathJoin(strFileCachePath, "priv", "_test.tmp"); + if (FileSave(strTestFileName, "x")) + { + FileDelete(strTestFileName); + // Use shared directory + m_strFileCacheRoot = strFileCachePath; + AddReportLog(7411, SString("CClientGame::SetFileCacheRoot - Is shared '%s'", *m_strFileCacheRoot)); + return; + } + } + } + + // Otherwise set this install mod directory as shared + m_strFileCacheRoot = GetModRoot(); + SetCommonRegistryValue("", "File Cache Path", m_strFileCacheRoot); + + if (strFileCachePath.empty()) + AddReportLog(7412, SString("CClientGame::SetFileCacheRoot - Initial setting '%s'", *m_strFileCacheRoot)); + else + AddReportLog(7413, SString("CClientGame::SetFileCacheRoot - Change shared from '%s' to '%s'", *strFileCachePath, *m_strFileCacheRoot)); + } +} + +bool CClientGame::TriggerBrowserRequestResultEvent(const std::unordered_set& newPages) +{ + CLuaArguments Arguments; + CLuaArguments LuaTable; + int i = 0; + + for (auto& domain : newPages) + { + LuaTable.PushNumber(++i); + LuaTable.PushString(domain); + } + Arguments.PushTable(&LuaTable); + + return GetRootEntity()->CallEvent("onClientBrowserWhitelistChange", Arguments, false); +} + +void CClientGame::RestreamModel(unsigned short usModel) +{ + // Is this a vehicle ID? + if (CClientVehicleManager::IsValidModel(usModel)) + { + // Stream the vehicles of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetVehicleManager()->RestreamVehicles(usModel); + } + + // Is this an object ID? + else if (CClientObjectManager::IsValidModel(usModel)) + { + if (CClientPedManager::IsValidWeaponModel(usModel)) + { + // Stream the weapon of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetPedManager()->RestreamWeapon(usModel); + m_pManager->GetPickupManager()->RestreamPickups(usModel); + } + // Stream the objects of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetObjectManager()->RestreamObjects(usModel); + g_pGame->GetModelInfo(usModel)->RestreamIPL(); + } + // Is this an ped ID? + else if (CClientPlayerManager::IsValidModel(usModel)) + { + // Stream the ped of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetPedManager()->RestreamPeds(usModel); + } + else + + // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect + if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) + m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); +} + +void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) +{ + m_mapOfIfpPointers[u32BlockNameHash] = pIFP; +} + +std::shared_ptr CClientGame::GetIFPPointerFromMap(const unsigned int u32BlockNameHash) +{ + auto it = m_mapOfIfpPointers.find(u32BlockNameHash); + if (it != m_mapOfIfpPointers.end()) + { + return it->second; + } + return nullptr; +} + +void CClientGame::RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash) +{ + m_mapOfIfpPointers.erase(u32BlockNameHash); +} + +void CClientGame::InsertPedPointerToSet(CClientPed* pPed) +{ + m_setOfPedPointers.insert(pPed); +} + +void CClientGame::RemovePedPointerFromSet(CClientPed* pPed) +{ + m_setOfPedPointers.erase(pPed); +} + +CClientPed* CClientGame::GetClientPedByClump(const RpClump& Clump) +{ + for (auto& pPed : m_setOfPedPointers) + { + CEntity* pEntity = pPed->GetGameEntity(); + if (pEntity != nullptr) + { + if (pEntity->GetRpClump() != nullptr) + { + const RpClump& entityClump = *pEntity->GetRpClump(); + if (std::addressof(entityClump) == std::addressof(Clump)) + { + return pPed; + } + } + } + } + return nullptr; +} + +void CClientGame::OnClientIFPUnload(const std::shared_ptr& IFP) +{ + IFP->MarkAsUnloading(); + for (auto& pPed : m_setOfPedPointers) + { + // Remove IFP animations from replaced animations of peds/players + pPed->RestoreAnimations(IFP); + + // Make sure that streamed in pulses or changing model does not accidently + // play our custom animation. We can do that by making the custom animation + // untriggerable + if (pPed->GetCustomAnimationBlockNameHash() == IFP->GetBlockNameHash()) + { + if (pPed->IsCustomAnimationPlaying()) + { + pPed->SetCustomAnimationUntriggerable(); + } + + // Important! As we are using a shared_ptr, we need to decrement the reference counter + // by setting the shared_ptr to nullptr, this will avoid memory leak + if (!pPed->IsNextAnimationCustom() && pPed->IsCurrentAnimationCustom()) + { + pPed->DereferenceCustomAnimationBlock(); + } + } + } +} + +void CClientGame::InsertAnimationAssociationToMap(CAnimBlendAssociationSAInterface* pAnimAssociation, const std::shared_ptr& pIFPAnimations) +{ + m_mapOfCustomAnimationAssociations[pAnimAssociation] = pIFPAnimations; +} + +void CClientGame::RemoveAnimationAssociationFromMap(CAnimBlendAssociationSAInterface* pAnimAssociation) +{ + m_mapOfCustomAnimationAssociations.erase(pAnimAssociation); +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index d98579e147f..9445398f4cb 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -1,3877 +1,3887 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto - * LICENSE: See LICENSE in the top level directory - * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp - * PURPOSE: Lua definitions class - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#include "StdInc.h" - -void CLuaGUIDefs::LoadFunctions(void) -{ - CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); - CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); - CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); - CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); - - CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); - CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); - CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); - CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); - CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); - CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); - - CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); - CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); - CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); - - CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); - CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); - CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); - CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); - CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); - CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); - CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); - CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); - CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); - CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); - CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); - CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); - CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); - CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); - CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); - CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); - - CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); - CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); - CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); - CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); - CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); - - CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); - CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); - CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); - CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); - CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); - CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); - CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); - CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); - CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); - CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); - CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); - CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); - CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); - CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); - CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); - CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); - CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); - CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); - CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); - CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); - CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); - CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); - - CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); - CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); - CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); - CLuaCFunctions::AddFunction("guiSetText", GUISetText); - CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); - CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); - CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); - CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); - - CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); - CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); - - CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); - - CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); - CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); - CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); - CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); - CLuaCFunctions::AddFunction("guiGetText", GUIGetText); - CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); - CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); - CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); - CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); - CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); - - CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); - - CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); - CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); - - CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); - - CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); - CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); - CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); - CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); - CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); - CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); - - CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); - CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); - CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); - CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); - CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); - CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); - - CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); - CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); - - CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); - CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); - - CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); - - CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); - CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); - CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); - CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); - CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); - CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); - CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); -} - -void CLuaGUIDefs::AddClass(lua_State* luaVM) -{ - AddGuiElementClass(luaVM); - AddGuiFontClass(luaVM); - AddGuiWindowClass(luaVM); - AddGuiButtonClass(luaVM); - AddGuiEditClass(luaVM); - AddGuiLabelClass(luaVM); - AddGuiMemoClass(luaVM); - AddGuiImageClass(luaVM); - AddGuiComboBoxClass(luaVM); - AddGuiCheckBoxClass(luaVM); - AddGuiRadioButtonClass(luaVM); - AddGuiScrollPaneClass(luaVM); - AddGuiScrollBarClass(luaVM); - AddGuiProgressBarClass(luaVM); - AddGuiGridlistClass(luaVM); - AddGuiTabPanelClass(luaVM); - AddGuiTabClass(luaVM); -} - -// TODO: vector class -void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "bringToFront", "guiBringToFront"); - lua_classfunction(luaVM, "moveToBack", "guiMoveToBack"); - - lua_classfunction(luaVM, "isChatBoxInputActive", "isChatBoxInputActive"); - lua_classfunction(luaVM, "isConsoleActive", "isConsoleActive"); - lua_classfunction(luaVM, "isDebugViewActive", "isDebugViewActive"); - lua_classfunction(luaVM, "setDebugViewActive", "setDebugViewActive"); - lua_classfunction(luaVM, "isMainMenuActive", "isMainMenuActive"); - lua_classfunction(luaVM, "isMTAWindowActive", "isMTAWindowActive"); - lua_classfunction(luaVM, "isTransferBoxActive", "isTransferBoxActive"); - lua_classfunction(luaVM, "isInputEnabled", "guiGetInputEnabled"); - lua_classfunction(luaVM, "getInputMode", "guiGetInputMode"); - lua_classfunction(luaVM, "getCursorType", "guiGetCursorType"); - - lua_classfunction(luaVM, "getScreenSize", "guiGetScreenSize"); - lua_classfunction(luaVM, "getProperties", "guiGetProperties"); - lua_classfunction(luaVM, "getAlpha", "guiGetAlpha"); - lua_classfunction(luaVM, "getFont", "guiGetFont"); - lua_classfunction(luaVM, "getEnabled", "guiGetEnabled"); - lua_classfunction(luaVM, "getVisible", "guiGetVisible"); - lua_classfunction(luaVM, "getText", "guiGetText"); - lua_classfunction(luaVM, "getPosition", "guiGetPosition"); - lua_classfunction(luaVM, "getSize", "guiGetSize"); - lua_classfunction(luaVM, "getProperty", "guiGetProperty"); - - lua_classfunction(luaVM, "setInputEnabled", "guiSetInputEnabled"); - lua_classfunction(luaVM, "setAlpha", "guiSetAlpha"); - lua_classfunction(luaVM, "setEnabled", "guiSetEnabled"); - lua_classfunction(luaVM, "setFont", "guiSetFont"); - lua_classfunction(luaVM, "setVisible", "guiSetVisible"); - lua_classfunction(luaVM, "setText", "guiSetText"); - lua_classfunction(luaVM, "setInputMode", "guiSetInputMode"); - lua_classfunction(luaVM, "setProperty", "guiSetProperty"); - lua_classfunction(luaVM, "setPosition", "guiSetPosition"); - lua_classfunction(luaVM, "setSize", "guiSetSize"); - - lua_classvariable(luaVM, "chatBoxInputActive", NULL, "isChatBoxInputActive"); - lua_classvariable(luaVM, "consoleActive", NULL, "isConsoleActive"); - lua_classvariable(luaVM, "debugViewActive", "setDebugViewActive", "isDebugViewActive"); - lua_classvariable(luaVM, "mainMenuActive", NULL, "isMainMenuActive"); - lua_classvariable(luaVM, "mtaWindowActive", NULL, "isMTAWindowActive"); - lua_classvariable(luaVM, "transferBoxActive", NULL, "isTransferBoxActive"); - lua_classvariable(luaVM, "inputEnabled", "guiSetInputEnabled", "guiGetInputEnabled"); - lua_classvariable(luaVM, "inputMode", "guiGetInputMode", "guiSetInputMode"); - lua_classvariable(luaVM, "cursorAlpha", "setCursorAlpha", "getCursorAlpha"); - lua_classvariable(luaVM, "cursorType", NULL, "guiGetCursorType"); - lua_classvariable(luaVM, "font", "guiSetFont", "guiGetFont"); - lua_classvariable(luaVM, "visible", "guiSetVisible", "guiGetVisible"); - lua_classvariable(luaVM, "properties", NULL, "guiGetProperties"); - lua_classvariable(luaVM, "alpha", "guiSetAlpha", "guiGetAlpha"); - lua_classvariable(luaVM, "enabled", "guiSetEnabled", "guiGetEnabled"); - lua_classvariable(luaVM, "text", "guiSetText", "guiGetText"); - lua_classvariable(luaVM, "size", "guiSetSize", "guiGetSize"); - lua_classvariable(luaVM, "position", "guiSetPosition", "guiGetPosition"); - lua_classvariable(luaVM, "screenSize", NULL, "guiGetScreenSize"); - // lua_classvariable ( luaVM, "property" "guiSetProperty", "guiGetProperty" ); todo: .property[name] = value - - lua_registerclass(luaVM, "GuiElement", "Element"); -} - -void CLuaGUIDefs::AddGuiWindowClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateWindow"); - lua_classfunction(luaVM, "setMovable", "guiWindowSetMovable"); - lua_classfunction(luaVM, "setSizable", "guiWindowSetSizable"); - - lua_classvariable(luaVM, "movable", "guiWindowSetMovable", NULL); - lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", NULL); - - lua_registerclass(luaVM, "GuiWindow", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiButtonClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateButton"); - - lua_registerclass(luaVM, "GuiButton", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateEdit"); - lua_classfunction(luaVM, "getCaretIndex", "guiEditGetCaretIndex"); - lua_classfunction(luaVM, "setCaretIndex", "guiEditSetCaretIndex"); - lua_classfunction(luaVM, "setReadOnly", "guiEditSetReadOnly"); - lua_classfunction(luaVM, "setMasked", "guiEditSetMasked"); - lua_classfunction(luaVM, "setMaxLength", "guiEditSetMaxLength"); - - lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); - lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", "guiEditIsReadOnly"); - lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); - lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); - - lua_registerclass(luaVM, "GuiEdit", "GuiElement"); -} - -// TODO: specials -void CLuaGUIDefs::AddGuiLabelClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateLabel"); - - lua_classfunction(luaVM, "getFontHeight", "guiLabelGetFontHeight"); - lua_classfunction(luaVM, "getTextExtent", "guiLabelGetTextExtent"); - lua_classfunction(luaVM, "getColor", "guiLabelGetColor"); - - lua_classfunction(luaVM, "setColor", "guiLabelSetColor"); - lua_classfunction(luaVM, "setHorizontalAlign", "guiLabelSetHorizontalAlign"); - lua_classfunction(luaVM, "setVerticalAlign", "guiLabelSetVerticalAlign"); - - lua_classvariable(luaVM, "horizontalAlign", "guiLabelSetHorizontalAlign", NULL); - lua_classvariable(luaVM, "verticalAlign", "guiLabelSetVerticalAlign", NULL); - lua_classvariable(luaVM, "fontHeight", NULL, "guiLabelGetFontHeight"); - lua_classvariable(luaVM, "textExtent", NULL, "guiLabelGetTextExtent"); - // lua_classvariable ( luaVM, "color", "guiLabelGetColor", "guiLabelSetColor" ); - - lua_registerclass(luaVM, "GuiLabel", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiMemoClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateMemo"); - - lua_classfunction(luaVM, "getCaretIndex", "guiMemoGetCaretIndex"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); - - lua_classfunction(luaVM, "setCaretIndex", "guiMemoSetCaretIndex"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiMemoSetVerticalScrollPosition"); - lua_classfunction(luaVM, "setReadOnly", "guiMemoSetReadOnly"); - - lua_classvariable(luaVM, "caretIndex", "guiMemoSetCaretIndex", "guiMemoGetCaretIndex"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiMemoSetVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); - lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", "guiMemoIsReadOnly"); - - lua_registerclass(luaVM, "GuiMemo", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiImageClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateStaticImage"); - lua_classfunction(luaVM, "loadImage", "guiStaticImageLoadImage"); - - lua_classvariable(luaVM, "image", "guiStaticImageLoadImage", NULL); - - lua_registerclass(luaVM, "GuiStaticImage", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiComboBoxClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateComboBox"); - lua_classfunction(luaVM, "addItem", "guiComboBoxAddItem"); - lua_classfunction(luaVM, "clear", "guiComboBoxClear"); - lua_classfunction(luaVM, "removeItem", "guiComboBoxRemoveItem"); - - lua_classfunction(luaVM, "getSelected", "guiComboBoxGetSelected"); - lua_classfunction(luaVM, "getItemText", "guiComboBoxGetItemText"); - - lua_classfunction(luaVM, "setItemText", "guiComboBoxSetItemText"); - lua_classfunction(luaVM, "setSelected", "guiComboBoxSetSelected"); - - lua_classvariable(luaVM, "selected", "guiComboBoxSetSelected", "guiComboBoxGetSelected"); - - lua_registerclass(luaVM, "GuiComboBox", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiCheckBoxClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateCheckBox"); - - lua_classfunction(luaVM, "getSelected", "guiCheckBoxGetSelected"); - - lua_classfunction(luaVM, "setSelected", "guiCheckBoxSetSelected"); - - lua_classvariable(luaVM, "selected", "guiCheckBoxSetSelected", "guiCheckBoxGetSelected"); - - lua_registerclass(luaVM, "GuiCheckBox", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiRadioButtonClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateRadioButton"); - - lua_classfunction(luaVM, "getSelected", "guiRadioButtonGetSelected"); - - lua_classfunction(luaVM, "setSelected", "guiRadioButtonSetSelected"); - - lua_classvariable(luaVM, "selected", "guiRadioButtonSetSelected", "guiRadioButtonGetSelected"); - - lua_registerclass(luaVM, "GuiRadioButton", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiScrollPaneClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateScrollPane"); - - lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); - - lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition"); - lua_classfunction(luaVM, "setScrollBars", "guiScrollPaneSetScrollBars"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition"); - - lua_classvariable(luaVM, "horizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); - - lua_registerclass(luaVM, "GuiScrollPane", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiScrollBarClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateScrollBar"); - - lua_classfunction(luaVM, "getScrollPosition", "guiScrollBarGetScrollPosition"); - - lua_classfunction(luaVM, "setScrollPosition", "guiScrollBarSetScrollPosition"); - - lua_classvariable(luaVM, "scrollPosition", "guiScrollBarSetScrollPosition", "guiScrollBarGetScrollPosition"); - - lua_registerclass(luaVM, "GuiScrollBar", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiProgressBarClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateProgressBar"); - - lua_classfunction(luaVM, "getProgress", "guiProgressBarGetProgress"); - - lua_classfunction(luaVM, "setProgress", "guiProgressBarSetProgress"); - - lua_classvariable(luaVM, "progress", "guiProgressBarSetProgress", "guiProgressBarGetProgress"); - - lua_registerclass(luaVM, "GuiProgressBar", "GuiElement"); -} - -// TODO: special tables -void CLuaGUIDefs::AddGuiGridlistClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateGridList"); - lua_classfunction(luaVM, "addColumn", "guiGridListAddColumn"); - lua_classfunction(luaVM, "addRow", "guiGridListAddRow"); - lua_classfunction(luaVM, "autoSizeColumn", "guiGridListAutoSizeColumn"); - lua_classfunction(luaVM, "clear", "guiGridListClear"); - lua_classfunction(luaVM, "insertRowAfter", "guiGridListInsertRowAfter"); - lua_classfunction(luaVM, "removeColumn", "guiGridListRemoveColumn"); - lua_classfunction(luaVM, "removeRow", "guiGridListRemoveRow"); - - lua_classfunction(luaVM, "getItemData", "guiGridListGetItemData"); - lua_classfunction(luaVM, "getItemText", "guiGridListGetItemText"); - lua_classfunction(luaVM, "getRowCount", "guiGridListGetRowCount"); - lua_classfunction(luaVM, "getSelectedItem", "guiGridListGetSelectedItem"); - lua_classfunction(luaVM, "getItemColor", "guiGridListGetItemColor"); - lua_classfunction(luaVM, "getColumnTitle", "guiGridListGetColumnTitle"); - lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); - lua_classfunction(luaVM, "getSelectedCount", "guiGridListGetSelectedCount"); - lua_classfunction(luaVM, "getSelectedItems", "guiGridListGetSelectedItems"); - lua_classfunction(luaVM, "getColumnCount", "guiGridListGetColumnCount"); - - lua_classfunction(luaVM, "setItemData", "guiGridListSetItemData"); - lua_classfunction(luaVM, "setItemText", "guiGridListSetItemText"); - lua_classfunction(luaVM, "setScrollBars", "guiGridListSetScrollBars"); - lua_classfunction(luaVM, "setSelectedItem", "guiGridListSetSelectedItem"); - lua_classfunction(luaVM, "setSelectionMode", "guiGridListSetSelectionMode"); - lua_classfunction(luaVM, "setSortingEnabled", "guiGridListSetSortingEnabled"); - lua_classfunction(luaVM, "setColumnWidth", "guiGridListSetColumnWidth"); - lua_classfunction(luaVM, "setItemColor", "guiGridListSetItemColor"); - lua_classfunction(luaVM, "setColumnTitle", "guiGridListSetColumnTitle"); - lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiGridListSetHorizontalScrollPosition"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiGridListSetVerticalScrollPosition"); - - lua_classvariable(luaVM, "rowCount", NULL, "guiGridListGetRowCount"); - lua_classvariable(luaVM, "selectedCount", NULL, "guiGridListGetSelectedCount"); - lua_classvariable(luaVM, "selectedItems", NULL, "guiGridListGetSelectedItems"); - lua_classvariable(luaVM, "columnCount", NULL, "guiGridListGetColumnCount"); - lua_classvariable(luaVM, "selectionMode", "guiGridListSetSelectionMode", NULL); - lua_classvariable(luaVM, "sortingEnabled", "guiGridListSetSortingEnabled", NULL); - lua_classvariable(luaVM, "horizontalScrollPosition", "guiGridListSetHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiGridListGetVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); - // lua_classvariable ( luaVM, "selectedItem", NULL, "guiGridListGetSelectedItem" ); table - // lua_classvariable ( luaVM, "selectedItem", "guiGridListSetSelectedItem", NULL ); .selectedItem[column] = row (row in column) table - // lua_classvariable ( luaVM, "itemColor", "setItemColor", "getItemColor" ); table - // lua_classvariable ( luaVM, "columnTitle", "setColumnTitle", "getColumnTitle" ); table - - lua_registerclass(luaVM, "GuiGridList", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiTabPanelClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateTabPanel"); - - lua_classfunction(luaVM, "getSelectedTab", "guiGetSelectedTab"); - - lua_classfunction(luaVM, "setSelectedTab", "guiSetSelectedTab"); - - lua_classvariable(luaVM, "selectedTab", "guiSetSelectedTab", "guiGetSelectedTab"); - - lua_registerclass(luaVM, "GuiTabPanel", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiTabClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateTab"); - lua_classfunction(luaVM, "delete", "guiDeleteTab"); - - lua_registerclass(luaVM, "GuiTab", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiFontClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateFont"); - - lua_registerclass(luaVM, "GuiFont", "Element"); -} - -int CLuaGUIDefs::GUIGetInputEnabled(lua_State* luaVM) -{ - lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIGetInputEnabled()); - return 1; -} - -int CLuaGUIDefs::GUISetInputEnabled(lua_State* luaVM) -{ - // bool guiSetInputEnabled ( bool enabled ) - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetInputMode(enabled ? INPUTMODE_NO_BINDS : INPUTMODE_ALLOW_BINDS); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetInputMode(lua_State* luaVM) -{ - // bool guiSetInputMode ( string mode ) - eInputMode mode; - - CScriptArgReader argStream(luaVM); - argStream.ReadEnumString(mode); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetInputMode(mode); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetInputMode(lua_State* luaVM) -{ - eInputMode mode = CStaticFunctionDefinitions::GUIGetInputMode(); - lua_pushstring(luaVM, EnumToString(mode)); - return 1; -} - -int CLuaGUIDefs::GUIIsChatBoxInputActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsChatInputEnabled()); - return 1; -} - -int CLuaGUIDefs::GUIIsConsoleActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->GetConsole()->IsVisible()); - return 1; -} - -int CLuaGUIDefs::GUIIsDebugViewActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsDebugVisible()); - return 1; -} - -int CLuaGUIDefs::GUISetDebugViewActive(lua_State* luaVM) -{ - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - g_pCore->SetDebugVisible(enabled); - - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIIsMainMenuActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsMenuVisible()); - return 1; -} - -int CLuaGUIDefs::GUIIsMTAWindowActive(lua_State* luaVM) -{ - bool bActive = - (g_pCore->IsChatInputEnabled() || g_pCore->IsMenuVisible() || g_pCore->GetConsole()->IsVisible() || g_pClientGame->GetTransferBox()->IsVisible()); - - lua_pushboolean(luaVM, bActive); - return 1; -} - -int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); - return 1; -} - -int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) -{ - bool bEnabled; - CScriptArgReader argStream(luaVM); - argStream.ReadBool(bEnabled); - - if (!argStream.HasErrors()) - { - g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - return 1; -} - -int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); - return 1; -} - -int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) -{ - // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) - CVector2D position; - CVector2D size; - SString titleBarText; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(titleBarText); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateWindow(*pLuaMain, position, size, titleBarText, relative); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateLabel(lua_State* luaVM) -{ - // element guiCreateLabel ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateLabel(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateStaticImage(lua_State* luaVM) -{ - // element guiCreateStaticImage ( float x, float y, float width, float height, string path, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString path; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(path); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CResource* pResource = pLuaMain->GetResource(); - SString strPath; - if (CResourceManager::ParseResourcePathInput(path, pResource, &strPath)) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateStaticImage(*pLuaMain, position, size, strPath, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - else - argStream.SetCustomError(path, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateButton(lua_State* luaVM) -{ - // element guiCreateButton ( float x, float y, float width, float height, string text, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateButton(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateProgressBar(lua_State* luaVM) -{ - // element guiCreateProgressBar ( float x, float y, float width, float height, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateProgressBar(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateCheckBox(lua_State* luaVM) -{ - // element guiCreateCheckBox ( float x, float y, float width, float height, string text, bool selected, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool selected; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(selected); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateCheckBox(*pLuaMain, position, size, text, selected, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateRadioButton(lua_State* luaVM) -{ - // element guiCreateRadioButton ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateRadioButton(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateEdit(lua_State* luaVM) -{ - // gui-edit guiCreateEdit ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateEdit(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateMemo(lua_State* luaVM) -{ - // gui-memo guiCreateMemo ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateMemo(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateGridList(lua_State* luaVM) -{ - // element guiCreateGridList ( float x, float y, float width, float height, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateGridList(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateScrollPane(lua_State* luaVM) -{ - // element guiCreateScrollPane( float x, float y, float width, float height, bool relative, [gui-element parent = nil]) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollPane(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateScrollBar(lua_State* luaVM) -{ - // gui-scrollbar guiCreateScrollBar ( float x, float y, float width, float height, bool horizontal, bool relative, [gui-element parent = nil]) - CVector2D position; - CVector2D size; - bool horizontal; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(horizontal); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollBar(*pLuaMain, position, size, horizontal, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateTabPanel(lua_State* luaVM) -{ - // element guiCreateTabPanel ( float x, float y, float width, float height, bool relative, [element parent = nil ] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTabPanel(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIStaticImageLoadImage(lua_State* luaVM) -{ - // bool guiStaticImageLoadImage ( element theElement, string filename ) - CClientGUIElement* theElement; - SString filename; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadString(filename); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CResource* pResource = pLuaMain->GetResource(); - SString strPath; - if (CResourceManager::ParseResourcePathInput(filename, pResource, &strPath)) - { - if (CStaticFunctionDefinitions::GUIStaticImageLoadImage(*theElement, strPath)) - { - lua_pushboolean(luaVM, true); - return 1; - } - else - argStream.SetCustomError(filename, "Error loading image"); - } - else - argStream.SetCustomError(filename, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIStaticImageGetNativeSize(lua_State* luaVM) -{ - // bool guiStaticImageGetNativeSize ( element theElement, string filename ) - CClientGUIElement* theElement; - CVector2D vecSize; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - if (CStaticFunctionDefinitions::GUIStaticImageGetNativeSize(*theElement, vecSize)) - { - lua_pushnumber(luaVM, vecSize.fX); - lua_pushnumber(luaVM, vecSize.fY); - return 2; - } - - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateTab(lua_State* luaVM) -{ - // element guiCreateTab ( string text, element parent ) - SString text; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadString(text); - argStream.ReadUserData(parent); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTab(*pLuaMain, text, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetSelectedTab(lua_State* luaVM) -{ - // element guiGetSelectedTab ( element tabPanel ) - CClientGUIElement* tabPanel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabPanel); - - if (!argStream.HasErrors()) - { - CClientGUIElement* pTab = CStaticFunctionDefinitions::GUIGetSelectedTab(*tabPanel); - lua_pushelement(luaVM, pTab); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetSelectedTab(lua_State* luaVM) -{ - // bool guiSetSelectedTab ( element tabPanel, element theTab ) - CClientGUIElement* tabPanel; - CClientGUIElement* theTab; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabPanel); - argStream.ReadUserData(theTab); - - if (!argStream.HasErrors()) - { - if (CStaticFunctionDefinitions::GUISetSelectedTab(*tabPanel, *theTab)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIDeleteTab(lua_State* luaVM) -{ - // bool guiDeleteTab ( element tabToDelete, element tabPanel ) - CClientGUIElement* tabToDelete; - CClientGUIElement* tabPanel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabToDelete); - argStream.ReadUserData(tabPanel); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - if (CStaticFunctionDefinitions::GUIDeleteTab(*pLuaMain, tabToDelete, tabPanel)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetText(lua_State* luaVM) -{ - // bool guiSetText ( element guiElement, string text ) - CClientGUIElement* guiElement; - SString text; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(text); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetText(*guiElement, text); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetFont(lua_State* luaVM) -{ - // bool guiSetFont ( element guiElement, mixed font ) - CClientGUIElement* guiElement; - SString strFontName; - CClientGuiFont* pGuiFontElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - MixedReadGuiFontString(argStream, strFontName, "default-normal", pGuiFontElement); - - if (!argStream.HasErrors()) - { - if (guiElement->SetFont(strFontName, pGuiFontElement)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIBringToFront(lua_State* luaVM) -{ - // bool guiBringToFront ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - if (CStaticFunctionDefinitions::GUIBringToFront(*guiElement)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMoveToBack(lua_State* luaVM) -{ - // bool guiMoveToBack( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMoveToBack(*guiElement); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIRadioButtonSetSelected(lua_State* luaVM) -{ - // bool guiRadioButtonSetSelected ( element guiRadioButton, bool state ) - CClientGUIElement* guiRadioButton; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiRadioButton); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIRadioButtonSetSelected(*guiRadioButton, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICheckBoxSetSelected(lua_State* luaVM) -{ - // bool guiCheckBoxSetSelected ( element theCheckbox, bool state ) - CClientGUIElement* theCheckbox; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theCheckbox); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUICheckBoxSetSelected(*theCheckbox, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIRadioButtonGetSelected(lua_State* luaVM) -{ - // bool guiRadioButtonGetSelected( element guiRadioButton ) - CClientGUIElement* guiRadioButton; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiRadioButton); - - if (!argStream.HasErrors()) - { - bool bResult = static_cast(guiRadioButton->GetCGUIElement())->GetSelected(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICheckBoxGetSelected(lua_State* luaVM) -{ - // bool guiCheckBoxGetSelected ( element theCheckbox ) - CClientGUIElement* theCheckbox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theCheckbox); - - if (!argStream.HasErrors()) - { - bool bResult = static_cast(theCheckbox->GetCGUIElement())->GetSelected(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIProgressBarSetProgress(lua_State* luaVM) -{ - // bool guiProgressBarSetProgress ( progressBar theProgressbar, float progress ) - CClientGUIElement* theProgressbar; - float progress; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theProgressbar); - argStream.ReadNumber(progress); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIProgressBarSetProgress(*theProgressbar, static_cast(progress)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollBarSetScrollPosition(lua_State* luaVM) -{ - // bool guiScrollBarSetScrollPosition ( gui-scrollBar theScrollBar, float amount ) - CClientGUIElement* theScrollBar; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollBar); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollBarSetScrollPosition(*theScrollBar, static_cast(amount)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetHorizontalScrollPosition(lua_State* luaVM) -{ - // bool guiScrollPaneSetHorizontalScrollPosition ( gui-scrollPane theScrollPane, float amount ) - CClientGUIElement* theScrollPane; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetHorizontalScrollPosition(*theScrollPane, amount); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiScrollPaneSetVerticalScrollPosition ( gui-scrollPane theScrollPane, float amount ) - CClientGUIElement* theScrollPane; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetVerticalScrollPosition(*theScrollPane, amount); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIProgressBarGetProgress(lua_State* luaVM) -{ - // float guiProgressBarGetProgress ( progressBar theProgressbar ); - CClientGUIElement* theProgressbar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theProgressbar); - - if (!argStream.HasErrors()) - { - int iProgress = (int)(static_cast(theProgressbar->GetCGUIElement())->GetProgress() * 100.0f + 0.5f); - lua_pushnumber(luaVM, iProgress); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneGetHorizontalScrollPosition(lua_State* luaVM) -{ - // float guiScrollPaneGetHorizontalScrollPosition ( gui-scrollPane theScrollPane ) - CClientGUIElement* theScrollPane; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - - if (!argStream.HasErrors()) - { - float fPos = static_cast(theScrollPane->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiScrollPaneGetVerticalScrollPosition ( gui-scrollPane theScrollPane ) - CClientGUIElement* theScrollPane; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - - if (!argStream.HasErrors()) - { - float fPos = static_cast(theScrollPane->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollBarGetScrollPosition(lua_State* luaVM) -{ - // float guiScrollBarGetScrollPosition ( gui-scrollBar theScrollBar ) - CClientGUIElement* theScrollBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollBar); - - if (!argStream.HasErrors()) - { - int iPos = (int)(static_cast(theScrollBar->GetCGUIElement())->GetScrollPosition() * 100.0f); - lua_pushnumber(luaVM, iPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetText(lua_State* luaVM) -{ - // string guiGetText ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - SString strText = guiElement->GetCGUIElement()->GetText(); - lua_pushstring(luaVM, strText); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetFont(lua_State* luaVM) -{ - // string,font guiGetFont ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - CClientGuiFont* pGuiFontElement; - SString strFontName = guiElement->GetFont(&pGuiFontElement); - - if (strFontName != "") - lua_pushstring(luaVM, strFontName); - else - lua_pushnil(luaVM); - lua_pushelement(luaVM, pGuiFontElement); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetSize(lua_State* luaVM) -{ - // float float guiGetSize ( element theElement, bool relative ) - CClientGUIElement* theElement; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CVector2D Size; - theElement->GetCGUIElement()->GetSize(Size, relative); - - lua_pushnumber(luaVM, Size.fX); - lua_pushnumber(luaVM, Size.fY); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetScreenSize(lua_State* luaVM) -{ - const CVector2D Size = CStaticFunctionDefinitions::GUIGetScreenSize(); - - lua_pushnumber(luaVM, Size.fX); - lua_pushnumber(luaVM, Size.fY); - return 2; -} - -int CLuaGUIDefs::GUIGetPosition(lua_State* luaVM) -{ - // float, float guiGetPosition ( element guiElement, bool relative ) - CClientGUIElement* guiElement; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CVector2D Pos; - guiElement->GetCGUIElement()->GetPosition(Pos, relative); - - lua_pushnumber(luaVM, Pos.fX); - lua_pushnumber(luaVM, Pos.fY); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetAlpha(lua_State* luaVM) -{ - // bool guiSetAlpha ( element guielement, float alpha ) - CClientGUIElement* guiElement; - float alpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(alpha); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetAlpha(*guiElement, Clamp(0.0f, alpha, 1.0f)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetAlpha(lua_State* luaVM) -{ - // int guiGetAlpha ( element guiElement [, bool effectiveAlpha = false] ) - CClientGUIElement* guiElement; - bool bEffectiveAlpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(bEffectiveAlpha, false); - - if (!argStream.HasErrors()) - { - float fAlpha = !bEffectiveAlpha ? guiElement->GetCGUIElement()->GetAlpha() : guiElement->GetCGUIElement()->GetEffectiveAlpha(); - lua_pushnumber(luaVM, fAlpha); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetVisible(lua_State* luaVM) -{ - // bool guiSetVisible ( element guiElement, bool state ) - CClientGUIElement* guiElement; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetVisible(*guiElement, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetEnabled(lua_State* luaVM) -{ - // bool guiSetEnabled ( element guiElement, bool enabled ) - CClientGUIElement* guiElement; - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetEnabled(*guiElement, enabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetProperty(lua_State* luaVM) -{ - // bool guiSetProperty ( element guiElement, string property, string value ) - CClientGUIElement* guiElement; - SString property; - SString value; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(property); - argStream.ReadString(value); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetProperty(*guiElement, property, value); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetVisible(lua_State* luaVM) -{ - // bool guiGetVisible ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - bool bResult = guiElement->GetCGUIElement()->IsVisible(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetEnabled(lua_State* luaVM) -{ - // bool guiGetEnabled ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - bool bResult = guiElement->GetCGUIElement()->IsEnabled(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetProperty(lua_State* luaVM) -{ - // string guiGetProperty ( element guiElement, string property ) - CClientGUIElement* guiElement; - SString property; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(property); - - if (!argStream.HasErrors()) - { - SString strValue = guiElement->GetCGUIElement()->GetProperty(property); - lua_pushstring(luaVM, strValue); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetProperties(lua_State* luaVM) -{ - // table guiGetProperties ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - // Create a new table - lua_newtable(luaVM); - - // Add all our properties to the table on top of the given lua main's stack - unsigned int uiIndex = 0; - CGUIPropertyIter iter = guiElement->GetCGUIElement()->GetPropertiesBegin(); - CGUIPropertyIter iterEnd = guiElement->GetCGUIElement()->GetPropertiesEnd(); - for (; iter != iterEnd; iter++) - { - const char* szKey = (*iter)->strKey; - const char* szValue = (*iter)->strValue; - - // Add it to the table - lua_pushstring(luaVM, szKey); - lua_pushstring(luaVM, szValue); - lua_settable(luaVM, -3); - } - - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetSize(lua_State* luaVM) -{ - // bool guiSetSize ( element guiElement, float width, float height, bool relative ) - CClientGUIElement* guiElement; - float width; - float height; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(width); - argStream.ReadNumber(height); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetSize(*guiElement, CVector2D(width, height), relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetPosition(lua_State* luaVM) -{ - // bool guiSetPosition ( element guiElement, float x, float y, bool relative ) - CClientGUIElement* guiElement; - float x; - float y; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(x); - argStream.ReadNumber(y); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetPosition(*guiElement, CVector2D(x, y), relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSortingEnabled(lua_State* luaVM) -{ - // bool guiGridListSetSortingEnabled ( element guiGridlist, bool enabled ) - CClientGUIElement* guiGridlist; - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSortingEnabled(*guiGridlist, enabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAddColumn(lua_State* luaVM) -{ - // int guiGridListAddColumn ( element gridList, string title, float width ) - CClientGUIElement* guiGridlist; - SString title; - float width; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadString(title); - argStream.ReadNumber(width); - - if (!argStream.HasErrors()) - { - uint id = CStaticFunctionDefinitions::GUIGridListAddColumn(*guiGridlist, title, width); - lua_pushnumber(luaVM, id); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListRemoveColumn(lua_State* luaVM) -{ - // bool guiGridListRemoveColumn ( element guiGridlist, int columnIndex ) - CClientGUIElement* guiGridlist; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListRemoveColumn(*guiGridlist, columnIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetColumnWidth(lua_State* luaVM) -{ - // bool guiGridListSetColumnWidth ( element gridList, int columnIndex, number width, bool relative ) - CClientGUIElement* guiGridlist; - int columnIndex; - float width; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - argStream.ReadNumber(width); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetColumnWidth(*guiGridlist, columnIndex, width, relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnWidth(lua_State* luaVM) -{ - // float guiGridListGetColumnWidth ( element gridList, int columnIndex, bool relative ) - CClientGUIElement* pGridList; - int columnIndex; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pGridList); - argStream.ReadNumber(columnIndex); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - float width; - if (static_cast(pGridList->GetCGUIElement())->GetColumnWidth(columnIndex, width, relative)) - { - lua_pushnumber(luaVM, width); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetColumnTitle(lua_State* luaVM) -{ - // bool guiGridListSetColumnTitle ( element guiGridlist, int columnIndex, string title ) - CClientGUIElement* guiGridlist; - int iColumnIndex; - SString sTitle; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(iColumnIndex); - argStream.ReadString(sTitle); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) - { - CStaticFunctionDefinitions::GUIGridListSetColumnTitle(*guiGridlist, iColumnIndex, sTitle); - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnTitle(lua_State* luaVM) -{ - // string guiGridListGetColumnTitle ( element guiGridlist, int columnIndex ) - CClientGUIElement* guiGridlist; - int iColumnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(iColumnIndex); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) - { - const char* szTitle = static_cast(guiGridlist->GetCGUIElement())->GetColumnTitle(iColumnIndex); - lua_pushstring(luaVM, szTitle); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAddRow(lua_State* luaVM) -{ - // int guiGridListAddRow ( element gridList ) - // int guiGridListAddRow ( element gridList, int/string itemText1, int/string itemText2 ... ) - CClientGUIElement* guiGridlist; - CLuaArguments Arguments; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadLuaArguments(Arguments); - - if (!argStream.HasErrors()) - { - int iRet = 0; - if (Arguments.Count() == 0) - iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true); - else - { - // Vector containing our string arguments. We add a bool to store whether it was originally a number. - std::vector > m_items; - std::vector::const_iterator it = Arguments.IterBegin(); - for (it; it != Arguments.IterEnd(); it++) - { - CLuaArgument* pArgument = *it; - SString strItemText; - bool bNumber = false; - - // Check the type of the argument and convert it to a string we can process - uint type = pArgument->GetType(); - if (type == LUA_TNUMBER) - { - // Grab the lua string and its size - const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); - size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); - - // Set our string - strItemText.assign(szLuaString, sizeLuaString); - bNumber = true; - } - else if (type == LUA_TSTRING) - strItemText = pArgument->GetString(); - else - continue; - - m_items.push_back(std::make_pair(strItemText, bNumber)); - } - iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true, &m_items); - } - - if (iRet >= 0) - { - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushnumber(luaVM, iRet); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListInsertRowAfter(lua_State* luaVM) -{ - // int guiGridListInsertRowAfter ( element gridList, int rowIndex ) - // int guiGridListInsertRowAfter ( element gridList, int rowIndex, int/string itemText1, int/string itemText2 ... ) - CClientGUIElement* guiGridlist; - int rowIndex; - CLuaArguments Arguments; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadLuaArguments(Arguments); - - if (!argStream.HasErrors()) - { - int iRet = 0; - if (Arguments.Count() == 0) - iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex); - else - { - // Vector containing our string arguments. We add a bool to store whether it was originally a number. - std::vector > m_items; - std::vector::const_iterator it = Arguments.IterBegin(); - for (it; it != Arguments.IterEnd(); it++) - { - CLuaArgument* pArgument = *it; - SString strItemText; - bool bNumber = false; - - // Check the type of the argument and convert it to a string we can process - uint type = pArgument->GetType(); - if (type == LUA_TNUMBER) - { - // Grab the lua string and its size - const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); - size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); - - // Set our string - strItemText.assign(szLuaString, sizeLuaString); - bNumber = true; - } - else if (type == LUA_TSTRING) - strItemText = pArgument->GetString(); - else - continue; - - m_items.push_back(std::make_pair(strItemText, bNumber)); - } - iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex, &m_items); - } - - if (iRet >= 0) - { - lua_pushnumber(luaVM, iRet); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAutoSizeColumn(lua_State* luaVM) -{ - // bool guiGridListAutoSizeColumn ( element gridList, int columnIndex ) - CClientGUIElement* guiGridlist; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListAutoSizeColumn(*guiGridlist, columnIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListClear(lua_State* luaVM) -{ - // bool guiGridListClear ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListClear(*guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSelectionMode(lua_State* luaVM) -{ - // bool guiGridListSetSelectionMode ( guiElement gridlist, int mode ) - CClientGUIElement* guiGridlist; - int mode; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(mode); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSelectionMode(*guiGridlist, mode); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedItem(lua_State* luaVM) -{ - // int, int guiGridListGetSelectedItem ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iRow = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemRow(); - int iColumn = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemColumn(); - lua_pushnumber(luaVM, iRow); - lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedItems(lua_State* luaVM) -{ - // table guiGridListGetSelectedItems ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - CGUIGridList* pList = static_cast(guiGridlist->GetCGUIElement()); - CGUIListItem* pItem = NULL; - - lua_newtable(luaVM); - - for (int i = 1; i <= pList->GetSelectedCount(); i++) - { - pItem = pList->GetNextSelectedItem(pItem); - if (!pItem) - break; - - lua_pushnumber(luaVM, i); - lua_newtable(luaVM); - - // column - lua_pushstring(luaVM, "column"); - lua_pushnumber(luaVM, pList->GetItemColumnIndex(pItem)); - lua_settable(luaVM, -3); - - // row - lua_pushstring(luaVM, "row"); - lua_pushnumber(luaVM, pList->GetItemRowIndex(pItem)); - lua_settable(luaVM, -3); - - // push to main table - lua_settable(luaVM, -3); - } - - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedCount(lua_State* luaVM) -{ - // int guiGridListGetSelectedCount ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iCount = static_cast(guiGridlist->GetCGUIElement())->GetSelectedCount(); - lua_pushnumber(luaVM, iCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSelectedItem(lua_State* luaVM) -{ - // bool guiGridListSetSelectedItem ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - bool bReset; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadBool(bReset, true); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSelectedItem(*guiGridlist, rowIndex, columnIndex, bReset); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListRemoveRow(lua_State* luaVM) -{ - // bool guiGridListRemoveRow ( element gridList, int rowIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListRemoveRow(*guiGridlist, rowIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemText(lua_State* luaVM) -{ - // string guiGridListGetItemText ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - const char* szText = static_cast(guiGridlist->GetCGUIElement())->GetItemText(rowIndex, columnIndex); - lua_pushstring(luaVM, szText); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemData(lua_State* luaVM) -{ - // string guiGridListGetItemData ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - void* pData = static_cast(guiGridlist->GetCGUIElement())->GetItemData(rowIndex, columnIndex); - CLuaArgument* pVariable = reinterpret_cast(pData); - if (pVariable) - pVariable->Push(luaVM); - else - lua_pushnil(luaVM); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemColor(lua_State* luaVM) -{ - // int int int int guiGridListGetItemColor ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255, ucAlpha = 255; - if (static_cast(guiGridlist->GetCGUIElement())->GetItemColor(rowIndex, columnIndex, ucRed, ucGreen, ucBlue, ucAlpha)) - { - lua_pushnumber(luaVM, ucRed); - lua_pushnumber(luaVM, ucGreen); - lua_pushnumber(luaVM, ucBlue); - lua_pushnumber(luaVM, ucAlpha); - return 4; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetHorizontalScrollPosition(lua_State* luaVM) -{ - // float guiGridListGetHorizontalScrollPosition ( element guiGridlist ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPosition); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiGridListGetVerticalScrollPosition ( element guiGridlist ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPosition); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemText(lua_State* luaVM) -{ - // bool guiGridListSetItemText ( element gridList, int rowIndex, int columnIndex, string text, bool section, bool number ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - SString text; - bool section; - bool number; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadString(text); - argStream.ReadBool(section); - argStream.ReadBool(number); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetItemText(*guiGridlist, rowIndex, columnIndex, text, section, number, true); - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemData(lua_State* luaVM) -{ - // bool guiGridListSetItemData ( element gridList, int rowIndex, int columnIndex, string data ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - CLuaArgument data; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadLuaArgument(data); - - if (!argStream.HasErrors()) - { - CLuaArgument* pData = new CLuaArgument(data); - CStaticFunctionDefinitions::GUIGridListSetItemData(*guiGridlist, rowIndex, columnIndex, pData); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemColor(lua_State* luaVM) -{ - // bool guiGridListSetItemColor ( element gridList, int rowIndex, int columnIndex, int red, int green, int blue[, int alpha = 255 ] ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - int red; - int green; - int blue; - int alpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadNumber(red); - argStream.ReadNumber(green); - argStream.ReadNumber(blue); - argStream.ReadNumber(alpha, 255); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetItemColor(*guiGridlist, rowIndex, columnIndex, red, green, blue, alpha); - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetScrollBars(lua_State* luaVM) -{ - // bool guiGridListSetScrollBars ( element guiGridlist, bool horizontalBar, bool verticalBar ) - CClientGUIElement* guiGridlist; - bool horizontalBar; - bool verticalBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadBool(horizontalBar); - argStream.ReadBool(verticalBar); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetScrollBars(*guiGridlist, horizontalBar, verticalBar); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetHorizontalScrollPosition(lua_State* luaVM) -{ - // bool guiGridListSetHorizontalScrollPosition ( element guiGridlist, float fPosition ) - CClientGUIElement* guiGridlist; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetHorizontalScrollPosition(*guiGridlist, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiGridListSetVerticalScrollPosition ( element guiGridlist, float fPosition ) - CClientGUIElement* guiGridlist; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetVerticalScrollPosition(*guiGridlist, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetScrollBars(lua_State* luaVM) -{ - // bool guiScrollPaneSetScrollBars ( element scrollPane, bool horizontal, bool vertical ) - CClientGUIElement* scrollPane; - bool horizontalBar; - bool verticalBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(scrollPane); - argStream.ReadBool(horizontalBar); - argStream.ReadBool(verticalBar); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetScrollBars(*scrollPane, horizontalBar, verticalBar); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetRowCount(lua_State* luaVM) -{ - // int guiGridListGetRowCount ( element theList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iRowCount = static_cast(guiGridlist->GetCGUIElement())->GetRowCount(); - lua_pushnumber(luaVM, iRowCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnCount(lua_State* luaVM) -{ - // int guiGridListGetColumnCount ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - lua_pushnumber(luaVM, iColumnCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) -{ - // bool guiEditSetReadOnly ( element editField, bool status ) - CClientGUIElement* editField; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetReadOnly(*editField, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) -{ - // bool guiEditIsReadOnly( element editField ) - CClientGUIElement* editField; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) -{ - // bool guiMemoSetReadOnly ( gui-memo theMemo, bool status ) - CClientGUIElement* theMemo; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetReadOnly(*theMemo, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) -{ - // bool guiMemoIsReadOnly( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) -{ - // bool guiEditSetMasked ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) -{ - // bool guiEditSetMaxLength ( element theElement, int length ) - CClientGUIElement* theElement; - int length; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(length); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetMaxLength(*theElement, length); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) -{ - // bool guiEditSetCaretIndex ( element theElement, int index ) - CClientGUIElement* theElement; - int index; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(index); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetCaretIndex(*theElement, index); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) -{ - // int guiEditGetCaretIndex ( element theElement ) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - lua_pushnumber(luaVM, static_cast(theElement->GetCGUIElement())->GetCaretIndex()); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) -{ - // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) - CClientGUIElement* theMemo; - int index; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(index); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetCaretIndex(*theMemo, index); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiMemoSetVerticalScrollPosition ( gui-memo theMemo, float fPosition ) - CClientGUIElement* theMemo; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) -{ - // bool guiMemoGetCaretIndex ( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - lua_pushnumber(luaVM, static_cast(theMemo->GetCGUIElement())->GetCaretIndex()); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiMemoGetVerticalScrollPosition ( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); - float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) -{ - // bool guiWindowSetMovable ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIWindowSetMovable(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) -{ - // bool guiWindowSetSizable ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIWindowSetSizable(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) -{ - // float guiLabelGetTextExtent ( element theLabel ) - CClientGUIElement* theLabel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - - if (!argStream.HasErrors()) - { - float fExtent = static_cast(theLabel->GetCGUIElement())->GetTextExtent(); - lua_pushnumber(luaVM, fExtent); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetFontHeight(lua_State* luaVM) -{ - // float guiLabelGetFontHeight ( element theLabel ) - CClientGUIElement* theLabel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - - if (!argStream.HasErrors()) - { - float fHeight = static_cast(theLabel->GetCGUIElement())->GetFontHeight(); - lua_pushnumber(luaVM, fHeight); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetColor(lua_State* luaVM) -{ - // bool guiLabelSetColor ( element theElement, int red, int green, int blue ) - CClientGUIElement* theElement; - int red; - int green; - int blue; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(red); - argStream.ReadNumber(green); - argStream.ReadNumber(blue); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUILabelSetColor(*theElement, red, green, blue); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetColor(lua_State* luaVM) -{ - // int r, int g, int b guiLabelGetColor ( element theElement ) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255; - static_cast(theElement->GetCGUIElement())->GetTextColor(ucRed, ucGreen, ucBlue); - lua_pushnumber(luaVM, ucRed); - lua_pushnumber(luaVM, ucGreen); - lua_pushnumber(luaVM, ucBlue); - return 3; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetVerticalAlign(lua_State* luaVM) -{ - // bool guiLabelSetVerticalAlign ( element theLabel, string align ) - CClientGUIElement* theLabel; - CGUIVerticalAlign align; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - argStream.ReadEnumString(align); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUILabelSetVerticalAlign(*theLabel, align); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetHorizontalAlign(lua_State* luaVM) -{ - // bool guiLabelSetHorizontalAlign ( element theLabel, string align, [ bool wordwrap = false ] ) - CClientGUIElement* theLabel; - CGUIHorizontalAlign align; - bool wordwrap; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - argStream.ReadEnumString(align); - argStream.ReadBool(wordwrap, false); - - if (!argStream.HasErrors()) - { - if (wordwrap) - align = (CGUIHorizontalAlign)(align + 4); - CStaticFunctionDefinitions::GUILabelSetHorizontalAlign(*theLabel, align); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) -{ - //* chat_font - Returns the chatbox font - //* chat_lines - Returns how many lines the chatbox has - //* chat_color - Returns the background color of the chatbox - //* chat_text_color - Returns the chatbox text color - //* chat_input_color - Returns the background color of the chatbox input - //* chat_input_prefix_color - Returns the color of the input prefix text - //* chat_input_text_color - Returns the color of the text in the chatbox input - //* chat_scale - Returns the scale of the text in the chatbox - //* chat_position_offset_x - Returns the position offset of the chatbox on the x axis - //* chat_position_offset_y - Returns the position offset of the chatbox on the y axis - //* chat_position_horizontal - Returns the horizontal position of the chatbox - //* chat_position_vertical - Returns the vertical position of the chatbox - //* chat_text_alignment - Returns the horizontal alignment of the chatbox text - //* chat_width - Returns the scale of the background width - //* chat_css_style_text - Returns whether text fades out over time - //* chat_css_style_background - Returns whether the background fades out over time - //* chat_line_life - Returns how long it takes for text to start fading out - //* chat_line_fade_out - Returns how long takes for text to fade out - //* chat_use_cegui - Returns whether CEGUI is used to render the chatbox - //* text_scale - Returns text scale - - CCVarsInterface* pCVars = g_pCore->GetCVars(); - int iNumber; - float fNumber; - pCVars->Get("chat_font", fNumber); - lua_newtable(luaVM); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_font"); - pCVars->Get("chat_lines", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_lines"); - pCVars->Get("chat_width", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_width"); - pCVars->Get("chat_position_offset_x", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_x"); - pCVars->Get("chat_position_offset_y", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_y"); - pCVars->Get("chat_position_horizontal", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_horizontal"); - pCVars->Get("chat_position_vertical", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_vertical"); - pCVars->Get("chat_text_alignment", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_text_alignment"); - pCVars->Get("chat_css_style_text", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_text"); - pCVars->Get("chat_css_style_background", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_background"); - pCVars->Get("chat_line_life", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_life"); - pCVars->Get("chat_line_fade_out", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_fade_out"); - pCVars->Get("text_scale", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "text_scale"); - pCVars->Get("chat_use_cegui", fNumber); - lua_pushboolean(luaVM, fNumber ? true : false); - lua_setfield(luaVM, -2, "chat_use_cegui"); - std::string strCVar; - std::stringstream ss; - int iR, iG, iB, iA; - pCVars->Get("chat_color", strCVar); - if (!strCVar.empty()) - { - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_color"); - } - pCVars->Get("chat_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_text_color"); - } - pCVars->Get("chat_input_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_color"); - } - pCVars->Get("chat_input_prefix_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_prefix_color"); - } - pCVars->Get("chat_input_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_text_color"); - } - pCVars->Get("chat_scale", strCVar); - if (!strCVar.empty()) - { - float fX, fY; - ss.clear(); - ss.str(strCVar); - ss >> fX >> fY; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, fX); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, fY); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_scale"); - } - - return 1; -} - -int CLuaGUIDefs::GUICreateComboBox(lua_State* luaVM) -{ - // element guiCreateComboBox ( float x, float y, float width, float height, string caption, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - SString caption; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(caption); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateComboBox(*pLuaMain, position, size, caption, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxAddItem(lua_State* luaVM) -{ - // int guiComboBoxAddItem( element comboBox, string value ) - CClientGUIElement* comboBox; - SString value; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadString(value); - - if (!argStream.HasErrors()) - { - int newId = CStaticFunctionDefinitions::GUIComboBoxAddItem(*comboBox, value); - lua_pushnumber(luaVM, newId); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxRemoveItem(lua_State* luaVM) -{ - // bool guiComboBoxRemoveItem( element comboBox, int itemId ) - CClientGUIElement* comboBox; - int itemId; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxRemoveItem(*comboBox, itemId); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxClear(lua_State* luaVM) -{ - // bool guiComboBoxClear ( element comboBox ) - CClientGUIElement* comboBox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxClear(*comboBox); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxGetSelected(lua_State* luaVM) -{ - // int guiComboBoxGetSelected ( element comboBox ) - CClientGUIElement* comboBox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - - if (!argStream.HasErrors()) - { - int selected = CStaticFunctionDefinitions::GUIComboBoxGetSelected(*comboBox); - lua_pushnumber(luaVM, selected); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxSetSelected(lua_State* luaVM) -{ - // bool guiComboBoxSetSelected ( element comboBox, int itemIndex ) - CClientGUIElement* comboBox; - int itemIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemIndex); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxSetSelected(*comboBox, itemIndex); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxGetItemText(lua_State* luaVM) -{ - // string guiComboBoxGetItemText ( element comboBox, int itemId ) - CClientGUIElement* comboBox; - int itemId; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - - if (!argStream.HasErrors()) - { - SString ret = CStaticFunctionDefinitions::GUIComboBoxGetItemText(*comboBox, itemId); - lua_pushstring(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxSetItemText(lua_State* luaVM) -{ - // bool guiComboBoxSetItemText ( element comboBox, int itemId, string text ) - CClientGUIElement* comboBox; - int itemId; - SString text; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - argStream.ReadString(text); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxSetItemText(*comboBox, itemId, text); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateFont(lua_State* luaVM) -{ - // element guiCreateFont( string filepath [, int size=9 ] ) - SString strFilePath; - int iSize; - - CScriptArgReader argStream(luaVM); - argStream.ReadString(strFilePath); - argStream.ReadNumber(iSize, 9); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CResource* pParentResource = pLuaMain->GetResource(); - CResource* pFileResource = pParentResource; - SString strPath, strMetaPath; - if (CResourceManager::ParseResourcePathInput(strFilePath, pFileResource, &strPath, &strMetaPath)) - { - if (FileExists(strPath)) - { - SString strUniqueName = SString("%s*%s*%s", pParentResource->GetName(), pFileResource->GetName(), strMetaPath.c_str()).Replace("\\", "/"); - CClientGuiFont* pGuiFont = g_pClientGame->GetManager()->GetRenderElementManager()->CreateGuiFont(strPath, strUniqueName, iSize); - if (pGuiFont) - { - // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's - // ElementGroup? ** - pGuiFont->SetParent(pParentResource->GetResourceDynamicEntity()); - lua_pushelement(luaVM, pGuiFont); - return 1; - } - argStream.SetCustomError(strFilePath, "Error creating font"); - } - else - argStream.SetCustomError(strFilePath, "File not found"); - } - else - argStream.SetCustomError(strFilePath, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) -{ - // string guiGetCursorType ( ) - auto eType = CStaticFunctionDefinitions::GUIGetCursorType(); - lua_pushstring(luaVM, EnumToString(eType)); - return 1; -} +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp + * PURPOSE: Lua definitions class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" + +void CLuaGUIDefs::LoadFunctions(void) +{ + CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); + CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); + CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); + CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); + + CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); + CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); + CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); + CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); + CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); + CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); + + CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); + CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); + CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); + + CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); + CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); + CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); + CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); + CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); + CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); + CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); + CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); + CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); + CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); + CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); + CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); + CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); + CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); + CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); + CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); + + CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); + CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); + CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); + CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); + CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); + + CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); + CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); + CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); + CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); + CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); + CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); + CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); + CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); + CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); + CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); + CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); + CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); + CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); + CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); + CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); + CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); + CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); + CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); + CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); + CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); + CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); + CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); + CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); + CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); + CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); + CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); + CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); + CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); + CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); + + CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); + CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); + CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); + CLuaCFunctions::AddFunction("guiSetText", GUISetText); + CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); + CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); + CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); + CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); + + CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); + CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); + + CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); + CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); + + CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); + CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); + CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); + CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); + CLuaCFunctions::AddFunction("guiGetText", GUIGetText); + CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); + CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); + CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); + CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); + CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); + + CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); + CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); + + CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); + CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); + + CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); + + CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); + CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); + CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); + CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); + CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); + CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); + + CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); + CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); + CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); + CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); + CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); + CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); + CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); + CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); + + CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); + CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); + + CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); + CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); + + CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); + + CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); + CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); + CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); + CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); + CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); + CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); + CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); +} + +void CLuaGUIDefs::AddClass(lua_State* luaVM) +{ + AddGuiElementClass(luaVM); + AddGuiFontClass(luaVM); + AddGuiWindowClass(luaVM); + AddGuiButtonClass(luaVM); + AddGuiEditClass(luaVM); + AddGuiLabelClass(luaVM); + AddGuiMemoClass(luaVM); + AddGuiImageClass(luaVM); + AddGuiComboBoxClass(luaVM); + AddGuiCheckBoxClass(luaVM); + AddGuiRadioButtonClass(luaVM); + AddGuiScrollPaneClass(luaVM); + AddGuiScrollBarClass(luaVM); + AddGuiProgressBarClass(luaVM); + AddGuiGridlistClass(luaVM); + AddGuiTabPanelClass(luaVM); + AddGuiTabClass(luaVM); +} + +// TODO: vector class +void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "bringToFront", "guiBringToFront"); + lua_classfunction(luaVM, "moveToBack", "guiMoveToBack"); + + lua_classfunction(luaVM, "isChatBoxInputActive", "isChatBoxInputActive"); + lua_classfunction(luaVM, "isConsoleActive", "isConsoleActive"); + lua_classfunction(luaVM, "isDebugViewActive", "isDebugViewActive"); + lua_classfunction(luaVM, "setDebugViewActive", "setDebugViewActive"); + lua_classfunction(luaVM, "isMainMenuActive", "isMainMenuActive"); + lua_classfunction(luaVM, "isMTAWindowActive", "isMTAWindowActive"); + lua_classfunction(luaVM, "isTransferBoxActive", "isTransferBoxActive"); + lua_classfunction(luaVM, "isInputEnabled", "guiGetInputEnabled"); + lua_classfunction(luaVM, "getInputMode", "guiGetInputMode"); + lua_classfunction(luaVM, "getCursorType", "guiGetCursorType"); + + lua_classfunction(luaVM, "getScreenSize", "guiGetScreenSize"); + lua_classfunction(luaVM, "getProperties", "guiGetProperties"); + lua_classfunction(luaVM, "getAlpha", "guiGetAlpha"); + lua_classfunction(luaVM, "getFont", "guiGetFont"); + lua_classfunction(luaVM, "getEnabled", "guiGetEnabled"); + lua_classfunction(luaVM, "getVisible", "guiGetVisible"); + lua_classfunction(luaVM, "getText", "guiGetText"); + lua_classfunction(luaVM, "getPosition", "guiGetPosition"); + lua_classfunction(luaVM, "getSize", "guiGetSize"); + lua_classfunction(luaVM, "getProperty", "guiGetProperty"); + + lua_classfunction(luaVM, "setInputEnabled", "guiSetInputEnabled"); + lua_classfunction(luaVM, "setAlpha", "guiSetAlpha"); + lua_classfunction(luaVM, "setEnabled", "guiSetEnabled"); + lua_classfunction(luaVM, "setFont", "guiSetFont"); + lua_classfunction(luaVM, "setVisible", "guiSetVisible"); + lua_classfunction(luaVM, "setText", "guiSetText"); + lua_classfunction(luaVM, "setInputMode", "guiSetInputMode"); + lua_classfunction(luaVM, "setProperty", "guiSetProperty"); + lua_classfunction(luaVM, "setPosition", "guiSetPosition"); + lua_classfunction(luaVM, "setSize", "guiSetSize"); + + lua_classvariable(luaVM, "chatBoxInputActive", NULL, "isChatBoxInputActive"); + lua_classvariable(luaVM, "consoleActive", NULL, "isConsoleActive"); + lua_classvariable(luaVM, "debugViewActive", "setDebugViewActive", "isDebugViewActive"); + lua_classvariable(luaVM, "mainMenuActive", NULL, "isMainMenuActive"); + lua_classvariable(luaVM, "mtaWindowActive", NULL, "isMTAWindowActive"); + lua_classvariable(luaVM, "transferBoxActive", NULL, "isTransferBoxActive"); + lua_classvariable(luaVM, "inputEnabled", "guiSetInputEnabled", "guiGetInputEnabled"); + lua_classvariable(luaVM, "inputMode", "guiGetInputMode", "guiSetInputMode"); + lua_classvariable(luaVM, "cursorAlpha", "setCursorAlpha", "getCursorAlpha"); + lua_classvariable(luaVM, "cursorType", NULL, "guiGetCursorType"); + lua_classvariable(luaVM, "font", "guiSetFont", "guiGetFont"); + lua_classvariable(luaVM, "visible", "guiSetVisible", "guiGetVisible"); + lua_classvariable(luaVM, "properties", NULL, "guiGetProperties"); + lua_classvariable(luaVM, "alpha", "guiSetAlpha", "guiGetAlpha"); + lua_classvariable(luaVM, "enabled", "guiSetEnabled", "guiGetEnabled"); + lua_classvariable(luaVM, "text", "guiSetText", "guiGetText"); + lua_classvariable(luaVM, "size", "guiSetSize", "guiGetSize"); + lua_classvariable(luaVM, "position", "guiSetPosition", "guiGetPosition"); + lua_classvariable(luaVM, "screenSize", NULL, "guiGetScreenSize"); + // lua_classvariable ( luaVM, "property" "guiSetProperty", "guiGetProperty" ); todo: .property[name] = value + + lua_registerclass(luaVM, "GuiElement", "Element"); +} + +void CLuaGUIDefs::AddGuiWindowClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateWindow"); + lua_classfunction(luaVM, "setMovable", "guiWindowSetMovable"); + lua_classfunction(luaVM, "setSizable", "guiWindowSetSizable"); + + lua_classvariable(luaVM, "movable", "guiWindowSetMovable", NULL); + lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", NULL); + + lua_registerclass(luaVM, "GuiWindow", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiButtonClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateButton"); + + lua_registerclass(luaVM, "GuiButton", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateEdit"); + lua_classfunction(luaVM, "getCaretIndex", "guiEditGetCaretIndex"); + lua_classfunction(luaVM, "setCaretIndex", "guiEditSetCaretIndex"); + lua_classfunction(luaVM, "setReadOnly", "guiEditSetReadOnly"); + lua_classfunction(luaVM, "setMasked", "guiEditSetMasked"); + lua_classfunction(luaVM, "setMaxLength", "guiEditSetMaxLength"); + + lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); + lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", "guiEditIsReadOnly"); + lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); + lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); + + lua_registerclass(luaVM, "GuiEdit", "GuiElement"); +} + +// TODO: specials +void CLuaGUIDefs::AddGuiLabelClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateLabel"); + + lua_classfunction(luaVM, "getFontHeight", "guiLabelGetFontHeight"); + lua_classfunction(luaVM, "getTextExtent", "guiLabelGetTextExtent"); + lua_classfunction(luaVM, "getColor", "guiLabelGetColor"); + + lua_classfunction(luaVM, "setColor", "guiLabelSetColor"); + lua_classfunction(luaVM, "setHorizontalAlign", "guiLabelSetHorizontalAlign"); + lua_classfunction(luaVM, "setVerticalAlign", "guiLabelSetVerticalAlign"); + + lua_classvariable(luaVM, "horizontalAlign", "guiLabelSetHorizontalAlign", NULL); + lua_classvariable(luaVM, "verticalAlign", "guiLabelSetVerticalAlign", NULL); + lua_classvariable(luaVM, "fontHeight", NULL, "guiLabelGetFontHeight"); + lua_classvariable(luaVM, "textExtent", NULL, "guiLabelGetTextExtent"); + // lua_classvariable ( luaVM, "color", "guiLabelGetColor", "guiLabelSetColor" ); + + lua_registerclass(luaVM, "GuiLabel", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiMemoClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateMemo"); + + lua_classfunction(luaVM, "getCaretIndex", "guiMemoGetCaretIndex"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); + + lua_classfunction(luaVM, "setCaretIndex", "guiMemoSetCaretIndex"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiMemoSetVerticalScrollPosition"); + lua_classfunction(luaVM, "setReadOnly", "guiMemoSetReadOnly"); + + lua_classvariable(luaVM, "caretIndex", "guiMemoSetCaretIndex", "guiMemoGetCaretIndex"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiMemoSetVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); + lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", "guiMemoIsReadOnly"); + + lua_registerclass(luaVM, "GuiMemo", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiImageClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateStaticImage"); + lua_classfunction(luaVM, "loadImage", "guiStaticImageLoadImage"); + + lua_classvariable(luaVM, "image", "guiStaticImageLoadImage", NULL); + + lua_registerclass(luaVM, "GuiStaticImage", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiComboBoxClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateComboBox"); + lua_classfunction(luaVM, "addItem", "guiComboBoxAddItem"); + lua_classfunction(luaVM, "clear", "guiComboBoxClear"); + lua_classfunction(luaVM, "removeItem", "guiComboBoxRemoveItem"); + + lua_classfunction(luaVM, "getSelected", "guiComboBoxGetSelected"); + lua_classfunction(luaVM, "getItemText", "guiComboBoxGetItemText"); + + lua_classfunction(luaVM, "setItemText", "guiComboBoxSetItemText"); + lua_classfunction(luaVM, "setSelected", "guiComboBoxSetSelected"); + + lua_classvariable(luaVM, "selected", "guiComboBoxSetSelected", "guiComboBoxGetSelected"); + + lua_registerclass(luaVM, "GuiComboBox", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiCheckBoxClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateCheckBox"); + + lua_classfunction(luaVM, "getSelected", "guiCheckBoxGetSelected"); + + lua_classfunction(luaVM, "setSelected", "guiCheckBoxSetSelected"); + + lua_classvariable(luaVM, "selected", "guiCheckBoxSetSelected", "guiCheckBoxGetSelected"); + + lua_registerclass(luaVM, "GuiCheckBox", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiRadioButtonClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateRadioButton"); + + lua_classfunction(luaVM, "getSelected", "guiRadioButtonGetSelected"); + + lua_classfunction(luaVM, "setSelected", "guiRadioButtonSetSelected"); + + lua_classvariable(luaVM, "selected", "guiRadioButtonSetSelected", "guiRadioButtonGetSelected"); + + lua_registerclass(luaVM, "GuiRadioButton", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiScrollPaneClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateScrollPane"); + + lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); + + lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition"); + lua_classfunction(luaVM, "setScrollBars", "guiScrollPaneSetScrollBars"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition"); + + lua_classvariable(luaVM, "horizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); + + lua_registerclass(luaVM, "GuiScrollPane", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiScrollBarClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateScrollBar"); + + lua_classfunction(luaVM, "getScrollPosition", "guiScrollBarGetScrollPosition"); + + lua_classfunction(luaVM, "setScrollPosition", "guiScrollBarSetScrollPosition"); + + lua_classvariable(luaVM, "scrollPosition", "guiScrollBarSetScrollPosition", "guiScrollBarGetScrollPosition"); + + lua_registerclass(luaVM, "GuiScrollBar", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiProgressBarClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateProgressBar"); + + lua_classfunction(luaVM, "getProgress", "guiProgressBarGetProgress"); + + lua_classfunction(luaVM, "setProgress", "guiProgressBarSetProgress"); + + lua_classvariable(luaVM, "progress", "guiProgressBarSetProgress", "guiProgressBarGetProgress"); + + lua_registerclass(luaVM, "GuiProgressBar", "GuiElement"); +} + +// TODO: special tables +void CLuaGUIDefs::AddGuiGridlistClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateGridList"); + lua_classfunction(luaVM, "addColumn", "guiGridListAddColumn"); + lua_classfunction(luaVM, "addRow", "guiGridListAddRow"); + lua_classfunction(luaVM, "autoSizeColumn", "guiGridListAutoSizeColumn"); + lua_classfunction(luaVM, "clear", "guiGridListClear"); + lua_classfunction(luaVM, "insertRowAfter", "guiGridListInsertRowAfter"); + lua_classfunction(luaVM, "removeColumn", "guiGridListRemoveColumn"); + lua_classfunction(luaVM, "removeRow", "guiGridListRemoveRow"); + + lua_classfunction(luaVM, "getItemData", "guiGridListGetItemData"); + lua_classfunction(luaVM, "getItemText", "guiGridListGetItemText"); + lua_classfunction(luaVM, "getRowCount", "guiGridListGetRowCount"); + lua_classfunction(luaVM, "getSelectedItem", "guiGridListGetSelectedItem"); + lua_classfunction(luaVM, "getItemColor", "guiGridListGetItemColor"); + lua_classfunction(luaVM, "getColumnTitle", "guiGridListGetColumnTitle"); + lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); + lua_classfunction(luaVM, "getSelectedCount", "guiGridListGetSelectedCount"); + lua_classfunction(luaVM, "getSelectedItems", "guiGridListGetSelectedItems"); + lua_classfunction(luaVM, "getColumnCount", "guiGridListGetColumnCount"); + + lua_classfunction(luaVM, "setItemData", "guiGridListSetItemData"); + lua_classfunction(luaVM, "setItemText", "guiGridListSetItemText"); + lua_classfunction(luaVM, "setScrollBars", "guiGridListSetScrollBars"); + lua_classfunction(luaVM, "setSelectedItem", "guiGridListSetSelectedItem"); + lua_classfunction(luaVM, "setSelectionMode", "guiGridListSetSelectionMode"); + lua_classfunction(luaVM, "setSortingEnabled", "guiGridListSetSortingEnabled"); + lua_classfunction(luaVM, "setColumnWidth", "guiGridListSetColumnWidth"); + lua_classfunction(luaVM, "setItemColor", "guiGridListSetItemColor"); + lua_classfunction(luaVM, "setColumnTitle", "guiGridListSetColumnTitle"); + lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiGridListSetHorizontalScrollPosition"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiGridListSetVerticalScrollPosition"); + + lua_classvariable(luaVM, "rowCount", NULL, "guiGridListGetRowCount"); + lua_classvariable(luaVM, "selectedCount", NULL, "guiGridListGetSelectedCount"); + lua_classvariable(luaVM, "selectedItems", NULL, "guiGridListGetSelectedItems"); + lua_classvariable(luaVM, "columnCount", NULL, "guiGridListGetColumnCount"); + lua_classvariable(luaVM, "selectionMode", "guiGridListSetSelectionMode", NULL); + lua_classvariable(luaVM, "sortingEnabled", "guiGridListSetSortingEnabled", NULL); + lua_classvariable(luaVM, "horizontalScrollPosition", "guiGridListSetHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiGridListGetVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); + // lua_classvariable ( luaVM, "selectedItem", NULL, "guiGridListGetSelectedItem" ); table + // lua_classvariable ( luaVM, "selectedItem", "guiGridListSetSelectedItem", NULL ); .selectedItem[column] = row (row in column) table + // lua_classvariable ( luaVM, "itemColor", "setItemColor", "getItemColor" ); table + // lua_classvariable ( luaVM, "columnTitle", "setColumnTitle", "getColumnTitle" ); table + + lua_registerclass(luaVM, "GuiGridList", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiTabPanelClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateTabPanel"); + + lua_classfunction(luaVM, "getSelectedTab", "guiGetSelectedTab"); + + lua_classfunction(luaVM, "setSelectedTab", "guiSetSelectedTab"); + + lua_classvariable(luaVM, "selectedTab", "guiSetSelectedTab", "guiGetSelectedTab"); + + lua_registerclass(luaVM, "GuiTabPanel", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiTabClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateTab"); + lua_classfunction(luaVM, "delete", "guiDeleteTab"); + + lua_registerclass(luaVM, "GuiTab", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiFontClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateFont"); + + lua_registerclass(luaVM, "GuiFont", "Element"); +} + +int CLuaGUIDefs::GUIGetInputEnabled(lua_State* luaVM) +{ + lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIGetInputEnabled()); + return 1; +} + +int CLuaGUIDefs::GUISetInputEnabled(lua_State* luaVM) +{ + // bool guiSetInputEnabled ( bool enabled ) + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetInputMode(enabled ? INPUTMODE_NO_BINDS : INPUTMODE_ALLOW_BINDS); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetInputMode(lua_State* luaVM) +{ + // bool guiSetInputMode ( string mode ) + eInputMode mode; + + CScriptArgReader argStream(luaVM); + argStream.ReadEnumString(mode); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetInputMode(mode); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetInputMode(lua_State* luaVM) +{ + eInputMode mode = CStaticFunctionDefinitions::GUIGetInputMode(); + lua_pushstring(luaVM, EnumToString(mode)); + return 1; +} + +int CLuaGUIDefs::GUIIsChatBoxInputActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsChatInputEnabled()); + return 1; +} + +int CLuaGUIDefs::GUIIsConsoleActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->GetConsole()->IsVisible()); + return 1; +} + +int CLuaGUIDefs::GUIIsDebugViewActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsDebugVisible()); + return 1; +} + +int CLuaGUIDefs::GUISetDebugViewActive(lua_State* luaVM) +{ + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + g_pCore->SetDebugVisible(enabled); + + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIIsMainMenuActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsMenuVisible()); + return 1; +} + +int CLuaGUIDefs::GUIIsMTAWindowActive(lua_State* luaVM) +{ + bool bActive = + (g_pCore->IsChatInputEnabled() || g_pCore->IsMenuVisible() || g_pCore->GetConsole()->IsVisible() || g_pClientGame->GetTransferBox()->IsVisible()); + + lua_pushboolean(luaVM, bActive); + return 1; +} + +int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); + return 1; +} + +int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) +{ + bool bEnabled; + CScriptArgReader argStream(luaVM); + argStream.ReadBool(bEnabled); + + if (!argStream.HasErrors()) + { + bool bAllowed = false; + g_pCore->GetCVars()->Get("allow_server_control_transfebox", bAllowed); + if (bAllowed) + { + g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + { + lua_pushboolean(luaVM, false); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + return 1; +} + +int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); + return 1; +} + +int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) +{ + // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) + CVector2D position; + CVector2D size; + SString titleBarText; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(titleBarText); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateWindow(*pLuaMain, position, size, titleBarText, relative); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateLabel(lua_State* luaVM) +{ + // element guiCreateLabel ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateLabel(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateStaticImage(lua_State* luaVM) +{ + // element guiCreateStaticImage ( float x, float y, float width, float height, string path, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString path; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(path); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CResource* pResource = pLuaMain->GetResource(); + SString strPath; + if (CResourceManager::ParseResourcePathInput(path, pResource, &strPath)) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateStaticImage(*pLuaMain, position, size, strPath, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + else + argStream.SetCustomError(path, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateButton(lua_State* luaVM) +{ + // element guiCreateButton ( float x, float y, float width, float height, string text, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateButton(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateProgressBar(lua_State* luaVM) +{ + // element guiCreateProgressBar ( float x, float y, float width, float height, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateProgressBar(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateCheckBox(lua_State* luaVM) +{ + // element guiCreateCheckBox ( float x, float y, float width, float height, string text, bool selected, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool selected; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(selected); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateCheckBox(*pLuaMain, position, size, text, selected, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateRadioButton(lua_State* luaVM) +{ + // element guiCreateRadioButton ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateRadioButton(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateEdit(lua_State* luaVM) +{ + // gui-edit guiCreateEdit ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateEdit(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateMemo(lua_State* luaVM) +{ + // gui-memo guiCreateMemo ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateMemo(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateGridList(lua_State* luaVM) +{ + // element guiCreateGridList ( float x, float y, float width, float height, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateGridList(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateScrollPane(lua_State* luaVM) +{ + // element guiCreateScrollPane( float x, float y, float width, float height, bool relative, [gui-element parent = nil]) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollPane(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateScrollBar(lua_State* luaVM) +{ + // gui-scrollbar guiCreateScrollBar ( float x, float y, float width, float height, bool horizontal, bool relative, [gui-element parent = nil]) + CVector2D position; + CVector2D size; + bool horizontal; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(horizontal); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollBar(*pLuaMain, position, size, horizontal, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateTabPanel(lua_State* luaVM) +{ + // element guiCreateTabPanel ( float x, float y, float width, float height, bool relative, [element parent = nil ] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTabPanel(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIStaticImageLoadImage(lua_State* luaVM) +{ + // bool guiStaticImageLoadImage ( element theElement, string filename ) + CClientGUIElement* theElement; + SString filename; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadString(filename); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CResource* pResource = pLuaMain->GetResource(); + SString strPath; + if (CResourceManager::ParseResourcePathInput(filename, pResource, &strPath)) + { + if (CStaticFunctionDefinitions::GUIStaticImageLoadImage(*theElement, strPath)) + { + lua_pushboolean(luaVM, true); + return 1; + } + else + argStream.SetCustomError(filename, "Error loading image"); + } + else + argStream.SetCustomError(filename, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIStaticImageGetNativeSize(lua_State* luaVM) +{ + // bool guiStaticImageGetNativeSize ( element theElement, string filename ) + CClientGUIElement* theElement; + CVector2D vecSize; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + if (CStaticFunctionDefinitions::GUIStaticImageGetNativeSize(*theElement, vecSize)) + { + lua_pushnumber(luaVM, vecSize.fX); + lua_pushnumber(luaVM, vecSize.fY); + return 2; + } + + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateTab(lua_State* luaVM) +{ + // element guiCreateTab ( string text, element parent ) + SString text; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadString(text); + argStream.ReadUserData(parent); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTab(*pLuaMain, text, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetSelectedTab(lua_State* luaVM) +{ + // element guiGetSelectedTab ( element tabPanel ) + CClientGUIElement* tabPanel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabPanel); + + if (!argStream.HasErrors()) + { + CClientGUIElement* pTab = CStaticFunctionDefinitions::GUIGetSelectedTab(*tabPanel); + lua_pushelement(luaVM, pTab); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetSelectedTab(lua_State* luaVM) +{ + // bool guiSetSelectedTab ( element tabPanel, element theTab ) + CClientGUIElement* tabPanel; + CClientGUIElement* theTab; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabPanel); + argStream.ReadUserData(theTab); + + if (!argStream.HasErrors()) + { + if (CStaticFunctionDefinitions::GUISetSelectedTab(*tabPanel, *theTab)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIDeleteTab(lua_State* luaVM) +{ + // bool guiDeleteTab ( element tabToDelete, element tabPanel ) + CClientGUIElement* tabToDelete; + CClientGUIElement* tabPanel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabToDelete); + argStream.ReadUserData(tabPanel); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + if (CStaticFunctionDefinitions::GUIDeleteTab(*pLuaMain, tabToDelete, tabPanel)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetText(lua_State* luaVM) +{ + // bool guiSetText ( element guiElement, string text ) + CClientGUIElement* guiElement; + SString text; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(text); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetText(*guiElement, text); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetFont(lua_State* luaVM) +{ + // bool guiSetFont ( element guiElement, mixed font ) + CClientGUIElement* guiElement; + SString strFontName; + CClientGuiFont* pGuiFontElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + MixedReadGuiFontString(argStream, strFontName, "default-normal", pGuiFontElement); + + if (!argStream.HasErrors()) + { + if (guiElement->SetFont(strFontName, pGuiFontElement)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIBringToFront(lua_State* luaVM) +{ + // bool guiBringToFront ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + if (CStaticFunctionDefinitions::GUIBringToFront(*guiElement)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMoveToBack(lua_State* luaVM) +{ + // bool guiMoveToBack( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMoveToBack(*guiElement); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIRadioButtonSetSelected(lua_State* luaVM) +{ + // bool guiRadioButtonSetSelected ( element guiRadioButton, bool state ) + CClientGUIElement* guiRadioButton; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiRadioButton); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIRadioButtonSetSelected(*guiRadioButton, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICheckBoxSetSelected(lua_State* luaVM) +{ + // bool guiCheckBoxSetSelected ( element theCheckbox, bool state ) + CClientGUIElement* theCheckbox; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theCheckbox); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUICheckBoxSetSelected(*theCheckbox, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIRadioButtonGetSelected(lua_State* luaVM) +{ + // bool guiRadioButtonGetSelected( element guiRadioButton ) + CClientGUIElement* guiRadioButton; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiRadioButton); + + if (!argStream.HasErrors()) + { + bool bResult = static_cast(guiRadioButton->GetCGUIElement())->GetSelected(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICheckBoxGetSelected(lua_State* luaVM) +{ + // bool guiCheckBoxGetSelected ( element theCheckbox ) + CClientGUIElement* theCheckbox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theCheckbox); + + if (!argStream.HasErrors()) + { + bool bResult = static_cast(theCheckbox->GetCGUIElement())->GetSelected(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIProgressBarSetProgress(lua_State* luaVM) +{ + // bool guiProgressBarSetProgress ( progressBar theProgressbar, float progress ) + CClientGUIElement* theProgressbar; + float progress; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theProgressbar); + argStream.ReadNumber(progress); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIProgressBarSetProgress(*theProgressbar, static_cast(progress)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollBarSetScrollPosition(lua_State* luaVM) +{ + // bool guiScrollBarSetScrollPosition ( gui-scrollBar theScrollBar, float amount ) + CClientGUIElement* theScrollBar; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollBar); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollBarSetScrollPosition(*theScrollBar, static_cast(amount)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetHorizontalScrollPosition(lua_State* luaVM) +{ + // bool guiScrollPaneSetHorizontalScrollPosition ( gui-scrollPane theScrollPane, float amount ) + CClientGUIElement* theScrollPane; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetHorizontalScrollPosition(*theScrollPane, amount); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiScrollPaneSetVerticalScrollPosition ( gui-scrollPane theScrollPane, float amount ) + CClientGUIElement* theScrollPane; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetVerticalScrollPosition(*theScrollPane, amount); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIProgressBarGetProgress(lua_State* luaVM) +{ + // float guiProgressBarGetProgress ( progressBar theProgressbar ); + CClientGUIElement* theProgressbar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theProgressbar); + + if (!argStream.HasErrors()) + { + int iProgress = (int)(static_cast(theProgressbar->GetCGUIElement())->GetProgress() * 100.0f + 0.5f); + lua_pushnumber(luaVM, iProgress); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneGetHorizontalScrollPosition(lua_State* luaVM) +{ + // float guiScrollPaneGetHorizontalScrollPosition ( gui-scrollPane theScrollPane ) + CClientGUIElement* theScrollPane; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + + if (!argStream.HasErrors()) + { + float fPos = static_cast(theScrollPane->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiScrollPaneGetVerticalScrollPosition ( gui-scrollPane theScrollPane ) + CClientGUIElement* theScrollPane; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + + if (!argStream.HasErrors()) + { + float fPos = static_cast(theScrollPane->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollBarGetScrollPosition(lua_State* luaVM) +{ + // float guiScrollBarGetScrollPosition ( gui-scrollBar theScrollBar ) + CClientGUIElement* theScrollBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollBar); + + if (!argStream.HasErrors()) + { + int iPos = (int)(static_cast(theScrollBar->GetCGUIElement())->GetScrollPosition() * 100.0f); + lua_pushnumber(luaVM, iPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetText(lua_State* luaVM) +{ + // string guiGetText ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + SString strText = guiElement->GetCGUIElement()->GetText(); + lua_pushstring(luaVM, strText); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetFont(lua_State* luaVM) +{ + // string,font guiGetFont ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + CClientGuiFont* pGuiFontElement; + SString strFontName = guiElement->GetFont(&pGuiFontElement); + + if (strFontName != "") + lua_pushstring(luaVM, strFontName); + else + lua_pushnil(luaVM); + lua_pushelement(luaVM, pGuiFontElement); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetSize(lua_State* luaVM) +{ + // float float guiGetSize ( element theElement, bool relative ) + CClientGUIElement* theElement; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CVector2D Size; + theElement->GetCGUIElement()->GetSize(Size, relative); + + lua_pushnumber(luaVM, Size.fX); + lua_pushnumber(luaVM, Size.fY); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetScreenSize(lua_State* luaVM) +{ + const CVector2D Size = CStaticFunctionDefinitions::GUIGetScreenSize(); + + lua_pushnumber(luaVM, Size.fX); + lua_pushnumber(luaVM, Size.fY); + return 2; +} + +int CLuaGUIDefs::GUIGetPosition(lua_State* luaVM) +{ + // float, float guiGetPosition ( element guiElement, bool relative ) + CClientGUIElement* guiElement; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CVector2D Pos; + guiElement->GetCGUIElement()->GetPosition(Pos, relative); + + lua_pushnumber(luaVM, Pos.fX); + lua_pushnumber(luaVM, Pos.fY); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetAlpha(lua_State* luaVM) +{ + // bool guiSetAlpha ( element guielement, float alpha ) + CClientGUIElement* guiElement; + float alpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(alpha); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetAlpha(*guiElement, Clamp(0.0f, alpha, 1.0f)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetAlpha(lua_State* luaVM) +{ + // int guiGetAlpha ( element guiElement [, bool effectiveAlpha = false] ) + CClientGUIElement* guiElement; + bool bEffectiveAlpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(bEffectiveAlpha, false); + + if (!argStream.HasErrors()) + { + float fAlpha = !bEffectiveAlpha ? guiElement->GetCGUIElement()->GetAlpha() : guiElement->GetCGUIElement()->GetEffectiveAlpha(); + lua_pushnumber(luaVM, fAlpha); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetVisible(lua_State* luaVM) +{ + // bool guiSetVisible ( element guiElement, bool state ) + CClientGUIElement* guiElement; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetVisible(*guiElement, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetEnabled(lua_State* luaVM) +{ + // bool guiSetEnabled ( element guiElement, bool enabled ) + CClientGUIElement* guiElement; + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetEnabled(*guiElement, enabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetProperty(lua_State* luaVM) +{ + // bool guiSetProperty ( element guiElement, string property, string value ) + CClientGUIElement* guiElement; + SString property; + SString value; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(property); + argStream.ReadString(value); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetProperty(*guiElement, property, value); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetVisible(lua_State* luaVM) +{ + // bool guiGetVisible ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + bool bResult = guiElement->GetCGUIElement()->IsVisible(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetEnabled(lua_State* luaVM) +{ + // bool guiGetEnabled ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + bool bResult = guiElement->GetCGUIElement()->IsEnabled(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetProperty(lua_State* luaVM) +{ + // string guiGetProperty ( element guiElement, string property ) + CClientGUIElement* guiElement; + SString property; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(property); + + if (!argStream.HasErrors()) + { + SString strValue = guiElement->GetCGUIElement()->GetProperty(property); + lua_pushstring(luaVM, strValue); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetProperties(lua_State* luaVM) +{ + // table guiGetProperties ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + // Create a new table + lua_newtable(luaVM); + + // Add all our properties to the table on top of the given lua main's stack + unsigned int uiIndex = 0; + CGUIPropertyIter iter = guiElement->GetCGUIElement()->GetPropertiesBegin(); + CGUIPropertyIter iterEnd = guiElement->GetCGUIElement()->GetPropertiesEnd(); + for (; iter != iterEnd; iter++) + { + const char* szKey = (*iter)->strKey; + const char* szValue = (*iter)->strValue; + + // Add it to the table + lua_pushstring(luaVM, szKey); + lua_pushstring(luaVM, szValue); + lua_settable(luaVM, -3); + } + + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetSize(lua_State* luaVM) +{ + // bool guiSetSize ( element guiElement, float width, float height, bool relative ) + CClientGUIElement* guiElement; + float width; + float height; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(width); + argStream.ReadNumber(height); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetSize(*guiElement, CVector2D(width, height), relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetPosition(lua_State* luaVM) +{ + // bool guiSetPosition ( element guiElement, float x, float y, bool relative ) + CClientGUIElement* guiElement; + float x; + float y; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(x); + argStream.ReadNumber(y); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetPosition(*guiElement, CVector2D(x, y), relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSortingEnabled(lua_State* luaVM) +{ + // bool guiGridListSetSortingEnabled ( element guiGridlist, bool enabled ) + CClientGUIElement* guiGridlist; + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSortingEnabled(*guiGridlist, enabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAddColumn(lua_State* luaVM) +{ + // int guiGridListAddColumn ( element gridList, string title, float width ) + CClientGUIElement* guiGridlist; + SString title; + float width; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadString(title); + argStream.ReadNumber(width); + + if (!argStream.HasErrors()) + { + uint id = CStaticFunctionDefinitions::GUIGridListAddColumn(*guiGridlist, title, width); + lua_pushnumber(luaVM, id); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListRemoveColumn(lua_State* luaVM) +{ + // bool guiGridListRemoveColumn ( element guiGridlist, int columnIndex ) + CClientGUIElement* guiGridlist; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListRemoveColumn(*guiGridlist, columnIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetColumnWidth(lua_State* luaVM) +{ + // bool guiGridListSetColumnWidth ( element gridList, int columnIndex, number width, bool relative ) + CClientGUIElement* guiGridlist; + int columnIndex; + float width; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + argStream.ReadNumber(width); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetColumnWidth(*guiGridlist, columnIndex, width, relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnWidth(lua_State* luaVM) +{ + // float guiGridListGetColumnWidth ( element gridList, int columnIndex, bool relative ) + CClientGUIElement* pGridList; + int columnIndex; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pGridList); + argStream.ReadNumber(columnIndex); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + float width; + if (static_cast(pGridList->GetCGUIElement())->GetColumnWidth(columnIndex, width, relative)) + { + lua_pushnumber(luaVM, width); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetColumnTitle(lua_State* luaVM) +{ + // bool guiGridListSetColumnTitle ( element guiGridlist, int columnIndex, string title ) + CClientGUIElement* guiGridlist; + int iColumnIndex; + SString sTitle; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(iColumnIndex); + argStream.ReadString(sTitle); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) + { + CStaticFunctionDefinitions::GUIGridListSetColumnTitle(*guiGridlist, iColumnIndex, sTitle); + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnTitle(lua_State* luaVM) +{ + // string guiGridListGetColumnTitle ( element guiGridlist, int columnIndex ) + CClientGUIElement* guiGridlist; + int iColumnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(iColumnIndex); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) + { + const char* szTitle = static_cast(guiGridlist->GetCGUIElement())->GetColumnTitle(iColumnIndex); + lua_pushstring(luaVM, szTitle); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAddRow(lua_State* luaVM) +{ + // int guiGridListAddRow ( element gridList ) + // int guiGridListAddRow ( element gridList, int/string itemText1, int/string itemText2 ... ) + CClientGUIElement* guiGridlist; + CLuaArguments Arguments; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadLuaArguments(Arguments); + + if (!argStream.HasErrors()) + { + int iRet = 0; + if (Arguments.Count() == 0) + iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true); + else + { + // Vector containing our string arguments. We add a bool to store whether it was originally a number. + std::vector > m_items; + std::vector::const_iterator it = Arguments.IterBegin(); + for (it; it != Arguments.IterEnd(); it++) + { + CLuaArgument* pArgument = *it; + SString strItemText; + bool bNumber = false; + + // Check the type of the argument and convert it to a string we can process + uint type = pArgument->GetType(); + if (type == LUA_TNUMBER) + { + // Grab the lua string and its size + const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); + size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); + + // Set our string + strItemText.assign(szLuaString, sizeLuaString); + bNumber = true; + } + else if (type == LUA_TSTRING) + strItemText = pArgument->GetString(); + else + continue; + + m_items.push_back(std::make_pair(strItemText, bNumber)); + } + iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true, &m_items); + } + + if (iRet >= 0) + { + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushnumber(luaVM, iRet); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListInsertRowAfter(lua_State* luaVM) +{ + // int guiGridListInsertRowAfter ( element gridList, int rowIndex ) + // int guiGridListInsertRowAfter ( element gridList, int rowIndex, int/string itemText1, int/string itemText2 ... ) + CClientGUIElement* guiGridlist; + int rowIndex; + CLuaArguments Arguments; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadLuaArguments(Arguments); + + if (!argStream.HasErrors()) + { + int iRet = 0; + if (Arguments.Count() == 0) + iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex); + else + { + // Vector containing our string arguments. We add a bool to store whether it was originally a number. + std::vector > m_items; + std::vector::const_iterator it = Arguments.IterBegin(); + for (it; it != Arguments.IterEnd(); it++) + { + CLuaArgument* pArgument = *it; + SString strItemText; + bool bNumber = false; + + // Check the type of the argument and convert it to a string we can process + uint type = pArgument->GetType(); + if (type == LUA_TNUMBER) + { + // Grab the lua string and its size + const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); + size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); + + // Set our string + strItemText.assign(szLuaString, sizeLuaString); + bNumber = true; + } + else if (type == LUA_TSTRING) + strItemText = pArgument->GetString(); + else + continue; + + m_items.push_back(std::make_pair(strItemText, bNumber)); + } + iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex, &m_items); + } + + if (iRet >= 0) + { + lua_pushnumber(luaVM, iRet); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAutoSizeColumn(lua_State* luaVM) +{ + // bool guiGridListAutoSizeColumn ( element gridList, int columnIndex ) + CClientGUIElement* guiGridlist; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListAutoSizeColumn(*guiGridlist, columnIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListClear(lua_State* luaVM) +{ + // bool guiGridListClear ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListClear(*guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSelectionMode(lua_State* luaVM) +{ + // bool guiGridListSetSelectionMode ( guiElement gridlist, int mode ) + CClientGUIElement* guiGridlist; + int mode; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(mode); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSelectionMode(*guiGridlist, mode); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedItem(lua_State* luaVM) +{ + // int, int guiGridListGetSelectedItem ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iRow = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemRow(); + int iColumn = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemColumn(); + lua_pushnumber(luaVM, iRow); + lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedItems(lua_State* luaVM) +{ + // table guiGridListGetSelectedItems ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + CGUIGridList* pList = static_cast(guiGridlist->GetCGUIElement()); + CGUIListItem* pItem = NULL; + + lua_newtable(luaVM); + + for (int i = 1; i <= pList->GetSelectedCount(); i++) + { + pItem = pList->GetNextSelectedItem(pItem); + if (!pItem) + break; + + lua_pushnumber(luaVM, i); + lua_newtable(luaVM); + + // column + lua_pushstring(luaVM, "column"); + lua_pushnumber(luaVM, pList->GetItemColumnIndex(pItem)); + lua_settable(luaVM, -3); + + // row + lua_pushstring(luaVM, "row"); + lua_pushnumber(luaVM, pList->GetItemRowIndex(pItem)); + lua_settable(luaVM, -3); + + // push to main table + lua_settable(luaVM, -3); + } + + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedCount(lua_State* luaVM) +{ + // int guiGridListGetSelectedCount ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iCount = static_cast(guiGridlist->GetCGUIElement())->GetSelectedCount(); + lua_pushnumber(luaVM, iCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSelectedItem(lua_State* luaVM) +{ + // bool guiGridListSetSelectedItem ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + bool bReset; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadBool(bReset, true); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSelectedItem(*guiGridlist, rowIndex, columnIndex, bReset); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListRemoveRow(lua_State* luaVM) +{ + // bool guiGridListRemoveRow ( element gridList, int rowIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListRemoveRow(*guiGridlist, rowIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemText(lua_State* luaVM) +{ + // string guiGridListGetItemText ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + const char* szText = static_cast(guiGridlist->GetCGUIElement())->GetItemText(rowIndex, columnIndex); + lua_pushstring(luaVM, szText); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemData(lua_State* luaVM) +{ + // string guiGridListGetItemData ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + void* pData = static_cast(guiGridlist->GetCGUIElement())->GetItemData(rowIndex, columnIndex); + CLuaArgument* pVariable = reinterpret_cast(pData); + if (pVariable) + pVariable->Push(luaVM); + else + lua_pushnil(luaVM); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemColor(lua_State* luaVM) +{ + // int int int int guiGridListGetItemColor ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255, ucAlpha = 255; + if (static_cast(guiGridlist->GetCGUIElement())->GetItemColor(rowIndex, columnIndex, ucRed, ucGreen, ucBlue, ucAlpha)) + { + lua_pushnumber(luaVM, ucRed); + lua_pushnumber(luaVM, ucGreen); + lua_pushnumber(luaVM, ucBlue); + lua_pushnumber(luaVM, ucAlpha); + return 4; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetHorizontalScrollPosition(lua_State* luaVM) +{ + // float guiGridListGetHorizontalScrollPosition ( element guiGridlist ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPosition); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiGridListGetVerticalScrollPosition ( element guiGridlist ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPosition); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemText(lua_State* luaVM) +{ + // bool guiGridListSetItemText ( element gridList, int rowIndex, int columnIndex, string text, bool section, bool number ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + SString text; + bool section; + bool number; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadString(text); + argStream.ReadBool(section); + argStream.ReadBool(number); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetItemText(*guiGridlist, rowIndex, columnIndex, text, section, number, true); + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemData(lua_State* luaVM) +{ + // bool guiGridListSetItemData ( element gridList, int rowIndex, int columnIndex, string data ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + CLuaArgument data; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadLuaArgument(data); + + if (!argStream.HasErrors()) + { + CLuaArgument* pData = new CLuaArgument(data); + CStaticFunctionDefinitions::GUIGridListSetItemData(*guiGridlist, rowIndex, columnIndex, pData); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemColor(lua_State* luaVM) +{ + // bool guiGridListSetItemColor ( element gridList, int rowIndex, int columnIndex, int red, int green, int blue[, int alpha = 255 ] ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + int red; + int green; + int blue; + int alpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadNumber(red); + argStream.ReadNumber(green); + argStream.ReadNumber(blue); + argStream.ReadNumber(alpha, 255); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetItemColor(*guiGridlist, rowIndex, columnIndex, red, green, blue, alpha); + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetScrollBars(lua_State* luaVM) +{ + // bool guiGridListSetScrollBars ( element guiGridlist, bool horizontalBar, bool verticalBar ) + CClientGUIElement* guiGridlist; + bool horizontalBar; + bool verticalBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadBool(horizontalBar); + argStream.ReadBool(verticalBar); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetScrollBars(*guiGridlist, horizontalBar, verticalBar); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetHorizontalScrollPosition(lua_State* luaVM) +{ + // bool guiGridListSetHorizontalScrollPosition ( element guiGridlist, float fPosition ) + CClientGUIElement* guiGridlist; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetHorizontalScrollPosition(*guiGridlist, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiGridListSetVerticalScrollPosition ( element guiGridlist, float fPosition ) + CClientGUIElement* guiGridlist; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetVerticalScrollPosition(*guiGridlist, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetScrollBars(lua_State* luaVM) +{ + // bool guiScrollPaneSetScrollBars ( element scrollPane, bool horizontal, bool vertical ) + CClientGUIElement* scrollPane; + bool horizontalBar; + bool verticalBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(scrollPane); + argStream.ReadBool(horizontalBar); + argStream.ReadBool(verticalBar); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetScrollBars(*scrollPane, horizontalBar, verticalBar); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetRowCount(lua_State* luaVM) +{ + // int guiGridListGetRowCount ( element theList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iRowCount = static_cast(guiGridlist->GetCGUIElement())->GetRowCount(); + lua_pushnumber(luaVM, iRowCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnCount(lua_State* luaVM) +{ + // int guiGridListGetColumnCount ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + lua_pushnumber(luaVM, iColumnCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) +{ + // bool guiEditSetReadOnly ( element editField, bool status ) + CClientGUIElement* editField; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(editField); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetReadOnly(*editField, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) +{ + // bool guiEditIsReadOnly( element editField ) + CClientGUIElement* editField; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(editField); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) +{ + // bool guiMemoSetReadOnly ( gui-memo theMemo, bool status ) + CClientGUIElement* theMemo; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetReadOnly(*theMemo, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) +{ + // bool guiMemoIsReadOnly( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) +{ + // bool guiEditSetMasked ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) +{ + // bool guiEditSetMaxLength ( element theElement, int length ) + CClientGUIElement* theElement; + int length; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(length); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetMaxLength(*theElement, length); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) +{ + // bool guiEditSetCaretIndex ( element theElement, int index ) + CClientGUIElement* theElement; + int index; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(index); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetCaretIndex(*theElement, index); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) +{ + // int guiEditGetCaretIndex ( element theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, static_cast(theElement->GetCGUIElement())->GetCaretIndex()); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) +{ + // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) + CClientGUIElement* theMemo; + int index; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadNumber(index); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetCaretIndex(*theMemo, index); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiMemoSetVerticalScrollPosition ( gui-memo theMemo, float fPosition ) + CClientGUIElement* theMemo; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) +{ + // bool guiMemoGetCaretIndex ( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, static_cast(theMemo->GetCGUIElement())->GetCaretIndex()); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiMemoGetVerticalScrollPosition ( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); + float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) +{ + // bool guiWindowSetMovable ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIWindowSetMovable(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) +{ + // bool guiWindowSetSizable ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIWindowSetSizable(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) +{ + // float guiLabelGetTextExtent ( element theLabel ) + CClientGUIElement* theLabel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + + if (!argStream.HasErrors()) + { + float fExtent = static_cast(theLabel->GetCGUIElement())->GetTextExtent(); + lua_pushnumber(luaVM, fExtent); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetFontHeight(lua_State* luaVM) +{ + // float guiLabelGetFontHeight ( element theLabel ) + CClientGUIElement* theLabel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + + if (!argStream.HasErrors()) + { + float fHeight = static_cast(theLabel->GetCGUIElement())->GetFontHeight(); + lua_pushnumber(luaVM, fHeight); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetColor(lua_State* luaVM) +{ + // bool guiLabelSetColor ( element theElement, int red, int green, int blue ) + CClientGUIElement* theElement; + int red; + int green; + int blue; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(red); + argStream.ReadNumber(green); + argStream.ReadNumber(blue); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUILabelSetColor(*theElement, red, green, blue); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetColor(lua_State* luaVM) +{ + // int r, int g, int b guiLabelGetColor ( element theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255; + static_cast(theElement->GetCGUIElement())->GetTextColor(ucRed, ucGreen, ucBlue); + lua_pushnumber(luaVM, ucRed); + lua_pushnumber(luaVM, ucGreen); + lua_pushnumber(luaVM, ucBlue); + return 3; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetVerticalAlign(lua_State* luaVM) +{ + // bool guiLabelSetVerticalAlign ( element theLabel, string align ) + CClientGUIElement* theLabel; + CGUIVerticalAlign align; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + argStream.ReadEnumString(align); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUILabelSetVerticalAlign(*theLabel, align); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetHorizontalAlign(lua_State* luaVM) +{ + // bool guiLabelSetHorizontalAlign ( element theLabel, string align, [ bool wordwrap = false ] ) + CClientGUIElement* theLabel; + CGUIHorizontalAlign align; + bool wordwrap; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + argStream.ReadEnumString(align); + argStream.ReadBool(wordwrap, false); + + if (!argStream.HasErrors()) + { + if (wordwrap) + align = (CGUIHorizontalAlign)(align + 4); + CStaticFunctionDefinitions::GUILabelSetHorizontalAlign(*theLabel, align); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) +{ + //* chat_font - Returns the chatbox font + //* chat_lines - Returns how many lines the chatbox has + //* chat_color - Returns the background color of the chatbox + //* chat_text_color - Returns the chatbox text color + //* chat_input_color - Returns the background color of the chatbox input + //* chat_input_prefix_color - Returns the color of the input prefix text + //* chat_input_text_color - Returns the color of the text in the chatbox input + //* chat_scale - Returns the scale of the text in the chatbox + //* chat_position_offset_x - Returns the position offset of the chatbox on the x axis + //* chat_position_offset_y - Returns the position offset of the chatbox on the y axis + //* chat_position_horizontal - Returns the horizontal position of the chatbox + //* chat_position_vertical - Returns the vertical position of the chatbox + //* chat_text_alignment - Returns the horizontal alignment of the chatbox text + //* chat_width - Returns the scale of the background width + //* chat_css_style_text - Returns whether text fades out over time + //* chat_css_style_background - Returns whether the background fades out over time + //* chat_line_life - Returns how long it takes for text to start fading out + //* chat_line_fade_out - Returns how long takes for text to fade out + //* chat_use_cegui - Returns whether CEGUI is used to render the chatbox + //* text_scale - Returns text scale + + CCVarsInterface* pCVars = g_pCore->GetCVars(); + int iNumber; + float fNumber; + pCVars->Get("chat_font", fNumber); + lua_newtable(luaVM); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_font"); + pCVars->Get("chat_lines", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_lines"); + pCVars->Get("chat_width", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_width"); + pCVars->Get("chat_position_offset_x", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_position_offset_x"); + pCVars->Get("chat_position_offset_y", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_position_offset_y"); + pCVars->Get("chat_position_horizontal", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_position_horizontal"); + pCVars->Get("chat_position_vertical", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_position_vertical"); + pCVars->Get("chat_text_alignment", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_text_alignment"); + pCVars->Get("chat_css_style_text", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_css_style_text"); + pCVars->Get("chat_css_style_background", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_css_style_background"); + pCVars->Get("chat_line_life", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_line_life"); + pCVars->Get("chat_line_fade_out", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_line_fade_out"); + pCVars->Get("text_scale", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "text_scale"); + pCVars->Get("chat_use_cegui", fNumber); + lua_pushboolean(luaVM, fNumber ? true : false); + lua_setfield(luaVM, -2, "chat_use_cegui"); + std::string strCVar; + std::stringstream ss; + int iR, iG, iB, iA; + pCVars->Get("chat_color", strCVar); + if (!strCVar.empty()) + { + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_color"); + } + pCVars->Get("chat_text_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_text_color"); + } + pCVars->Get("chat_input_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_color"); + } + pCVars->Get("chat_input_prefix_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_prefix_color"); + } + pCVars->Get("chat_input_text_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_text_color"); + } + pCVars->Get("chat_scale", strCVar); + if (!strCVar.empty()) + { + float fX, fY; + ss.clear(); + ss.str(strCVar); + ss >> fX >> fY; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, fX); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, fY); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_scale"); + } + + return 1; +} + +int CLuaGUIDefs::GUICreateComboBox(lua_State* luaVM) +{ + // element guiCreateComboBox ( float x, float y, float width, float height, string caption, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + SString caption; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(caption); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateComboBox(*pLuaMain, position, size, caption, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxAddItem(lua_State* luaVM) +{ + // int guiComboBoxAddItem( element comboBox, string value ) + CClientGUIElement* comboBox; + SString value; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadString(value); + + if (!argStream.HasErrors()) + { + int newId = CStaticFunctionDefinitions::GUIComboBoxAddItem(*comboBox, value); + lua_pushnumber(luaVM, newId); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxRemoveItem(lua_State* luaVM) +{ + // bool guiComboBoxRemoveItem( element comboBox, int itemId ) + CClientGUIElement* comboBox; + int itemId; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxRemoveItem(*comboBox, itemId); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxClear(lua_State* luaVM) +{ + // bool guiComboBoxClear ( element comboBox ) + CClientGUIElement* comboBox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxClear(*comboBox); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxGetSelected(lua_State* luaVM) +{ + // int guiComboBoxGetSelected ( element comboBox ) + CClientGUIElement* comboBox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + int selected = CStaticFunctionDefinitions::GUIComboBoxGetSelected(*comboBox); + lua_pushnumber(luaVM, selected); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxSetSelected(lua_State* luaVM) +{ + // bool guiComboBoxSetSelected ( element comboBox, int itemIndex ) + CClientGUIElement* comboBox; + int itemIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemIndex); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxSetSelected(*comboBox, itemIndex); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxGetItemText(lua_State* luaVM) +{ + // string guiComboBoxGetItemText ( element comboBox, int itemId ) + CClientGUIElement* comboBox; + int itemId; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + + if (!argStream.HasErrors()) + { + SString ret = CStaticFunctionDefinitions::GUIComboBoxGetItemText(*comboBox, itemId); + lua_pushstring(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxSetItemText(lua_State* luaVM) +{ + // bool guiComboBoxSetItemText ( element comboBox, int itemId, string text ) + CClientGUIElement* comboBox; + int itemId; + SString text; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + argStream.ReadString(text); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxSetItemText(*comboBox, itemId, text); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateFont(lua_State* luaVM) +{ + // element guiCreateFont( string filepath [, int size=9 ] ) + SString strFilePath; + int iSize; + + CScriptArgReader argStream(luaVM); + argStream.ReadString(strFilePath); + argStream.ReadNumber(iSize, 9); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CResource* pParentResource = pLuaMain->GetResource(); + CResource* pFileResource = pParentResource; + SString strPath, strMetaPath; + if (CResourceManager::ParseResourcePathInput(strFilePath, pFileResource, &strPath, &strMetaPath)) + { + if (FileExists(strPath)) + { + SString strUniqueName = SString("%s*%s*%s", pParentResource->GetName(), pFileResource->GetName(), strMetaPath.c_str()).Replace("\\", "/"); + CClientGuiFont* pGuiFont = g_pClientGame->GetManager()->GetRenderElementManager()->CreateGuiFont(strPath, strUniqueName, iSize); + if (pGuiFont) + { + // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's + // ElementGroup? ** + pGuiFont->SetParent(pParentResource->GetResourceDynamicEntity()); + lua_pushelement(luaVM, pGuiFont); + return 1; + } + argStream.SetCustomError(strFilePath, "Error creating font"); + } + else + argStream.SetCustomError(strFilePath, "File not found"); + } + else + argStream.SetCustomError(strFilePath, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) +{ + // string guiGetCursorType ( ) + auto eType = CStaticFunctionDefinitions::GUIGetCursorType(); + lua_pushstring(luaVM, EnumToString(eType)); + return 1; +} From 174ea6b0c7e5e77632a67cd6b69a7453f42ecf6e Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 17:46:40 +0200 Subject: [PATCH 12/27] fix cclientgame --- Client/mods/deathmatch/logic/CClientGame.cpp | 13748 ++++++++--------- 1 file changed, 6874 insertions(+), 6874 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 80cb359d464..73852452eeb 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -1,6874 +1,6874 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto v1.0 - * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/CClientGame.cpp - * PURPOSE: Client game manager - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#include "StdInc.h" -#include -#include "game/CAnimBlendAssocGroup.h" -#include "game/CAnimBlendAssociation.h" -#include "game/CAnimBlendHierarchy.h" - -SString StringZeroPadout(const SString& strInput, uint uiPadoutSize) -{ - SString strResult = strInput; - while (strResult.length() < uiPadoutSize) - strResult += '\0'; - return strResult; -} - -using SharedUtil::CalcMTASAPath; -using std::list; -using std::vector; - -// Hide the "conversion from 'unsigned long' to 'DWORD*' of greater size" warning -#pragma warning(disable:4312) - -// Used within this file by the packet handler to grab the this pointer of CClientGame -extern CClientGame* g_pClientGame; -extern int g_iDamageEventLimit; -float g_fApplyDamageLastAmount; -uchar g_ucApplyDamageLastHitZone; -CClientPed* g_pApplyDamageLastDamagedPed; -bool g_bBulletFireVectorsValid; -CVector g_vecBulletFireStartPosition; -CVector g_vecBulletFireEndPosition; - -#define DEFAULT_GRAVITY 0.008f -#define DEFAULT_GAME_SPEED 1.0f -#define DEFAULT_BLUR_LEVEL 36 -#define DEFAULT_JETPACK_MAXHEIGHT 100 -#define DEFAULT_AIRCRAFT_MAXHEIGHT 800 -#define DEFAULT_AIRCRAFT_MAXVELOCITY 1.5f -#define DEFAULT_MINUTE_DURATION 1000 -#define DOUBLECLICK_TIMEOUT 330 -#define DOUBLECLICK_MOVE_THRESHOLD 10.0f - -CClientGame::CClientGame(bool bLocalPlay) -{ - // Init the global var with ourself - g_pClientGame = this; - - // Packet handler - m_pPacketHandler = new CPacketHandler(); - - // Init - m_bLocalPlay = bLocalPlay; - m_bErrorStartingLocal = false; - m_iLocalConnectAttempts = 0; - m_Status = CClientGame::STATUS_CONNECTING; - m_ulVerifyTimeStart = 0; - m_ulLastClickTick = 0; - m_pLocalPlayer = NULL; - m_LocalID = INVALID_ELEMENT_ID; - m_bShowNametags = true; - m_bWaitingForLocalConnect = false; - m_bShowRadar = false; - m_bGameLoaded = false; - m_bTriggeredIngameAndConnected = false; - m_bGracefulDisconnect = false; - m_ulLastVehicleInOutTime = 0; - m_bIsGettingOutOfVehicle = false; - m_bIsGettingIntoVehicle = false; - m_bIsGettingJacked = false; - m_bIsJackingVehicle = false; - m_VehicleInOutID = INVALID_ELEMENT_ID; - m_pGettingJackedBy = NULL; - m_ucVehicleInOutSeat = 0xFF; - m_pTargetedEntity = NULL; - m_TargetedPlayerID = INVALID_ELEMENT_ID; - m_pDamageEntity = NULL; - m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageBodyPiece = 0xFF; - m_ucDamageWeapon = 0xFF; - m_ulDamageTime = 0; - m_bDamageSent = true; - m_bShowNetstat = false; - m_bShowFPS = false; - m_bHudAreaNameDisabled = false; - m_fGameSpeed = 1.0f; - m_lMoney = 0; - m_dwWanted = 0; - m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) - ResetAmmoInClip(); - - m_bNoNewVehicleTask = false; - m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; - - m_bCursorEventsEnabled = false; - m_bInitiallyFadedOut = true; - - m_bIsPlayingBack = false; - m_bFirstPlaybackFrame = false; - - // Setup game glitch defaults ( false = disabled ). Remember to update these serverside if you alter them! - m_Glitches[GLITCH_QUICKRELOAD] = false; - g_pMultiplayer->DisableQuickReload(true); - m_Glitches[GLITCH_FASTFIRE] = false; - m_Glitches[GLITCH_FASTMOVE] = false; - m_Glitches[GLITCH_CROUCHBUG] = false; - m_Glitches[GLITCH_CLOSEDAMAGE] = false; - g_pMultiplayer->DisableCloseRangeDamage(true); - m_Glitches[GLITCH_HITANIM] = false; - m_Glitches[GLITCH_FASTSPRINT] = false; - m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; - m_Glitches[GLITCH_QUICKSTAND] = false; - g_pMultiplayer->DisableBadDrivebyHitboxes(true); - - // Remove Night & Thermal vision view (if enabled). - g_pMultiplayer->SetNightVisionEnabled(false); - g_pMultiplayer->SetThermalVisionEnabled(false); - - m_bCloudsEnabled = true; - - m_bBirdsEnabled = true; - - m_bWasMinimized = false; - - // Grab the mod path - m_strModRoot = g_pCore->GetModInstallRoot("deathmatch"); - - // Figure out which directory to use for the client resource file cache - SetFileCacheRoot(); - - // Override CGUI's global events - g_pCore->GetGUI()->SetKeyDownHandler(INPUT_MOD, GUI_CALLBACK_KEY(&CClientGame::OnKeyDown, this)); - g_pCore->GetGUI()->SetMouseClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseClick, this)); - g_pCore->GetGUI()->SetMouseDoubleClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseDoubleClick, this)); - g_pCore->GetGUI()->SetMouseButtonDownHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonDown, this)); - g_pCore->GetGUI()->SetMouseButtonUpHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonUp, this)); - g_pCore->GetGUI()->SetMouseMoveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseMove, this)); - g_pCore->GetGUI()->SetMouseEnterHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseEnter, this)); - g_pCore->GetGUI()->SetMouseLeaveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseLeave, this)); - g_pCore->GetGUI()->SetMouseWheelHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseWheel, this)); - g_pCore->GetGUI()->SetMovedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnMove, this)); - g_pCore->GetGUI()->SetSizedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnSize, this)); - g_pCore->GetGUI()->SetFocusGainedHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusGain, this)); - g_pCore->GetGUI()->SetFocusLostHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusLoss, this)); - g_pCore->GetGUI()->SelectInputHandlers(INPUT_MOD); - - // Startup "entities from root" optimization for getElementsByType - CClientEntity::StartupEntitiesFromRoot(); - - // Startup game entity tracking manager - m_pGameEntityXRefManager = NewGameEntityXRefManager(); - m_pModelCacheManager = NewClientModelCacheManager(); - - // Initialize our root entity with an invalid id, we dont know the true id until map-start - m_pRootEntity = new CClientDummy(NULL, INVALID_ELEMENT_ID, "root"); - m_pRootEntity->MakeSystemEntity(); - - m_pDebugHookManager = new CDebugHookManager(); - - // Movings objects manager - m_pMovingObjectsManager = new CMovingObjectsManager(); - - // Create the manager and grab the most important pointers - m_pManager = new CClientManager; - m_pCamera = m_pManager->GetCamera(); - m_pMarkerManager = m_pManager->GetMarkerManager(); - m_pObjectManager = m_pManager->GetObjectManager(); - m_pPickupManager = m_pManager->GetPickupManager(); - m_pPlayerManager = m_pManager->GetPlayerManager(); - m_pRadarAreaManager = m_pManager->GetRadarAreaManager(); - m_pDisplayManager = m_pManager->GetDisplayManager(); - m_pVehicleManager = m_pManager->GetVehicleManager(); - m_pRadarMarkerManager = m_pManager->GetRadarMarkerManager(); - m_pPathManager = m_pManager->GetPathManager(); - m_pTeamManager = m_pManager->GetTeamManager(); - m_pPedManager = m_pManager->GetPedManager(); - m_pGUIManager = m_pManager->GetGUIManager(); - m_pResourceManager = m_pManager->GetResourceManager(); - m_pProjectileManager = m_pManager->GetProjectileManager(); - m_pLocalServer = NULL; - - m_pLatentTransferManager = new CLatentTransferManager(); - m_pZoneNames = new CZoneNames; - m_pScriptKeyBinds = new CScriptKeyBinds; - m_pRemoteCalls = new CRemoteCalls(); - m_pResourceFileDownloadManager = new CResourceFileDownloadManager(); - - // Create our net API - m_pNetAPI = new CNetAPI(m_pManager); - m_pNetworkStats = new CNetworkStats(m_pDisplayManager); - m_pSyncDebug = new CSyncDebug(m_pManager); - - // Create our blended weather class - m_pBlendedWeather = new CBlendedWeather; - - // Create our RPC class - m_pRPCFunctions = new CRPCFunctions(this); - - // Our management classes - m_pUnoccupiedVehicleSync = new CUnoccupiedVehicleSync(m_pVehicleManager); - m_pPedSync = new CPedSync(m_pPedManager); -#ifdef WITH_OBJECT_SYNC - m_pObjectSync = new CObjectSync(m_pObjectManager); -#endif - m_pNametags = new CNametags(m_pManager); - m_pRadarMap = new CRadarMap(m_pManager); - - // Set the screenshot path - /* This is now done in CCore, to maintain a global screenshot path - SString strScreenShotPath = SString::Printf ( "%s\\screenshots", m_szModRoot ); - g_pCore->SetScreenShotPath ( strScreenShotPath ); - */ - - // Create the transfer boxes (GUI) - m_pTransferBox = new CTransferBox(); - m_pBigPacketTransferBox = new CTransferBox(); - - // Store the time we started on - if (bLocalPlay) - m_ulTimeStart = 0; - else - m_ulTimeStart = CClientTime::GetTime(); - - // MTA Voice - m_pVoiceRecorder = new CVoiceRecorder(); - - // Singular file download manager - m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); - - // Register the message and the net packet handler - g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); - g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); - g_pMultiplayer->SetBulletImpactHandler(CClientGame::BulletImpact); - g_pMultiplayer->SetBulletFireHandler(CClientGame::BulletFire); - g_pMultiplayer->SetExplosionHandler(CClientExplosionManager::Hook_StaticExplosionCreation); - g_pMultiplayer->SetBreakTowLinkHandler(CClientGame::StaticBreakTowLinkHandler); - g_pMultiplayer->SetDrawRadarAreasHandler(CClientGame::StaticDrawRadarAreasHandler); - g_pMultiplayer->SetDamageHandler(CClientGame::StaticDamageHandler); - g_pMultiplayer->SetDeathHandler(CClientGame::StaticDeathHandler); - g_pMultiplayer->SetFireHandler(CClientGame::StaticFireHandler); - g_pMultiplayer->SetProjectileStopHandler(CClientProjectileManager::Hook_StaticProjectileAllow); - g_pMultiplayer->SetProjectileHandler(CClientProjectileManager::Hook_StaticProjectileCreation); - g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); - g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); - g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); - g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); - g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); - g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); - g_pMultiplayer->SetPreFxRenderHandler(CClientGame::StaticPreFxRenderHandler); - g_pMultiplayer->SetPreHudRenderHandler(CClientGame::StaticPreHudRenderHandler); - g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(CClientGame::StaticCAnimBlendAssocDestructorHandler); - g_pMultiplayer->SetAddAnimationHandler(CClientGame::StaticAddAnimationHandler); - g_pMultiplayer->SetAddAnimationAndSyncHandler(CClientGame::StaticAddAnimationAndSyncHandler); - g_pMultiplayer->SetAssocGroupCopyAnimationHandler(CClientGame::StaticAssocGroupCopyAnimationHandler); - g_pMultiplayer->SetBlendAnimationHierarchyHandler(CClientGame::StaticBlendAnimationHierarchyHandler); - g_pMultiplayer->SetProcessCollisionHandler(CClientGame::StaticProcessCollisionHandler); - g_pMultiplayer->SetVehicleCollisionHandler(CClientGame::StaticVehicleCollisionHandler); - g_pMultiplayer->SetVehicleDamageHandler(CClientGame::StaticVehicleDamageHandler); - g_pMultiplayer->SetHeliKillHandler(CClientGame::StaticHeliKillHandler); - g_pMultiplayer->SetObjectDamageHandler(CClientGame::StaticObjectDamageHandler); - g_pMultiplayer->SetObjectBreakHandler(CClientGame::StaticObjectBreakHandler); - g_pMultiplayer->SetWaterCannonHitHandler(CClientGame::StaticWaterCannonHandler); - g_pMultiplayer->SetVehicleFellThroughMapHandler(CClientGame::StaticVehicleFellThroughMapHandler); - g_pMultiplayer->SetGameObjectDestructHandler(CClientGame::StaticGameObjectDestructHandler); - g_pMultiplayer->SetGameVehicleDestructHandler(CClientGame::StaticGameVehicleDestructHandler); - g_pMultiplayer->SetGamePlayerDestructHandler(CClientGame::StaticGamePlayerDestructHandler); - g_pMultiplayer->SetGameProjectileDestructHandler(CClientGame::StaticGameProjectileDestructHandler); - g_pMultiplayer->SetGameModelRemoveHandler(CClientGame::StaticGameModelRemoveHandler); - g_pMultiplayer->SetGameEntityRenderHandler(CClientGame::StaticGameEntityRenderHandler); - g_pMultiplayer->SetFxSystemDestructionHandler(CClientGame::StaticFxSystemDestructionHandler); - g_pMultiplayer->SetDrivebyAnimationHandler(CClientGame::StaticDrivebyAnimationHandler); - g_pGame->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); - g_pGame->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); - g_pGame->SetTaskSimpleBeHitHandler(CClientGame::StaticTaskSimpleBeHitHandler); - g_pCore->SetMessageProcessor(CClientGame::StaticProcessMessage); - g_pCore->GetKeyBinds()->SetKeyStrokeHandler(CClientGame::StaticKeyStrokeHandler); - g_pCore->GetKeyBinds()->SetCharacterKeyHandler(CClientGame::StaticCharacterKeyHandler); - g_pNet->RegisterPacketHandler(CClientGame::StaticProcessPacket); - - m_pLuaManager = new CLuaManager(this); - m_pScriptDebugging = new CScriptDebugging(m_pLuaManager); - m_pScriptDebugging->SetLogfile(CalcMTASAPath("mta\\logs\\clientscript.log"), 3); - - CStaticFunctionDefinitions(m_pLuaManager, &m_Events, g_pCore, g_pGame, this, m_pManager); - CLuaFunctionDefs::Initialize(m_pLuaManager, m_pScriptDebugging, this); - CLuaDefs::Initialize(this, m_pLuaManager, m_pScriptDebugging); - - // Start async task scheduler - m_pAsyncTaskScheduler = new SharedUtil::CAsyncTaskScheduler(2); - - // Disable the enter/exit vehicle key button (we want to handle this button ourselves) - g_pMultiplayer->DisableEnterExitVehicleKey(true); - - // Disable GTA's pickup processing as we want to confirm the hits with the server - m_pPickupManager->SetPickupProcessingDisabled(true); - - // Key-bind for fire-key (for handling satchels and stealth-kills) - g_pCore->GetKeyBinds()->AddControlFunction("fire", CClientGame::StaticUpdateFireKey, true); - - // Init big packet progress vars - m_bReceivingBigPacket = false; - m_ulBigPacketSize = 0; - m_ulBigPacketBytesReceivedBase = 0; - - m_bBeingDeleted = false; - - #if defined (MTA_DEBUG) || defined (MTA_BETA) - m_bShowSyncingInfo = false; - #endif - - #ifdef MTA_DEBUG - m_pShowPlayer = m_pShowPlayerTasks = NULL; - m_bMimicLag = false; - m_ulLastMimicLag = 0; - m_bDoPaintballs = false; - m_bShowInterpolation = false; - #endif - - // Add our lua events - AddBuiltInEvents(); - - // Init debugger class - m_Foo.Init(this); - - // Load some stuff from the core config - float fScale; - g_pCore->GetCVars()->Get("text_scale", fScale); - CClientTextDisplay::SetGlobalScale(fScale); - - // Reset async loading script settings to default - g_pGame->SetAsyncLoadingFromScript(true, false); - - // Reset test mode script settings to default - g_pCore->GetGraphics()->GetRenderItemManager()->SetTestMode(DX_TEST_MODE_NONE); -} - -CClientGame::~CClientGame(void) -{ - m_bBeingDeleted = true; - // Stop all explosions. Unfortunately this doesn't fix the crash - // if a vehicle is destroyed while it explodes. - g_pGame->GetExplosionManager()->RemoveAllExplosions(); - - // Reset camera shaking - g_pGame->GetCamera()->SetShakeForce(0.0f); - - // Stop playing the continious sounds - // if the game was loaded. This is done by - // playing these special IDS. - if (m_bGameLoaded) - { - g_pGame->GetAudio()->PlayFrontEndSound(35); - g_pGame->GetAudio()->PlayFrontEndSound(48); - } - - // Reset the GUI input mode - g_pCore->GetGUI()->SetGUIInputMode(INPUTMODE_NO_BINDS_ON_EDIT); - - // Reset CGUI's global events - g_pCore->GetGUI()->ClearInputHandlers(INPUT_MOD); - - // Destroy mimics - #ifdef MTA_DEBUG - list::const_iterator iterMimics = m_Mimics.begin(); - for (; iterMimics != m_Mimics.end(); iterMimics++) - { - CClientPlayer* pPlayer = *iterMimics; - CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); - if (pVehicle) - delete pVehicle; - - delete pPlayer; - } - #endif - - // Hide the transfer box incase it is showing - m_pTransferBox->Hide(); - m_pBigPacketTransferBox->Hide(); - - // Stop async task scheduler - SAFE_DELETE(m_pAsyncTaskScheduler); - - SAFE_DELETE(m_pVoiceRecorder); - - // Singular file download manager - SAFE_DELETE(m_pSingularFileDownloadManager); - - // NULL the message/net stuff - g_pMultiplayer->SetPreContextSwitchHandler(NULL); - g_pMultiplayer->SetPostContextSwitchHandler(NULL); - g_pMultiplayer->SetPreWeaponFireHandler(NULL); - g_pMultiplayer->SetPostWeaponFireHandler(NULL); - g_pMultiplayer->SetBulletImpactHandler(NULL); - g_pMultiplayer->SetBulletFireHandler(NULL); - g_pMultiplayer->SetExplosionHandler(NULL); - g_pMultiplayer->SetBreakTowLinkHandler(NULL); - g_pMultiplayer->SetDrawRadarAreasHandler(NULL); - g_pMultiplayer->SetDamageHandler(NULL); - g_pMultiplayer->SetFireHandler(NULL); - g_pMultiplayer->SetProjectileStopHandler(NULL); - g_pMultiplayer->SetProjectileHandler(NULL); - g_pMultiplayer->SetProcessCamHandler(nullptr); - g_pMultiplayer->SetRender3DStuffHandler(NULL); - g_pMultiplayer->SetPreRenderSkyHandler(NULL); - g_pMultiplayer->SetRenderHeliLightHandler(nullptr); - g_pMultiplayer->SetChokingHandler(NULL); - g_pMultiplayer->SetPreWorldProcessHandler(NULL); - g_pMultiplayer->SetPostWorldProcessHandler(NULL); - g_pMultiplayer->SetPreFxRenderHandler(NULL); - g_pMultiplayer->SetPreHudRenderHandler(NULL); - g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(NULL); - g_pMultiplayer->SetAddAnimationHandler(NULL); - g_pMultiplayer->SetAddAnimationAndSyncHandler(NULL); - g_pMultiplayer->SetAssocGroupCopyAnimationHandler(NULL); - g_pMultiplayer->SetBlendAnimationHierarchyHandler(NULL); - g_pMultiplayer->SetProcessCollisionHandler(NULL); - g_pMultiplayer->SetVehicleCollisionHandler(NULL); - g_pMultiplayer->SetVehicleDamageHandler(NULL); - g_pMultiplayer->SetHeliKillHandler(NULL); - g_pMultiplayer->SetObjectDamageHandler(NULL); - g_pMultiplayer->SetObjectBreakHandler(NULL); - g_pMultiplayer->SetWaterCannonHitHandler(NULL); - g_pMultiplayer->SetGameObjectDestructHandler(NULL); - g_pMultiplayer->SetGameVehicleDestructHandler(NULL); - g_pMultiplayer->SetGamePlayerDestructHandler(NULL); - g_pMultiplayer->SetGameProjectileDestructHandler(NULL); - g_pMultiplayer->SetGameModelRemoveHandler(NULL); - g_pMultiplayer->SetGameEntityRenderHandler(NULL); - g_pMultiplayer->SetDrivebyAnimationHandler(nullptr); - g_pGame->SetPreWeaponFireHandler(NULL); - g_pGame->SetPostWeaponFireHandler(NULL); - g_pGame->SetTaskSimpleBeHitHandler(NULL); - g_pGame->GetAudio()->SetWorldSoundHandler(NULL); - g_pCore->SetMessageProcessor(NULL); - g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); - g_pCore->GetKeyBinds()->SetCharacterKeyHandler(NULL); - g_pNet->StopNetwork(); - g_pNet->RegisterPacketHandler(NULL); - CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); - pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessClientKeyBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessClientControlBind); - pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessServerKeyBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessServerControlBind); - pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticUpdateFireKey); - pKeyBinds->SetAllControlsEnabled(true, true, true); - g_pCore->ForceCursorVisible(false); - SetCursorEventsEnabled(false); - - // Destroy our stuff - SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop - SAFE_DELETE(m_pNametags); - SAFE_DELETE(m_pSyncDebug); - SAFE_DELETE(m_pNetworkStats); - SAFE_DELETE(m_pNetAPI); - SAFE_DELETE(m_pRPCFunctions); - SAFE_DELETE(m_pUnoccupiedVehicleSync); - SAFE_DELETE(m_pPedSync); -#ifdef WITH_OBJECT_SYNC - SAFE_DELETE(m_pObjectSync); -#endif - SAFE_DELETE(m_pBlendedWeather); - SAFE_DELETE(m_pMovingObjectsManager); - SAFE_DELETE(m_pRadarMap); - SAFE_DELETE(m_pRemoteCalls); - SAFE_DELETE(m_pLuaManager); - SAFE_DELETE(m_pLatentTransferManager); - SAFE_DELETE(m_pResourceFileDownloadManager); - - SAFE_DELETE(m_pRootEntity); - - SAFE_DELETE(m_pModelCacheManager); - SAFE_DELETE(m_pGameEntityXRefManager); - SAFE_DELETE(m_pZoneNames); - SAFE_DELETE(m_pScriptKeyBinds); - - // Delete the scriptdebugger - SAFE_DELETE(m_pScriptDebugging); - - // Delete the transfer boxes - SAFE_DELETE(m_pTransferBox); - SAFE_DELETE(m_pBigPacketTransferBox); - - SAFE_DELETE(m_pLocalServer); - SAFE_DELETE(m_pDebugHookManager); - - // Packet handler - SAFE_DELETE(m_pPacketHandler); - - // Delete PerfStatManager - delete CClientPerfStatManager::GetSingleton(); - - // NULL the global CClientGame var - g_pClientGame = NULL; - m_bBeingDeleted = false; -} - -/* -bool CClientGame::StartGame ( void ) // for an offline game (e.g. editor) -{ - m_Status = STATUS_OFFLINE; - g_pCore->SetOfflineMod ( true ); // hide chatbox etc - g_pCore->SetConnected ( true ); // not sure, but its required :) - g_pCore->HideMainMenu (); // duh - - // If the game isn't started, start it - if ( g_pGame->GetSystemState () == 7 ) - { - g_pGame->StartGame (); - } - return true; -} -*/ - -#include -//#define _CRTDBG_CHECK_EVERY_16_DF 0x00100000 /* check heap every 16 heap ops */ -//#define _CRTDBG_CHECK_EVERY_128_DF 0x00800000 /* check heap every 128 heap ops */ -//#define _CRTDBG_CHECK_EVERY_1024_DF 0x04000000 /* check heap every 1024 heap ops */ - -void CClientGame::EnablePacketRecorder(const char* szFilename) -{ - m_pManager->GetPacketRecorder()->StartRecord(szFilename, true); -} - -void CClientGame::StartPlayback(void) -{ - // strcpy ( m_szNick, "Playback" ); - - m_bIsPlayingBack = true; - m_bFirstPlaybackFrame = true; - m_pManager->GetPacketRecorder()->SetPacketHandler(CClientGame::StaticProcessPacket); - - if (!m_pManager->IsGameLoaded()) - { - g_pGame->StartGame(); - } -} - -bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerType Type) -{ - m_ServerType = Type; - // int dbg = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ); - // dbg |= _CRTDBG_ALLOC_MEM_DF; - // dbg |= _CRTDBG_CHECK_ALWAYS_DF; - // dbg |= _CRTDBG_DELAY_FREE_MEM_DF; - // dbg |= _CRTDBG_LEAK_CHECK_DF; - //_CrtSetDbgFlag(dbg); - - // Verify that the nickname is valid - if (!IsNickValid(szNick)) - { - g_pCore->ShowMessageBox(_("Error") + _E("CD01"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - // Store our nickname - m_strLocalNick.AssignLeft(szNick, MAX_PLAYER_NICK_LENGTH); - - // Are we connected? - if (g_pNet->IsConnected() || m_bIsPlayingBack) - { - // Hide the console when connecting.. - if (g_pCore->GetConsole()->IsVisible()) - g_pCore->GetConsole()->SetVisible(false); - - // Display the status box - g_pCore->ShowMessageBox(_("CONNECTING"), _("Entering the game ..."), MB_ICON_INFO); - - // Send the initial data to the server - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Hash the password if neccessary - MD5 Password; - memset(Password.data, 0, sizeof(MD5)); - if (szPassword) - { - // Is it long enough? - size_t sizePassword = strlen(szPassword); - if (sizePassword > 0) - { - // Hash the password and put it in the struct - CMD5Hasher Hasher; - Hasher.Calculate(szPassword, sizePassword, Password); - } - } - - // Append version information - pBitStream->Write(static_cast(MTA_DM_NETCODE_VERSION)); - pBitStream->Write(static_cast(MTA_DM_VERSION)); - pBitStream->Write(static_cast(MTA_DM_BITSTREAM_VERSION)); - - SString strPlayerVersion("%d.%d.%d-%d.%05d.%d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, - MTASA_VERSION_BUILD, g_pNet->GetNetRev()); - pBitStream->WriteString(strPlayerVersion); - - pBitStream->WriteBit(g_pCore->IsOptionalUpdateInfoRequired(g_pNet->GetConnectedServer(true))); - - pBitStream->Write(static_cast(g_pGame->GetGameVersion())); - - // Append user details - SString strTemp = StringZeroPadout(m_strLocalNick, MAX_PLAYER_NICK_LENGTH); - pBitStream->Write(strTemp.c_str(), MAX_PLAYER_NICK_LENGTH); - pBitStream->Write(reinterpret_cast(Password.data), sizeof(MD5)); - - // Append community information (Removed) - std::string strUser; - pBitStream->Write(strUser.c_str(), MAX_SERIAL_LENGTH); - - // Send the packet as joindata - g_pNet->SendPacket(PACKET_ID_PLAYER_JOINDATA, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - return true; - } - } - else - { - g_pCore->ShowMessageBox(_("Error") + _E("CD02"), _("Not connected; please use Quick Connect or the 'connect' command to connect to a server."), - MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - } - - return false; -} - -void CClientGame::SetupLocalGame(eServerType Type) -{ - SString strConfig = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; - m_bWaitingForLocalConnect = true; - if (!m_pLocalServer) - m_pLocalServer = new CLocalServer(strConfig); -} - -bool CClientGame::StartLocalGame(eServerType Type, const char* szPassword) -{ - // Verify that the nickname is valid - std::string strNick; - g_pCore->GetCVars()->Get("nick", strNick); - - if (!IsNickValid(strNick.c_str())) - { - g_pCore->ShowMessageBox(_("Error") + _E("CD03"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - m_bWaitingForLocalConnect = false; - m_ServerType = Type; - SString strTemp = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; - - SAFE_DELETE(m_pLocalServer); - - // Store our nickname - m_strLocalNick.AssignLeft(strNick.c_str(), MAX_PLAYER_NICK_LENGTH); - - // Got a server? - if (m_bLocalPlay) - { - // Start the server locally - if (!m_Server.Start(strTemp)) - { - m_bWaitingForLocalConnect = true; - m_bErrorStartingLocal = true; - g_pCore->ShowMessageBox(_("Error") + _E("CD04"), _("The server is not installed"), MB_ICON_ERROR | MB_BUTTON_OK); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - if (szPassword) - m_Server.SetPassword(szPassword); - - // Display the status box<<<<< - m_OnCancelLocalGameClick = GUI_CALLBACK(&CClientGame::OnCancelLocalGameClick, this); - g_pCore->ShowMessageBox(_("Local Server"), _("Starting local server ..."), MB_BUTTON_CANCEL | MB_ICON_INFO, &m_OnCancelLocalGameClick); - } - else - { - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - // We're waiting for connection - m_bWaitingForLocalConnect = true; - return true; -} - -bool CClientGame::OnCancelLocalGameClick(CGUIElement* pElement) -{ - if (m_bLocalPlay && m_bWaitingForLocalConnect) - { - g_pCore->RemoveMessageBox(); - g_pCore->GetModManager()->RequestUnload(); - return true; - } - return false; -} - -void CClientGame::DoPulsePreFrame(void) -{ - if (m_Status == CClientGame::STATUS_JOINED) - { - if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) - { - m_pVoiceRecorder->DoPulse(); - } - } -} - -void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRenderTargets) -{ - // Allow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); - - // If appropriate, call onClientRestore - if (bDidUnminimize) - { - CLuaArguments Arguments; - Arguments.PushBoolean(bDidRecreateRenderTargets); - m_pRootEntity->CallEvent("onClientRestore", Arguments, false); - m_bWasMinimized = false; - - // Reverse any mute on minimize effects - g_pGame->GetAudio()->SetEffectsMasterVolume(g_pGame->GetSettings()->GetSFXVolume()); - g_pGame->GetAudio()->SetMusicMasterVolume(g_pGame->GetSettings()->GetRadioVolume()); - m_pManager->GetSoundManager()->SetMinimizeMuted(false); - } - - // Call onClientHUDRender LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientHUDRender", Arguments, false); - - // Disallow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); - - // Restore in case script forgets - g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); - - DebugElementRender(); -} - -void CClientGame::DoPulsePostFrame(void) -{ - TIMING_CHECKPOINT("+CClientGame::DoPulsePostFrame"); - #ifdef DEBUG_KEYSTATES - // Get the controller state - CControllerState cs; - g_pGame->GetPad()->GetCurrentControllerState(&cs); - - SString strBuffer; - strBuffer = SString::Printf( - "LeftShoulder1: %u\n" - "LeftShoulder2: %u\n" - "RightShoulder1: %u\n" - "RightShoulder2: %u\n" - "DPadUp: %u\n" - "DPadDown: %u\n" - "DPadLeft: %u\n" - "DPadRight: %u\n" - "Start: %u\n" - "Select: %u\n" - "ButtonSquare: %u\n" - "ButtonTriangle: %u\n" - "ButtonCross: %u\n" - "ButtonCircle: %u\n" - "ShockButtonL: %u\n" - "ShockButtonR: %u\n" - "PedWalk: %u\n", - cs.LeftShoulder1, cs.LeftShoulder2, cs.RightShoulder1, cs.RightShoulder2, cs.DPadUp, cs.DPadDown, cs.DPadLeft, cs.DPadRight, cs.Start, cs.Select, - cs.ButtonSquare, cs.ButtonTriangle, cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.ShockButtonR, cs.m_bPedWalk); - - g_pCore->GetGraphics()->DrawTextTTF(300, 10, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); - - strBuffer = SString::Printf( - "VehicleMouseLook: %u\n" - "LeftStickX: %u\n" - "LeftStickY: %u\n" - "RightStickX: %u\n" - "RightStickY: %u", - cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, cs.RightStickX, cs.RightStickY); - - g_pCore->GetGraphics()->DrawTextTTF(300, 320, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); - #endif - - UpdateModuleTickCount64(); - - if (m_pManager->IsGameLoaded()) - { - // Pulse the nametags before anything that changes player positions, we'll be 1 frame behind, but so is the camera - // If nametags are enabled, pulse the nametag manager - if (m_bShowNametags) - { - m_pNametags->DoPulse(); - } - - // Sync debug - m_pSyncDebug->OnPulse(); - - // Also eventually draw FPS - if (m_bShowFPS) - { - DrawFPS(); - } - - CGraphicsInterface* pGraphics = g_pCore->GetGraphics(); - unsigned int uiHeight = pGraphics->GetViewportHeight(); - unsigned int uiWidth = pGraphics->GetViewportWidth(); - - // Draw a little star in the corner if async is on - if (g_pGame->IsASyncLoadingEnabled(true)) - { - unsigned int uiPosY = g_pGame->IsASyncLoadingEnabled() ? uiHeight - 7 : uiHeight - 12; - pGraphics->DrawString(uiWidth - 5, uiPosY, 0x80ffffff, 1, "*"); - } - - // Draw notice text if dx test mode is enabled - if (g_pCore->GetGraphics()->GetRenderItemManager()->GetTestMode()) - { - unsigned int uiPosY = uiHeight - 30; - pGraphics->DrawString(uiWidth - 155, uiPosY, 0x40ffffff, 1, "dx test mode enabled"); - } - - // Draw notice text if diagnostic mode enabled - EDiagnosticDebugType diagnosticDebug = g_pCore->GetDiagnosticDebug(); - if (diagnosticDebug == EDiagnosticDebug::LOG_TIMING_0000) - { - unsigned int uiPosY = uiHeight - 30; - pGraphics->DrawString(uiWidth - 185, uiPosY, 0xffffff00, 1, "Debug setting: #0000 Log timing"); - } - - // Draw network trouble message if required - if (m_pNetAPI->IsNetworkTrouble()) - { - int iPosX = uiWidth / 2; // Half way across - int iPosY = uiHeight * 45 / 100; // 45/100 down - g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, - DT_NOCLIP | DT_CENTER); - } - - // Adjust the streaming memory limit. - unsigned int uiStreamingMemoryPrev; - g_pCore->GetCVars()->Get("streaming_memory", uiStreamingMemoryPrev); - uint uiStreamingMemory = SharedUtil::Clamp(g_pCore->GetMinStreamingMemory(), uiStreamingMemoryPrev, g_pCore->GetMaxStreamingMemory()); - if (uiStreamingMemory != uiStreamingMemoryPrev) - g_pCore->GetCVars()->Set("streaming_memory", uiStreamingMemory); - - int iStreamingMemoryBytes = static_cast(uiStreamingMemory) * 1024 * 1024; - if (g_pMultiplayer->GetLimits()->GetStreamingMemory() != iStreamingMemoryBytes) - g_pMultiplayer->GetLimits()->SetStreamingMemory(iStreamingMemoryBytes); - - // If we're in debug mode and are supposed to show task data, do it - #ifdef MTA_DEBUG - if (m_pShowPlayerTasks) - { - DrawTasks(m_pShowPlayerTasks); - } - - if (m_pShowPlayer) - { - DrawPlayerDetails(m_pShowPlayer); - } - - std::vector::const_iterator iter = m_pPlayerManager->IterBegin(); - for (; iter != m_pPlayerManager->IterEnd(); ++iter) - { - CClientPlayer* pPlayer = *iter; - if (pPlayer->IsStreamedIn() && pPlayer->IsShowingWepdata()) - DrawWeaponsyncData(pPlayer); - } - #endif - - #if defined (MTA_DEBUG) || defined (MTA_BETA) - if (m_bShowSyncingInfo) - { - // Draw the header boxz - CVector vecPosition = CVector(0.05f, 0.32f, 0); - m_pDisplayManager->DrawText2D("Syncing vehicles:", vecPosition, 1.0f, 0xFFFFFFFF); - - // Print each vehicle we're syncing - CDeathmatchVehicle* pVehicle; - list::const_iterator iter = m_pUnoccupiedVehicleSync->IterBegin(); - for (; iter != m_pUnoccupiedVehicleSync->IterEnd(); iter++) - { - vecPosition.fY += 0.03f; - pVehicle = *iter; - - SString strBuffer("ID: %u (%s)", pVehicle->GetID(), pVehicle->GetNamePointer()); - - m_pDisplayManager->DrawText2D(strBuffer, vecPosition, 1.0f, 0xFFFFFFFF); - } - } - #endif - // Heli Clear time - if (m_LastClearTime.Get() > HeliKill_List_Clear_Rate) - { - // Clear our list now - m_HeliCollisionsMap.clear(); - m_LastClearTime.Reset(); - } - - CClientPerfStatManager::GetSingleton()->DoPulse(); - } - - m_pRadarMap->DoRender(); - m_pManager->DoRender(); - DoPulses(); - - // If we're supposed to show netstat, draw them infront of everything else - if (m_bShowNetstat) - { - m_pNetworkStats->Draw(); - } -} - -void CClientGame::DoPulses(void) -{ - TIMING_CHECKPOINT("-CClientGame::DoPulsePostFrame"); - - g_pCore->ApplyFrameRateLimit(); - - TIMING_CHECKPOINT("+CClientGame::DoPulses"); - - m_BuiltCollisionMapThisFrame = false; - - if (m_bIsPlayingBack && m_bFirstPlaybackFrame && m_pManager->IsGameLoaded()) - { - g_pCore->GetConsole()->Printf("First playback frame, starting"); - m_pManager->GetPacketRecorder()->StartPlayback("log.rec", false); - m_bFirstPlaybackFrame = false; - } - - // Call debug code if debug mode - m_Foo.DoPulse(); - - // Output stuff from our internal server eventually - m_Server.DoPulse(); - - if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED && GetTickCount64_() - m_llLastTransgressionTime > 60000) - { - uint uiLevel = 0; - uint uiInform = 0; - SString strMessage; - - // Is the player a cheater? - if (!m_pManager->GetAntiCheat().PerformChecks()) - { - uiLevel = 1; - uiInform = 2; - } - else - { - strMessage = g_pNet->GetNextBuffer(); - if (strMessage.length()) - { - uiLevel = atoi(strMessage.SplitLeft(":", &strMessage)); - uiInform = atoi(strMessage.SplitLeft(":", &strMessage)); - } - } - - // Send message to the server - if (uiLevel) - { - SString strPrefix = (uiInform == 2) ? "AC" : (uiInform == 1) ? "VF" : "SD"; - SString strMessageCombo = SString("%s #%d %s", *strPrefix, uiLevel, strMessage.c_str()).TrimEnd(" "); - m_llLastTransgressionTime = GetTickCount64_(); - AddReportLog(3100, strMessageCombo + SString(" (%d)", uiInform)); - - if (uiInform > 0) - { - // The server will use the whole message as supplied here - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write(uiLevel); - pBitStream->WriteString(strMessageCombo); - g_pNet->SendPacket(PACKET_ID_PLAYER_TRANSGRESSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - else - { - // Otherwise, disconnect here - AddReportLog(7105, SString("Core - Kicked (%s)", *strMessageCombo)); - g_pCore->ShowMessageBox(_("Error") + _E("CD05"), SString(_("You were kicked from the game ( %s )"), *strMessageCombo), - MB_BUTTON_OK | MB_ICON_ERROR); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - } - - // Send diagnostic info - if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED) - { - // Retrieve data - SString strMessage = g_pNet->GetDiagnosticStatus(); - - // Send to the server if changed - if (strMessage != m_strLastDiagnosticStatus) - { - m_strLastDiagnosticStatus = strMessage; - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->WriteString(strMessage); - g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } - - // Pulse the network interface - - // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) - DoPulses2(false); - - m_pUnoccupiedVehicleSync->DoPulse(); - m_pPedSync->DoPulse(); -#ifdef WITH_OBJECT_SYNC - m_pObjectSync->DoPulse(); -#endif - m_pLatentTransferManager->DoPulse(); - m_pLuaManager->DoPulse(); - m_pScriptDebugging->UpdateLogOutput(); - - GetModelCacheManager()->DoPulse(); - - #ifdef MTA_DEBUG - UpdateMimics(); - #endif - - // Grab the current time - unsigned long ulCurrentTime = CClientTime::GetTime(); - - // Waiting for a connect? - if (m_bWaitingForLocalConnect) - { - // Connected? - if (g_pNet->IsConnected()) - { - // No longer waiting for connect - m_bWaitingForLocalConnect = false; - - // Assume local server has the same bitstream version - g_pNet->SetServerBitStreamVersion(MTA_DM_BITSTREAM_VERSION); - - // Run the game normally. - StartGame(m_strLocalNick, m_Server.GetPassword().c_str(), m_ServerType); - } - else - { - // Going to try connecting? Do this when the internal server has booted - // and we haven't started the connecting. - if (m_Server.IsReady() && m_iLocalConnectAttempts == 0) - { - g_pCore->ShowMessageBox(_("Local Server"), _("Connecting to local server..."), MB_ICON_INFO); - - // Connect - if (g_pNet->StartNetwork("localhost", 22010)) - { - // We're waiting for connection - m_iLocalConnectAttempts = 1; - m_ulTimeStart = CClientTime::GetTime(); - } - else - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD06"), _("Error connecting to server.")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - - // Timeout? - if (m_ulTimeStart != 0 && CClientTime::GetTime() >= m_ulTimeStart + 5000) - { - // Show timeout message and disconnect - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD07"), _("Connecting to local server timed out. See console for details.")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - } - - // If the game is loaded ... - if (m_pManager->IsGameLoaded()) - { - // Pulse the blended weather manager - m_pBlendedWeather->DoPulse(); - - // If we weren't ingame last frame; call the on ingame event - if (!m_bGameLoaded) - { - // Fix for gta not being focused sometimes - SetActiveWindow(g_pCore->GetHookedWindow()); - SetFocus(g_pCore->GetHookedWindow()); - - m_bGameLoaded = true; - Event_OnIngame(); - } - - // Check if the player is hitting the enter vehicle button - DoVehicleInKeyCheck(); - - // Pulse some stuff - m_pMovingObjectsManager->DoPulse(); - - // Get rid of our deleted elements - m_ElementDeleter.DoDeleteAll(); - m_pLuaManager->ProcessPendingDeleteList(); - - // Get rid of deleted GUI elements - g_pCore->GetGUI()->CleanDeadPool(); - - // Allow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); - - // Call onClientRender LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientRender", Arguments, false); - - // Disallow scripted dxSetRenderTarget for old scripts - g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); - - // Restore in case script forgets - g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); - - // Ensure replaced/restored textures for models in the GTA map are correct - g_pGame->FlushPendingRestreamIPL(); - - // Respawn objects in respawn pool - m_ObjectRespawner.DoRespawnAll(); - } - - // Are we connecting? - if (m_Status == CClientGame::STATUS_CONNECTING) - { - if (m_bErrorStartingLocal) - { - g_pCore->GetModManager()->RequestUnload(); - return; - } - - // Timed out? - if (!m_bWaitingForLocalConnect && ulCurrentTime >= m_ulTimeStart + NET_CONNECT_TIMEOUT) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD08"), _("Connection timed out"), "connect-timed-out", true); - g_pCore->GetModManager()->RequestUnload(); - return; - } - } - else if (m_Status == CClientGame::STATUS_JOINED) - { - // Pulse DownloadFiles if we're transferring stuff - GetResourceFileDownloadManager()->DoPulse(); - DownloadSingularResourceFiles(); - GetRemoteCalls()->ProcessQueuedFiles(); - } - - // Not waiting for local connect? - if (!m_bWaitingForLocalConnect) - { - // Trigger the ingame and connected event - if (!m_bTriggeredIngameAndConnected && m_pManager->IsGameLoaded() && g_pCore->IsConnected()) - { - m_bTriggeredIngameAndConnected = true; - Event_OnIngameAndConnected(); - - // Initialize the game - g_pCore->GetGame()->Initialize(); - } - - unsigned char ucError = g_pNet->GetConnectionError(); - - // Lost connection? - if (!g_pNet->IsConnected() && !m_bGracefulDisconnect && !m_bIsPlayingBack) - { - // See if we can figure out what specifically it was - if (ucError == 0) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD09"), _("Connection with the server was lost")); - g_pCore->GetModManager()->RequestUnload(); - return; - } - else - { - SString strError; - SString strErrorCode; - switch (ucError) - { - case RID_RSA_PUBLIC_KEY_MISMATCH: - strError = _("Disconnected: unknown protocol error"); - strErrorCode = _E("CD10"); // encryption key mismatch - break; - case RID_REMOTE_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected remotely"); - strErrorCode = _E("CD11"); - break; - case RID_REMOTE_CONNECTION_LOST: - strError = _("Disconnected: connection lost remotely"); - strErrorCode = _E("CD12"); - break; - case RID_CONNECTION_BANNED: - strError = _("Disconnected: you are banned from this server"); - strErrorCode = _E("CD13"); - break; - case RID_NO_FREE_INCOMING_CONNECTIONS: - strError = _("Disconnected: the server is currently full"); - strErrorCode = _E("CD14"); - break; - case RID_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected from the server"); - strErrorCode = _E("CD15"); - break; - case RID_CONNECTION_LOST: - strError = _("Disconnected: connection to the server was lost"); - strErrorCode = _E("CD16"); - break; - case RID_INVALID_PASSWORD: - strError = _("Disconnected: invalid password specified"); - strErrorCode = _E("CD17"); - break; - default: - strError = _("Disconnected: connection was refused"); - strErrorCode = _E("CD18"); - break; - } - - // Display an error, reset the error status and exit - g_pCore->ShowNetErrorMessageBox(_("Error") + strErrorCode, strError); - g_pNet->SetConnectionError(0); - g_pCore->GetModManager()->RequestUnload(); - } - } - - // If we're in the verificating status - if (m_Status == CClientGame::STATUS_JOINING) - { - // Time out the verification if it takes too long - if (m_ulVerifyTimeStart != 0 && ulCurrentTime >= m_ulVerifyTimeStart + CLIENT_VERIFICATION_TIMEOUT) - { - g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD19"), _("MTA Client verification failed!")); - g_pCore->GetModManager()->RequestUnload(); - } - } - } - - // Check for radar input - m_pRadarMap->DoPulse(); - g_pCore->GetGraphics()->SetAspectRatioAdjustmentSuspended(m_pRadarMap->IsRadarShowing()); - - // Got a local player? - if (m_pLocalPlayer) - { - // Network updates - UpdateVehicleInOut(); - UpdatePlayerTarget(); - UpdatePlayerWeapons(); - // UpdateTrailers (); // Test: Does it always work without this check? - UpdateStunts(); - // Clear last damager if more than 2 seconds old - if (CClientTime::GetTime() - m_ulDamageTime > 2000) - { - m_DamagerID = INVALID_ELEMENT_ID; - m_ucDamageWeapon = 0xFF; - m_ucDamageBodyPiece = 0xFF; - } - DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); - } - - // Game hacks, restore certain variables - // game-speed changes after spawning - g_pGame->SetGameSpeed(m_fGameSpeed); - // money changes on death/getting into taxis - g_pGame->GetPlayerInfo()->SetPlayerMoney(m_lMoney); - // wanted to stop it changing on skin change etc - if (m_pLocalPlayer) - { - if (m_dwWanted != g_pGame->GetPlayerInfo()->GetWanted()->GetWantedLevel()) - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevelNoFlash(m_dwWanted); - } - // stop players dying from starvation - g_pGame->GetPlayerInfo()->SetLastTimeEaten(0); - // reset weapon logs (for preventing quickreload) - - // Update streaming - m_pManager->UpdateStreamers(); - - // Send screen shot data - ProcessDelayedSendList(); - - // Collect async task scheduler results - m_pAsyncTaskScheduler->CollectResults(); - - TIMING_CHECKPOINT("-CClientGame::DoPulses"); -} - -// Extrapolation test -void CClientGame::DoPulses2(bool bCalledFromIdle) -{ - bool bIsUsingAlternatePulseOrder = IsUsingAlternatePulseOrder(!bCalledFromIdle); - - // Figure out which pulses to do - bool bDoStandardPulses; - bool bDoVehicleManagerPulse; - - if (!bIsUsingAlternatePulseOrder) - { - // With std pulse order, do pulses when not called from idle - bDoStandardPulses = !bCalledFromIdle; - bDoVehicleManagerPulse = !bCalledFromIdle; - } - else - { - // With alt pulse order, do pulses when called from idle - bDoStandardPulses = bCalledFromIdle; - bDoVehicleManagerPulse = bCalledFromIdle; - - // Except when watching a remote synced vehicle - if (CClientVehicle* pTargetVehicle = DynamicCast(m_pCamera->GetTargetEntity())) - if (pTargetVehicle->GetControllingPlayer() != m_pPlayerManager->GetLocalPlayer()) - bDoVehicleManagerPulse = !bDoVehicleManagerPulse; - } - - if (bDoStandardPulses) - { - // Change to high precision so arguments in element data and events can - // be rounded to look more like what is expected - ChangeFloatPrecision(true); - - // Pulse the network interface - TIMING_CHECKPOINT("+NetPulse"); - g_pNet->DoPulse(); - TIMING_CHECKPOINT("-NetPulse"); - - // Change precision back, and check we are in low precision mode 4 sure - ChangeFloatPrecision(false); - assert(!IsHighFloatPrecision()); - } - - m_pManager->DoPulse(bDoStandardPulses, bDoVehicleManagerPulse); - - if (bDoStandardPulses) - { - m_pNetAPI->DoPulse(); - } -} - -void CClientGame::HandleException(CExceptionInformation* pExceptionInformation) -{ -} - -void CClientGame::HandleRadioNext(CControlFunctionBind*) -{ - if (g_pClientGame) - { - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); - if (pPlayer) - { - pPlayer->NextRadioChannel(); - } - } -} - -void CClientGame::HandleRadioPrevious(CControlFunctionBind*) -{ - if (g_pClientGame) - { - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); - if (pPlayer) - { - pPlayer->PreviousRadioChannel(); - } - } -} -bool CClientGame::IsNametagValid(const char* szNick) -{ - // Grab the size of the nametag. Check that it's not to long or short - size_t sizeNick = MbUTF8ToUTF16(szNick).size(); - if (sizeNick < MIN_PLAYER_NAMETAG_LENGTH || sizeNick > MAX_PLAYER_NAMETAG_LENGTH) - { - return false; - } - - // Check that each character is valid (Anything above 32) - unsigned char ucTemp; - for (size_t i = 0; i < sizeNick; i++) - { - ucTemp = szNick[i]; - if (ucTemp < 32) - { - return false; - } - } - - // nametag is valid, return true - return true; -} - -bool CClientGame::IsNickValid(const char* szNick) -{ - // Grab the size of the nick. Check that it's within the player - size_t sizeNick = strlen(szNick); - if (sizeNick < MIN_PLAYER_NICK_LENGTH || sizeNick > MAX_PLAYER_NICK_LENGTH) - { - return false; - } - - // Check that each character is valid (visible characters exluding space) - unsigned char ucTemp; - for (size_t i = 0; i < sizeNick; i++) - { - ucTemp = szNick[i]; - if (ucTemp < 33 || ucTemp > 126) - { - return false; - } - } - - // Nickname is valid, return true - return true; -} - -void CClientGame::ShowNetstat(int iCmd) -{ - bool bShow = (iCmd == 1) ? true : (iCmd == 0) ? false : !m_bShowNetstat; - - if (bShow && !m_bShowNetstat) - { - m_pNetworkStats->Reset(); - } - m_bShowNetstat = bShow; -} - -void CClientGame::ShowEaeg(bool) -{ - if (m_pLocalPlayer) - m_pLocalPlayer->SetStat(0x2329, 1.0f); -} - -#ifdef MTA_WEPSYNCDBG -void CClientGame::ShowWepdata(const char* szNick) -{ - CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); - if (pPlayer) - { - pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); - } -} -#endif - -#ifdef MTA_DEBUG - -void CClientGame::ShowWepdata(const char* szNick) -{ - CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); - if (pPlayer) - { - pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); - } -} - -void CClientGame::ShowPlayer(const char* szNick) -{ - m_pShowPlayer = m_pPlayerManager->Get(szNick); -} - -void CClientGame::ShowTasks(const char* szNick) -{ - m_pShowPlayerTasks = m_pPlayerManager->Get(szNick); -} - -void CClientGame::SetMimic(unsigned int uiMimicCount) -{ - // Check if we're within the max mimics boundary - if (uiMimicCount > MAX_MIMICS) - return; - - // Create neccessary players - while (m_Mimics.size() < uiMimicCount) - { - CClientPlayer* pPlayer = new CClientPlayer(m_pManager, static_cast(MAX_NET_PLAYERS_REAL + (int)m_Mimics.size())); - pPlayer->SetNick("Mimic"); - m_Mimics.push_back(pPlayer); - } - - // Destroy neccessary players - while (m_Mimics.size() > uiMimicCount) - { - CClientPlayer* pPlayer = m_Mimics.back(); - CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); - if (pVehicle) - delete pVehicle; - - delete pPlayer; - m_Mimics.pop_back(); - } -} - -#endif - -void CClientGame::DoVehicleInKeyCheck(void) -{ - // Grab the controller state - CControllerState cs; - g_pGame->GetPad()->GetCurrentControllerState(&cs); - static bool bButtonTriangleWasDown = false; - if (cs.ButtonTriangle) - { - if (!bButtonTriangleWasDown) - { - bButtonTriangleWasDown = true; - - // Process the hit - ProcessVehicleInOutKey(false); - } - } - else - { - bButtonTriangleWasDown = false; - } -} - -void CClientGame::UpdateVehicleInOut(void) -{ - // We got told by the server to animate into a certain vehicle? - if (m_VehicleInOutID != INVALID_ELEMENT_ID) - { - // Grab the vehicle we're getting in/out of - CDeathmatchVehicle* pInOutVehicle = static_cast(m_pVehicleManager->Get(m_VehicleInOutID)); - - // In or out? - if (m_bIsGettingOutOfVehicle) - { - // If we aren't working on leaving the car (he's eiter finished or cancelled/failed leaving) - if (!m_pLocalPlayer->IsLeavingVehicle()) - { - // Are we outside the car? - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - if (!pVehicle) - { - // Tell the server that we successfully left the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction = VEHICLE_NOTIFY_OUT; - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself out (so we're sure the records are correct) - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it, and damagable if we're syncing it - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - }*/ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - - // Reset the vehicle in out stuff so we're ready for another car entry/leave. - // Don't allow a new entry/leave until we've gotten the notify return packet - ElementID ReasonVehicleID = m_VehicleInOutID; - g_pClientGame->ResetVehicleInOut(); - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = ReasonVehicleID; - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_out"); -#endif - } - // Are we still inside the car? - else - { - // Warp us out now to keep in sync with the server - m_pLocalPlayer->RemoveFromVehicle(); - } - } - } - - // Are we getting into a vehicle? - else if (m_bIsGettingIntoVehicle) - { - // If we aren't working on entering the car (he's either finished or cancelled) - if (!m_pLocalPlayer->IsEnteringVehicle()) - { - // Is he in a vehicle now? - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - if (pVehicle) - { - // Tell the server that we successfully entered the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction; - - if (m_bIsJackingVehicle) - { - ucAction = static_cast(VEHICLE_NOTIFY_JACK); -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack"); -#endif - } - else - { - ucAction = static_cast(VEHICLE_NOTIFY_IN); -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in"); -#endif - } - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself in (so we're sure the records are correct) - pVehicle->AllowDoorRatioSetting(m_pLocalPlayer->m_ucEnteringDoor, true); - m_pLocalPlayer->WarpIntoVehicle(pVehicle, m_ucVehicleInOutSeat); - - /* - // Make it damagable - if ( pInOutVehicle ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - */ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - } - else - { - // Tell the server that we aborted entered the car - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write the car id and the action id (enter complete) - pBitStream->Write(m_VehicleInOutID); - unsigned char ucAction; - if (m_bIsJackingVehicle) - { - ucAction = static_cast(VEHICLE_NOTIFY_JACK_ABORT); - pBitStream->WriteBits(&ucAction, 4); - - // Did we start jacking them? - bool bAlreadyStartedJacking = false; - CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); - if (pVehicle) - { - CClientPed* pJackedPlayer = pVehicle->GetOccupant(); - if (pJackedPlayer) - { - // Jax: have we already started to jack the other player? - if (pJackedPlayer->IsGettingJacked()) - { - bAlreadyStartedJacking = true; - } - } - unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; - pBitStream->WriteBits(&ucDoor, 3); - SDoorOpenRatioSync door; - door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); - pBitStream->Write(&door); - } - pBitStream->WriteBit(bAlreadyStartedJacking); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack_abort"); -#endif - } - else - { - ucAction = static_cast(VEHICLE_NOTIFY_IN_ABORT); - pBitStream->WriteBits(&ucAction, 4); - CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); - if (pVehicle) - { - unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; - pBitStream->WriteBits(&ucDoor, 3); - SDoorOpenRatioSync door; - door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); - pBitStream->Write(&door); - } - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in_abort"); -#endif - } - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - - // Warp ourself out again (so we're sure the records are correct) - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it, and damagable if we're syncing it - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - } - */ - if (pInOutVehicle) - { - pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); - pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); - } - } - - // Reset - // Don't allow a new entry/leave until we've gotten the notify return packet - ElementID ReasonID = m_VehicleInOutID; - ResetVehicleInOut(); - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = ReasonID; - } - } - } - else - { - // If we aren't getting jacked - if (!m_bIsGettingJacked) - { - CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); - CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - - // Jax: this was commented, re-comment if it was there for a reason (..and give the reason!) - // Are we in a vehicle we aren't supposed to be in? - if (pVehicle && !pOccupiedVehicle) - { - g_pCore->GetConsole()->Print("You shouldn't be in this vehicle"); - m_pLocalPlayer->RemoveFromVehicle(); - } - - // Are we supposed to be in a vehicle? But aren't? - if (pOccupiedVehicle && !pVehicle) - { - // Jax: this happens when we try to warp into a streamed out vehicle, including when we use CClientVehicle::StreamInNow - // ..maybe we need a different way to detect bike falls? - - // Tell the server - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Vehicle id - pBitStream->Write(pOccupiedVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_NOTIFY_FELL_OFF); - pBitStream->WriteBits(&ucAction, 4); - - // Send it and destroy the packet - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're not allowed to enter any vehicle before we get a confirm - m_bNoNewVehicleTask = true; - m_NoNewVehicleTaskReasonID = pOccupiedVehicle->GetID(); - - // Remove him from the vehicle - m_pLocalPlayer->RemoveFromVehicle(); - - /* - // Make it undamagable if we're not syncing it - CDeathmatchVehicle* pInOutVehicle = static_cast < CDeathmatchVehicle* > ( pOccupiedVehicle ); - if ( pInOutVehicle ) - { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } - } - */ - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_fell_off"); -#endif - } - } - } - } -} - -void CClientGame::UpdatePlayerTarget(void) -{ - CControllerState ControllerState; - m_pLocalPlayer->GetControllerState(ControllerState); - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - - // Ignore the local player so we don't get hit - m_pLocalPlayer->WorldIgnore(true); - - // Run a process line of sight and look for an entity we target - CEntity* pColEntity = NULL; - CColPoint* pColPoint = NULL; - g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pColEntity); - - // Unignore the local player again - m_pLocalPlayer->WorldIgnore(false); - - // Kill the colpoint or we get a severe memoryleak - if (pColPoint) - pColPoint->Destroy(); - - if (pColEntity != m_pTargetedGameEntity) - { - m_pTargetedGameEntity = pColEntity; - - if (pColEntity) - { - m_pTargetedEntity = m_pManager->FindEntity(pColEntity); - } - else - m_pTargetedEntity = NULL; - - // Store the last targeted player's id - if (m_pTargetedEntity && m_pTargetedEntity->GetType() == CCLIENTPLAYER) - { - m_TargetedPlayerID = m_pTargetedEntity->GetID(); - } - else - m_TargetedPlayerID = INVALID_ELEMENT_ID; - - // Send the target - ElementID TargetID = INVALID_ELEMENT_ID; - if (m_pTargetedEntity && !m_pTargetedEntity->IsLocalEntity()) - { - TargetID = m_pTargetedEntity->GetID(); - } - - CBitStream bitStream; - bitStream.pBitStream->Write(TargetID); - m_pNetAPI->RPC(PLAYER_TARGET, bitStream.pBitStream); - - // Call our onClientPlayerTarget event - CLuaArguments Arguments; - if (m_pTargetedEntity) - Arguments.PushElement(m_pTargetedEntity); - else - Arguments.PushBoolean(false); - m_pLocalPlayer->CallEvent("onClientPlayerTarget", Arguments, true); - } -} - -void CClientGame::UpdatePlayerWeapons(void) -{ - // Check whether we changed weapon slots - eWeaponSlot currentSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - if (currentSlot != m_lastWeaponSlot) - { - CLuaArguments Arguments; - Arguments.PushNumber(m_lastWeaponSlot); - Arguments.PushNumber(currentSlot); - bool bCancelled = !m_pLocalPlayer->CallEvent("onClientPlayerWeaponSwitch", Arguments, true); - - if (bCancelled) - { - // Save the current ammo in clip - unsigned short usAmmoInClip = 0; - CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); - if (pWeapon) - usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); - - // Force it back to the old slot - m_pLocalPlayer->SetCurrentWeaponSlot(m_lastWeaponSlot); - - // Restore the ammo in clip that there was in that slot - if (usAmmoInClip > 0) - m_pLocalPlayer->GetWeapon()->SetAmmoInClip(usAmmoInClip); - } - else - { - CBitStream bitStream; - CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(); - NetBitStreamInterface& BitStream = *(bitStream.pBitStream); - SWeaponSlotSync slot; - - // Always send bit in case server is not in sync - if ((BitStream.Version() >= 0x44 && m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN) || BitStream.Version() >= 0x4D) - { - CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); - if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && - (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || - (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) - BitStream.WriteBit(true); - else - BitStream.WriteBit(false); - } - - if (pWeapon) - { - /* Send a packet to the server with info about the new weapon, - so the server stays in sync reliably */ - unsigned int uiSlot = static_cast(pWeapon->GetSlot()); - slot.data.uiSlot = uiSlot; - BitStream.Write(&slot); - - if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) - { - SWeaponAmmoSync ammo(pWeapon->GetType(), true, true); - ammo.data.usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); - ammo.data.usTotalAmmo = static_cast(pWeapon->GetAmmoTotal()); - BitStream.Write(&ammo); - } - } - else - { - slot.data.uiSlot = 0; - BitStream.Write(&slot); - } - - m_pNetAPI->RPC(PLAYER_WEAPON, bitStream.pBitStream); - m_lastWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - } - } -} - -void CClientGame::UpdateTrailers(void) -{ - // This function is here to re-attach trailers if they fall off - - unsigned long ulCurrentTime = GetTickCount32(); - - CClientVehicle * pVehicle = NULL, *pTrailer = NULL; - CVehicle * pGameVehicle = NULL, *pGameTrailer = NULL; - unsigned long ulIllegalTowBreakTime; - vector::const_iterator iterVehicles = m_pVehicleManager->StreamedBegin(); - for (; iterVehicles != m_pVehicleManager->StreamedEnd(); iterVehicles++) - { - pVehicle = *iterVehicles; - ulIllegalTowBreakTime = pVehicle->GetIllegalTowBreakTime(); - - // Do we have an illegal break? - if (ulIllegalTowBreakTime != 0) - { - // Has it been atleast 1 second since the break - if (ulCurrentTime > (ulIllegalTowBreakTime + 1000)) - { - // Try to re-attach them - CClientVehicle* pTowedBy = pVehicle->GetTowedByVehicle(); - if (pTowedBy) - { - // Little hack to keep illegaly detached trailers close to their tower - CVector vecPosition; - pVehicle->GetPosition(vecPosition); - pVehicle->SetPosition(vecPosition); - - pGameVehicle = pTowedBy->GetGameVehicle(); - pGameTrailer = pVehicle->GetGameVehicle(); - if (pGameVehicle && pGameTrailer) - { - // pGameTrailer->SetTowLink ( pGameVehicle ); - CVector vecRotation; - pTowedBy->GetRotationRadians(vecRotation); - pVehicle->SetRotationRadians(vecRotation); - pTowedBy->InternalSetTowLink(pVehicle); - } - } - - // Reset the break time, even if we couldnt re-attach it - pVehicle->SetIllegalTowBreakTime(0); - } - } - } -} - -void CClientGame::UpdateFireKey(void) -{ - if (m_pLocalPlayer) - { - SBindableGTAControl* pControl = g_pCore->GetKeyBinds()->GetBindableFromControl("fire"); - - // Is our 'fire' control enabled? - if (pControl->bEnabled) - { - // ** Satchel charge detonation ** - { - // Do we have a detonator in our hand? - if (m_pLocalPlayer->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_DETONATOR) - { - // Planted any satchels? - if (m_pLocalPlayer->CountProjectiles(WEAPONTYPE_REMOTE_SATCHEL_CHARGE) > 0) - { - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - - // Tell the server we want to detonate our satchels - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - g_pNet->SendPacket(PACKET_ID_DETONATE_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } - // Remove the detonator if we dont have any satchels planted - else - { - m_pLocalPlayer->RemoveWeapon(WEAPONTYPE_DETONATOR); - } - } - } - - // Has our control state been cut short? - if (!pControl->bState) - return; - - // ** Stealth kill ** - { - if (m_pLocalPlayer->IsStealthAiming()) - { - // Do we have a target ped? - CClientPed* pTargetPed = m_pLocalPlayer->GetTargetedPed(); - if (pTargetPed) - { - // Do we have a target player? - if (IS_PLAYER(pTargetPed)) - { - CClientPlayer* pTargetPlayer = static_cast(pTargetPed); - - // Is the targetted player on a team - CClientTeam* pTeam = pTargetPlayer->GetTeam(); - if (pTeam) - { - // Is this friendly-fire? - if (pTargetPlayer->IsOnMyTeam(m_pLocalPlayer) && !pTeam->GetFriendlyFire()) - { - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - return; - } - } - } - CPlayerPed* pGameTarget = static_cast(pTargetPed)->GetGamePlayer(); - if (pGameTarget) - { - // Would GTA let us stealth kill now? - if (m_pLocalPlayer->GetGamePlayer()->GetPedIntelligence()->TestForStealthKill(pGameTarget, false)) - { - // Grab our local position - CVector vecLocalPosition; - m_pLocalPlayer->GetPosition(vecLocalPosition); - - // Grab the target's position - CVector vecTargetPosition; - pTargetPed->GetPosition(vecTargetPosition); - - // Work out an angle between the players, and set this as we initiate our knife kill - float fAngle = AngleBetweenPoints2D(vecLocalPosition, vecTargetPosition); - m_pLocalPlayer->SetCurrentRotation(fAngle); - - // Change the state back to false so this press doesn't do anything else - pControl->bState = false; - CLuaArguments Arguments; - Arguments.PushElement(pTargetPed); - if (m_pLocalPlayer->CallEvent("onClientPlayerStealthKill", Arguments, false)) - { - if (pTargetPed->IsLocalEntity()) - { - CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, 4 /*WEAPONTYPE_KNIFE*/, 9 /*BODYPART_HEAD*/, true); - return; - } - - // Lets request a stealth kill - CBitStream bitStream; - bitStream.pBitStream->Write(pTargetPed->GetID()); - m_pNetAPI->RPC(REQUEST_STEALTH_KILL, bitStream.pBitStream); - } - else - { - return; - } - } - } - } - } - } - } - } -} - -void CClientGame::UpdateStunts(void) -{ - // * Two wheeler * - static unsigned long ulLastCarTwoWheelCounter = 0; - static float fLastCarTwoWheelDist = 0.0f; - unsigned long ulTemp = g_pGame->GetPlayerInfo()->GetCarTwoWheelCounter(); - // Did we start a stunt? - if (ulLastCarTwoWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("2wheeler"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastCarTwoWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("2wheeler"); - Arguments.PushNumber(ulLastCarTwoWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastCarTwoWheelCounter = ulTemp; - fLastCarTwoWheelDist = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); - - // * Wheelie * - static unsigned long ulLastBikeRearWheelCounter = 0; - static float fLastBikeRearWheelDist = 0.0f; - ulTemp = g_pGame->GetPlayerInfo()->GetBikeRearWheelCounter(); - // Did we start a stunt? - if (ulLastBikeRearWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("wheelie"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastBikeRearWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("wheelie"); - Arguments.PushNumber(ulLastBikeRearWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastBikeRearWheelCounter = ulTemp; - fLastBikeRearWheelDist = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); - - // * Stoppie * - static unsigned long ulLastBikeFrontWheelCounter = 0; - static float fLastBikeFrontWheelDist = 0.0f; - ulTemp = g_pGame->GetPlayerInfo()->GetBikeFrontWheelCounter(); - // Did we start a stunt? - if (ulLastBikeFrontWheelCounter == 0 && ulTemp != 0) - { - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("stoppie"); - m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); - } - // Did we finish a stunt? - else if (ulLastBikeFrontWheelCounter != 0 && ulTemp == 0) - { - float fDistance = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); - - // Call our stunt event - CLuaArguments Arguments; - Arguments.PushString("stoppie"); - Arguments.PushNumber(ulLastBikeFrontWheelCounter); - Arguments.PushNumber(fDistance); - m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); - } - ulLastBikeFrontWheelCounter = ulTemp; - fLastBikeFrontWheelDist = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); -} - -void CClientGame::StaticUpdateFireKey(CControlFunctionBind* pBind) -{ - g_pClientGame->UpdateFireKey(); -} - -void CClientGame::ChangeVehicleWeapon(bool bNext) -{ - if (m_pLocalPlayer && m_pLocalPlayer->GetRealOccupiedVehicle()) - { - eWeaponSlot currentWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); - eWeaponSlot weaponSlot = currentWeaponSlot; - CWeapon* pWeapon = NULL; - while (!pWeapon || pWeapon->GetType() == WEAPONTYPE_UNARMED) - { - if (bNext) - { - if (weaponSlot == WEAPONSLOT_TYPE_DETONATOR) - { - weaponSlot = WEAPONSLOT_TYPE_UNARMED; - break; - } - - weaponSlot = (eWeaponSlot)(weaponSlot + 1); - - if (weaponSlot == currentWeaponSlot) - break; - - pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); - } - else - { - if (weaponSlot == WEAPONSLOT_TYPE_UNARMED) - { - if (weaponSlot != currentWeaponSlot) - break; - weaponSlot = WEAPONSLOT_TYPE_DETONATOR; - } - - weaponSlot = (eWeaponSlot)(weaponSlot - 1); - - if (weaponSlot == currentWeaponSlot) - break; - - pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); - } - } - if (pWeapon || weaponSlot == WEAPONSLOT_TYPE_UNARMED) - { - m_pLocalPlayer->SetCurrentWeaponSlot(weaponSlot); - } - } -} - -void CClientGame::ResetVehicleInOut(void) -{ - m_ulLastVehicleInOutTime = 0; - m_bIsGettingOutOfVehicle = false; - m_bIsGettingIntoVehicle = false; - m_bIsJackingVehicle = false; - m_bIsGettingJacked = false; - m_VehicleInOutID = INVALID_ELEMENT_ID; - m_ucVehicleInOutSeat = 0xFF; - m_bNoNewVehicleTask = false; - m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; - m_pGettingJackedBy = NULL; -} - -void CClientGame::SetAllDimensions(unsigned short usDimension) -{ - m_pManager->GetMarkerStreamer()->SetDimension(usDimension); - m_pManager->GetObjectStreamer()->SetDimension(usDimension); - m_pManager->GetObjectLodStreamer()->SetDimension(usDimension); - m_pManager->GetPickupStreamer()->SetDimension(usDimension); - m_pManager->GetPlayerStreamer()->SetDimension(usDimension); - m_pManager->GetRadarAreaManager()->SetDimension(usDimension); - m_pManager->GetVehicleStreamer()->SetDimension(usDimension); - m_pManager->GetRadarMarkerManager()->SetDimension(usDimension); - m_pManager->GetSoundManager()->SetDimension(usDimension); - m_pManager->GetPointLightsManager()->SetDimension(usDimension); - m_pManager->GetWaterManager()->SetDimension(usDimension); - m_pNametags->SetDimension(usDimension); - m_pCamera->SetDimension(usDimension); -} - -bool CClientGame::StaticKeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) -{ - return g_pClientGame->KeyStrokeHandler(strKey, bState, bIsConsoleInputKey); -} - -bool CClientGame::KeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) -{ - // Do we have a root yet? - if (m_pRootEntity) - { - // Ignore keydown/up pair if main menu is displayed, or console input will use the character - bool bIgnore = false; - if (bState) - { - auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; - bool isMouseKey = strKey.substr(0, 5) == "mouse"; - - if (g_pCore->IsMenuVisible() || (g_pCore->GetConsole()->IsInputActive() && bIsConsoleInputKey) || - (pFocusedBrowser && !pFocusedBrowser->IsLocal() && !isMouseKey)) - - bIgnore = true; // Ignore this keydown and the matching keyup - else - MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup - } - else - { - if (!MapContains(m_AllowKeyUpMap, strKey)) - bIgnore = true; // Ignore this keyup - else - MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup - } - - if (!bIgnore) - { - bool bAllow = true; - // Call our key-stroke event - CLuaArguments Arguments; - Arguments.PushString(strKey); - Arguments.PushBoolean(bState); - bAllow = m_pRootEntity->CallEvent("onClientKey", Arguments, false); - if (bState == true) - { - if (bAllow == false && strKey == "escape") - { - if (m_bLastKeyWasEscapeCancelled) - { - // Escape cannot be skipped twice - bAllow = true; - m_bLastKeyWasEscapeCancelled = false; - } - else - m_bLastKeyWasEscapeCancelled = true; - } - else - m_bLastKeyWasEscapeCancelled = false; - } - return bAllow; - } - } - m_bLastKeyWasEscapeCancelled = false; - return true; -} - -bool CClientGame::StaticCharacterKeyHandler(WPARAM wChar) -{ - return g_pClientGame->CharacterKeyHandler(wChar); -} - -bool CClientGame::CharacterKeyHandler(WPARAM wChar) -{ - // Do we have a root yet? - if (m_pRootEntity && g_pCore->IsMenuVisible() == false && g_pCore->GetConsole()->IsInputActive() == false) - { - // Cancel event if remote browser is focused - auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; - if (pFocusedBrowser && !pFocusedBrowser->IsLocal()) - return false; - - // Safe character? - if (wChar >= 32) - { - // Generate a null-terminating string for our character - wchar_t wUNICODE[2] = {wChar, '\0'}; - - // Convert our UTF character into an ANSI string - SString strANSI = UTF16ToMbUTF8(wUNICODE); - - // Call our character event - CLuaArguments Arguments; - Arguments.PushString(strANSI); - m_pRootEntity->CallEvent("onClientCharacter", Arguments, false); - } - } - - return false; -} - -void CClientGame::StaticProcessClientKeyBind(CKeyFunctionBind* pBind) -{ - g_pClientGame->ProcessClientKeyBind(pBind); -} - -void CClientGame::ProcessClientKeyBind(CKeyFunctionBind* pBind) -{ - m_pScriptKeyBinds->ProcessKey(pBind->boundKey->szKey, pBind->bHitState, SCRIPT_KEY_BIND_FUNCTION); -} - -void CClientGame::StaticProcessClientControlBind(CControlFunctionBind* pBind) -{ - g_pClientGame->ProcessClientControlBind(pBind); -} - -void CClientGame::ProcessClientControlBind(CControlFunctionBind* pBind) -{ - m_pScriptKeyBinds->ProcessKey(pBind->control->szControl, pBind->bHitState, SCRIPT_KEY_BIND_CONTROL_FUNCTION); -} - -void CClientGame::StaticProcessServerKeyBind(CKeyFunctionBind* pBind) -{ - g_pClientGame->ProcessServerKeyBind(pBind); -} - -void CClientGame::ProcessServerKeyBind(CKeyFunctionBind* pBind) -{ - const char* szName = pBind->boundKey->szKey; - unsigned char ucNameLength = (unsigned char)strlen(szName); - CBitStream bitStream; - bitStream.pBitStream->WriteBit(false); - bitStream.pBitStream->WriteBit(pBind->bHitState); - bitStream.pBitStream->Write(szName, ucNameLength); - m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); -} - -void CClientGame::StaticProcessServerControlBind(CControlFunctionBind* pBind) -{ - g_pClientGame->ProcessServerControlBind(pBind); -} - -void CClientGame::ProcessServerControlBind(CControlFunctionBind* pBind) -{ - const char* szName = pBind->control->szControl; - unsigned char ucNameLength = (unsigned char)strlen(szName); - CBitStream bitStream; - bitStream.pBitStream->WriteBit(true); - bitStream.pBitStream->WriteBit(pBind->bHitState); - bitStream.pBitStream->Write(szName, ucNameLength); - m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); -} - -bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - bool bCursorForcedVisible = g_pCore->IsCursorForcedVisible(); - bool bMenuVisible = g_pCore->IsMenuVisible(); - bool bConsoleVisible = g_pCore->GetConsole()->IsVisible(); - - if (bCursorForcedVisible) - { - if (!bMenuVisible && !bConsoleVisible) - { - if (m_bCursorEventsEnabled) - { - unsigned char ucButtonHit = 0xFF; - switch (uMsg) - { - case WM_LBUTTONDOWN: - ucButtonHit = 0; - break; - case WM_LBUTTONUP: - ucButtonHit = 1; - break; - case WM_MBUTTONDOWN: - ucButtonHit = 2; - break; - case WM_MBUTTONUP: - ucButtonHit = 3; - break; - case WM_RBUTTONDOWN: - ucButtonHit = 4; - break; - case WM_RBUTTONUP: - ucButtonHit = 5; - break; - } - if (ucButtonHit != 0xFF) - { - int iX = LOWORD(lParam); - int iY = HIWORD(lParam); - - CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); - - /* - // (IJs) why are these relative? it doesn't make sense - CVector2D vecCursorPosition ( ( ( float ) iX ) / vecResolution.fX, - ( ( float ) iY ) / vecResolution.fY ); - */ - - CVector2D vecCursorPosition((float)iX, (float)iY); - - CVector vecOrigin, vecTarget, vecScreen((float)iX, (float)iY, 300.0f); - g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); - - // Grab the camera position - CCamera* pCamera = g_pGame->GetCamera(); - CCam* pCam = pCamera->GetCam(pCamera->GetActiveCam()); - CMatrix matCamera; - pCamera->GetMatrix(&matCamera); - vecOrigin = matCamera.vPos; - - CColPoint* pColPoint = NULL; - CEntity* pGameEntity = NULL; - - // Grab the collision point/entity - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pGameEntity); - - CVector vecCollision; - ElementID CollisionEntityID = INVALID_ELEMENT_ID; - CClientEntity* pCollisionEntity = NULL; - if (bCollision && pColPoint) - { - vecCollision = pColPoint->GetPosition(); - if (pGameEntity) - { - CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity); - if (pEntity) - { - pCollisionEntity = pEntity; - if (!pEntity->IsLocalEntity()) - CollisionEntityID = pEntity->GetID(); - } - } - } - else - { - vecCollision = vecTarget; - } - - // Destroy the colpoint so we don't get a leak - if (pColPoint) - { - pColPoint->Destroy(); - } - - const char* szButton = NULL; - const char* szState = NULL; - switch (ucButtonHit) - { - case 0: - szButton = "left"; - szState = "down"; - break; - case 1: - szButton = "left"; - szState = "up"; - break; - case 2: - szButton = "middle"; - szState = "down"; - break; - case 3: - szButton = "middle"; - szState = "up"; - break; - case 4: - szButton = "right"; - szState = "down"; - break; - case 5: - szButton = "right"; - szState = "up"; - break; - } - if (szButton && szState) - { - if (std::isnan(vecCollision.fX)) - vecCollision.fX = 0; - if (std::isnan(vecCollision.fY)) - vecCollision.fY = 0; - if (std::isnan(vecCollision.fZ)) - vecCollision.fZ = 0; - - // Call the event for the client - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(vecCursorPosition.fX); - Arguments.PushNumber(vecCursorPosition.fY); - Arguments.PushNumber(vecCollision.fX); - Arguments.PushNumber(vecCollision.fY); - Arguments.PushNumber(vecCollision.fZ); - if (pCollisionEntity) - Arguments.PushElement(pCollisionEntity); - else - Arguments.PushBoolean(false); - m_pRootEntity->CallEvent("onClientClick", Arguments, false); - - // Send the button, cursor position, 3d position and the entity collided with - CBitStream bitStream; - - SMouseButtonSync button; - button.data.ucButton = ucButtonHit; - bitStream.pBitStream->Write(&button); - - bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fX)); - bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fY)); - - SPositionSync position(false); - position.data.vecPosition = vecCollision; - bitStream.pBitStream->Write(&position); - - if (CollisionEntityID != INVALID_ELEMENT_ID) - { - bitStream.pBitStream->WriteBit(true); - bitStream.pBitStream->Write(CollisionEntityID); - } - else - bitStream.pBitStream->WriteBit(false); - - m_pNetAPI->RPC(CURSOR_EVENT, bitStream.pBitStream); - - if (strcmp(szState, "down") == 0) - { - CVector2D vecDelta = m_vecLastCursorPosition - vecCursorPosition; - - if ((GetTickCount32() - m_ulLastClickTick) < DOUBLECLICK_TIMEOUT && vecDelta.Length() <= DOUBLECLICK_MOVE_THRESHOLD) - { - // Call the event for the client - CLuaArguments DoubleClickArguments; - DoubleClickArguments.PushString(szButton); - DoubleClickArguments.PushNumber(vecCursorPosition.fX); - DoubleClickArguments.PushNumber(vecCursorPosition.fY); - DoubleClickArguments.PushNumber(vecCollision.fX); - DoubleClickArguments.PushNumber(vecCollision.fY); - DoubleClickArguments.PushNumber(vecCollision.fZ); - if (pCollisionEntity) - DoubleClickArguments.PushElement(pCollisionEntity); - else - DoubleClickArguments.PushBoolean(false); - m_pRootEntity->CallEvent("onClientDoubleClick", DoubleClickArguments, false); - } - - m_ulLastClickTick = GetTickCount32(); - m_vecLastCursorPosition = vecCursorPosition; - } - - return true; - } - } - } - } - } - switch (uMsg) - { - case WM_MOUSEMOVE: - { - int iX = LOWORD(lParam), iY = HIWORD(lParam); - static int iPreviousX = 0, iPreviousY = 0; - if (iX != iPreviousX || iY != iPreviousY) - { - iPreviousX = iX, iPreviousY = iY; - - CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); - CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); - - CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); - g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); - - // Call the onClientCursorMove event - CLuaArguments Arguments; - Arguments.PushNumber((double)vecCursorPosition.fX); - Arguments.PushNumber((double)vecCursorPosition.fY); - Arguments.PushNumber((double)iX); - Arguments.PushNumber((double)iY); - Arguments.PushNumber((double)vecTarget.fX); - Arguments.PushNumber((double)vecTarget.fY); - Arguments.PushNumber((double)vecTarget.fZ); - m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); - } - break; - } - } - return false; -} - -CClientPlayer* CClientGame::GetClosestRemotePlayer(const CVector& vecPosition, float fMaxDistance) -{ - CClientPlayer* pClosest = NULL; - float fDistance = 0.0f, fTemp; - CVector vecTemp; - CClientPlayer* pPlayer; - vector::const_iterator iter = m_pPlayerManager->IterBegin(); - for (; iter != m_pPlayerManager->IterEnd(); ++iter) - { - pPlayer = *iter; - if (!pPlayer->IsLocalPlayer() && !pPlayer->IsDeadOnNetwork() && pPlayer->GetHealth() > 0) - { - // Ensure remote player is alive and sending position updates - ulong ulTimeSinceLastPuresync = CClientTime::GetTime() - pPlayer->GetLastPuresyncTime(); - if (ulTimeSinceLastPuresync < static_cast(g_TickRateSettings.iPureSync) * 2) - { - pPlayer->GetPosition(vecTemp); - fTemp = DistanceBetweenPoints3D(vecPosition, vecTemp); - if (fTemp < fMaxDistance) - { - if (!pClosest || fTemp < fDistance) - { - pClosest = pPlayer; - fDistance = fTemp; - } - } - } - } - } - return pClosest; -} - -void CClientGame::SetGameSpeed(float fSpeed) -{ - g_pGame->SetGameSpeed(fSpeed); - m_fGameSpeed = fSpeed; -} - -void CClientGame::SetMinuteDuration(unsigned long ulDelay) -{ - g_pGame->SetMinuteDuration(ulDelay); - m_ulMinuteDuration = ulDelay; -} - -void CClientGame::SetMoney(long lMoney, bool bInstant) -{ - g_pGame->GetPlayerInfo()->SetPlayerMoney(lMoney, bInstant); - m_lMoney = lMoney; -} - -void CClientGame::SetWanted(DWORD dwWanted) -{ - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(dwWanted); - m_dwWanted = dwWanted; -} - -void CClientGame::AddBuiltInEvents(void) -{ - // Resource events - m_Events.AddEvent("onClientResourceStart", "resource", NULL, false); - m_Events.AddEvent("onClientResourceStop", "resource", NULL, false); - - // Element events - m_Events.AddEvent("onClientElementDataChange", "name", NULL, false); - m_Events.AddEvent("onClientElementStreamIn", "", NULL, false); - m_Events.AddEvent("onClientElementStreamOut", "", NULL, false); - m_Events.AddEvent("onClientElementDestroy", "", NULL, false); - - // Player events - m_Events.AddEvent("onClientPlayerJoin", "", NULL, false); - m_Events.AddEvent("onClientPlayerQuit", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerTarget", "target", NULL, false); - m_Events.AddEvent("onClientPlayerSpawn", "team", NULL, false); - m_Events.AddEvent("onClientPlayerChangeNick", "oldNick", NULL, false); - m_Events.AddEvent("onClientPlayerVehicleEnter", "vehicle, seat", NULL, false); - m_Events.AddEvent("onClientPlayerVehicleExit", "vehicle, seat", NULL, false); - m_Events.AddEvent("onClientPlayerTask", "priority, slot, name", NULL, false); - m_Events.AddEvent("onClientPlayerWeaponSwitch", "previous, current", NULL, false); - m_Events.AddEvent("onClientPlayerStuntStart", "type", NULL, false); - m_Events.AddEvent("onClientPlayerStuntFinish", "type, time, distance", NULL, false); - m_Events.AddEvent("onClientPlayerRadioSwitch", "", NULL, false); - m_Events.AddEvent("onClientPlayerDamage", "attacker, weapon, bodypart", NULL, false); - m_Events.AddEvent("onClientPlayerWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); - m_Events.AddEvent("onClientPlayerWasted", "", NULL, false); - m_Events.AddEvent("onClientPlayerChoke", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceStart", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceStop", "", NULL, false); - m_Events.AddEvent("onClientPlayerVoicePause", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerVoiceResumed", "reason", NULL, false); - m_Events.AddEvent("onClientPlayerStealthKill", "target", NULL, false); - m_Events.AddEvent("onClientPlayerHitByWaterCannon", "vehicle", NULL, false); - m_Events.AddEvent("onClientPlayerHeliKilled", "heli", NULL, false); - m_Events.AddEvent("onClientPlayerPickupHit", "pickup, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPlayerPickupLeave", "pickup, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPlayerNetworkStatus", "type, ticks", NULL, false); - - // Ped events - m_Events.AddEvent("onClientPedDamage", "attacker, weapon, bodypart", NULL, false); - m_Events.AddEvent("onClientPedWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); - m_Events.AddEvent("onClientPedWasted", "", NULL, false); - m_Events.AddEvent("onClientPedChoke", "", NULL, false); - m_Events.AddEvent("onClientPedHeliKilled", "heli", NULL, false); - m_Events.AddEvent("onClientPedHitByWaterCannon", "vehicle", NULL, false); - - // Vehicle events - m_Events.AddEvent("onClientVehicleRespawn", "", NULL, false); - m_Events.AddEvent("onClientVehicleEnter", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleExit", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleStartEnter", "player, seat", NULL, false); - m_Events.AddEvent("onClientVehicleStartExit", "player, seat", NULL, false); - m_Events.AddEvent("onClientTrailerAttach", "towedBy", NULL, false); - m_Events.AddEvent("onClientTrailerDetach", "towedBy", NULL, false); - m_Events.AddEvent("onClientVehicleExplode", "", NULL, false); - m_Events.AddEvent("onClientVehicleCollision", "collidedelement, damageImpulseMag, bodypart, x, y, z, velX, velY, velZ", NULL, false); - m_Events.AddEvent("onClientVehicleDamage", "attacker, weapon, loss, x, y, z, tyre", NULL, false); - m_Events.AddEvent("onClientVehicleNitroStateChange", "activated", NULL, false); - - // GUI events - m_Events.AddEvent("onClientGUIClick", "button, state, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIDoubleClick", "button, state, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIMouseDown", "button, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIMouseUp", "button, absoluteX, absoluteY", NULL, false); - m_Events.AddEvent("onClientGUIScroll", "element", NULL, false); - m_Events.AddEvent("onClientGUIChanged", "element", NULL, false); - m_Events.AddEvent("onClientGUIAccepted", "element", NULL, false); - // m_Events.AddEvent ( "onClientGUIClose", "element", NULL, false ); - // m_Events.AddEvent ( "onClientGUIKeyDown", "element", NULL, false ); - m_Events.AddEvent("onClientGUITabSwitched", "element", NULL, false); - m_Events.AddEvent("onClientGUIComboBoxAccepted", "element", NULL, false); - - // Input events - m_Events.AddEvent("onClientDoubleClick", "button, screenX, screenY, worldX, worldY, worldZ, element", NULL, false); - m_Events.AddEvent("onClientMouseMove", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseEnter", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseLeave", "screenX, screenY", NULL, false); - m_Events.AddEvent("onClientMouseWheel", "", NULL, false); - m_Events.AddEvent("onClientGUIMove", "", NULL, false); - m_Events.AddEvent("onClientGUISize", "", NULL, false); - m_Events.AddEvent("onClientGUIFocus", "", NULL, false); - m_Events.AddEvent("onClientGUIBlur", "", NULL, false); - m_Events.AddEvent("onClientKey", "key, state", NULL, false); - m_Events.AddEvent("onClientCharacter", "character", NULL, false); - - // Console events - m_Events.AddEvent("onClientConsole", "text", NULL, false); - - // Chat events - m_Events.AddEvent("onClientChatMessage", "test, r, g, b", NULL, false); - - // Debug events - m_Events.AddEvent("onClientDebugMessage", "message, level, file, line", NULL, false); - - // Game events - m_Events.AddEvent("onClientPreRender", "", NULL, false); - m_Events.AddEvent("onClientHUDRender", "", NULL, false); - m_Events.AddEvent("onClientRender", "", NULL, false); - m_Events.AddEvent("onClientMinimize", "", NULL, false); - m_Events.AddEvent("onClientRestore", "", NULL, false); - - // Cursor events - m_Events.AddEvent("onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false); - m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); - - // Transfer box event - m_Events.AddEvent( "onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false ); - - // Marker events - m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); - - // Marker events - m_Events.AddEvent("onClientPickupHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientPickupLeave", "entity, matchingDimension", NULL, false); - - // Col-shape events - m_Events.AddEvent("onClientColShapeHit", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientColShapeLeave", "entity, matchingDimension", NULL, false); - m_Events.AddEvent("onClientElementColShapeHit", "colShape, matchingDimension", NULL, false); - m_Events.AddEvent("onClientElementColShapeLeave", "colShape, matchingDimension", NULL, false); - - // Explosion events - m_Events.AddEvent("onClientExplosion", "x, y, z, type", NULL, false); - - // Projectile events - m_Events.AddEvent("onClientProjectileCreation", "creator", NULL, false); - - // Sound events - m_Events.AddEvent("onClientSoundStream", "success, length, streamName, error", NULL, false); - m_Events.AddEvent("onClientSoundFinishedDownload", "length", NULL, false); - m_Events.AddEvent("onClientSoundChangedMeta", "streamTitle", NULL, false); - m_Events.AddEvent("onClientSoundStarted", "reason", NULL, false); - m_Events.AddEvent("onClientSoundStopped", "reason", NULL, false); - m_Events.AddEvent("onClientSoundBeat", "time", NULL, false); - - // Object events - m_Events.AddEvent("onClientObjectDamage", "loss, attacker", NULL, false); - m_Events.AddEvent("onClientObjectBreak", "attacker", NULL, false); - - // Web events - m_Events.AddEvent("onClientBrowserWhitelistChange", "newPages", NULL, false); - m_Events.AddEvent("onClientBrowserCreated", "", NULL, false); - m_Events.AddEvent("onClientBrowserLoadingStart", "url, mainframe", NULL, false); - m_Events.AddEvent("onClientBrowserDocumentReady", "url", NULL, false); - m_Events.AddEvent("onClientBrowserLoadingFailed", "url, errorcode, errordescription", NULL, false); - m_Events.AddEvent("onClientBrowserNavigate", "url, isblocked", NULL, false); - m_Events.AddEvent("onClientBrowserPopup", "targeturl, openerurl, ispopup", NULL, false); - m_Events.AddEvent("onClientBrowserCursorChange", "cursor", NULL, false); - m_Events.AddEvent("onClientBrowserTooltip", "text", NULL, false); - m_Events.AddEvent("onClientBrowserInputFocusChanged", "gainedfocus", NULL, false); - m_Events.AddEvent("onClientBrowserResourceBlocked", "url, domain, reason", NULL, false); - - // Misc events - m_Events.AddEvent("onClientFileDownloadComplete", "fileName, success", NULL, false); - - m_Events.AddEvent("onClientWeaponFire", "ped, x, y, z", NULL, false); -} - -void CClientGame::DrawFPS(void) -{ - // Draw the background - float fResWidth = static_cast(g_pCore->GetGraphics()->GetViewportWidth()); - float fResHeight = static_cast(g_pCore->GetGraphics()->GetViewportHeight()); - g_pCore->GetGraphics()->DrawRectangle(0.75f * fResWidth, 0.22f * fResHeight, 0.25f * fResWidth, 0.04f * fResHeight, 0x78000000); - - static char x = 0; - static float fDisp = 0.0f; - if (x == 20) - { - x = 0; - fDisp = g_pGame->GetFPS(); - } - else - x++; - SString strBuffer("FrameRate: %4.2f\n", fDisp); - - // Print it - m_pDisplayManager->DrawText2D(strBuffer, CVector(0.76f, 0.23f, 0), 1.0f, 0xFFFFFFFF); -} - -#ifdef MTA_DEBUG - -void CClientGame::DrawTasks(CClientPlayer* pPlayer) -{ - CTask* pTask = NULL; - CTask* pSubTask = NULL; - - // Got a local player model - if (pPlayer) - { - CTaskManager* man = pPlayer->GetTaskManager(); - if (man == NULL) - return; - if ((unsigned long)man == 0xDDDDDDDD) - { - m_pDisplayManager->DrawText2D("HELP! MANAGER FUCKED", CVector(0.05f, 0.5f, 0), 1.0f); - return; - } - - // Grab the current task - SString strOutput; - SString strSubOutput; - - pTask = man->GetTask(TASK_PRIORITY_PHYSICAL_RESPONSE); - strOutput += SString("Physical Response: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_TEMP); - strOutput += SString("Event Response Temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_NONTEMP); - strOutput += SString("Event Response Non-temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_PRIMARY); - strOutput += SString("Primary: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTask(TASK_PRIORITY_DEFAULT); - strOutput += SString("Default: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_ATTACK); - strOutput += SString("Secondary Attack: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_DUCK); - strOutput += SString("Secondary Duck: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_SAY); - strOutput += SString("Secondary Say: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX); - strOutput += SString("Secondary Facial Complex: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM); - strOutput += SString("Secondary Partial Anim: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - pTask = man->GetTaskSecondary(TASK_SECONDARY_IK); - strOutput += SString("Secondary IK: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); - strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); - - m_pDisplayManager->DrawText2D(strOutput, CVector(0.05f, 0.5f, 0), 1.0f); - m_pDisplayManager->DrawText2D(strSubOutput, CVector(0.5f, 0.5f, 0), 1.0f); - } -} - -int iPlayerTask = 0; -void CClientGame::DrawPlayerDetails(CClientPlayer* pPlayer) -{ - // Get the info - CControllerState cs; - - pPlayer->GetControllerState(cs); - - CVector vecPosition; - pPlayer->GetPosition(vecPosition); - - float fRotation = pPlayer->GetCurrentRotation(); - float fCameraRotation = pPlayer->GetCameraRotation(); - float fHealth = pPlayer->GetHealth(); - bool bIsDucked = pPlayer->IsDucked(); - bool bWearingGoggles = pPlayer->IsWearingGoggles(); - bool bInVehicle = pPlayer->GetOccupiedVehicle() != NULL; - float fWeaponRange = 0.0f; - - unsigned char ucWeapon = 0; - unsigned char ucWeaponState = 0; - unsigned short usWeaponAmmo = 0; - CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); - if (pWeapon) - { - ucWeapon = static_cast(pWeapon->GetType()); - ucWeaponState = static_cast(pWeapon->GetState()); - usWeaponAmmo = static_cast(pWeapon->GetAmmoInClip()); - float fSkill = pPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(pWeapon->GetType())); - CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(pWeapon->GetType(), fSkill); - fWeaponRange = pWeaponInfo->GetWeaponRange(); - } - - float fAimX, fAimY; - pPlayer->GetAim(fAimX, fAimY); - const CVector& vecAimSource = pPlayer->GetAimSource(); - const CVector& vecAimTarget = pPlayer->GetAimTarget(); - unsigned char ucDrivebyAim = pPlayer->GetVehicleAimAnim(); - - g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x10DE1212, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x90DE1212, false); - - CTask* pPrimaryTask = pPlayer->GetCurrentPrimaryTask(); - int iPrimaryTask = pPrimaryTask ? pPrimaryTask->GetTaskType() : -1; - - // Copy the stuff - SString strBuffer( - "Orient:\n" - "Position: %f %f %f\n" - "Rotation/camera: %f %f\n" - "Health: %f\n" - "\n" - "Keys:\n" - "LeftShoulder1: %hi\n" - "RightShoulder1: %hi\n" - "ButtonSquare: %hi\n" - "ButtonCross: %hi\n" - "ButtonCircle: %hi\n" - "ShockButtonL: %hi\n" - "PedWalk: %hi\n" - "VehicleMouseLook: %hi\n" - "LeftStickX: %hi\n" - "LeftStickY: %hi\n" - "\n" - "Misc:\n" - "Primary task: %d\n" - "Ducked: %u\n" - "Goggles: %u\n" - "In vehicle: %u\n" - "Weapon: %u\n" - "Weapon state: %u\n" - "Weapon ammo: %u\n" - "Weapon range: %f\n" - "Aim: %f %f\n" - "Aim source: %f %f %f\n" - "Aim target: %f %f %f\n" - "Driveby aim: %u\n" - "Frozen: %u\n", - vecPosition.fX, vecPosition.fY, vecPosition.fZ, fRotation, fCameraRotation, fHealth, cs.LeftShoulder1, cs.RightShoulder1, cs.ButtonSquare, - cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.m_bPedWalk, cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, iPrimaryTask, bIsDucked, - bWearingGoggles, bInVehicle, ucWeapon, ucWeaponState, usWeaponAmmo, fWeaponRange, fAimX, fAimY, vecAimSource.fX, vecAimSource.fY, vecAimSource.fZ, - vecAimTarget.fX, vecAimTarget.fY, vecAimTarget.fZ, ucDrivebyAim, pPlayer->IsFrozen()); - - // Draw it - m_pDisplayManager->DrawText2D(strBuffer, CVector(0.45f, 0.05f, 0), 1.0f, 0xFFFFFFFF); -} - -void CClientGame::DrawWeaponsyncData(CClientPlayer* pPlayer) -{ - CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); - - if (pWeapon) - { - CVector vecSource; - CVector vecTarget; - - // red line: Draw their synced aim line - pPlayer->GetShotData(&vecSource, &vecTarget); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x10DE1212, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x90DE1212, false); - - // green line: Set muzzle as origin and perform a collision test for the target - CColPoint* pCollision; - CVector vecTemp; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecSource, &vecTarget, &pCollision, NULL); - if (pCollision) - { - if (bCollision) - { - CVector vecBullet = pCollision->GetPosition() - vecSource; - vecBullet.Normalize(); - CVector vecTarget = vecSource + (vecBullet * 200); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x1012DE12, true); - g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x9012DE12, false); - } - pCollision->Destroy(); - } - - if (m_pLocalPlayer != pPlayer) - { - // Draw information about their weapon state, total ammo and ammo in clip - CVector vecScreenPosition; - CVector vecPosition; - - pPlayer->GetPosition(vecPosition); - - vecPosition.fZ += 1.0f; - g_pCore->GetGraphics()->CalcScreenCoors(&vecPosition, &vecScreenPosition); - - SString strTemp; - int yoffset; - - yoffset = 0; - strTemp.Format("Ammo in clip: %d", pWeapon->GetAmmoInClip()); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); - - yoffset = 15; - strTemp.Format("State: %d", pWeapon->GetState()); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); - g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); - } - } -} - -void CClientGame::UpdateMimics(void) -{ - // Got a local player? - if (m_pLocalPlayer) - { - unsigned char ucWeaponType = 0; - unsigned char ucWeaponState = 0; - unsigned long ulWeaponAmmoInClip = 0; - eWeaponSlot weaponSlot = WEAPONSLOT_TYPE_UNARMED; - - CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(m_pLocalPlayer->GetCurrentWeaponSlot()); - if (pPlayerWeapon) - { - ucWeaponType = static_cast(pPlayerWeapon->GetType()); - ucWeaponState = static_cast(pPlayerWeapon->GetState()); - weaponSlot = pPlayerWeapon->GetSlot(); - ulWeaponAmmoInClip = pPlayerWeapon->GetAmmoInClip(); - } - - // Simulate lag (or not) - if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) - { - m_ulLastMimicLag = CClientTime::GetTime(); - - // Grab the local data - CControllerState Controller; - m_pLocalPlayer->GetControllerState(Controller); - CVector vecPosition; - m_pLocalPlayer->GetPosition(vecPosition); - float fRotation = m_pLocalPlayer->GetCurrentRotation(); - CVector vecMoveSpeed; - m_pLocalPlayer->GetMoveSpeed(vecMoveSpeed); - float fHealth = m_pLocalPlayer->GetHealth(); - float fArmor = m_pLocalPlayer->GetArmor(); - float fCameraRotation = g_pGame->GetCamera()->GetCameraRotation(); - bool bDucked = m_pLocalPlayer->IsDucked(); - bool bWearingGoggles = m_pLocalPlayer->IsWearingGoggles(true); - bool bHasJetpack = m_pLocalPlayer->HasJetPack(); - bool bChoking = m_pLocalPlayer->IsChoking(); - bool bSunbathing = m_pLocalPlayer->IsSunbathing(); - bool bDoingDriveby = m_pLocalPlayer->IsDoingGangDriveby(); - bool bStealthAiming = m_pLocalPlayer->IsStealthAiming(); - - // Is the current weapon goggles (44 or 45) or a camera (43), or a detonator (40), don't apply the fire key - if (weaponSlot == 11 || weaponSlot == 12 || ucWeaponType == 43) - Controller.ButtonCircle = 0; - - CClientVehicle* pVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - unsigned int uiSeat = m_pLocalPlayer->GetOccupiedVehicleSeat(); - - CShotSyncData* pShotSync = g_pMultiplayer->GetLocalShotSyncData(); - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - float fAimX = pShotSync->m_fArmDirectionX; - float fAimY = pShotSync->m_fArmDirectionY; - char cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; - bool bAkimboUp = g_pMultiplayer->GetAkimboTargetUp(); - - /* - static CClientMarker *pOriginCorona = NULL, *pTargetCorona = NULL; - if ( pOriginCorona == NULL ) - { - pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); - pOriginCorona->SetColor ( 0, 255, 0, 255 ); - pOriginCorona->SetSize ( 0.5f ); - } - else - pOriginCorona->SetPosition ( vecOrigin ); - - if ( pTargetCorona == NULL ) - { - pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); - pTargetCorona->SetColor ( 255, 0, 0, 255 ); - pTargetCorona->SetSize ( 0.5f ); - } - else - pTargetCorona->SetPosition ( vecTarget );*/ - - // Apply this to each of our mimic players - unsigned int uiMimicIndex = 0; - list::const_iterator iterMimics = m_Mimics.begin(); - for (; iterMimics != m_Mimics.end(); ++iterMimics, ++uiMimicIndex) - { - vecPosition.fX += 4.0f; - vecOrigin.fX += 4.0f; - vecTarget.fX += 4.0f; - - CClientPlayer* pMimic = *iterMimics; - - pMimic->SetHealth(fHealth); - pMimic->LockHealth(fHealth); - pMimic->SetArmor(fArmor); - pMimic->LockArmor(fArmor); - pMimic->SetWearingGoggles(bWearingGoggles); - pMimic->SetHasJetPack(bHasJetpack); - pMimic->SetChoking(bChoking); - pMimic->SetSunbathing(bSunbathing); - pMimic->SetDoingGangDriveby(bDoingDriveby); - pMimic->SetStealthAiming(bStealthAiming); - - Controller.ShockButtonL = 0; - - if (m_bMimicLag) - { - pMimic->SetTargetPosition(vecPosition, TICK_RATE); - pMimic->SetMoveSpeed(vecMoveSpeed); - pMimic->SetControllerState(Controller); - pMimic->SetTargetRotation(fRotation); - pMimic->SetCameraRotation(fCameraRotation); - pMimic->Duck(bDucked); - } - else - { - pMimic->SetPosition(vecPosition); - pMimic->SetMoveSpeed(vecMoveSpeed); - pMimic->SetTargetRotation(fRotation); - pMimic->SetCameraRotation(fCameraRotation); - pMimic->SetControllerState(Controller); - pMimic->Duck(bDucked); - } - - if (ucWeaponType != 0) - { - if (ucWeaponType == 44 || ucWeaponType == 45) - { - Controller.ButtonCircle = 0; - } - - if (m_bMimicLag) - { - pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); - pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); - - pMimic->AddChangeWeapon(TICK_RATE, weaponSlot, (unsigned char)ulWeaponAmmoInClip); - } - else - { - CWeapon* pPlayerWeapon = pMimic->GetWeapon(); - eWeaponType eCurrentWeapon = static_cast(ucWeaponType); - if ((pPlayerWeapon && pPlayerWeapon->GetType() != eCurrentWeapon) || !pPlayerWeapon) - { - pPlayerWeapon = pMimic->GiveWeapon(eCurrentWeapon, ulWeaponAmmoInClip); - if (pPlayerWeapon) - { - pPlayerWeapon->SetAsCurrentWeapon(); - } - } - - if (pPlayerWeapon) - { - pPlayerWeapon->SetAmmoTotal(9999); - pPlayerWeapon->SetAmmoInClip(ulWeaponAmmoInClip); - pPlayerWeapon->SetState(static_cast(ucWeaponState)); - } - pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); - pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); - } - } - else - { - pMimic->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); - } - - CClientVehicle* pMimicVehicle = pMimic->GetOccupiedVehicle(); - if (pVehicle) - { - unsigned int uiModel; - CVector vecPosition, vecRotationDegrees; - CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; - float fHealth; - - uiModel = pVehicle->GetModel(); - pVehicle->GetPosition(vecPosition); - pVehicle->GetRotationDegrees(vecRotationDegrees); - pVehicle->GetMoveSpeed(vecMoveSpeed); - pVehicle->GetTurnSpeed(vecTurnSpeed); - fHealth = pVehicle->GetHealth(); - - if (pMimicVehicle && pMimicVehicle->GetModel() != uiModel) - { - delete pMimicVehicle; - pMimicVehicle = NULL; - } - - vecPosition.fX += ((float)(uiMimicIndex + 1) * 10.0f); - - if (pMimicVehicle == NULL) - { - pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, uiModel, 0, 0); - pMimicVehicle->SetPosition(vecPosition); - - const SSlotStates& usUpgrades = pVehicle->GetUpgrades()->GetSlotStates(); - for (unsigned char uc = 0; uc < VEHICLE_UPGRADE_SLOTS; uc++) - { - if (usUpgrades[uc]) - { - pMimicVehicle->GetUpgrades()->AddUpgrade(usUpgrades[uc], true); - } - } - - m_vecLastMimicPos = vecPosition; - } - - if (m_bMimicLag) - { - pMimicVehicle->SetTargetPosition(vecPosition, TICK_RATE); - pMimicVehicle->SetTargetRotation(vecRotationDegrees, TICK_RATE); - pMimicVehicle->SetMoveSpeed(vecMoveSpeed); - pMimicVehicle->SetTurnSpeed(vecTurnSpeed); - } - else - { - pMimicVehicle->SetPosition(vecPosition); - pMimicVehicle->SetRotationDegrees(vecRotationDegrees); - pMimicVehicle->SetMoveSpeed(vecMoveSpeed); - pMimicVehicle->SetTurnSpeed(vecTurnSpeed); - } - pMimicVehicle->SetHealth(fHealth); - if (pMimic->GetOccupiedVehicle() != pMimicVehicle) - pMimic->WarpIntoVehicle(pMimicVehicle, uiSeat); - - unsigned int uiTrailerLoop = 0; - CClientVehicle* pTrailer = pVehicle->GetTowedVehicle(); - CClientVehicle* pMimicTrailer = NULL; - while (pTrailer) - { - uiModel = pTrailer->GetModel(); - pTrailer->GetPosition(vecPosition); - pTrailer->GetRotationDegrees(vecRotationDegrees); - pTrailer->GetMoveSpeed(vecMoveSpeed); - pTrailer->GetTurnSpeed(vecTurnSpeed); - fHealth = pTrailer->GetHealth(); - - pMimicTrailer = DynamicCast(CElementIDs::GetElement(static_cast(450 + uiMimicIndex + uiTrailerLoop))); - - if (pMimicTrailer && pMimicTrailer->GetModel() != uiModel) - { - delete pMimicTrailer; - pMimicTrailer = NULL; - } - - if (!pMimicTrailer) - { - pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, - static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); - pMimicVehicle->SetTowedVehicle(pMimicTrailer); - } - - pTrailer = pTrailer->GetTowedVehicle(); - pMimicTrailer = pMimicTrailer->GetTowedVehicle(); - uiTrailerLoop++; - } - if (pMimicTrailer) - { - if (pMimicTrailer->GetTowedByVehicle()) - { - pMimicTrailer->GetTowedByVehicle()->SetTowedVehicle(NULL); - } - } - } - else if (pMimicVehicle) - { - pMimic->RemoveFromVehicle(); - delete pMimicVehicle; - } - } - } - } -} - -void CClientGame::DoPaintballs(void) -{ - if (m_pLocalPlayer) - { - CVector vecOrigin, vecTarget; - m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); - - CColPoint* pCollision = NULL; - CEntity* pCollisionEntity = NULL; - m_pLocalPlayer->WorldIgnore(true); - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionEntity); - m_pLocalPlayer->WorldIgnore(false); - - static list paintBalls; - if (paintBalls.size() >= 5) - { - CClientMarker* pCorona = paintBalls.back(); - delete pCorona; - paintBalls.pop_back(); - } - - CClientMarker* pCorona = new CClientMarker(m_pManager, INVALID_ELEMENT_ID, CClientMarker::MARKER_CORONA); - paintBalls.push_front(pCorona); - pCorona->SetSize(0.2f); - if (bCollision && pCollision) - { - pCorona->SetPosition(pCollision->GetPosition()); - pCorona->SetColor(SColorRGBA(255, 0, 0, 255)); - } - else - { - pCorona->SetPosition(vecTarget); - pCorona->SetColor(SColorRGBA(255, 255, 0, 255)); - } - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - } -} - -#endif - -void CClientGame::QuitPlayer(CClientPlayer* pPlayer, eQuitReason Reason) -{ - // Get the nick pointer and echo the quit message to the chat - const char* szNick = pPlayer->GetNick(); - const char* szReason = "Unknown"; - switch (Reason) - { - case QUIT_QUIT: - szReason = "Quit"; - break; - case QUIT_KICK: - szReason = "Kicked"; - break; - case QUIT_BAN: - szReason = "Banned"; - break; - case QUIT_CONNECTION_DESYNC: - szReason = "Bad Connection"; - break; - case QUIT_TIMEOUT: - szReason = "Timed Out"; - break; - } - - // In debug, make sure we don't look at this player's details -#ifdef MTA_DEBUG - if (m_pShowPlayer == pPlayer) - { - m_pShowPlayer = NULL; - } -#endif - - // Call our onClientPlayerQuit event - CLuaArguments Arguments; - Arguments.PushString(szReason); - pPlayer->CallEvent("onClientPlayerQuit", Arguments, true); - - // Detach the camera from this player if we're watching them - m_pManager->GetCamera()->UnreferencePlayer(pPlayer); - - // Was this player jacking us? - if (m_bIsGettingJacked && m_pGettingJackedBy == pPlayer) - { - ResetVehicleInOut(); - m_pLocalPlayer->RemoveFromVehicle(false); - m_pLocalPlayer->SetVehicleInOutState(VEHICLE_INOUT_NONE); - } - - // Delete the player - delete pPlayer; -} - -void CClientGame::Event_OnIngame(void) -{ - // Unpause the game - g_pGame->Pause(false); - - // Disable parts of the Hud - CHud* pHud = g_pGame->GetHud(); - pHud->SetComponentVisible(HUD_HELP_TEXT, false); - pHud->SetComponentVisible(HUD_VITAL_STATS, false); - pHud->SetComponentVisible(HUD_AREA_NAME, false); - - g_pMultiplayer->DeleteAndDisableGangTags(); - - // Switch off peds and traffic - SFixedArray vecs = {CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), - CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0)}; - g_pGame->GetPathFind()->SwitchRoadsOffInArea(&vecs[0], &vecs[1]); - g_pGame->GetPathFind()->SwitchPedRoadsOffInArea(&vecs[2], &vecs[3]); - g_pGame->GetPathFind()->SetPedDensity(0.0f); - g_pGame->GetPathFind()->SetVehicleDensity(0.0f); - - g_pGame->GetWorld()->ClearRemovedBuildingLists(); - g_pGame->GetWorld()->SetOcclusionsEnabled(true); - - g_pGame->ResetModelLodDistances(); - g_pGame->ResetAlphaTransparencies(); - - // Make sure we can access all areas - g_pGame->GetStats()->ModifyStat(CITIES_PASSED, 2.0); - - // This is to prevent the 'white arrows in checkpoints' bug (#274) - g_pGame->Get3DMarkers()->CreateMarker(87654, (e3DMarkerType)5, &vecs[4], 1, 0.2f, 0, 0, 0, 0); - - // Stop us getting 4 stars if we visit the SF or LV - // g_pGame->GetPlayerInfo()->GetWanted()->SetMaximumWantedLevel ( 0 ); - g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(0); - - // Reset anything from last game - ResetMapInfo(); - g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level - g_pGame->GetWaterManager()->SetWaterDrawnLast(true); - m_pCamera->SetCameraClip(true, true); - - // Create a local player for us - m_pLocalPlayer = new CClientPlayer(m_pManager, m_LocalID, true); - if (m_pLocalPlayer) - { - // Set our parent the root entity - m_pLocalPlayer->SetParent(m_pRootEntity); - - // Give the local player our nickname - m_pLocalPlayer->SetNick(m_strLocalNick); - - // Freeze the player at some location we won't see - m_pLocalPlayer->SetHealth(100); - m_pLocalPlayer->SetPosition(CVector(0, 0, 0)); - m_pLocalPlayer->SetFrozen(true); - m_pLocalPlayer->ResetInterpolation(); - - // Reset him - m_pLocalPlayer->ResetStats(); - } - else - { - RaiseFatalError(2); - } - - // Make sure we never get tired - g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true); - - // Tell doggy we got the game running - WatchDogCompletedSection("L1"); -} - -void CClientGame::Event_OnIngameAndConnected(void) -{ - m_ulVerifyTimeStart = CClientTime::GetTime(); - - // Keep criminal records of how many times they've connected to servers - SetApplicationSettingInt("times-connected", GetApplicationSettingInt("times-connected") + 1); - if (m_ServerType == SERVER_TYPE_EDITOR) - SetApplicationSettingInt("times-connected-editor", GetApplicationSettingInt("times-connected-editor") + 1); - - // Notify the server telling we're ingame - m_pNetAPI->RPC(PLAYER_INGAME_NOTICE); -} - -bool CClientGame::StaticBreakTowLinkHandler(CVehicle* pTowingVehicle) -{ - return g_pClientGame->BreakTowLinkHandler(pTowingVehicle); -} - -void CClientGame::StaticDrawRadarAreasHandler(void) -{ - g_pClientGame->DrawRadarAreasHandler(); -} - -bool CClientGame::StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent) -{ - return g_pClientGame->DamageHandler(pDamagePed, pEvent); -} - -void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart) -{ - g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart); -} - -void CClientGame::StaticFireHandler(CFire* pFire) -{ - g_pClientGame->FireHandler(pFire); -} - -void CClientGame::StaticRender3DStuffHandler(void) -{ - g_pClientGame->Render3DStuffHandler(); -} - -void CClientGame::StaticPreRenderSkyHandler(void) -{ - g_pClientGame->PreRenderSkyHandler(); -} - -void CClientGame::StaticRenderHeliLightHandler() -{ - g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); -} - -bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) -{ - return g_pClientGame->ChokingHandler(ucWeaponType); -} - -void CClientGame::StaticCAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) -{ - g_pClientGame->CAnimBlendAssocDestructorHandler(pThis); -} - -CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) -{ - return g_pClientGame->AddAnimationHandler(pClump, animGroup, animID); -} - -CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) -{ - return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); -} - -bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) -{ - return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); -} - -bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, - int* pFlags, RpClump* pClump) -{ - return g_pClientGame->BlendAnimationHierarchyHandler(pAnimAssoc, pOutAnimHierarchy, pFlags, pClump); -} - -void CClientGame::StaticPreWorldProcessHandler(void) -{ - g_pClientGame->PreWorldProcessHandler(); -} - -void CClientGame::StaticPostWorldProcessHandler(void) -{ - g_pClientGame->PostWorldProcessHandler(); -} - -void CClientGame::StaticPreFxRenderHandler(void) -{ - g_pCore->OnPreFxRender(); -} - -void CClientGame::StaticPreHudRenderHandler(void) -{ - g_pCore->OnPreHUDRender(); -} - -bool CClientGame::StaticProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) -{ - return g_pClientGame->ProcessCollisionHandler(pThisInterface, pOtherInterface); -} - -bool CClientGame::StaticVehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, - float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, - CVector vecCollisionVelocity) -{ - return g_pClientGame->VehicleCollisionHandler(pCollidingVehicle, pCollidedVehicle, iModelIndex, fDamageImpulseMag, fCollidingDamageImpulseMag, usPieceType, - vecCollisionPos, vecCollisionVelocity); -} - -bool CClientGame::StaticVehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) -{ - return g_pClientGame->VehicleDamageHandler(pVehicleInterface, fLoss, pAttackerInterface, weaponType, vecDamagePos, ucTyre); -} - -bool CClientGame::StaticHeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) -{ - return g_pClientGame->HeliKillHandler(pHeliInterface, pHitInterface); -} - -bool CClientGame::StaticObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) -{ - return g_pClientGame->ObjectDamageHandler(pObjectInterface, fLoss, pAttackerInterface); -} - -bool CClientGame::StaticObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) -{ - return g_pClientGame->ObjectBreakHandler(pObjectInterface, pAttackerInterface); -} - -bool CClientGame::StaticWaterCannonHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) -{ - return g_pClientGame->WaterCannonHitHandler(pCannonVehicle, pHitPed); -} - -bool CClientGame::StaticVehicleFellThroughMapHandler(CVehicleSAInterface* pVehicle) -{ - return g_pClientGame->VehicleFellThroughMapHandler(pVehicle); -} - -void CClientGame::StaticGameObjectDestructHandler(CEntitySAInterface* pObject) -{ - g_pClientGame->GameObjectDestructHandler(pObject); -} - -void CClientGame::StaticGameVehicleDestructHandler(CEntitySAInterface* pVehicle) -{ - g_pClientGame->GameVehicleDestructHandler(pVehicle); -} - -void CClientGame::StaticGamePlayerDestructHandler(CEntitySAInterface* pPlayer) -{ - g_pClientGame->GamePlayerDestructHandler(pPlayer); -} - -void CClientGame::StaticGameProjectileDestructHandler(CEntitySAInterface* pProjectile) -{ - g_pClientGame->GameProjectileDestructHandler(pProjectile); -} - -void CClientGame::StaticGameModelRemoveHandler(ushort usModelId) -{ - g_pClientGame->GameModelRemoveHandler(usModelId); -} - -void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) -{ - if (pGameEntity) - { - // Map to client entity and pass to the texture replacer - CClientEntity* pClientEntity = g_pClientGame->GetGameEntityXRefManager()->FindClientEntity(pGameEntity); - if (pClientEntity) - { - int iTypeMask; - ushort usModelId = 0xFFFF; - switch (pClientEntity->GetType()) - { - case CCLIENTPED: - case CCLIENTPLAYER: - iTypeMask = TYPE_MASK_PED; - usModelId = (ushort) static_cast(pClientEntity)->GetModel(); - break; - case CCLIENTVEHICLE: - iTypeMask = TYPE_MASK_VEHICLE; - break; - case CCLIENTOBJECT: - iTypeMask = TYPE_MASK_OBJECT; - break; - default: - iTypeMask = TYPE_MASK_OTHER; - break; - } - g_pGame->GetRenderWare()->SetRenderingClientEntity(pClientEntity, usModelId, iTypeMask); - return; - } - } - - g_pGame->GetRenderWare()->SetRenderingClientEntity(NULL, 0xFFFF, TYPE_MASK_WORLD); -} - -void CClientGame::StaticTaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) -{ - g_pClientGame->TaskSimpleBeHitHandler(pPedAttacker, hitBodyPart, hitBodySide, weaponId); -} - -void CClientGame::StaticFxSystemDestructionHandler(void* pFxSAInterface) -{ - g_pClientGame->GetManager()->GetEffectManager()->SAEffectDestroyed(pFxSAInterface); -} - -AnimationId CClientGame::StaticDrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId) -{ - return g_pClientGame->DrivebyAnimationHandler(animGroup, animId); -} - -void CClientGame::DrawRadarAreasHandler(void) -{ - m_pRadarAreaManager->DoPulse(); -} - -bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle) -{ - CClientVehicle* pVehicle = m_pVehicleManager->Get(pTowedVehicle, false); - if (pVehicle) - { - // Check if this is a legal break - bool bLegal = ((pVehicle->GetControllingPlayer() == m_pLocalPlayer) || (m_pUnoccupiedVehicleSync->Exists(static_cast(pVehicle)))); - - // Not a legal break? - if (!bLegal) - { - // Save the time it broke (used in UpdateTrailers) - pVehicle->SetIllegalTowBreakTime(GetTickCount32()); - } - } - - // Allow it to break - return true; -} - -void CClientGame::FireHandler(CFire* pFire) -{ - // Disable spreading fires - pFire->SetNumGenerationsAllowed(0); -} - -void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) -{ - if (pProjectile->IsLocal()) - { - // Did the local player create this projectile? - if (m_pLocalPlayer && pProjectile->GetCreator() == m_pLocalPlayer) - { - // Physics says our projectile should start off at our velocity - CVector vecVelocity, vecPlayerVelocity; - pProjectile->GetVelocity(vecVelocity); - m_pLocalPlayer->GetMoveSpeed(vecPlayerVelocity); - vecVelocity += vecPlayerVelocity; - pProjectile->SetVelocity(vecVelocity); - } - - SendProjectileSync(pProjectile); - } - - // Renew the interior and dimension - if (pProjectile->GetCreator()) - { - pProjectile->SetInterior(pProjectile->GetCreator()->GetInterior()); - pProjectile->SetDimension(pProjectile->GetCreator()->GetDimension()); - } - - // Validate the projectile for our element tree - pProjectile->SetParent(m_pRootEntity); - - // Call our creation event - CLuaArguments Arguments; - Arguments.PushElement(pProjectile->GetCreator()); - pProjectile->CallEvent("onClientProjectileCreation", Arguments, true); -} - -void CClientGame::Render3DStuffHandler(void) -{ -} - -void CClientGame::PreRenderSkyHandler(void) -{ - g_pCore->GetGraphics()->GetRenderItemManager()->PreDrawWorld(); -} - -void CClientGame::PreWorldProcessHandler(void) -{ -} - -void CClientGame::PostWorldProcessHandler(void) -{ - m_pManager->GetMarkerManager()->DoPulse(); - m_pManager->GetPointLightsManager()->DoPulse(); - m_pManager->GetObjectManager()->DoPulse(); - - // Update frame time slice - uint uiCurrentTick = GetTickCount32(); - if (m_uiLastFrameTick) - { - m_uiFrameTimeSlice = uiCurrentTick - m_uiLastFrameTick; - m_uiFrameCount++; - - // Call onClientPreRender LUA event - CLuaArguments Arguments; - Arguments.PushNumber(m_uiFrameTimeSlice); - m_pRootEntity->CallEvent("onClientPreRender", Arguments, false); - } - m_uiLastFrameTick = uiCurrentTick; -} - -void CClientGame::IdleHandler(void) -{ - // If we are minimized we do the pulsing here - if (g_pCore->IsWindowMinimized()) - { - if (!m_bWasMinimized) - { - m_bWasMinimized = true; - // Call onClientMinimize LUA event - CLuaArguments Arguments; - m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); - - bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); - - // Apply mute on minimize options - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) - g_pGame->GetAudio()->SetMusicMasterVolume(0); - - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) - g_pGame->GetAudio()->SetEffectsMasterVolume(0); - - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) - m_pManager->GetSoundManager()->SetMinimizeMuted(true); - } - } - - // Ensure dummy progress graphic will be displayed when using alt pulse order - g_pCore->SetDummyProgressUpdateAlways(true); - - // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) - DoPulses2(true); - - g_pCore->SetDummyProgressUpdateAlways(false); -} - -bool CClientGame::ChokingHandler(unsigned char ucWeaponType) -{ - if (!m_pLocalPlayer) - return true; - CLuaArguments Arguments; - Arguments.PushNumber(ucWeaponType); - return m_pLocalPlayer->CallEvent("onClientPlayerChoke", Arguments, true); -} - -void CClientGame::CAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) -{ - // printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID); - RemoveAnimationAssociationFromMap(pThis); -} - -CAnimBlendAssociationSAInterface* CClientGame::AddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) -{ - // printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); - return nullptr; -} - -CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) -{ - // printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); - return nullptr; -} - -bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) -{ - bool isCustomAnimationToPlay = false; - CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); - auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); - auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); - auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); - auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); - - CClientPed* pClientPed = GetClientPedByClump(*pClump); - if (pClientPed != nullptr) - { - auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); - if (pReplacedAnimation != nullptr) - { - std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); - - // Play our custom animation instead of default - auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); - pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); - pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); - pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); - isCustomAnimationToPlay = true; - } - } - - if (!isCustomAnimationToPlay) - { - auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); - - // Play default internal animation - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); - } - return isCustomAnimationToPlay; -} - -bool CClientGame::BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags, - RpClump* pClump) -{ - bool isCustomAnimationToPlay = false; - CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); - CClientPed* pClientPed = GetClientPedByClump(*pClump); - if (pClientPed != nullptr) - { - if (pClientPed->IsNextAnimationCustom()) - { - std::shared_ptr pIFP = pClientPed->GetCustomAnimationIFP(); - if (pIFP) - { - const SString& strAnimationName = pClientPed->GetNextAnimationCustomName(); - auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy(strAnimationName); - if (pCustomAnimBlendHierarchy != nullptr) - { - std::shared_ptr pIFPAnimations = pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); - - pClientPed->SetCurrentAnimationCustom(true); - pClientPed->SetNextAnimationNormal(); - - if (pIFP->IsUnloading()) - { - pClientPed->DereferenceCustomAnimationBlock(); - } - *pOutAnimHierarchy = pCustomAnimBlendHierarchy; - isCustomAnimationToPlay = true; - return isCustomAnimationToPlay; - } - } - } - - pClientPed->SetCurrentAnimationCustom(false); - pClientPed->SetNextAnimationNormal(); - } - return isCustomAnimationToPlay; -} - -bool CClientGame::ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) -{ - if (pThisInterface == pOtherInterface) - return true; - - if (!m_BuiltCollisionMapThisFrame) - { - // Build a map of CPhysicalSAInterface*/CClientEntity*'s that have collision disabled - m_BuiltCollisionMapThisFrame = true; - m_CachedCollisionMap.clear(); - - std::map::iterator iter = m_AllDisabledCollisions.begin(); - for (; iter != m_AllDisabledCollisions.end(); ++iter) - { - CClientEntity* pEntity = iter->first; - CEntity* pGameEntity = pEntity->GetGameEntity(); - CEntitySAInterface* pInterface = pGameEntity ? pGameEntity->GetInterface() : NULL; - - if (pInterface) - m_CachedCollisionMap[pInterface] = pEntity; - } - } - - // Check both elements appear in the cached map before doing extra processing - std::map::iterator iter1 = m_CachedCollisionMap.find((CEntitySAInterface*)pThisInterface); - if (iter1 != m_CachedCollisionMap.end()) - { - std::map::iterator iter2 = m_CachedCollisionMap.find((CEntitySAInterface*)pOtherInterface); - if (iter2 != m_CachedCollisionMap.end()) - { - // Re-get the entity pointers using a safer method - CEntity* pGameEntity = g_pGame->GetPools()->GetEntity((DWORD*)pThisInterface); - CEntity* pGameColEntity = g_pGame->GetPools()->GetEntity((DWORD*)pOtherInterface); - - if (pGameEntity && pGameColEntity) - { - CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity, true); - CClientEntity* pColEntity = m_pManager->FindEntity(pGameColEntity, true); - - if (pEntity && pColEntity) - { - #if MTA_DEBUG - CClientEntity* ppThisEntity2 = iter1->second; - CClientEntity* ppOtherEntity2 = iter2->second; - // These should match, but its not essential. - assert(ppThisEntity2 == pEntity); - assert(ppOtherEntity2 == pColEntity); - #endif - if (!pEntity->IsCollidableWith(pColEntity)) - return false; - } - } - } - } - - return true; -} - -// -// On demand files -// -void CClientGame::DownloadSingularResourceFiles(void) -{ - if (!IsTransferringSingularFiles()) - return; - - if (!g_pNet->IsConnected()) - return; - - CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES); - if (!pHTTP->ProcessQueuedFiles()) - { - // Downloading - } - else - { - // Can't clear list until all files have been processed - if (m_pSingularFileDownloadManager->AllComplete()) - { - SetTransferringSingularFiles(false); - m_pSingularFileDownloadManager->ClearList(); - } - } -} - -// Get relevant death anim for animation purposes during death situation -void GetDeathAnim(CClientPed* pDamagedPed, CEventDamage* pEvent, AssocGroupId& outAnimGroup, AnimationId& outAnimID) -{ - if (pEvent) - { - pEvent->ComputeDeathAnim(pDamagedPed->GetGamePlayer(), false); - outAnimGroup = pEvent->GetAnimGroup(); - outAnimID = pEvent->GetAnimId(); - } - else - { - // Using same numbers as CClientGame::DoWastedCheck defaults - outAnimGroup = 0; - outAnimID = 15; - } -} - -// -// DamageHandler seems to be called 3 times for each bit of damage: -// -// pass 1 - preApplyDamage -// is pass 1 if: fDamage == zero && fCurrentHealth == fPreviousHealth -// returning false stops any damage being inflicted -// returning true applies damage and allows pass 2 -// pass 2 - postApplyDamage/preApplyAnim -// is pass 2 if: fDamage > zero && fCurrentHealth != fPreviousHealth -// returning false stops damage anim -// returning true allows damage anim and allows pass 3 -// pass 3 - postApplyAnim -// is pass 3 if: fDamage > zero && fCurrentHealth == fPreviousHealth -// returning false ?? -// returning true ?? -// -bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) -{ - // CEventDamage::AffectsPed: This is/can be called more than once for each bit of damage (and may not actually take any more health (even if we return - // true)) - - // Grab some data from the event - CEntity* pInflictor = pEvent->GetInflictingEntity(); - eWeaponType weaponUsed = pEvent->GetWeaponUsed(); - ePedPieceTypes hitZone = pEvent->GetPedPieceType(); - CWeaponInfo* pWeaponInfo = g_pGame->GetWeaponInfo(weaponUsed); - float fDamage = pEvent->GetDamageApplied(); - EDamageReasonType damageReason = pEvent->GetDamageReason(); - - /* Causes too much desync right now - // Is this shotgun damage? - if ( weaponUsed == WEAPONTYPE_SHOTGUN || weaponUsed == WEAPONTYPE_SPAS12_SHOTGUN ) - { - // Make the ped fall down - pEvent->MakePedFallDown (); - } */ - - // Grab the damaged ped - CClientPed* pDamagedPed = NULL; - if (pDamagePed) - pDamagedPed = m_pPedManager->Get(dynamic_cast(pDamagePed), true, true); - - // Grab the inflictor - CClientEntity* pInflictingEntity = NULL; - if (pInflictor) - pInflictingEntity = m_pManager->FindEntity(pInflictor, true); - - // If the damage was caused by an explosion - if (weaponUsed == WEAPONTYPE_EXPLOSION) - { - CClientEntity* pLastExplosionCreator = m_pManager->GetExplosionManager()->m_pLastCreator; - - // If we don't have an inflictor, look for the last explosion creator - if (!pInflictor && pLastExplosionCreator) - pInflictingEntity = pLastExplosionCreator; - - // Change the weapon used to whatever created the explosion - weaponUsed = m_pManager->GetExplosionManager()->m_LastWeaponType; - } - - // Do we have a damaged ped? - if (pDamagedPed) - { - /////////////////////////////////////////////////////////////////////////// - // - // Pass 1 stuff - // - // return false to stop any damage being inflicted - // - /////////////////////////////////////////////////////////////////////////// - - // Pass 1 checks for double shots - if (fDamage == 0.0f && damageReason != EDamageReason::PISTOL_WHIP) - { - // Only check for remote players - CClientPlayer* pInflictingPlayer = DynamicCast(pInflictingEntity); - if (pInflictingPlayer && !pInflictingPlayer->IsLocalPlayer()) - { - bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon - bool bBulletSyncWeapon = GetWeaponTypeUsesBulletSync(weaponUsed); - - if (bBulletSyncShot) - { - if (g_iDamageEventLimit == 0) - { - AddReportLog(5501, SString("2nd pass 1 for BulletSyncShot damage. weaponUsed:%d", weaponUsed)); - return false; - } - g_iDamageEventLimit--; - if (!bBulletSyncWeapon) - { - AddReportLog(5502, SString("BulletSyncShot but not bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); - return false; - } - } - else - { - if (bBulletSyncWeapon) - { - AddReportLog(5503, SString("not BulletSyncShot but bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); - return false; - } - } - } - } - - // Is the damaged ped a player? - if (IS_PLAYER(pDamagedPed)) - { - CClientPlayer* pDamagedPlayer = static_cast(pDamagedPed); - - // Do we have an inflicting entity? - if (pInflictingEntity) - { - // Grab the inflicting player - CClientPlayer* pInflictingPlayer = NULL; - - switch (pInflictingEntity->GetType()) - { - case CCLIENTPLAYER: - { - pInflictingPlayer = static_cast(pInflictingEntity); - break; - } - case CCLIENTVEHICLE: - { - CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); - if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) - { - CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); - if (pPed && pPed->GetType() == CCLIENTPLAYER) - pInflictingPlayer = static_cast(pPed); - } - break; - } - default: - break; - } - if (pInflictingPlayer) - { - // Is the damaged player on a team - CClientTeam* pTeam = pDamagedPlayer->GetTeam(); - if (pTeam) - { - // Is this friendly-fire from a team-mate? - if (pDamagedPlayer->IsOnMyTeam(pInflictingPlayer) && !pTeam->GetFriendlyFire() && pDamagedPlayer != pInflictingPlayer) - return false; - } - } - } - } - /////////////////////////////////////////////////////////////////////////// - // Pass 1 end - /////////////////////////////////////////////////////////////////////////// - - return ApplyPedDamageFromGame(weaponUsed, fDamage, hitZone, pDamagedPed, pInflictingEntity, pEvent); - } - - // No damage anim for fire - if (weaponUsed == WEAPONTYPE_FLAMETHROWER) - return false; - - // Allow the damage processing to continue - return true; -} - -// -// Check GTA stored health with our stored health and do stuff -// -bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, uchar hitZone, CClientPed* pDamagedPed, CClientEntity* pInflictingEntity, - CEventDamage* pEvent) -{ - float fPreviousHealth = pDamagedPed->m_fHealth; - float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); - float fPreviousArmor = pDamagedPed->m_fArmor; - float fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); - - // Have we taken any damage here? - if ((fPreviousHealth != fCurrentHealth || fPreviousArmor != fCurrentArmor) && fDamage != 0.0f) - { - /////////////////////////////////////////////////////////////////////////// - /// - // Pass 2 stuff - (GTA has applied the damage) - // - // return false to stop damage anim (incl. death task) - // - /////////////////////////////////////////////////////////////////////////// - - g_fApplyDamageLastAmount = fDamage; - g_ucApplyDamageLastHitZone = hitZone; - g_pApplyDamageLastDamagedPed = pDamagedPed; - - CLuaArguments Arguments; - if (pInflictingEntity) - Arguments.PushElement(pInflictingEntity); - else - Arguments.PushBoolean(false); - Arguments.PushNumber(static_cast(weaponUsed)); - Arguments.PushNumber(static_cast(hitZone)); - Arguments.PushNumber(fDamage); - - // Call our event - if ((IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPlayerDamage", Arguments, true)) || - (!IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPedDamage", Arguments, true))) - { - // Stop here if they cancelEvent it - if (pDamagedPed->IsLocalPlayer()) - { - // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) - fPreviousHealth = pDamagedPed->m_fHealth; - fPreviousArmor = pDamagedPed->m_fArmor; - } - pDamagedPed->GetGamePlayer()->SetHealth(fPreviousHealth); - pDamagedPed->GetGamePlayer()->SetArmor(fPreviousArmor); - return false; - } - - if (pDamagedPed->IsLocalPlayer()) - { - // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) - fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); - fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); - } - - bool bIsBeingShotWhilstAiming = (weaponUsed >= WEAPONTYPE_PISTOL && weaponUsed <= WEAPONTYPE_MINIGUN && pDamagedPed->IsUsingGun()); - bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); - - bool bAllowChoke = true; - // Is this is a remote player? - if (!pDamagedPed->IsLocalPlayer()) - { - // Don't allow GTA to start the choking task - if (weaponUsed == WEAPONTYPE_TEARGAS || weaponUsed == WEAPONTYPE_SPRAYCAN || weaponUsed == WEAPONTYPE_EXTINGUISHER) - bAllowChoke = false; - } - - // Check if their health or armor is locked, and if so prevent applying the damage locally - if (pDamagedPed->IsHealthLocked() || pDamagedPed->IsArmorLocked()) - { - // Restore health+armor - pDamagedPed->GetGamePlayer()->SetHealth(pDamagedPed->GetHealth()); - pDamagedPed->GetGamePlayer()->SetArmor(pDamagedPed->GetArmor()); - - if (bOldBehaviour) - { - // Don't play the animation if it's going to be a death one, or if it's going to interrupt aiming - if (fCurrentHealth == 0.0f || bIsBeingShotWhilstAiming) - return false; - - // Allow animation for remote players (if currently we don't need block choke) - return bAllowChoke; - } - - // No hit animation for remote players - return false; - } - - // Update our stored health/armor - pDamagedPed->m_fHealth = fCurrentHealth; - pDamagedPed->m_fArmor = fCurrentArmor; - - ElementID damagerID = INVALID_ELEMENT_ID; - if (pInflictingEntity && !pInflictingEntity->IsLocalEntity()) - damagerID = pInflictingEntity->GetID(); - - // Is it the local player? - if (pDamagedPed->IsLocalPlayer()) - { - // Update our stored damage stuff - m_ucDamageWeapon = static_cast(weaponUsed); - m_ucDamageBodyPiece = static_cast(hitZone); - m_pDamageEntity = pInflictingEntity; - m_ulDamageTime = CClientTime::GetTime(); - m_DamagerID = damagerID; - m_bDamageSent = false; - } - // Does this damage kill the player? - if (fCurrentHealth == 0.0f) - { - if (pDamagedPed->GetType() == CCLIENTPLAYER) - { - // Is the local player dying? - if (pDamagedPed->IsLocalPlayer() && fPreviousHealth > 0.0f) - { - // Grab our death animation - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - - // Check if we're dead - DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); - } - - // Allow GTA to kill us if we've fell to our death - if (pDamagedPed->IsLocalPlayer() && weaponUsed == WEAPONTYPE_FALL) - return true; - - // Don't let GTA start the death task - return false; - } - else - { - if (pDamagedPed->IsLocalEntity() && fPreviousHealth > 0.0f) - { - // Client-side ped - pDamagedPed->CallEvent("onClientPedWasted", Arguments, true); - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - pDamagedPed->Kill(weaponUsed, hitZone, false, false, animGroup, animID); - return true; - } - if (fPreviousHealth > 0.0f) - { - // Grab our death animation - AssocGroupId animGroup; - AnimationId animID; - GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); - - SendPedWastedPacket(pDamagedPed, damagerID, weaponUsed, hitZone, animGroup, animID); - } - } - } - - // Disallow choke task if it's necessary - if (!bAllowChoke) - return false; - - // Inhibit hit-by-gun animation for local player if required - if (bOldBehaviour) - if (pDamagedPed->IsLocalPlayer() && bIsBeingShotWhilstAiming) - return false; - - /////////////////////////////////////////////////////////////////////////// - // Pass 2 end - /////////////////////////////////////////////////////////////////////////// - } - - // No damage anim for fire - if (weaponUsed == WEAPONTYPE_FLAMETHROWER) - return false; - - // Allow the damage processing to continue - return true; -} - -void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, unsigned char ucBodyPart) -{ - CClientPed* pKilledPed = m_pPedManager->Get(dynamic_cast(pKilledPedSA), true, true); - - if (!pKilledPed) - return; - - // Not required for remote players. Local player is handled in DoPulses->DoWastedCheck - if (IS_PLAYER(pKilledPed)) - return; - - // Set the health to zero (this is safe as GTA will do it anyway in a few ticks) - pKilledPed->SetHealth(0.0f); - - // Call Lua - CLuaArguments Arguments; - Arguments.PushBoolean(false); - Arguments.PushNumber(ucDeathReason); - Arguments.PushNumber(ucBodyPart); - - pKilledPed->CallEvent("onClientPedWasted", Arguments, true); - - // Notify the server - SendPedWastedPacket(pKilledPed, INVALID_ELEMENT_ID, ucDeathReason, ucBodyPart); -} - -bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, - float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) -{ - if (pCollidingVehicle && pCollidedWith) - { - CVehicle* pColliderVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidingVehicle); - CClientEntity* pVehicleClientEntity = m_pManager->FindEntity(pColliderVehicle, true); - if (pVehicleClientEntity) - { - CClientVehicle* pClientVehicle = static_cast(pVehicleClientEntity); - - CEntity* pCollidedWithEntity = g_pGame->GetPools()->GetEntity((DWORD*)pCollidedWith); - CClientEntity* pCollidedWithClientEntity = NULL; - if (pCollidedWithEntity) - { - if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pCollidedWithVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithVehicle, true); - } - else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_OBJECT) - { - CObject* pCollidedWithObject = g_pGame->GetPools()->GetObject((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithObject, true); - } - else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pCollidedWithPed = g_pGame->GetPools()->GetPed((DWORD*)pCollidedWith); - pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithPed, true); - } - } - CLuaArguments Arguments; - if (pCollidedWithClientEntity) - { - Arguments.PushElement(pCollidedWithClientEntity); - } - else - { - Arguments.PushNil(); - } - Arguments.PushNumber(fDamageImpulseMag); - Arguments.PushNumber(usPieceType); - Arguments.PushNumber(vecCollisionPos.fX); - Arguments.PushNumber(vecCollisionPos.fY); - Arguments.PushNumber(vecCollisionPos.fZ); - Arguments.PushNumber(vecCollisionVelocity.fX); - Arguments.PushNumber(vecCollisionVelocity.fY); - Arguments.PushNumber(vecCollisionVelocity.fZ); - Arguments.PushNumber(fCollidingDamageImpulseMag); - Arguments.PushNumber(iModelIndex); - - pVehicleClientEntity->CallEvent("onClientVehicleCollision", Arguments, true); - // Alocate a BitStream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - // Make sure it created - if (pBitStream) - { - if (pBitStream->Version() >= 0x028) - { - // Sync Stuff - // if it's not a local vehicle + it collided with the local player - if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) - { - // is it below the anti spam threshold? - if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) - { - // if there is no controlling player - if (!pClientVehicle->GetControllingPlayer()) - { - CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); - // if We aren't already syncing the vehicle - if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) - { - // Write the vehicle ID - pBitStream->Write(pVehicleClientEntity->GetID()); - // Send! - g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, - PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); - // Reset our push time - pClientVehicle->ResetLastPushTime(); - } - } - } - } - } - g_pNet->DeallocateNetBitStream(pBitStream); - } - return true; - } - } - return false; -} - -bool CClientGame::HeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) -{ - if (pHeliInterface && pHitInterface) - { - // Get our heli and client heli - CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); - CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); - if (pHeli && pClientHeli && pClientHeli->AreHeliBladeCollisionsEnabled()) - { - // Get our ped and client ped - CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitInterface); - CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); - // Was our client ped valid - if (pClientPed) - { - // Get our heli and client heli - CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); - CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); - - // Iterate our "stored" cancel state and find the heli in question - std::pair::iterator, std::multimap::iterator> iterators = - m_HeliCollisionsMap.equal_range(pClientHeli); - std::multimap::const_iterator iter = iterators.first; - for (; iter != iterators.second; ++iter) - { - // If the Heli and ped collided within the clear rate return false - if ((*iter).first == pClientHeli && (*iter).second == pClientPed) - return false; - } - - CLuaArguments Arguments; - if (pClientHeli) - { - // Push our heli - Arguments.PushElement(pClientHeli); - } - else - { - Arguments.PushNil(); - } - - // Trigger our event - bool bContinue; - if (IS_PLAYER(pClientPed)) - bContinue = pClientPed->CallEvent("onClientPlayerHeliKilled", Arguments, true); - else - bContinue = pClientPed->CallEvent("onClientPedHeliKilled", Arguments, true); - - // Was our event cancelled - if (!bContinue) - { - // Add our heli and ped pair to the list - std::pair pair = std::pair(pClientHeli, pClientPed); - m_HeliCollisionsMap.insert(pair); - } - // Return if it was cancelled - return bContinue; - } - } - else - { - return false; - } - } - return true; -} - -bool CClientGame::VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) -{ - bool bAllowDamage = true; - CClientVehicle* pClientVehicle = GetGameEntityXRefManager()->FindClientVehicle(pVehicleInterface); - if (pClientVehicle) - { - CClientEntity* pClientAttacker = GetGameEntityXRefManager()->FindClientEntity(pAttackerInterface); - - // Compose arguments - // attacker, weapon, loss, damagepos, tyreIdx - CLuaArguments Arguments; - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - if (weaponType != WEAPONTYPE_INVALID) - Arguments.PushNumber(weaponType); - else - Arguments.PushNil(); - Arguments.PushNumber(fLoss); - Arguments.PushNumber(vecDamagePos.fX); - Arguments.PushNumber(vecDamagePos.fY); - Arguments.PushNumber(vecDamagePos.fZ); - if (ucTyre != UCHAR_INVALID_INDEX) - Arguments.PushNumber(ucTyre); - else - Arguments.PushNil(); - - if (!pClientVehicle->CallEvent("onClientVehicleDamage", Arguments, true)) - { - bAllowDamage = false; - } - } - - return bAllowDamage; -} - -bool CClientGame::ObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) -{ - if (pObjectInterface) - { - // Get our object and client object - CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); - CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); - - // Is our client vehicle valid? - if (pClientObject) - { - CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); - CClientEntity* pClientAttacker = NULL; - if (pAttacker) - { - if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); - } - else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerPed); - } - } - - CLuaArguments Arguments; - Arguments.PushNumber(fLoss); - - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - - return pClientObject->CallEvent("onClientObjectDamage", Arguments, true); - } - } - return true; -} - -bool CClientGame::ObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) -{ - if (pObjectInterface) - { - // Get our object and client object - CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); - CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); - - // Is our client vehicle valid? - if (pClientObject) - { - if (!pClientObject->IsBreakable(false)) - return false; - - // Apply to MTA's "internal storage", too - pClientObject->SetHealth(0.0f); - - CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); - CClientEntity* pClientAttacker = NULL; - if (pAttacker) - { - if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) - { - CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); - } - else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) - { - CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); - pClientAttacker = m_pManager->FindEntity(pAttackerPed); - } - } - - CLuaArguments Arguments; - - if (pClientAttacker) - Arguments.PushElement(pClientAttacker); - else - Arguments.PushNil(); - - return pClientObject->CallEvent("onClientObjectBreak", Arguments, true); - } - } - return true; -} - -bool CClientGame::WaterCannonHitHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) -{ - if (pCannonVehicle && pHitPed) - { - // Get our vehicle and client vehicle - CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCannonVehicle); - CClientVehicle* pCannonClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); - // Was our client vehicle valid - if (pCannonClientVehicle) - { - // Get our ped and client ped - CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitPed); - CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); - - CLuaArguments Arguments; - if (pClientPed) - { - // Push our ped - Arguments.PushElement(pClientPed); - } - else - { - Arguments.PushNil(); - } - - // Trigger our event - bool bContinue = true; - if (!IS_PLAYER(pClientPed)) - bContinue = pCannonClientVehicle->CallEvent("onClientPedHitByWaterCannon", Arguments, true); - else - bContinue = pCannonClientVehicle->CallEvent("onClientPlayerHitByWaterCannon", Arguments, true); - - // Return if it was cancelled - return bContinue; - } - } - return false; -} - -bool CClientGame::VehicleFellThroughMapHandler(CVehicleSAInterface* pVehicleInterface) -{ - if (pVehicleInterface) - { - // Get our vehicle and client vehicle - CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pVehicleInterface); - CClientVehicle* pClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); - if (pClientVehicle) - { - // handle or don't - return pClientVehicle->OnVehicleFallThroughMap(); - } - } - // unhandled - return false; -} - -// Validate known objects -void CClientGame::GameObjectDestructHandler(CEntitySAInterface* pObject) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pObject); -} - -void CClientGame::GameVehicleDestructHandler(CEntitySAInterface* pVehicle) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pVehicle); -} - -void CClientGame::GamePlayerDestructHandler(CEntitySAInterface* pPlayer) -{ - m_pGameEntityXRefManager->OnGameEntityDestruct(pPlayer); -} - -void CClientGame::GameProjectileDestructHandler(CEntitySAInterface* pProjectile) -{ - CClientProjectile* pClientProjectile = m_pManager->GetProjectileManager()->Get(pProjectile); - // Happens when destroyElement is called rather than letting the projectile expire - // Normal code path is destruction from CProjectileSAInterface -> CProjectileSA -> CClientProjectile - // destroyElement is CClientProjectile -> CProjectileSA -> CProjectileSAInterface - // which means the CClientProjectile element is deleted when we get here - if (pClientProjectile) - CStaticFunctionDefinitions::DestroyElement(*pClientProjectile); -} - -void CClientGame::GameModelRemoveHandler(ushort usModelId) -{ - m_pGameEntityXRefManager->OnGameModelRemove(usModelId); -} - -void CClientGame::TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) -{ - bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); - if (bOldBehaviour) - return; - - CClientPed* pClientPedAttacker = DynamicCast(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedAttacker)); - - // Make sure cause was networked ped - if (pClientPedAttacker && !pClientPedAttacker->IsLocalEntity()) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write((ushort)TASK_SIMPLE_BE_HIT); - pBitStream->Write(pClientPedAttacker->GetID()); - pBitStream->Write((uchar)hitBodyPart); - pBitStream->Write((uchar)hitBodySide); - pBitStream->Write((uchar)weaponId); - g_pNet->SendPacket(PACKET_ID_PED_TASK, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -bool CClientGame::StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (g_pClientGame) - { - return g_pClientGame->ProcessMessage(hwnd, uMsg, wParam, lParam); - } - - return false; -} - -bool CClientGame::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (ProcessMessageForCursorEvents(hwnd, uMsg, wParam, lParam)) - { - return true; - } - - return false; -} - -void CClientGame::ProcessVehicleInOutKey(bool bPassenger) -{ - // Are we already sending an in/out request or not allowed to create a new in/out? - if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? - || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) - || m_bIsGettingJacked // Make sure we're not currently getting carjacked && - || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... - || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... - || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon - ) - { - return; - } - - // Reset the "is jacking" bit - m_bIsJackingVehicle = false; - - // Got a local player model? - if (!m_pLocalPlayer) - { - // No local player. Stop. - return; - } - - // If the player is in a vehicle we need to leave the vehicle. - CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); - if (pOccupiedVehicle) - { - // Only let us leave the vehicle if: - // - we press F (as driver) - // - we press either F or G as a passenger - if (bPassenger && m_pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - // Driver pressed G, so stop. - return; - } - - // We're about to exit a vehicle - // Send an in request - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!pBitStream) - { - return; - } - - // Write the vehicle id to it and that we're requesting to get out of it - pBitStream->Write(pOccupiedVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_REQUEST_OUT); - pBitStream->WriteBits(&ucAction, 4); - - unsigned char ucDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pLocalPlayer->GetGamePlayer(), pOccupiedVehicle->GetGameVehicle()); - if (ucDoor >= 2 && ucDoor <= 5) - { - ucDoor -= 2; - pBitStream->WriteBits(&ucDoor, 2); - } - - // Send and destroy it - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're now exiting a vehicle - m_bIsGettingOutOfVehicle = true; - m_ulLastVehicleInOutTime = CClientTime::GetTime(); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_out"); -#endif - return; - } - - // - // We're going to enter a vehicle - // - - // If the Jump task is playing and we are in water - I know right - // Kill the task. - // - CTask* pTask = m_pLocalPlayer->GetCurrentPrimaryTask(); - if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter - { - CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, nullptr, nullptr, 20.0f); - if (pVehicle && - (pVehicle->IsInWater() || - m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) - { - m_pLocalPlayer->KillTask(3, true); // Kill jump task if we are about to warp in - } - } - - // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle' - // task will replace it and fuck it up! - // - if (m_pLocalPlayer->GetCurrentPrimaryTask()) - { - // We already have a primary task, so stop. - return; - } - - // Are we holding the aim_weapon key? - SBindableGTAControl* pBind = g_pCore->GetKeyBinds()->GetBindableFromControl("aim_weapon"); - if (pBind && pBind->bState) - { - // Stop because the player is probably using rshift + f/g - return; - } - - if (m_pLocalPlayer->IsClimbing() // Make sure we're not currently climbing - || m_pLocalPlayer->HasJetPack() // Make sure we don't have a jetpack - || m_pLocalPlayer->IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway - || m_pLocalPlayer->IsRunningAnimation() // Make sure we aren't running an animation - ) - { - return; - } - - // Grab the closest vehicle - unsigned int uiDoor = 0; - CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, &uiDoor, nullptr, 20.0f); - unsigned int uiSeat = uiDoor; - - if (bPassenger && uiDoor == 0) - { - // We're trying to enter as a passenger, yet our closest door - // is the driver's door. Force an enter for the passenger seat. - uiSeat = 1; - } - else if (!bPassenger) - { - // We want to drive. Force our seat to the driver's seat. - uiSeat = 0; - } - - if (!pVehicle || !pVehicle->IsEnterable()) - { - // Stop if there isn't a vehicle, or the vehicle is not enterable - return; - } - - // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly) - if (pVehicle->GetVehicleType() == CLIENTVEHICLE_BOAT && m_pLocalPlayer->GetContactEntity() != pVehicle) - { - return; - } - - // Call the onClientVehicleStartEnter event for remote players - // Local player triggered before sending packet in CClientGame - CLuaArguments Arguments; - Arguments.PushElement(m_pLocalPlayer); // player - Arguments.PushNumber(uiSeat); // seat - Arguments.PushNumber(uiDoor); // Door - - if (!pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true)) - { - // Event has been cancelled - return; - } - - // Send an in request - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!pBitStream) - { - return; - } - - // Write the vehicle id to it and that we're requesting to get into it - pBitStream->Write(pVehicle->GetID()); - unsigned char ucAction = static_cast(VEHICLE_REQUEST_IN); - unsigned char ucSeat = static_cast(uiSeat); - bool bIsOnWater = pVehicle->IsOnWater(); - unsigned char ucDoor = static_cast(uiDoor); - pBitStream->WriteBits(&ucAction, 4); - pBitStream->WriteBits(&ucSeat, 4); - pBitStream->WriteBit(bIsOnWater); - pBitStream->WriteBits(&ucDoor, 3); - - // Send and destroy it - g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - - // We're now entering a vehicle - m_bIsGettingIntoVehicle = true; - m_ulLastVehicleInOutTime = CClientTime::GetTime(); - -#ifdef MTA_DEBUG - g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_in"); -#endif -} - -// Shot compensation (Jax): -// Positions the local player where he should of been on the shooting player's screen when he -// fired remotely. (the position we !reported! around the time he shot) -bool bShotCompensation = true; - -// Temporary pointers for pre- and post-functions -CVector vecWeaponFirePosition, vecRemoteWeaponFirePosition; -CPlayerPed* pWeaponFirePed = NULL; - -bool CClientGame::PreWeaponFire(CPlayerPed* pPlayerPed, bool bStopIfUsingBulletSync) -{ - pWeaponFirePed = pPlayerPed; - - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pWeaponFirePed) - { - CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); - - // Get the CClientNetPlayer class with the specified player ped - CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(pWeaponFirePed, true); - - // Move both players to where they should be for shot compensation - if (pPlayer && !pPlayer->IsLocalPlayer()) - { - if (bStopIfUsingBulletSync && pPlayer->IsCurrentWeaponUsingBulletSync()) - return false; // Don't apply shot compensation & tell caller to not do bullet trace - - if (bShotCompensation) - { - if (!pVehicle || pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - // Warp back in time to where we were when this player shot (their latency) - - // We don't account for interpolation here, +250ms seems to work better - // ** Changed ajustment to +125ms as the position of this clients player on the firers screen - // has been changed. See CClientPed::UpdateTargetPosition() ** - CVector vecPosition; - unsigned short usLatency = (pPlayer->GetLatency() + 125); - g_pClientGame->m_pNetAPI->GetInterpolation(vecPosition, usLatency); - - // Move the entity back - if (pVehicle) - { - pVehicle->GetPosition(vecWeaponFirePosition); - pVehicle->SetPosition(vecPosition, false, false); - } - else - { - pLocalPlayer->GetPosition(vecWeaponFirePosition); - pLocalPlayer->SetPosition(vecPosition, false, false); - } - } - } - } - } - return true; -} - -void CClientGame::PostWeaponFire(void) -{ - // Send bullet sync with local damage info - if (g_bBulletFireVectorsValid) - { - g_bBulletFireVectorsValid = false; - CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer) - { - eWeaponType weaponType = pLocalPlayer->GetCurrentWeaponType(); - if (g_pClientGame->GetWeaponTypeUsesBulletSync(weaponType)) - { - g_pClientGame->GetNetAPI()->SendBulletSyncFire(weaponType, g_vecBulletFireStartPosition, g_vecBulletFireEndPosition, g_fApplyDamageLastAmount, - g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); - } - } - } - - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pWeaponFirePed) - { - CClientPed* pPed = g_pClientGame->GetPedManager()->Get(pWeaponFirePed, true, true); - if (pPed) - { - if (pPed->GetType() == CCLIENTPLAYER) - { - if (bShotCompensation) - { - // Restore compensated positions - if (!pPed->IsLocalPlayer()) - { - CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); - if (!pVehicle) - { - pLocalPlayer->SetPosition(vecWeaponFirePosition, false, false); - } - else if (pLocalPlayer->GetOccupiedVehicleSeat() == 0) - { - pVehicle->SetPosition(vecWeaponFirePosition, false, false); - } - } - } - } - - // Call some events - CWeapon* pWeapon = pPed->GetWeapon(); - if (pWeapon) - { - CVector vecCollision; - CClientEntity* pCollisionEntity = NULL; - - if (pPed->GetBulletImpactData(&pCollisionEntity, &vecCollision) == false) - { - CShotSyncData* pShotsyncData = pPed->m_shotSyncData; - CVector vecOrigin, vecTarget; - pPed->GetShotData(&vecOrigin, &vecTarget); - - CColPoint* pCollision = NULL; - CEntity* pCollisionGameEntity = NULL; - vecCollision = vecTarget; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionGameEntity); - if (bCollision && pCollision) - vecCollision = pCollision->GetPosition(); - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - - if (pCollisionGameEntity) - pCollisionEntity = g_pClientGame->m_pManager->FindEntity(pCollisionGameEntity); - } - else - { - pPed->ClearBulletImpactData(); - } - - // Call our lua event - CLuaArguments Arguments; - Arguments.PushNumber((double)pWeapon->GetType()); - Arguments.PushNumber((double)pWeapon->GetAmmoTotal()); - Arguments.PushNumber((double)pWeapon->GetAmmoInClip()); - Arguments.PushNumber((double)vecCollision.fX); - Arguments.PushNumber((double)vecCollision.fY); - Arguments.PushNumber((double)vecCollision.fZ); - if (pCollisionEntity) - Arguments.PushElement(pCollisionEntity); - else - Arguments.PushNil(); - - if (IS_PLAYER(pPed)) - { - CVector vecOrigin; - pPed->GetShotData(&vecOrigin); - Arguments.PushNumber((double)vecOrigin.fX); - Arguments.PushNumber((double)vecOrigin.fY); - Arguments.PushNumber((double)vecOrigin.fZ); - pPed->CallEvent("onClientPlayerWeaponFire", Arguments, true); - } - else - pPed->CallEvent("onClientPedWeaponFire", Arguments, true); - } - pPed->PostWeaponFire(); -#ifdef MTA_DEBUG - if (pPed->IsLocalPlayer() && g_pClientGame->m_bDoPaintballs) - { - g_pClientGame->DoPaintballs(); - } -#endif - } - } - pWeaponFirePed = NULL; -} - -void CClientGame::BulletImpact(CPed* pInitiator, CEntity* pVictim, const CVector* pStartPosition, const CVector* pEndPosition) -{ - // Got a local player model? - CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pInitiator) - { - // Find the client ped that initiated the bullet impact - CClientPed* pInitiatorPed = g_pClientGame->GetPedManager()->Get(dynamic_cast(pInitiator), true, true); - - if (pInitiatorPed) - { - // Calculate the collision of the bullet - CVector vecCollision; - CColPoint* pCollision = NULL; - bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(pStartPosition, pEndPosition, &pCollision, NULL); - if (bCollision && pCollision) - { - vecCollision = pCollision->GetPosition(); - } - else - { - // If we don't have a collision, use the end of the ray that the bullet is tracing. - vecCollision = *pEndPosition; - } - - // Destroy the colpoint - if (pCollision) - { - pCollision->Destroy(); - } - - // Find the client entity for the victim. - CClientEntity* pClientVictim = NULL; - if (pVictim) - { - pClientVictim = g_pClientGame->m_pManager->FindEntity(pVictim); - } - - // Store the data in the bullet fire initiator. - pInitiatorPed->SetBulletImpactData(pClientVictim, vecCollision); - } - } -} - -void CClientGame::BulletFire(CPed* pInitiator, const CVector* pStartPosition, const CVector* pEndPosition) -{ - g_bBulletFireVectorsValid = false; - g_fApplyDamageLastAmount = 0; - g_ucApplyDamageLastHitZone = 0; - g_pApplyDamageLastDamagedPed = NULL; - - // Got a local player model? - CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; - if (pLocalPlayer && pLocalPlayer->GetGamePlayer() == pInitiator) - { - g_bBulletFireVectorsValid = true; - g_vecBulletFireStartPosition = *pStartPosition; - g_vecBulletFireEndPosition = *pEndPosition; - } -} - -bool CClientGame::StaticProcessPacket(unsigned char ucPacketID, NetBitStreamInterface& bitStream) -{ - if (g_pClientGame) - { - g_pCore->UpdateDummyProgress(); - g_pClientGame->GetManager()->GetPacketRecorder()->RecordPacket(ucPacketID, bitStream); - return g_pClientGame->m_pPacketHandler->ProcessPacket(ucPacketID, bitStream); - } - - return false; -} - -void CClientGame::SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin) -{ - SPositionSync position(false); - position.data.vecPosition = vecPosition; - - // Create the bitstream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write our origin id - if (pOrigin) - { - pBitStream->WriteBit(true); - pBitStream->Write(pOrigin->GetID()); - - // Convert position - CVector vecTemp; - pOrigin->GetPosition(vecTemp); - position.data.vecPosition -= vecTemp; - } - else - pBitStream->WriteBit(false); - - // Write the position and the type - pBitStream->Write(&position); - - SExplosionTypeSync explosionType; - explosionType.data.uiType = Type; - pBitStream->Write(&explosionType); - - // Destroy it - g_pNet->SendPacket(PACKET_ID_EXPLOSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -void CClientGame::SendFireSync(CFire* pFire) -{ -#ifdef MTA_DEBUG - CVector* vecPos = pFire->GetPosition(); - if (vecPos) - g_pCore->GetConsole()->Printf("we're sending fire: %f %f %f %f", pFire->GetStrength(), vecPos->fX, vecPos->fY, vecPos->fZ); - else - g_pCore->GetConsole()->Printf("we're sending a fire!"); -#endif -} - -void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) -{ - // Create the bitstream - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - SPositionSync origin(false); - CClientEntity* pOriginSource = NULL; - eWeaponType weaponType = pProjectile->GetWeaponType(); - CClientEntity* pTarget = pProjectile->GetTargetEntity(); - origin.data.vecPosition = *pProjectile->GetOrigin(); - - // Is this a heatseaking missile with a target? sync it relative to the target - if (weaponType == WEAPONTYPE_ROCKET_HS && pTarget && !pTarget->IsLocalEntity()) - pOriginSource = pTarget; - - // Write the source of the projectile, if it has - if (pOriginSource) - { - CVector vecTemp; - pOriginSource->GetPosition(vecTemp); - origin.data.vecPosition -= vecTemp; - - pBitStream->WriteBit(true); - pBitStream->Write(pOriginSource->GetID()); - } - else - pBitStream->WriteBit(false); - - // Write the origin position - pBitStream->Write(&origin); - - // Write the creator weapon type - SWeaponTypeSync weaponTypeSync; - weaponTypeSync.data.ucWeaponType = static_cast(weaponType); - pBitStream->Write(&weaponTypeSync); - - // Write the projectile's model - if (pBitStream->Version() >= 0x4F) - if (pBitStream->Version() >= 0x52 || pOriginSource) // Fix possible error for 0x51 server - pBitStream->Write(pProjectile->GetModel()); - - switch (weaponType) - { - case WEAPONTYPE_GRENADE: - case WEAPONTYPE_TEARGAS: - case WEAPONTYPE_MOLOTOV: - case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: - { - SFloatSync<7, 17> projectileForce; - projectileForce.data.fValue = pProjectile->GetForce(); - pBitStream->Write(&projectileForce); - - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); - - break; - } - case WEAPONTYPE_ROCKET: - case WEAPONTYPE_ROCKET_HS: - { - if (pTarget) - { - pBitStream->WriteBit(true); - pBitStream->Write(pTarget->GetID()); - } - else - pBitStream->WriteBit(false); - - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); - - SRotationRadiansSync rotation(true); - pProjectile->GetRotationRadians(rotation.data.vecRotation); - pBitStream->Write(&rotation); - - break; - } - case WEAPONTYPE_FLARE: - case WEAPONTYPE_FREEFALL_BOMB: - break; - } - g_pNet->SendPacket(PACKET_ID_PROJECTILE, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - - // Destroy it - g_pNet->DeallocateNetBitStream(pBitStream); - } -} - -void CClientGame::ResetAmmoInClip(void) -{ - memset(&m_wasWeaponAmmoInClip[0], 0, sizeof(m_wasWeaponAmmoInClip)); -} - -void CClientGame::ResetMapInfo(void) -{ - // Restore some game stuff - // Keybinds - g_pCore->GetKeyBinds()->SetAllControlsEnabled(true, true, true); - - // Radarmap - m_pRadarMap->SetForcedState(false); - - // Camera - m_pCamera->FadeOut(0.0f, 0, 0, 0); - g_pGame->GetWorld()->SetCurrentArea(0); - m_pCamera->SetFocusToLocalPlayer(); - g_pGame->GetSettings()->ResetFieldOfViewFromScript(); - - // Dimension - SetAllDimensions(0); - - // Hud - g_pGame->GetHud()->SetComponentVisible(HUD_ALL, true); - // Disable area names as they are on load until camera unfades - g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); - g_pGame->GetHud()->SetComponentVisible(HUD_VITAL_STATS, false); - - m_bHudAreaNameDisabled = false; - - // Gravity - g_pMultiplayer->SetLocalPlayerGravity(DEFAULT_GRAVITY); - g_pMultiplayer->SetGlobalGravity(DEFAULT_GRAVITY); - g_pGame->SetGravity(DEFAULT_GRAVITY); - - // Gamespeed - SetGameSpeed(DEFAULT_GAME_SPEED); - - // Game minute duration - SetMinuteDuration(DEFAULT_MINUTE_DURATION); - - // Wanted-level - SetWanted(0); - - // Money - SetMoney(0, true); - - // Weather - m_pBlendedWeather->SetWeather(0); - - // Rain - g_pGame->GetWeather()->ResetAmountOfRain(); - - // Wind - g_pMultiplayer->RestoreWindVelocity(); - - // Far clip distance - g_pMultiplayer->RestoreFarClipDistance(); - - // Near clip distance - g_pMultiplayer->RestoreNearClipDistance(); - - // Fog distance - g_pMultiplayer->RestoreFogDistance(); - - // Vehicles LOD distance - g_pGame->GetSettings()->ResetVehiclesLODDistance(); - - // Peds LOD distance - g_pGame->GetSettings()->ResetPedsLODDistance(); - - // Sun color - g_pMultiplayer->ResetSunColor(); - - // Sun size - g_pMultiplayer->ResetSunSize(); - - // Sky-gradient - g_pMultiplayer->ResetSky(); - - // Heat haze - g_pMultiplayer->ResetHeatHaze(); - - // Water-colour - g_pMultiplayer->ResetWater(); - - // Water - GetManager()->GetWaterManager()->ResetWorldWaterLevel(); - - // Re-enable interior sounds and furniture - g_pMultiplayer->SetInteriorSoundsEnabled(true); - for (int i = 0; i <= 4; ++i) - g_pMultiplayer->SetInteriorFurnitureEnabled(i, true); - - // Clouds - g_pMultiplayer->SetCloudsEnabled(true); - g_pClientGame->SetCloudsEnabled(true); - - // Birds - g_pMultiplayer->DisableBirds(false); - g_pClientGame->SetBirdsEnabled(true); - - // Ambient sounds - g_pGame->GetAudio()->ResetAmbientSounds(); - - // World sounds - g_pGame->GetAudio()->ResetWorldSounds(); - - // Cheats - g_pGame->ResetCheats(); - - // Players - m_pPlayerManager->ResetAll(); - - // Jetpack max height - g_pGame->GetWorld()->SetJetpackMaxHeight(DEFAULT_JETPACK_MAXHEIGHT); - - // Aircraft max height - g_pGame->GetWorld()->SetAircraftMaxHeight(DEFAULT_AIRCRAFT_MAXHEIGHT); - - // Aircraft max velocity - g_pGame->GetWorld()->SetAircraftMaxVelocity(DEFAULT_AIRCRAFT_MAXVELOCITY); - - // Moon size - g_pMultiplayer->ResetMoonSize(); - - // Disable the change of any player stats - g_pMultiplayer->SetLocalStatsStatic(true); - - // Restore blur -#ifdef MTA_DEBUG - g_pGame->SetBlurLevel(0); -#else - g_pGame->SetBlurLevel(DEFAULT_BLUR_LEVEL); -#endif - - // Close all garages - CGarage* pGarage = NULL; - CGarages* pGarages = g_pCore->GetGame()->GetGarages(); - - for (unsigned char i = 0; (pGarage = pGarages->GetGarage(i)) != NULL; i++) - { - pGarage->SetOpen(false); - } - - // Player specific stuff - if (m_pLocalPlayer) - { - // Interior - m_pLocalPlayer->SetInterior(0); - - // Headless state - m_pLocalPlayer->SetHeadless(false); - - // Frozen state - m_pLocalPlayer->SetFrozen(false); - - // Voice - short sVoiceType, sVoiceID; - m_pLocalPlayer->GetModelInfo()->GetVoice(&sVoiceType, &sVoiceID); - m_pLocalPlayer->SetVoice(sVoiceType, sVoiceID); - - m_pLocalPlayer->DestroySatchelCharges(false, true); - // Tell the server we want to destroy our satchels - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - g_pNet->SendPacket(PACKET_ID_DESTROY_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, - AnimationId animID) -{ - if (Ped && Ped->GetHealth() == 0.0f) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - // Write some death info - pBitStream->WriteCompressed(animGroup); - pBitStream->WriteCompressed(animID); - - pBitStream->Write(damagerID); - - SWeaponTypeSync weapon; - weapon.data.ucWeaponType = ucWeapon; - pBitStream->Write(&weapon); - - SBodypartSync bodyPart; - bodyPart.data.uiBodypart = ucBodyPiece; - pBitStream->Write(&bodyPart); - - // Write the position we died in - SPositionSync pos(false); - Ped->GetPosition(pos.data.vecPosition); - pBitStream->Write(&pos); - - pBitStream->Write(Ped->GetID()); - - // The ammo in our weapon and write the ammo total - CWeapon* pPlayerWeapon = Ped->GetWeapon(); - SWeaponAmmoSync ammo(ucWeapon, true, false); - ammo.data.usTotalAmmo = 0; - if (pPlayerWeapon) - ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); - pBitStream->Write(&ammo); - - // Send the packet - g_pNet->SendPacket(PACKET_ID_PED_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, AnimationId animID) -{ - // Are we not already marked as dead? and have we run out of health? - if (!m_pLocalPlayer->IsDeadOnNetwork() && m_pLocalPlayer->GetHealth() == 0.0f) - { - // Send the "i am dead" packet - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (pBitStream) - { - m_pLocalPlayer->SetDeadOnNetwork(true); - - // Call the onClientPlayerWasted event - CClientEntity* pKiller = (damagerID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(damagerID) : NULL; - CLuaArguments Arguments; - if (pKiller) - Arguments.PushElement(pKiller); - else - Arguments.PushBoolean(false); - if (ucWeapon != 0xFF) - Arguments.PushNumber(ucWeapon); - else - Arguments.PushBoolean(false); - if (ucBodyPiece != 0xFF) - Arguments.PushNumber(ucBodyPiece); - else - Arguments.PushBoolean(false); - Arguments.PushBoolean(false); - m_pLocalPlayer->CallEvent("onClientPlayerWasted", Arguments, true); - - // Write some death info - pBitStream->WriteCompressed(animGroup); - pBitStream->WriteCompressed(animID); - - pBitStream->Write(damagerID); - - SWeaponTypeSync weapon; - weapon.data.ucWeaponType = ucWeapon; - pBitStream->Write(&weapon); - - SBodypartSync bodyPart; - bodyPart.data.uiBodypart = ucBodyPiece; - pBitStream->Write(&bodyPart); - - // Write the position we died in - SPositionSync pos(false); - m_pLocalPlayer->GetPosition(pos.data.vecPosition); - pBitStream->Write(&pos); - - // The ammo in our weapon and write the ammo total - CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(); - SWeaponAmmoSync ammo(ucWeapon, true, false); - ammo.data.usTotalAmmo = 0; - if (pPlayerWeapon) - ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); - pBitStream->Write(&ammo); - - // Send the packet - g_pNet->SendPacket(PACKET_ID_PLAYER_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(pBitStream); - } - } -} - -bool CClientGame::OnKeyDown(CGUIKeyEventArgs Args) -{ - return true; -} - -bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - const char* szState = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIClick", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseDoubleClick(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - const char* szState = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushString(szState); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIDoubleClick", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIMouseDown", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseButtonUp(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - const char* szButton = NULL; - switch (Args.button) - { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; - } - - if (szButton) - { - CLuaArguments Arguments; - Arguments.PushString(szButton); - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - { - pGUIElement->CallEvent("onClientGUIMouseUp", Arguments, true); - } - } - - return true; -} - -bool CClientGame::OnMouseMove(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseMove", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseEnter(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - if (Args.pSwitchedWindow) - { - CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); - if (GetGUIManager()->Exists(pGUISwitchedElement)) - Arguments.PushElement(pGUISwitchedElement); - } - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseEnter", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseLeave(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.position.fX); - Arguments.PushNumber(Args.position.fY); - if (Args.pSwitchedWindow) - { - CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); - if (GetGUIManager()->Exists(pGUISwitchedElement)) - Arguments.PushElement(pGUISwitchedElement); - } - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseLeave", Arguments, true); - - return true; -} - -bool CClientGame::OnMouseWheel(CGUIMouseEventArgs Args) -{ - if (!Args.pWindow) - return false; - - CLuaArguments Arguments; - Arguments.PushNumber(Args.wheelChange); - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientMouseWheel", Arguments, true); - - return true; -} - -bool CClientGame::OnMove(CGUIElement* pElement) -{ - if (!pElement) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); - if (pGUIElement && GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientGUIMove", Arguments, true); - - return true; -} - -bool CClientGame::OnSize(CGUIElement* pElement) -{ - if (!pElement) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); - if (GetGUIManager()->Exists(pGUIElement)) - pGUIElement->CallEvent("onClientGUISize", Arguments, true); - - return true; -} - -bool CClientGame::OnFocusGain(CGUIFocusEventArgs Args) -{ - if (!Args.pActivatedWindow) - return false; - - CLuaArguments Arguments; - - CClientGUIElement* pActivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pActivatedWindow); - - if (Args.pDeactivatedWindow) - { - CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); - if (GetGUIManager()->Exists(pDeactivatedGUIElement)) - pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); - } - - if (GetGUIManager()->Exists(pActivatedGUIElement)) - pActivatedGUIElement->CallEvent("onClientGUIFocus", Arguments, true); - - return true; -} - -bool CClientGame::OnFocusLoss(CGUIFocusEventArgs Args) -{ - if (!Args.pDeactivatedWindow) - return false; - - CLuaArguments Arguments; - - if (Args.pActivatedWindow) - { - // pDeactivatedWindow looses focus but an other window is now gaining it so we let CClientGame::OnFocusGain trigger both events in the right order - return true; - } - - CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); - if (GetGUIManager()->Exists(pDeactivatedGUIElement)) - pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); - - return true; -} - -// -// Display a progress dialog if a big packet is coming in -// -void CClientGame::NotifyBigPacketProgress(unsigned long ulBytesReceived, unsigned long ulTotalSize) -{ - // Should display progress box? - if (ulBytesReceived >= ulTotalSize || ulTotalSize < 50000) - { - if (m_bReceivingBigPacket) - { - // Switch off progress box - m_bReceivingBigPacket = false; - m_pBigPacketTransferBox->Hide(); - } - return; - } - - // Update progress box - if (!m_bReceivingBigPacket || m_ulBigPacketSize != ulTotalSize) - { - m_bReceivingBigPacket = true; - m_ulBigPacketSize = ulTotalSize; - m_pBigPacketTransferBox->Hide(); - m_pBigPacketTransferBox->AddToTotalSize(ulTotalSize); - m_pBigPacketTransferBox->Show(); - } - - m_pBigPacketTransferBox->DoPulse(); - m_pBigPacketTransferBox->SetInfo(std::min(ulTotalSize, ulBytesReceived), CTransferBox::PACKET); -} - -bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled) -{ - if (ucGlitch < NUM_GLITCHES && bEnabled != m_Glitches[ucGlitch]) - { - m_Glitches[ucGlitch] = bEnabled; - if (ucGlitch == GLITCH_QUICKRELOAD) - g_pMultiplayer->DisableQuickReload(!bEnabled); - if (ucGlitch == GLITCH_CLOSEDAMAGE) - g_pMultiplayer->DisableCloseRangeDamage(!bEnabled); - return true; - } - return false; -} - -bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) -{ - return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; -} - -bool CClientGame::SetCloudsEnabled(bool bEnabled) -{ - m_bCloudsEnabled = bEnabled; - return true; -} -bool CClientGame::GetCloudsEnabled(void) -{ - return m_bCloudsEnabled; -} - -bool CClientGame::SetBirdsEnabled(bool bEnabled) -{ - m_bBirdsEnabled = bEnabled; - return true; -} -bool CClientGame::GetBirdsEnabled(void) -{ - return m_bBirdsEnabled; -} - -#pragma code_seg(".text") -bool CClientGame::VerifySADataFiles(int iEnableClientChecks) -{ - int& iCheckStatus = g_pGame->GetCheckStatus(); - - if (!g_pGame->VerifySADataFileNames()) - iCheckStatus |= (1 << 11); - - __declspec(allocate(".text")) static char szVerifyData[][32] = {"data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", - "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", - "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", - "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", - "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", - "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", - "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", - "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", - "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", - "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", - "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", - "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74"}; - - CMD5Hasher hasher; - for (int i = 0; i < NUMELMS(szVerifyData); i += 2) - { - MD5 md5; - if (!hasher.Calculate(szVerifyData[i], md5) || memcmp(md5.data, szVerifyData[i + 1], 0x10)) - { - iCheckStatus |= (1 << i); - } - } - - if (iCheckStatus & iEnableClientChecks) - { - g_pCore->InitiateDataFilesFix(); - g_pCore->GetModManager()->RequestUnload(); - return false; - } - - return true; -} - -void CClientGame::InitVoice(bool bEnabled, unsigned int uiServerSampleRate, unsigned char ucQuality, unsigned int uiBitrate) -{ - if (m_pVoiceRecorder) - { - m_pVoiceRecorder->Init(bEnabled, uiServerSampleRate, ucQuality, uiBitrate); - } -} - -// -// If debug render mode is on, allow each element in range to draw some stuff -// -void CClientGame::DebugElementRender(void) -{ - if (!GetDevelopmentMode() || !GetShowCollision()) - return; - - CVector vecCameraPos; - m_pCamera->GetPosition(vecCameraPos); - float fDrawRadius = 200.f; - - // Get all entities within range - CClientEntityResult result; - GetClientSpatialDatabase()->SphereQuery(result, CSphere(vecCameraPos, fDrawRadius)); - - // For each entity found - for (CClientEntityResult::const_iterator it = result.begin(); it != result.end(); ++it) - { - CClientEntity* pEntity = *it; - if (pEntity->GetParent()) - pEntity->DebugRender(vecCameraPos, fDrawRadius); - } -} - -////////////////////////////////////////////////////////////////// -// Click -// -void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString& strTag, uint uiQuality, uint uiMaxBandwidth, uint uiMaxPacketSize, - CResource* pResource, uint uiServerSentTime) -{ - if (!pResource) - return; - - bool bAllowScreenUploadEnabled = 1; - g_pCore->GetCVars()->Get("allow_screen_upload", bAllowScreenUploadEnabled); - bool bWindowMinimized = g_pCore->IsWindowMinimized(); - - if (bWindowMinimized || !bAllowScreenUploadEnabled) - { - // If alt-tabbed or opt-out - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - if (!bAllowScreenUploadEnabled) - pBitStream->Write((uchar)EPlayerScreenShotResult::DISABLED); - else - pBitStream->Write((uchar)EPlayerScreenShotResult::MINIMIZED); - pBitStream->Write(uiServerSentTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); - g_pNet->DeallocateNetBitStream(pBitStream); - } - else - { - // Do grab and send - SScreenShotArgs screenShotArgs; - screenShotArgs.uiMaxBandwidth = uiMaxBandwidth; - screenShotArgs.uiMaxPacketSize = uiMaxPacketSize; - screenShotArgs.usResourceNetId = pResource->GetNetID(); - screenShotArgs.strTag = strTag; - screenShotArgs.uiServerSentTime = uiServerSentTime; - m_ScreenShotArgList.push_back(screenShotArgs); - g_pCore->GetGraphics()->GetScreenGrabber()->QueueScreenShot(uiSizeX, uiSizeY, uiQuality, &CClientGame::StaticGottenPlayerScreenShot); - } -} - -////////////////////////////////////////////////////////////////// -// Callback from TakePlayerScreendsShot -// -void CClientGame::StaticGottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strError) -{ - if (g_pClientGame) - g_pClientGame->GottenPlayerScreenShot(pBuffer, uiTimeSpentInQueue, strError); -} - -////////////////////////////////////////////////////////////////// -// Break data into packets and put into delayed send list -// -void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strInError) -{ - SString strError = strInError; - - // Pop saved args - if (m_ScreenShotArgList.empty()) - return; - - SScreenShotArgs screenShotArgs = m_ScreenShotArgList.front(); - m_ScreenShotArgList.pop_front(); - const uint uiMaxBandwidth = Clamp(100, screenShotArgs.uiMaxBandwidth, 1000000); - const uint uiMaxPacketSize = Clamp(100, screenShotArgs.uiMaxPacketSize, 100000); - const ushort usResourceNetId = screenShotArgs.usResourceNetId; - const SString strTag = screenShotArgs.strTag; - const uint uiServerGrabTime = screenShotArgs.uiServerSentTime + uiTimeSpentInQueue; - - // Silently ignore if resource has been stopped - CResource* pResource = GetResourceManager()->GetResourceFromNetID(usResourceNetId); - if (!pResource) - return; - - // Validate buffer - if (strError.empty()) - { - if (!pBuffer || pBuffer->GetSize() == 0) - strError = "Buffer empty"; - } - - // Handle error - if (!strError.empty()) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->Write((uchar)EPlayerScreenShotResult::ERROR_); - pBitStream->Write(uiServerGrabTime); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - if (pBitStream->Version() >= 0x053) - pBitStream->WriteString(strError); - g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); - g_pNet->DeallocateNetBitStream(pBitStream); - return; - } - - // Calc constants stuff - const uint uiSendRate = Clamp(5, uiMaxBandwidth / uiMaxPacketSize, 20); - const long long llPacketInterval = 1000 / uiSendRate; - const uint uiTotalByteSize = pBuffer->GetSize(); - const char* pData = pBuffer->GetData(); - const uint uiBytesPerPart = std::min(std::min(std::max(100U, uiMaxBandwidth / uiSendRate), uiTotalByteSize), 30000U); - const uint uiNumParts = std::max(1U, (uiTotalByteSize + uiBytesPerPart - 1) / uiBytesPerPart); - - // Calc variables stuff - CTickCount tickCount = CTickCount::Now() + CTickCount(llPacketInterval); - uint uiBytesRemaining = uiTotalByteSize; - m_usNextScreenShotId++; - - // Make each packet - for (uint i = 0; i < uiNumParts; i++) - { - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - - ushort usPartNumber = i; - ushort usBytesThisPart = std::min(uiBytesRemaining, uiBytesPerPart); - assert(usBytesThisPart != 0); - - pBitStream->Write((uchar)EPlayerScreenShotResult::SUCCESS); - pBitStream->Write(m_usNextScreenShotId); - pBitStream->Write(usPartNumber); - pBitStream->Write(usBytesThisPart); - pBitStream->Write(pData, usBytesThisPart); - - // Write more info if first part - if (usPartNumber == 0) - { - pBitStream->Write(uiServerGrabTime); - pBitStream->Write(uiTotalByteSize); - pBitStream->Write((ushort)uiNumParts); - if (pBitStream->Version() >= 0x053) - pBitStream->Write(pResource->GetNetID()); - else - pBitStream->WriteString(pResource->GetName()); - pBitStream->WriteString(strTag); - } - - // Add to delay send list - SDelayedPacketInfo delayedPacketInfo; - delayedPacketInfo.useTickCount = tickCount; - delayedPacketInfo.ucPacketID = PACKET_ID_PLAYER_SCREENSHOT; - delayedPacketInfo.pBitStream = pBitStream; - delayedPacketInfo.packetPriority = PACKET_PRIORITY_LOW; - delayedPacketInfo.packetReliability = PACKET_RELIABILITY_RELIABLE_ORDERED; - delayedPacketInfo.packetOrdering = PACKET_ORDERING_DATA_TRANSFER; - m_DelayedSendList.push_back(delayedPacketInfo); - - // Increment stuff - pData += usBytesThisPart; - uiBytesRemaining -= usBytesThisPart; - tickCount += CTickCount(llPacketInterval); - } - - assert(uiBytesRemaining == 0); -} - -////////////////////////////////////////////////////////////////// -// Process delay send list -// -void CClientGame::ProcessDelayedSendList(void) -{ - CTickCount tickCount = CTickCount::Now(); - - while (!m_DelayedSendList.empty()) - { - SDelayedPacketInfo& info = m_DelayedSendList.front(); - if (info.useTickCount > tickCount) - break; - - g_pNet->SendPacket(info.ucPacketID, info.pBitStream, info.packetPriority, info.packetReliability, info.packetOrdering); - g_pNet->DeallocateNetBitStream(info.pBitStream); - m_DelayedSendList.pop_front(); - } -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetWeaponTypesUsingBulletSync -// -// Set whether the local player will send bulletsync messages for the supplied weapon type -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetWeaponTypesUsingBulletSync(const std::set& weaponTypesUsingBulletSync) -{ - m_weaponTypesUsingBulletSync = weaponTypesUsingBulletSync; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::GetWeaponTypeUsesBulletSync -// -// Get whether the local player should send bulletsync messages for the supplied weapon type -// -////////////////////////////////////////////////////////////////// -bool CClientGame::GetWeaponTypeUsesBulletSync(eWeaponType weaponType) -{ - return MapContains(m_weaponTypesUsingBulletSync, weaponType); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetDevelopmentMode -// -// Special mode which enables commands such as showcol and showsound -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetDevelopmentMode(bool bEnable, bool bEnableWeb) -{ - m_bDevelopmentMode = bEnable; - - if (m_bDevelopmentMode) - g_pGame->GetAudio()->SetWorldSoundHandler(CClientGame::StaticWorldSoundHandler); - else - g_pGame->GetAudio()->SetWorldSoundHandler(NULL); - - if (g_pCore->IsWebCoreLoaded()) - g_pCore->GetWebCore()->SetTestModeEnabled(bEnableWeb); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::StaticWorldSoundHandler -// -// Handle callback from CAudioSA when a world sound is played -// -////////////////////////////////////////////////////////////////// -void CClientGame::StaticWorldSoundHandler(uint uiGroup, uint uiIndex) -{ - g_pClientGame->WorldSoundHandler(uiGroup, uiIndex); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::WorldSoundHandler -// -// Handle callback from CAudioSA when a world sound is played -// -////////////////////////////////////////////////////////////////// -void CClientGame::WorldSoundHandler(uint uiGroup, uint uiIndex) -{ - if (m_bShowSound) - m_pScriptDebugging->LogInformation(NULL, "%s - World sound group:%d index:%d", *GetLocalTimeString(false, true), uiGroup, uiIndex); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::IsUsingAlternatePulseOrder -// -// Returns true if should be using alternate pulse order -// -////////////////////////////////////////////////////////////////// -bool CClientGame::IsUsingAlternatePulseOrder(bool bAdvanceDelayCounter) -{ - if (m_MiscGameSettings.bUseAltPulseOrder) - { - // Only actually start using alternate pulse order after 100 frames - if (m_uiAltPulseOrderCounter >= 100) - return true; - else if (bAdvanceDelayCounter) - m_uiAltPulseOrderCounter++; - } - - return false; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::OutputServerInfo -// -// Output info about the connected server for player -// -////////////////////////////////////////////////////////////////// -void CClientGame::OutputServerInfo(void) -{ - SString strTotalOutput; - strTotalOutput += SString("Server info for %s", g_pNet->GetConnectedServer(true)); - strTotalOutput += "\n"; - strTotalOutput += SString("Ver: %s\n", *GetServerVersionSortable()); - strTotalOutput += SString("AC: %s\n", *m_strACInfo); - - { - SString strVoice; - if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) - strVoice += SString("Enabled - Sample rate:%d Quality:%d", m_pVoiceRecorder->GetSampleRate(), m_pVoiceRecorder->GetSampleQuality()); - else - strVoice += "Disabled"; - - strTotalOutput += SString("Voice: %s\n", *strVoice); - } - - { - SString strEnabledGlitches; - const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", - "Bad driveby hitboxes", "Quick stand"}; - for (uint i = 0; i < NUM_GLITCHES; i++) - { - if (IsGlitchEnabled(i)) - { - if (!strEnabledGlitches.empty()) - strEnabledGlitches += ", "; - if (i < NUMELMS(szGlitchNames)) - strEnabledGlitches += szGlitchNames[i]; - else - strEnabledGlitches += SString("Unknown(#%d)", i + 1); - } - } - if (strEnabledGlitches.empty()) - strEnabledGlitches = "None"; - strTotalOutput += SString("Glitches: %s\n", *strEnabledGlitches); - } - - { - SString strEnabledBulletSync; - for (std::set::iterator iter = m_weaponTypesUsingBulletSync.begin(); iter != m_weaponTypesUsingBulletSync.end(); ++iter) - { - eWeaponType weaponType = *iter; - if (!strEnabledBulletSync.empty()) - strEnabledBulletSync += ","; - strEnabledBulletSync += SString("%d", weaponType); - } - if (strEnabledBulletSync.empty()) - strEnabledBulletSync = "None"; - strTotalOutput += SString("Bullet sync weapons: %s\n", *strEnabledBulletSync); - } - - { - SString strVehExtrapolate; - if (m_VehExtrapolateSettings.bEnabled) - strVehExtrapolate += SString("Amount:%d%% (LimitMs:%d)", m_VehExtrapolateSettings.iScalePercent, m_VehExtrapolateSettings.iMaxMs); - else - strVehExtrapolate += "Disabled"; - - strTotalOutput += SString("Vehicle extrapolation: %s\n", *strVehExtrapolate); - } - - { - SString strTickRates; - strTickRates += SString("Plr:%d Cam:%d Ped:%d UnocVeh:%d KeyRot:%d KeyJoy:%d", g_TickRateSettings.iPureSync, g_TickRateSettings.iCamSync, - g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, - g_TickRateSettings.iKeySyncAnalogMove); - - strTotalOutput += SString("Tick rates: %s\n", *strTickRates); - } - - { - SString strSyncerDists; - strSyncerDists += SString("Ped:%d UnoccupiedVehicle:%d ", g_TickRateSettings.iPedSyncerDistance, g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); - - strTotalOutput += SString("Syncer distances: %s\n", *strSyncerDists); - } - - g_pCore->GetConsole()->Print(strTotalOutput); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::TellServerSomethingImportant -// -// Report misc important warnings/errors to the current server -// -////////////////////////////////////////////////////////////////// -void CClientGame::TellServerSomethingImportant(uint uiId, const SString& strMessage, uint uiSendLimitForThisId) -{ - g_pCore->GetConsole()->Print(strMessage); - AddReportLog(3400 + uiId, strMessage + g_pNet->GetConnectedServer(true), 10); - - if (uiSendLimitForThisId) - { - uint& uiCount = MapGet(m_SentMessageIds, uiId); - if (uiCount++ >= uiSendLimitForThisId) - return; - } - - NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); - pBitStream->WriteString(SString("%d,%s", uiId, *strMessage)); - g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE); - g_pNet->DeallocateNetBitStream(pBitStream); -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::ChangeFloatPrecision -// -// Manage the change to high floating point precision -// -////////////////////////////////////////////////////////////////// -void CClientGame::ChangeFloatPrecision(bool bHigh) -{ - if (bHigh) - { - // Switch to 53 bit floating point precision on the first call - if (m_uiPrecisionCallDepth++ == 0) - _controlfp(_PC_53, MCW_PC); - } - else - { - // Even though is should never happen, m_uiPrecisionCallDepth is sometimes zero here - dassert(m_uiPrecisionCallDepth != 0); - if (m_uiPrecisionCallDepth != 0) - m_uiPrecisionCallDepth--; - // Switch back to 24 bit floating point precision on the last call - if (m_uiPrecisionCallDepth == 0) - _controlfp(_PC_24, MCW_PC); - } -} - -bool CClientGame::IsHighFloatPrecision(void) const -{ - return m_uiPrecisionCallDepth != 0; -} - -AnimationId CClientGame::DrivebyAnimationHandler(AnimationId animId, AssocGroupId animGroupId) -{ - // Only apply if all clients support the fix - if (!GetMiscGameSettings().bAllowBadDrivebyHitboxFix) - return animId; - - // If the glitch is enabled, don't apply the fix - if (IsGlitchEnabled(GLITCH_BADDRIVEBYHITBOX)) - return animId; - - // Bad animations are 232 and 236 of assoc group 72 - if (animGroupId != 72) - return animId; - - if (animId == 232) - return 235; - else if (animId == 236) - return 231; - - return animId; -} - -////////////////////////////////////////////////////////////////// -// -// CClientGame::SetFileCacheRoot -// -// Figure out which directory to use for the client resource file cache -// -////////////////////////////////////////////////////////////////// -void CClientGame::SetFileCacheRoot(void) -{ - if (g_pCore->GetCVars()->GetValue("share_file_cache") == false) - { - // Not sharing, so use current mod directory - m_strFileCacheRoot = GetModRoot(); - AddReportLog(7410, SString("CClientGame::SetFileCacheRoot - Not shared '%s'", *m_strFileCacheRoot)); - } - else - { - // Get shared directory - SString strFileCachePath = GetCommonRegistryValue("", "File Cache Path"); - // Check exists - if (!strFileCachePath.empty() && DirectoryExists(strFileCachePath)) - { - // Check writable - SString strTestFileName = PathJoin(strFileCachePath, "resources", "_test.tmp"); - if (FileSave(strTestFileName, "x")) - { - FileDelete(strTestFileName); - strTestFileName = PathJoin(strFileCachePath, "priv", "_test.tmp"); - if (FileSave(strTestFileName, "x")) - { - FileDelete(strTestFileName); - // Use shared directory - m_strFileCacheRoot = strFileCachePath; - AddReportLog(7411, SString("CClientGame::SetFileCacheRoot - Is shared '%s'", *m_strFileCacheRoot)); - return; - } - } - } - - // Otherwise set this install mod directory as shared - m_strFileCacheRoot = GetModRoot(); - SetCommonRegistryValue("", "File Cache Path", m_strFileCacheRoot); - - if (strFileCachePath.empty()) - AddReportLog(7412, SString("CClientGame::SetFileCacheRoot - Initial setting '%s'", *m_strFileCacheRoot)); - else - AddReportLog(7413, SString("CClientGame::SetFileCacheRoot - Change shared from '%s' to '%s'", *strFileCachePath, *m_strFileCacheRoot)); - } -} - -bool CClientGame::TriggerBrowserRequestResultEvent(const std::unordered_set& newPages) -{ - CLuaArguments Arguments; - CLuaArguments LuaTable; - int i = 0; - - for (auto& domain : newPages) - { - LuaTable.PushNumber(++i); - LuaTable.PushString(domain); - } - Arguments.PushTable(&LuaTable); - - return GetRootEntity()->CallEvent("onClientBrowserWhitelistChange", Arguments, false); -} - -void CClientGame::RestreamModel(unsigned short usModel) -{ - // Is this a vehicle ID? - if (CClientVehicleManager::IsValidModel(usModel)) - { - // Stream the vehicles of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetVehicleManager()->RestreamVehicles(usModel); - } - - // Is this an object ID? - else if (CClientObjectManager::IsValidModel(usModel)) - { - if (CClientPedManager::IsValidWeaponModel(usModel)) - { - // Stream the weapon of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamWeapon(usModel); - m_pManager->GetPickupManager()->RestreamPickups(usModel); - } - // Stream the objects of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetObjectManager()->RestreamObjects(usModel); - g_pGame->GetModelInfo(usModel)->RestreamIPL(); - } - // Is this an ped ID? - else if (CClientPlayerManager::IsValidModel(usModel)) - { - // Stream the ped of that model out so we have no - // loaded when we do the restore. The streamer will - // eventually stream them back in with async loading. - m_pManager->GetPedManager()->RestreamPeds(usModel); - } - else - - // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect - if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) - m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); -} - -void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) -{ - m_mapOfIfpPointers[u32BlockNameHash] = pIFP; -} - -std::shared_ptr CClientGame::GetIFPPointerFromMap(const unsigned int u32BlockNameHash) -{ - auto it = m_mapOfIfpPointers.find(u32BlockNameHash); - if (it != m_mapOfIfpPointers.end()) - { - return it->second; - } - return nullptr; -} - -void CClientGame::RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash) -{ - m_mapOfIfpPointers.erase(u32BlockNameHash); -} - -void CClientGame::InsertPedPointerToSet(CClientPed* pPed) -{ - m_setOfPedPointers.insert(pPed); -} - -void CClientGame::RemovePedPointerFromSet(CClientPed* pPed) -{ - m_setOfPedPointers.erase(pPed); -} - -CClientPed* CClientGame::GetClientPedByClump(const RpClump& Clump) -{ - for (auto& pPed : m_setOfPedPointers) - { - CEntity* pEntity = pPed->GetGameEntity(); - if (pEntity != nullptr) - { - if (pEntity->GetRpClump() != nullptr) - { - const RpClump& entityClump = *pEntity->GetRpClump(); - if (std::addressof(entityClump) == std::addressof(Clump)) - { - return pPed; - } - } - } - } - return nullptr; -} - -void CClientGame::OnClientIFPUnload(const std::shared_ptr& IFP) -{ - IFP->MarkAsUnloading(); - for (auto& pPed : m_setOfPedPointers) - { - // Remove IFP animations from replaced animations of peds/players - pPed->RestoreAnimations(IFP); - - // Make sure that streamed in pulses or changing model does not accidently - // play our custom animation. We can do that by making the custom animation - // untriggerable - if (pPed->GetCustomAnimationBlockNameHash() == IFP->GetBlockNameHash()) - { - if (pPed->IsCustomAnimationPlaying()) - { - pPed->SetCustomAnimationUntriggerable(); - } - - // Important! As we are using a shared_ptr, we need to decrement the reference counter - // by setting the shared_ptr to nullptr, this will avoid memory leak - if (!pPed->IsNextAnimationCustom() && pPed->IsCurrentAnimationCustom()) - { - pPed->DereferenceCustomAnimationBlock(); - } - } - } -} - -void CClientGame::InsertAnimationAssociationToMap(CAnimBlendAssociationSAInterface* pAnimAssociation, const std::shared_ptr& pIFPAnimations) -{ - m_mapOfCustomAnimationAssociations[pAnimAssociation] = pIFPAnimations; -} - -void CClientGame::RemoveAnimationAssociationFromMap(CAnimBlendAssociationSAInterface* pAnimAssociation) -{ - m_mapOfCustomAnimationAssociations.erase(pAnimAssociation); -} +/***************************************************************************** +* +* PROJECT: Multi Theft Auto v1.0 +* LICENSE: See LICENSE in the top level directory +* FILE: mods/deathmatch/logic/CClientGame.cpp +* PURPOSE: Client game manager +* +* Multi Theft Auto is available from http://www.multitheftauto.com/ +* +*****************************************************************************/ + +#include "StdInc.h" +#include +#include "game/CAnimBlendAssocGroup.h" +#include "game/CAnimBlendAssociation.h" +#include "game/CAnimBlendHierarchy.h" + +SString StringZeroPadout(const SString& strInput, uint uiPadoutSize) +{ + SString strResult = strInput; + while (strResult.length() < uiPadoutSize) + strResult += '\0'; + return strResult; +} + +using SharedUtil::CalcMTASAPath; +using std::list; +using std::vector; + +// Hide the "conversion from 'unsigned long' to 'DWORD*' of greater size" warning +#pragma warning(disable:4312) + +// Used within this file by the packet handler to grab the this pointer of CClientGame +extern CClientGame* g_pClientGame; +extern int g_iDamageEventLimit; +float g_fApplyDamageLastAmount; +uchar g_ucApplyDamageLastHitZone; +CClientPed* g_pApplyDamageLastDamagedPed; +bool g_bBulletFireVectorsValid; +CVector g_vecBulletFireStartPosition; +CVector g_vecBulletFireEndPosition; + +#define DEFAULT_GRAVITY 0.008f +#define DEFAULT_GAME_SPEED 1.0f +#define DEFAULT_BLUR_LEVEL 36 +#define DEFAULT_JETPACK_MAXHEIGHT 100 +#define DEFAULT_AIRCRAFT_MAXHEIGHT 800 +#define DEFAULT_AIRCRAFT_MAXVELOCITY 1.5f +#define DEFAULT_MINUTE_DURATION 1000 +#define DOUBLECLICK_TIMEOUT 330 +#define DOUBLECLICK_MOVE_THRESHOLD 10.0f + +CClientGame::CClientGame(bool bLocalPlay) +{ + // Init the global var with ourself + g_pClientGame = this; + + // Packet handler + m_pPacketHandler = new CPacketHandler(); + + // Init + m_bLocalPlay = bLocalPlay; + m_bErrorStartingLocal = false; + m_iLocalConnectAttempts = 0; + m_Status = CClientGame::STATUS_CONNECTING; + m_ulVerifyTimeStart = 0; + m_ulLastClickTick = 0; + m_pLocalPlayer = NULL; + m_LocalID = INVALID_ELEMENT_ID; + m_bShowNametags = true; + m_bWaitingForLocalConnect = false; + m_bShowRadar = false; + m_bGameLoaded = false; + m_bTriggeredIngameAndConnected = false; + m_bGracefulDisconnect = false; + m_ulLastVehicleInOutTime = 0; + m_bIsGettingOutOfVehicle = false; + m_bIsGettingIntoVehicle = false; + m_bIsGettingJacked = false; + m_bIsJackingVehicle = false; + m_VehicleInOutID = INVALID_ELEMENT_ID; + m_pGettingJackedBy = NULL; + m_ucVehicleInOutSeat = 0xFF; + m_pTargetedEntity = NULL; + m_TargetedPlayerID = INVALID_ELEMENT_ID; + m_pDamageEntity = NULL; + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageBodyPiece = 0xFF; + m_ucDamageWeapon = 0xFF; + m_ulDamageTime = 0; + m_bDamageSent = true; + m_bShowNetstat = false; + m_bShowFPS = false; + m_bHudAreaNameDisabled = false; + m_fGameSpeed = 1.0f; + m_lMoney = 0; + m_dwWanted = 0; + m_lastWeaponSlot = WEAPONSLOT_MAX; // last stored weapon slot, for weapon slot syncing to server (sets to invalid value) + ResetAmmoInClip(); + + m_bNoNewVehicleTask = false; + m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; + + m_bCursorEventsEnabled = false; + m_bInitiallyFadedOut = true; + + m_bIsPlayingBack = false; + m_bFirstPlaybackFrame = false; + + // Setup game glitch defaults ( false = disabled ). Remember to update these serverside if you alter them! + m_Glitches[GLITCH_QUICKRELOAD] = false; + g_pMultiplayer->DisableQuickReload(true); + m_Glitches[GLITCH_FASTFIRE] = false; + m_Glitches[GLITCH_FASTMOVE] = false; + m_Glitches[GLITCH_CROUCHBUG] = false; + m_Glitches[GLITCH_CLOSEDAMAGE] = false; + g_pMultiplayer->DisableCloseRangeDamage(true); + m_Glitches[GLITCH_HITANIM] = false; + m_Glitches[GLITCH_FASTSPRINT] = false; + m_Glitches[GLITCH_BADDRIVEBYHITBOX] = false; + m_Glitches[GLITCH_QUICKSTAND] = false; + g_pMultiplayer->DisableBadDrivebyHitboxes(true); + + // Remove Night & Thermal vision view (if enabled). + g_pMultiplayer->SetNightVisionEnabled(false); + g_pMultiplayer->SetThermalVisionEnabled(false); + + m_bCloudsEnabled = true; + + m_bBirdsEnabled = true; + + m_bWasMinimized = false; + + // Grab the mod path + m_strModRoot = g_pCore->GetModInstallRoot("deathmatch"); + + // Figure out which directory to use for the client resource file cache + SetFileCacheRoot(); + + // Override CGUI's global events + g_pCore->GetGUI()->SetKeyDownHandler(INPUT_MOD, GUI_CALLBACK_KEY(&CClientGame::OnKeyDown, this)); + g_pCore->GetGUI()->SetMouseClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseClick, this)); + g_pCore->GetGUI()->SetMouseDoubleClickHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseDoubleClick, this)); + g_pCore->GetGUI()->SetMouseButtonDownHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonDown, this)); + g_pCore->GetGUI()->SetMouseButtonUpHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseButtonUp, this)); + g_pCore->GetGUI()->SetMouseMoveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseMove, this)); + g_pCore->GetGUI()->SetMouseEnterHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseEnter, this)); + g_pCore->GetGUI()->SetMouseLeaveHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseLeave, this)); + g_pCore->GetGUI()->SetMouseWheelHandler(INPUT_MOD, GUI_CALLBACK_MOUSE(&CClientGame::OnMouseWheel, this)); + g_pCore->GetGUI()->SetMovedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnMove, this)); + g_pCore->GetGUI()->SetSizedHandler(INPUT_MOD, GUI_CALLBACK(&CClientGame::OnSize, this)); + g_pCore->GetGUI()->SetFocusGainedHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusGain, this)); + g_pCore->GetGUI()->SetFocusLostHandler(INPUT_MOD, GUI_CALLBACK_FOCUS(&CClientGame::OnFocusLoss, this)); + g_pCore->GetGUI()->SelectInputHandlers(INPUT_MOD); + + // Startup "entities from root" optimization for getElementsByType + CClientEntity::StartupEntitiesFromRoot(); + + // Startup game entity tracking manager + m_pGameEntityXRefManager = NewGameEntityXRefManager(); + m_pModelCacheManager = NewClientModelCacheManager(); + + // Initialize our root entity with an invalid id, we dont know the true id until map-start + m_pRootEntity = new CClientDummy(NULL, INVALID_ELEMENT_ID, "root"); + m_pRootEntity->MakeSystemEntity(); + + m_pDebugHookManager = new CDebugHookManager(); + + // Movings objects manager + m_pMovingObjectsManager = new CMovingObjectsManager(); + + // Create the manager and grab the most important pointers + m_pManager = new CClientManager; + m_pCamera = m_pManager->GetCamera(); + m_pMarkerManager = m_pManager->GetMarkerManager(); + m_pObjectManager = m_pManager->GetObjectManager(); + m_pPickupManager = m_pManager->GetPickupManager(); + m_pPlayerManager = m_pManager->GetPlayerManager(); + m_pRadarAreaManager = m_pManager->GetRadarAreaManager(); + m_pDisplayManager = m_pManager->GetDisplayManager(); + m_pVehicleManager = m_pManager->GetVehicleManager(); + m_pRadarMarkerManager = m_pManager->GetRadarMarkerManager(); + m_pPathManager = m_pManager->GetPathManager(); + m_pTeamManager = m_pManager->GetTeamManager(); + m_pPedManager = m_pManager->GetPedManager(); + m_pGUIManager = m_pManager->GetGUIManager(); + m_pResourceManager = m_pManager->GetResourceManager(); + m_pProjectileManager = m_pManager->GetProjectileManager(); + m_pLocalServer = NULL; + + m_pLatentTransferManager = new CLatentTransferManager(); + m_pZoneNames = new CZoneNames; + m_pScriptKeyBinds = new CScriptKeyBinds; + m_pRemoteCalls = new CRemoteCalls(); + m_pResourceFileDownloadManager = new CResourceFileDownloadManager(); + + // Create our net API + m_pNetAPI = new CNetAPI(m_pManager); + m_pNetworkStats = new CNetworkStats(m_pDisplayManager); + m_pSyncDebug = new CSyncDebug(m_pManager); + + // Create our blended weather class + m_pBlendedWeather = new CBlendedWeather; + + // Create our RPC class + m_pRPCFunctions = new CRPCFunctions(this); + + // Our management classes + m_pUnoccupiedVehicleSync = new CUnoccupiedVehicleSync(m_pVehicleManager); + m_pPedSync = new CPedSync(m_pPedManager); +#ifdef WITH_OBJECT_SYNC + m_pObjectSync = new CObjectSync(m_pObjectManager); +#endif + m_pNametags = new CNametags(m_pManager); + m_pRadarMap = new CRadarMap(m_pManager); + + // Set the screenshot path + /* This is now done in CCore, to maintain a global screenshot path + SString strScreenShotPath = SString::Printf ( "%s\\screenshots", m_szModRoot ); + g_pCore->SetScreenShotPath ( strScreenShotPath ); + */ + + // Create the transfer boxes (GUI) + m_pTransferBox = new CTransferBox(); + m_pBigPacketTransferBox = new CTransferBox(); + + // Store the time we started on + if (bLocalPlay) + m_ulTimeStart = 0; + else + m_ulTimeStart = CClientTime::GetTime(); + + // MTA Voice + m_pVoiceRecorder = new CVoiceRecorder(); + + // Singular file download manager + m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); + + // Register the message and the net packet handler + g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); + g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); + g_pMultiplayer->SetBulletImpactHandler(CClientGame::BulletImpact); + g_pMultiplayer->SetBulletFireHandler(CClientGame::BulletFire); + g_pMultiplayer->SetExplosionHandler(CClientExplosionManager::Hook_StaticExplosionCreation); + g_pMultiplayer->SetBreakTowLinkHandler(CClientGame::StaticBreakTowLinkHandler); + g_pMultiplayer->SetDrawRadarAreasHandler(CClientGame::StaticDrawRadarAreasHandler); + g_pMultiplayer->SetDamageHandler(CClientGame::StaticDamageHandler); + g_pMultiplayer->SetDeathHandler(CClientGame::StaticDeathHandler); + g_pMultiplayer->SetFireHandler(CClientGame::StaticFireHandler); + g_pMultiplayer->SetProjectileStopHandler(CClientProjectileManager::Hook_StaticProjectileAllow); + g_pMultiplayer->SetProjectileHandler(CClientProjectileManager::Hook_StaticProjectileCreation); + g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); + g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); + g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); + g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); + g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); + g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); + g_pMultiplayer->SetPreFxRenderHandler(CClientGame::StaticPreFxRenderHandler); + g_pMultiplayer->SetPreHudRenderHandler(CClientGame::StaticPreHudRenderHandler); + g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(CClientGame::StaticCAnimBlendAssocDestructorHandler); + g_pMultiplayer->SetAddAnimationHandler(CClientGame::StaticAddAnimationHandler); + g_pMultiplayer->SetAddAnimationAndSyncHandler(CClientGame::StaticAddAnimationAndSyncHandler); + g_pMultiplayer->SetAssocGroupCopyAnimationHandler(CClientGame::StaticAssocGroupCopyAnimationHandler); + g_pMultiplayer->SetBlendAnimationHierarchyHandler(CClientGame::StaticBlendAnimationHierarchyHandler); + g_pMultiplayer->SetProcessCollisionHandler(CClientGame::StaticProcessCollisionHandler); + g_pMultiplayer->SetVehicleCollisionHandler(CClientGame::StaticVehicleCollisionHandler); + g_pMultiplayer->SetVehicleDamageHandler(CClientGame::StaticVehicleDamageHandler); + g_pMultiplayer->SetHeliKillHandler(CClientGame::StaticHeliKillHandler); + g_pMultiplayer->SetObjectDamageHandler(CClientGame::StaticObjectDamageHandler); + g_pMultiplayer->SetObjectBreakHandler(CClientGame::StaticObjectBreakHandler); + g_pMultiplayer->SetWaterCannonHitHandler(CClientGame::StaticWaterCannonHandler); + g_pMultiplayer->SetVehicleFellThroughMapHandler(CClientGame::StaticVehicleFellThroughMapHandler); + g_pMultiplayer->SetGameObjectDestructHandler(CClientGame::StaticGameObjectDestructHandler); + g_pMultiplayer->SetGameVehicleDestructHandler(CClientGame::StaticGameVehicleDestructHandler); + g_pMultiplayer->SetGamePlayerDestructHandler(CClientGame::StaticGamePlayerDestructHandler); + g_pMultiplayer->SetGameProjectileDestructHandler(CClientGame::StaticGameProjectileDestructHandler); + g_pMultiplayer->SetGameModelRemoveHandler(CClientGame::StaticGameModelRemoveHandler); + g_pMultiplayer->SetGameEntityRenderHandler(CClientGame::StaticGameEntityRenderHandler); + g_pMultiplayer->SetFxSystemDestructionHandler(CClientGame::StaticFxSystemDestructionHandler); + g_pMultiplayer->SetDrivebyAnimationHandler(CClientGame::StaticDrivebyAnimationHandler); + g_pGame->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); + g_pGame->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); + g_pGame->SetTaskSimpleBeHitHandler(CClientGame::StaticTaskSimpleBeHitHandler); + g_pCore->SetMessageProcessor(CClientGame::StaticProcessMessage); + g_pCore->GetKeyBinds()->SetKeyStrokeHandler(CClientGame::StaticKeyStrokeHandler); + g_pCore->GetKeyBinds()->SetCharacterKeyHandler(CClientGame::StaticCharacterKeyHandler); + g_pNet->RegisterPacketHandler(CClientGame::StaticProcessPacket); + + m_pLuaManager = new CLuaManager(this); + m_pScriptDebugging = new CScriptDebugging(m_pLuaManager); + m_pScriptDebugging->SetLogfile(CalcMTASAPath("mta\\logs\\clientscript.log"), 3); + + CStaticFunctionDefinitions(m_pLuaManager, &m_Events, g_pCore, g_pGame, this, m_pManager); + CLuaFunctionDefs::Initialize(m_pLuaManager, m_pScriptDebugging, this); + CLuaDefs::Initialize(this, m_pLuaManager, m_pScriptDebugging); + + // Start async task scheduler + m_pAsyncTaskScheduler = new SharedUtil::CAsyncTaskScheduler(2); + + // Disable the enter/exit vehicle key button (we want to handle this button ourselves) + g_pMultiplayer->DisableEnterExitVehicleKey(true); + + // Disable GTA's pickup processing as we want to confirm the hits with the server + m_pPickupManager->SetPickupProcessingDisabled(true); + + // Key-bind for fire-key (for handling satchels and stealth-kills) + g_pCore->GetKeyBinds()->AddControlFunction("fire", CClientGame::StaticUpdateFireKey, true); + + // Init big packet progress vars + m_bReceivingBigPacket = false; + m_ulBigPacketSize = 0; + m_ulBigPacketBytesReceivedBase = 0; + + m_bBeingDeleted = false; + +#if defined (MTA_DEBUG) || defined (MTA_BETA) + m_bShowSyncingInfo = false; +#endif + +#ifdef MTA_DEBUG + m_pShowPlayer = m_pShowPlayerTasks = NULL; + m_bMimicLag = false; + m_ulLastMimicLag = 0; + m_bDoPaintballs = false; + m_bShowInterpolation = false; +#endif + + // Add our lua events + AddBuiltInEvents(); + + // Init debugger class + m_Foo.Init(this); + + // Load some stuff from the core config + float fScale; + g_pCore->GetCVars()->Get("text_scale", fScale); + CClientTextDisplay::SetGlobalScale(fScale); + + // Reset async loading script settings to default + g_pGame->SetAsyncLoadingFromScript(true, false); + + // Reset test mode script settings to default + g_pCore->GetGraphics()->GetRenderItemManager()->SetTestMode(DX_TEST_MODE_NONE); +} + +CClientGame::~CClientGame(void) +{ + m_bBeingDeleted = true; + // Stop all explosions. Unfortunately this doesn't fix the crash + // if a vehicle is destroyed while it explodes. + g_pGame->GetExplosionManager()->RemoveAllExplosions(); + + // Reset camera shaking + g_pGame->GetCamera()->SetShakeForce(0.0f); + + // Stop playing the continious sounds + // if the game was loaded. This is done by + // playing these special IDS. + if (m_bGameLoaded) + { + g_pGame->GetAudio()->PlayFrontEndSound(35); + g_pGame->GetAudio()->PlayFrontEndSound(48); + } + + // Reset the GUI input mode + g_pCore->GetGUI()->SetGUIInputMode(INPUTMODE_NO_BINDS_ON_EDIT); + + // Reset CGUI's global events + g_pCore->GetGUI()->ClearInputHandlers(INPUT_MOD); + + // Destroy mimics +#ifdef MTA_DEBUG + list::const_iterator iterMimics = m_Mimics.begin(); + for (; iterMimics != m_Mimics.end(); iterMimics++) + { + CClientPlayer* pPlayer = *iterMimics; + CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); + if (pVehicle) + delete pVehicle; + + delete pPlayer; + } +#endif + + // Hide the transfer box incase it is showing + m_pTransferBox->Hide(); + m_pBigPacketTransferBox->Hide(); + + // Stop async task scheduler + SAFE_DELETE(m_pAsyncTaskScheduler); + + SAFE_DELETE(m_pVoiceRecorder); + + // Singular file download manager + SAFE_DELETE(m_pSingularFileDownloadManager); + + // NULL the message/net stuff + g_pMultiplayer->SetPreContextSwitchHandler(NULL); + g_pMultiplayer->SetPostContextSwitchHandler(NULL); + g_pMultiplayer->SetPreWeaponFireHandler(NULL); + g_pMultiplayer->SetPostWeaponFireHandler(NULL); + g_pMultiplayer->SetBulletImpactHandler(NULL); + g_pMultiplayer->SetBulletFireHandler(NULL); + g_pMultiplayer->SetExplosionHandler(NULL); + g_pMultiplayer->SetBreakTowLinkHandler(NULL); + g_pMultiplayer->SetDrawRadarAreasHandler(NULL); + g_pMultiplayer->SetDamageHandler(NULL); + g_pMultiplayer->SetFireHandler(NULL); + g_pMultiplayer->SetProjectileStopHandler(NULL); + g_pMultiplayer->SetProjectileHandler(NULL); + g_pMultiplayer->SetProcessCamHandler(nullptr); + g_pMultiplayer->SetRender3DStuffHandler(NULL); + g_pMultiplayer->SetPreRenderSkyHandler(NULL); + g_pMultiplayer->SetRenderHeliLightHandler(nullptr); + g_pMultiplayer->SetChokingHandler(NULL); + g_pMultiplayer->SetPreWorldProcessHandler(NULL); + g_pMultiplayer->SetPostWorldProcessHandler(NULL); + g_pMultiplayer->SetPreFxRenderHandler(NULL); + g_pMultiplayer->SetPreHudRenderHandler(NULL); + g_pMultiplayer->SetCAnimBlendAssocDestructorHandler(NULL); + g_pMultiplayer->SetAddAnimationHandler(NULL); + g_pMultiplayer->SetAddAnimationAndSyncHandler(NULL); + g_pMultiplayer->SetAssocGroupCopyAnimationHandler(NULL); + g_pMultiplayer->SetBlendAnimationHierarchyHandler(NULL); + g_pMultiplayer->SetProcessCollisionHandler(NULL); + g_pMultiplayer->SetVehicleCollisionHandler(NULL); + g_pMultiplayer->SetVehicleDamageHandler(NULL); + g_pMultiplayer->SetHeliKillHandler(NULL); + g_pMultiplayer->SetObjectDamageHandler(NULL); + g_pMultiplayer->SetObjectBreakHandler(NULL); + g_pMultiplayer->SetWaterCannonHitHandler(NULL); + g_pMultiplayer->SetGameObjectDestructHandler(NULL); + g_pMultiplayer->SetGameVehicleDestructHandler(NULL); + g_pMultiplayer->SetGamePlayerDestructHandler(NULL); + g_pMultiplayer->SetGameProjectileDestructHandler(NULL); + g_pMultiplayer->SetGameModelRemoveHandler(NULL); + g_pMultiplayer->SetGameEntityRenderHandler(NULL); + g_pMultiplayer->SetDrivebyAnimationHandler(nullptr); + g_pGame->SetPreWeaponFireHandler(NULL); + g_pGame->SetPostWeaponFireHandler(NULL); + g_pGame->SetTaskSimpleBeHitHandler(NULL); + g_pGame->GetAudio()->SetWorldSoundHandler(NULL); + g_pCore->SetMessageProcessor(NULL); + g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); + g_pCore->GetKeyBinds()->SetCharacterKeyHandler(NULL); + g_pNet->StopNetwork(); + g_pNet->RegisterPacketHandler(NULL); + CKeyBindsInterface* pKeyBinds = g_pCore->GetKeyBinds(); + pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessClientKeyBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessClientControlBind); + pKeyBinds->RemoveAllFunctions(CClientGame::StaticProcessServerKeyBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticProcessServerControlBind); + pKeyBinds->RemoveAllControlFunctions(CClientGame::StaticUpdateFireKey); + pKeyBinds->SetAllControlsEnabled(true, true, true); + g_pCore->ForceCursorVisible(false); + SetCursorEventsEnabled(false); + + // Destroy our stuff + SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop + SAFE_DELETE(m_pNametags); + SAFE_DELETE(m_pSyncDebug); + SAFE_DELETE(m_pNetworkStats); + SAFE_DELETE(m_pNetAPI); + SAFE_DELETE(m_pRPCFunctions); + SAFE_DELETE(m_pUnoccupiedVehicleSync); + SAFE_DELETE(m_pPedSync); +#ifdef WITH_OBJECT_SYNC + SAFE_DELETE(m_pObjectSync); +#endif + SAFE_DELETE(m_pBlendedWeather); + SAFE_DELETE(m_pMovingObjectsManager); + SAFE_DELETE(m_pRadarMap); + SAFE_DELETE(m_pRemoteCalls); + SAFE_DELETE(m_pLuaManager); + SAFE_DELETE(m_pLatentTransferManager); + SAFE_DELETE(m_pResourceFileDownloadManager); + + SAFE_DELETE(m_pRootEntity); + + SAFE_DELETE(m_pModelCacheManager); + SAFE_DELETE(m_pGameEntityXRefManager); + SAFE_DELETE(m_pZoneNames); + SAFE_DELETE(m_pScriptKeyBinds); + + // Delete the scriptdebugger + SAFE_DELETE(m_pScriptDebugging); + + // Delete the transfer boxes + SAFE_DELETE(m_pTransferBox); + SAFE_DELETE(m_pBigPacketTransferBox); + + SAFE_DELETE(m_pLocalServer); + SAFE_DELETE(m_pDebugHookManager); + + // Packet handler + SAFE_DELETE(m_pPacketHandler); + + // Delete PerfStatManager + delete CClientPerfStatManager::GetSingleton(); + + // NULL the global CClientGame var + g_pClientGame = NULL; + m_bBeingDeleted = false; +} + +/* +bool CClientGame::StartGame ( void ) // for an offline game (e.g. editor) +{ +m_Status = STATUS_OFFLINE; +g_pCore->SetOfflineMod ( true ); // hide chatbox etc +g_pCore->SetConnected ( true ); // not sure, but its required :) +g_pCore->HideMainMenu (); // duh + +// If the game isn't started, start it +if ( g_pGame->GetSystemState () == 7 ) +{ +g_pGame->StartGame (); +} +return true; +} +*/ + +#include +//#define _CRTDBG_CHECK_EVERY_16_DF 0x00100000 /* check heap every 16 heap ops */ +//#define _CRTDBG_CHECK_EVERY_128_DF 0x00800000 /* check heap every 128 heap ops */ +//#define _CRTDBG_CHECK_EVERY_1024_DF 0x04000000 /* check heap every 1024 heap ops */ + +void CClientGame::EnablePacketRecorder(const char* szFilename) +{ + m_pManager->GetPacketRecorder()->StartRecord(szFilename, true); +} + +void CClientGame::StartPlayback(void) +{ + // strcpy ( m_szNick, "Playback" ); + + m_bIsPlayingBack = true; + m_bFirstPlaybackFrame = true; + m_pManager->GetPacketRecorder()->SetPacketHandler(CClientGame::StaticProcessPacket); + + if (!m_pManager->IsGameLoaded()) + { + g_pGame->StartGame(); + } +} + +bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerType Type) +{ + m_ServerType = Type; + // int dbg = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ); + // dbg |= _CRTDBG_ALLOC_MEM_DF; + // dbg |= _CRTDBG_CHECK_ALWAYS_DF; + // dbg |= _CRTDBG_DELAY_FREE_MEM_DF; + // dbg |= _CRTDBG_LEAK_CHECK_DF; + //_CrtSetDbgFlag(dbg); + + // Verify that the nickname is valid + if (!IsNickValid(szNick)) + { + g_pCore->ShowMessageBox(_("Error") + _E("CD01"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + // Store our nickname + m_strLocalNick.AssignLeft(szNick, MAX_PLAYER_NICK_LENGTH); + + // Are we connected? + if (g_pNet->IsConnected() || m_bIsPlayingBack) + { + // Hide the console when connecting.. + if (g_pCore->GetConsole()->IsVisible()) + g_pCore->GetConsole()->SetVisible(false); + + // Display the status box + g_pCore->ShowMessageBox(_("CONNECTING"), _("Entering the game ..."), MB_ICON_INFO); + + // Send the initial data to the server + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Hash the password if neccessary + MD5 Password; + memset(Password.data, 0, sizeof(MD5)); + if (szPassword) + { + // Is it long enough? + size_t sizePassword = strlen(szPassword); + if (sizePassword > 0) + { + // Hash the password and put it in the struct + CMD5Hasher Hasher; + Hasher.Calculate(szPassword, sizePassword, Password); + } + } + + // Append version information + pBitStream->Write(static_cast(MTA_DM_NETCODE_VERSION)); + pBitStream->Write(static_cast(MTA_DM_VERSION)); + pBitStream->Write(static_cast(MTA_DM_BITSTREAM_VERSION)); + + SString strPlayerVersion("%d.%d.%d-%d.%05d.%d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, + MTASA_VERSION_BUILD, g_pNet->GetNetRev()); + pBitStream->WriteString(strPlayerVersion); + + pBitStream->WriteBit(g_pCore->IsOptionalUpdateInfoRequired(g_pNet->GetConnectedServer(true))); + + pBitStream->Write(static_cast(g_pGame->GetGameVersion())); + + // Append user details + SString strTemp = StringZeroPadout(m_strLocalNick, MAX_PLAYER_NICK_LENGTH); + pBitStream->Write(strTemp.c_str(), MAX_PLAYER_NICK_LENGTH); + pBitStream->Write(reinterpret_cast(Password.data), sizeof(MD5)); + + // Append community information (Removed) + std::string strUser; + pBitStream->Write(strUser.c_str(), MAX_SERIAL_LENGTH); + + // Send the packet as joindata + g_pNet->SendPacket(PACKET_ID_PLAYER_JOINDATA, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + return true; + } + } + else + { + g_pCore->ShowMessageBox(_("Error") + _E("CD02"), _("Not connected; please use Quick Connect or the 'connect' command to connect to a server."), + MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + } + + return false; +} + +void CClientGame::SetupLocalGame(eServerType Type) +{ + SString strConfig = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; + m_bWaitingForLocalConnect = true; + if (!m_pLocalServer) + m_pLocalServer = new CLocalServer(strConfig); +} + +bool CClientGame::StartLocalGame(eServerType Type, const char* szPassword) +{ + // Verify that the nickname is valid + std::string strNick; + g_pCore->GetCVars()->Get("nick", strNick); + + if (!IsNickValid(strNick.c_str())) + { + g_pCore->ShowMessageBox(_("Error") + _E("CD03"), _("Invalid nickname! Please go to Settings and set a new one!"), MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + m_bWaitingForLocalConnect = false; + m_ServerType = Type; + SString strTemp = (Type == SERVER_TYPE_EDITOR) ? "editor.conf" : "local.conf"; + + SAFE_DELETE(m_pLocalServer); + + // Store our nickname + m_strLocalNick.AssignLeft(strNick.c_str(), MAX_PLAYER_NICK_LENGTH); + + // Got a server? + if (m_bLocalPlay) + { + // Start the server locally + if (!m_Server.Start(strTemp)) + { + m_bWaitingForLocalConnect = true; + m_bErrorStartingLocal = true; + g_pCore->ShowMessageBox(_("Error") + _E("CD04"), _("The server is not installed"), MB_ICON_ERROR | MB_BUTTON_OK); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + if (szPassword) + m_Server.SetPassword(szPassword); + + // Display the status box<<<<< + m_OnCancelLocalGameClick = GUI_CALLBACK(&CClientGame::OnCancelLocalGameClick, this); + g_pCore->ShowMessageBox(_("Local Server"), _("Starting local server ..."), MB_BUTTON_CANCEL | MB_ICON_INFO, &m_OnCancelLocalGameClick); + } + else + { + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + // We're waiting for connection + m_bWaitingForLocalConnect = true; + return true; +} + +bool CClientGame::OnCancelLocalGameClick(CGUIElement* pElement) +{ + if (m_bLocalPlay && m_bWaitingForLocalConnect) + { + g_pCore->RemoveMessageBox(); + g_pCore->GetModManager()->RequestUnload(); + return true; + } + return false; +} + +void CClientGame::DoPulsePreFrame(void) +{ + if (m_Status == CClientGame::STATUS_JOINED) + { + if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) + { + m_pVoiceRecorder->DoPulse(); + } + } +} + +void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRenderTargets) +{ + // Allow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); + + // If appropriate, call onClientRestore + if (bDidUnminimize) + { + CLuaArguments Arguments; + Arguments.PushBoolean(bDidRecreateRenderTargets); + m_pRootEntity->CallEvent("onClientRestore", Arguments, false); + m_bWasMinimized = false; + + // Reverse any mute on minimize effects + g_pGame->GetAudio()->SetEffectsMasterVolume(g_pGame->GetSettings()->GetSFXVolume()); + g_pGame->GetAudio()->SetMusicMasterVolume(g_pGame->GetSettings()->GetRadioVolume()); + m_pManager->GetSoundManager()->SetMinimizeMuted(false); + } + + // Call onClientHUDRender LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientHUDRender", Arguments, false); + + // Disallow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); + + // Restore in case script forgets + g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); + + DebugElementRender(); +} + +void CClientGame::DoPulsePostFrame(void) +{ + TIMING_CHECKPOINT("+CClientGame::DoPulsePostFrame"); +#ifdef DEBUG_KEYSTATES + // Get the controller state + CControllerState cs; + g_pGame->GetPad()->GetCurrentControllerState(&cs); + + SString strBuffer; + strBuffer = SString::Printf( + "LeftShoulder1: %u\n" + "LeftShoulder2: %u\n" + "RightShoulder1: %u\n" + "RightShoulder2: %u\n" + "DPadUp: %u\n" + "DPadDown: %u\n" + "DPadLeft: %u\n" + "DPadRight: %u\n" + "Start: %u\n" + "Select: %u\n" + "ButtonSquare: %u\n" + "ButtonTriangle: %u\n" + "ButtonCross: %u\n" + "ButtonCircle: %u\n" + "ShockButtonL: %u\n" + "ShockButtonR: %u\n" + "PedWalk: %u\n", + cs.LeftShoulder1, cs.LeftShoulder2, cs.RightShoulder1, cs.RightShoulder2, cs.DPadUp, cs.DPadDown, cs.DPadLeft, cs.DPadRight, cs.Start, cs.Select, + cs.ButtonSquare, cs.ButtonTriangle, cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.ShockButtonR, cs.m_bPedWalk); + + g_pCore->GetGraphics()->DrawTextTTF(300, 10, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); + + strBuffer = SString::Printf( + "VehicleMouseLook: %u\n" + "LeftStickX: %u\n" + "LeftStickY: %u\n" + "RightStickX: %u\n" + "RightStickY: %u", + cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, cs.RightStickX, cs.RightStickY); + + g_pCore->GetGraphics()->DrawTextTTF(300, 320, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); +#endif + + UpdateModuleTickCount64(); + + if (m_pManager->IsGameLoaded()) + { + // Pulse the nametags before anything that changes player positions, we'll be 1 frame behind, but so is the camera + // If nametags are enabled, pulse the nametag manager + if (m_bShowNametags) + { + m_pNametags->DoPulse(); + } + + // Sync debug + m_pSyncDebug->OnPulse(); + + // Also eventually draw FPS + if (m_bShowFPS) + { + DrawFPS(); + } + + CGraphicsInterface* pGraphics = g_pCore->GetGraphics(); + unsigned int uiHeight = pGraphics->GetViewportHeight(); + unsigned int uiWidth = pGraphics->GetViewportWidth(); + + // Draw a little star in the corner if async is on + if (g_pGame->IsASyncLoadingEnabled(true)) + { + unsigned int uiPosY = g_pGame->IsASyncLoadingEnabled() ? uiHeight - 7 : uiHeight - 12; + pGraphics->DrawString(uiWidth - 5, uiPosY, 0x80ffffff, 1, "*"); + } + + // Draw notice text if dx test mode is enabled + if (g_pCore->GetGraphics()->GetRenderItemManager()->GetTestMode()) + { + unsigned int uiPosY = uiHeight - 30; + pGraphics->DrawString(uiWidth - 155, uiPosY, 0x40ffffff, 1, "dx test mode enabled"); + } + + // Draw notice text if diagnostic mode enabled + EDiagnosticDebugType diagnosticDebug = g_pCore->GetDiagnosticDebug(); + if (diagnosticDebug == EDiagnosticDebug::LOG_TIMING_0000) + { + unsigned int uiPosY = uiHeight - 30; + pGraphics->DrawString(uiWidth - 185, uiPosY, 0xffffff00, 1, "Debug setting: #0000 Log timing"); + } + + // Draw network trouble message if required + if (m_pNetAPI->IsNetworkTrouble()) + { + int iPosX = uiWidth / 2; // Half way across + int iPosY = uiHeight * 45 / 100; // 45/100 down + g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, + DT_NOCLIP | DT_CENTER); + } + + // Adjust the streaming memory limit. + unsigned int uiStreamingMemoryPrev; + g_pCore->GetCVars()->Get("streaming_memory", uiStreamingMemoryPrev); + uint uiStreamingMemory = SharedUtil::Clamp(g_pCore->GetMinStreamingMemory(), uiStreamingMemoryPrev, g_pCore->GetMaxStreamingMemory()); + if (uiStreamingMemory != uiStreamingMemoryPrev) + g_pCore->GetCVars()->Set("streaming_memory", uiStreamingMemory); + + int iStreamingMemoryBytes = static_cast(uiStreamingMemory) * 1024 * 1024; + if (g_pMultiplayer->GetLimits()->GetStreamingMemory() != iStreamingMemoryBytes) + g_pMultiplayer->GetLimits()->SetStreamingMemory(iStreamingMemoryBytes); + + // If we're in debug mode and are supposed to show task data, do it +#ifdef MTA_DEBUG + if (m_pShowPlayerTasks) + { + DrawTasks(m_pShowPlayerTasks); + } + + if (m_pShowPlayer) + { + DrawPlayerDetails(m_pShowPlayer); + } + + std::vector::const_iterator iter = m_pPlayerManager->IterBegin(); + for (; iter != m_pPlayerManager->IterEnd(); ++iter) + { + CClientPlayer* pPlayer = *iter; + if (pPlayer->IsStreamedIn() && pPlayer->IsShowingWepdata()) + DrawWeaponsyncData(pPlayer); + } +#endif + +#if defined (MTA_DEBUG) || defined (MTA_BETA) + if (m_bShowSyncingInfo) + { + // Draw the header boxz + CVector vecPosition = CVector(0.05f, 0.32f, 0); + m_pDisplayManager->DrawText2D("Syncing vehicles:", vecPosition, 1.0f, 0xFFFFFFFF); + + // Print each vehicle we're syncing + CDeathmatchVehicle* pVehicle; + list::const_iterator iter = m_pUnoccupiedVehicleSync->IterBegin(); + for (; iter != m_pUnoccupiedVehicleSync->IterEnd(); iter++) + { + vecPosition.fY += 0.03f; + pVehicle = *iter; + + SString strBuffer("ID: %u (%s)", pVehicle->GetID(), pVehicle->GetNamePointer()); + + m_pDisplayManager->DrawText2D(strBuffer, vecPosition, 1.0f, 0xFFFFFFFF); + } + } +#endif + // Heli Clear time + if (m_LastClearTime.Get() > HeliKill_List_Clear_Rate) + { + // Clear our list now + m_HeliCollisionsMap.clear(); + m_LastClearTime.Reset(); + } + + CClientPerfStatManager::GetSingleton()->DoPulse(); + } + + m_pRadarMap->DoRender(); + m_pManager->DoRender(); + DoPulses(); + + // If we're supposed to show netstat, draw them infront of everything else + if (m_bShowNetstat) + { + m_pNetworkStats->Draw(); + } +} + +void CClientGame::DoPulses(void) +{ + TIMING_CHECKPOINT("-CClientGame::DoPulsePostFrame"); + + g_pCore->ApplyFrameRateLimit(); + + TIMING_CHECKPOINT("+CClientGame::DoPulses"); + + m_BuiltCollisionMapThisFrame = false; + + if (m_bIsPlayingBack && m_bFirstPlaybackFrame && m_pManager->IsGameLoaded()) + { + g_pCore->GetConsole()->Printf("First playback frame, starting"); + m_pManager->GetPacketRecorder()->StartPlayback("log.rec", false); + m_bFirstPlaybackFrame = false; + } + + // Call debug code if debug mode + m_Foo.DoPulse(); + + // Output stuff from our internal server eventually + m_Server.DoPulse(); + + if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED && GetTickCount64_() - m_llLastTransgressionTime > 60000) + { + uint uiLevel = 0; + uint uiInform = 0; + SString strMessage; + + // Is the player a cheater? + if (!m_pManager->GetAntiCheat().PerformChecks()) + { + uiLevel = 1; + uiInform = 2; + } + else + { + strMessage = g_pNet->GetNextBuffer(); + if (strMessage.length()) + { + uiLevel = atoi(strMessage.SplitLeft(":", &strMessage)); + uiInform = atoi(strMessage.SplitLeft(":", &strMessage)); + } + } + + // Send message to the server + if (uiLevel) + { + SString strPrefix = (uiInform == 2) ? "AC" : (uiInform == 1) ? "VF" : "SD"; + SString strMessageCombo = SString("%s #%d %s", *strPrefix, uiLevel, strMessage.c_str()).TrimEnd(" "); + m_llLastTransgressionTime = GetTickCount64_(); + AddReportLog(3100, strMessageCombo + SString(" (%d)", uiInform)); + + if (uiInform > 0) + { + // The server will use the whole message as supplied here + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write(uiLevel); + pBitStream->WriteString(strMessageCombo); + g_pNet->SendPacket(PACKET_ID_PLAYER_TRANSGRESSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + else + { + // Otherwise, disconnect here + AddReportLog(7105, SString("Core - Kicked (%s)", *strMessageCombo)); + g_pCore->ShowMessageBox(_("Error") + _E("CD05"), SString(_("You were kicked from the game ( %s )"), *strMessageCombo), + MB_BUTTON_OK | MB_ICON_ERROR); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + } + + // Send diagnostic info + if (m_pManager->IsGameLoaded() && m_Status == CClientGame::STATUS_JOINED) + { + // Retrieve data + SString strMessage = g_pNet->GetDiagnosticStatus(); + + // Send to the server if changed + if (strMessage != m_strLastDiagnosticStatus) + { + m_strLastDiagnosticStatus = strMessage; + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->WriteString(strMessage); + g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } + + // Pulse the network interface + + // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) + DoPulses2(false); + + m_pUnoccupiedVehicleSync->DoPulse(); + m_pPedSync->DoPulse(); +#ifdef WITH_OBJECT_SYNC + m_pObjectSync->DoPulse(); +#endif + m_pLatentTransferManager->DoPulse(); + m_pLuaManager->DoPulse(); + m_pScriptDebugging->UpdateLogOutput(); + + GetModelCacheManager()->DoPulse(); + +#ifdef MTA_DEBUG + UpdateMimics(); +#endif + + // Grab the current time + unsigned long ulCurrentTime = CClientTime::GetTime(); + + // Waiting for a connect? + if (m_bWaitingForLocalConnect) + { + // Connected? + if (g_pNet->IsConnected()) + { + // No longer waiting for connect + m_bWaitingForLocalConnect = false; + + // Assume local server has the same bitstream version + g_pNet->SetServerBitStreamVersion(MTA_DM_BITSTREAM_VERSION); + + // Run the game normally. + StartGame(m_strLocalNick, m_Server.GetPassword().c_str(), m_ServerType); + } + else + { + // Going to try connecting? Do this when the internal server has booted + // and we haven't started the connecting. + if (m_Server.IsReady() && m_iLocalConnectAttempts == 0) + { + g_pCore->ShowMessageBox(_("Local Server"), _("Connecting to local server..."), MB_ICON_INFO); + + // Connect + if (g_pNet->StartNetwork("localhost", 22010)) + { + // We're waiting for connection + m_iLocalConnectAttempts = 1; + m_ulTimeStart = CClientTime::GetTime(); + } + else + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD06"), _("Error connecting to server.")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + + // Timeout? + if (m_ulTimeStart != 0 && CClientTime::GetTime() >= m_ulTimeStart + 5000) + { + // Show timeout message and disconnect + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD07"), _("Connecting to local server timed out. See console for details.")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + } + + // If the game is loaded ... + if (m_pManager->IsGameLoaded()) + { + // Pulse the blended weather manager + m_pBlendedWeather->DoPulse(); + + // If we weren't ingame last frame; call the on ingame event + if (!m_bGameLoaded) + { + // Fix for gta not being focused sometimes + SetActiveWindow(g_pCore->GetHookedWindow()); + SetFocus(g_pCore->GetHookedWindow()); + + m_bGameLoaded = true; + Event_OnIngame(); + } + + // Check if the player is hitting the enter vehicle button + DoVehicleInKeyCheck(); + + // Pulse some stuff + m_pMovingObjectsManager->DoPulse(); + + // Get rid of our deleted elements + m_ElementDeleter.DoDeleteAll(); + m_pLuaManager->ProcessPendingDeleteList(); + + // Get rid of deleted GUI elements + g_pCore->GetGUI()->CleanDeadPool(); + + // Allow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(true); + + // Call onClientRender LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientRender", Arguments, false); + + // Disallow scripted dxSetRenderTarget for old scripts + g_pCore->GetGraphics()->GetRenderItemManager()->EnableSetRenderTargetOldVer(false); + + // Restore in case script forgets + g_pCore->GetGraphics()->GetRenderItemManager()->RestoreDefaultRenderTarget(); + + // Ensure replaced/restored textures for models in the GTA map are correct + g_pGame->FlushPendingRestreamIPL(); + + // Respawn objects in respawn pool + m_ObjectRespawner.DoRespawnAll(); + } + + // Are we connecting? + if (m_Status == CClientGame::STATUS_CONNECTING) + { + if (m_bErrorStartingLocal) + { + g_pCore->GetModManager()->RequestUnload(); + return; + } + + // Timed out? + if (!m_bWaitingForLocalConnect && ulCurrentTime >= m_ulTimeStart + NET_CONNECT_TIMEOUT) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD08"), _("Connection timed out"), "connect-timed-out", true); + g_pCore->GetModManager()->RequestUnload(); + return; + } + } + else if (m_Status == CClientGame::STATUS_JOINED) + { + // Pulse DownloadFiles if we're transferring stuff + GetResourceFileDownloadManager()->DoPulse(); + DownloadSingularResourceFiles(); + GetRemoteCalls()->ProcessQueuedFiles(); + } + + // Not waiting for local connect? + if (!m_bWaitingForLocalConnect) + { + // Trigger the ingame and connected event + if (!m_bTriggeredIngameAndConnected && m_pManager->IsGameLoaded() && g_pCore->IsConnected()) + { + m_bTriggeredIngameAndConnected = true; + Event_OnIngameAndConnected(); + + // Initialize the game + g_pCore->GetGame()->Initialize(); + } + + unsigned char ucError = g_pNet->GetConnectionError(); + + // Lost connection? + if (!g_pNet->IsConnected() && !m_bGracefulDisconnect && !m_bIsPlayingBack) + { + // See if we can figure out what specifically it was + if (ucError == 0) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD09"), _("Connection with the server was lost")); + g_pCore->GetModManager()->RequestUnload(); + return; + } + else + { + SString strError; + SString strErrorCode; + switch (ucError) + { + case RID_RSA_PUBLIC_KEY_MISMATCH: + strError = _("Disconnected: unknown protocol error"); + strErrorCode = _E("CD10"); // encryption key mismatch + break; + case RID_REMOTE_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected remotely"); + strErrorCode = _E("CD11"); + break; + case RID_REMOTE_CONNECTION_LOST: + strError = _("Disconnected: connection lost remotely"); + strErrorCode = _E("CD12"); + break; + case RID_CONNECTION_BANNED: + strError = _("Disconnected: you are banned from this server"); + strErrorCode = _E("CD13"); + break; + case RID_NO_FREE_INCOMING_CONNECTIONS: + strError = _("Disconnected: the server is currently full"); + strErrorCode = _E("CD14"); + break; + case RID_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected from the server"); + strErrorCode = _E("CD15"); + break; + case RID_CONNECTION_LOST: + strError = _("Disconnected: connection to the server was lost"); + strErrorCode = _E("CD16"); + break; + case RID_INVALID_PASSWORD: + strError = _("Disconnected: invalid password specified"); + strErrorCode = _E("CD17"); + break; + default: + strError = _("Disconnected: connection was refused"); + strErrorCode = _E("CD18"); + break; + } + + // Display an error, reset the error status and exit + g_pCore->ShowNetErrorMessageBox(_("Error") + strErrorCode, strError); + g_pNet->SetConnectionError(0); + g_pCore->GetModManager()->RequestUnload(); + } + } + + // If we're in the verificating status + if (m_Status == CClientGame::STATUS_JOINING) + { + // Time out the verification if it takes too long + if (m_ulVerifyTimeStart != 0 && ulCurrentTime >= m_ulVerifyTimeStart + CLIENT_VERIFICATION_TIMEOUT) + { + g_pCore->ShowNetErrorMessageBox(_("Error") + _E("CD19"), _("MTA Client verification failed!")); + g_pCore->GetModManager()->RequestUnload(); + } + } + } + + // Check for radar input + m_pRadarMap->DoPulse(); + g_pCore->GetGraphics()->SetAspectRatioAdjustmentSuspended(m_pRadarMap->IsRadarShowing()); + + // Got a local player? + if (m_pLocalPlayer) + { + // Network updates + UpdateVehicleInOut(); + UpdatePlayerTarget(); + UpdatePlayerWeapons(); + // UpdateTrailers (); // Test: Does it always work without this check? + UpdateStunts(); + // Clear last damager if more than 2 seconds old + if (CClientTime::GetTime() - m_ulDamageTime > 2000) + { + m_DamagerID = INVALID_ELEMENT_ID; + m_ucDamageWeapon = 0xFF; + m_ucDamageBodyPiece = 0xFF; + } + DoWastedCheck(m_DamagerID, m_ucDamageWeapon, m_ucDamageBodyPiece); + } + + // Game hacks, restore certain variables + // game-speed changes after spawning + g_pGame->SetGameSpeed(m_fGameSpeed); + // money changes on death/getting into taxis + g_pGame->GetPlayerInfo()->SetPlayerMoney(m_lMoney); + // wanted to stop it changing on skin change etc + if (m_pLocalPlayer) + { + if (m_dwWanted != g_pGame->GetPlayerInfo()->GetWanted()->GetWantedLevel()) + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevelNoFlash(m_dwWanted); + } + // stop players dying from starvation + g_pGame->GetPlayerInfo()->SetLastTimeEaten(0); + // reset weapon logs (for preventing quickreload) + + // Update streaming + m_pManager->UpdateStreamers(); + + // Send screen shot data + ProcessDelayedSendList(); + + // Collect async task scheduler results + m_pAsyncTaskScheduler->CollectResults(); + + TIMING_CHECKPOINT("-CClientGame::DoPulses"); +} + +// Extrapolation test +void CClientGame::DoPulses2(bool bCalledFromIdle) +{ + bool bIsUsingAlternatePulseOrder = IsUsingAlternatePulseOrder(!bCalledFromIdle); + + // Figure out which pulses to do + bool bDoStandardPulses; + bool bDoVehicleManagerPulse; + + if (!bIsUsingAlternatePulseOrder) + { + // With std pulse order, do pulses when not called from idle + bDoStandardPulses = !bCalledFromIdle; + bDoVehicleManagerPulse = !bCalledFromIdle; + } + else + { + // With alt pulse order, do pulses when called from idle + bDoStandardPulses = bCalledFromIdle; + bDoVehicleManagerPulse = bCalledFromIdle; + + // Except when watching a remote synced vehicle + if (CClientVehicle* pTargetVehicle = DynamicCast(m_pCamera->GetTargetEntity())) + if (pTargetVehicle->GetControllingPlayer() != m_pPlayerManager->GetLocalPlayer()) + bDoVehicleManagerPulse = !bDoVehicleManagerPulse; + } + + if (bDoStandardPulses) + { + // Change to high precision so arguments in element data and events can + // be rounded to look more like what is expected + ChangeFloatPrecision(true); + + // Pulse the network interface + TIMING_CHECKPOINT("+NetPulse"); + g_pNet->DoPulse(); + TIMING_CHECKPOINT("-NetPulse"); + + // Change precision back, and check we are in low precision mode 4 sure + ChangeFloatPrecision(false); + assert(!IsHighFloatPrecision()); + } + + m_pManager->DoPulse(bDoStandardPulses, bDoVehicleManagerPulse); + + if (bDoStandardPulses) + { + m_pNetAPI->DoPulse(); + } +} + +void CClientGame::HandleException(CExceptionInformation* pExceptionInformation) +{ +} + +void CClientGame::HandleRadioNext(CControlFunctionBind*) +{ + if (g_pClientGame) + { + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); + if (pPlayer) + { + pPlayer->NextRadioChannel(); + } + } +} + +void CClientGame::HandleRadioPrevious(CControlFunctionBind*) +{ + if (g_pClientGame) + { + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->GetLocalPlayer(); + if (pPlayer) + { + pPlayer->PreviousRadioChannel(); + } + } +} +bool CClientGame::IsNametagValid(const char* szNick) +{ + // Grab the size of the nametag. Check that it's not to long or short + size_t sizeNick = MbUTF8ToUTF16(szNick).size(); + if (sizeNick < MIN_PLAYER_NAMETAG_LENGTH || sizeNick > MAX_PLAYER_NAMETAG_LENGTH) + { + return false; + } + + // Check that each character is valid (Anything above 32) + unsigned char ucTemp; + for (size_t i = 0; i < sizeNick; i++) + { + ucTemp = szNick[i]; + if (ucTemp < 32) + { + return false; + } + } + + // nametag is valid, return true + return true; +} + +bool CClientGame::IsNickValid(const char* szNick) +{ + // Grab the size of the nick. Check that it's within the player + size_t sizeNick = strlen(szNick); + if (sizeNick < MIN_PLAYER_NICK_LENGTH || sizeNick > MAX_PLAYER_NICK_LENGTH) + { + return false; + } + + // Check that each character is valid (visible characters exluding space) + unsigned char ucTemp; + for (size_t i = 0; i < sizeNick; i++) + { + ucTemp = szNick[i]; + if (ucTemp < 33 || ucTemp > 126) + { + return false; + } + } + + // Nickname is valid, return true + return true; +} + +void CClientGame::ShowNetstat(int iCmd) +{ + bool bShow = (iCmd == 1) ? true : (iCmd == 0) ? false : !m_bShowNetstat; + + if (bShow && !m_bShowNetstat) + { + m_pNetworkStats->Reset(); + } + m_bShowNetstat = bShow; +} + +void CClientGame::ShowEaeg(bool) +{ + if (m_pLocalPlayer) + m_pLocalPlayer->SetStat(0x2329, 1.0f); +} + +#ifdef MTA_WEPSYNCDBG +void CClientGame::ShowWepdata(const char* szNick) +{ + CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); + if (pPlayer) + { + pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); + } +} +#endif + +#ifdef MTA_DEBUG + +void CClientGame::ShowWepdata(const char* szNick) +{ + CClientPlayer* pPlayer = m_pPlayerManager->Get(szNick); + if (pPlayer) + { + pPlayer->SetShowingWepdata(!pPlayer->IsShowingWepdata()); + } +} + +void CClientGame::ShowPlayer(const char* szNick) +{ + m_pShowPlayer = m_pPlayerManager->Get(szNick); +} + +void CClientGame::ShowTasks(const char* szNick) +{ + m_pShowPlayerTasks = m_pPlayerManager->Get(szNick); +} + +void CClientGame::SetMimic(unsigned int uiMimicCount) +{ + // Check if we're within the max mimics boundary + if (uiMimicCount > MAX_MIMICS) + return; + + // Create neccessary players + while (m_Mimics.size() < uiMimicCount) + { + CClientPlayer* pPlayer = new CClientPlayer(m_pManager, static_cast(MAX_NET_PLAYERS_REAL + (int)m_Mimics.size())); + pPlayer->SetNick("Mimic"); + m_Mimics.push_back(pPlayer); + } + + // Destroy neccessary players + while (m_Mimics.size() > uiMimicCount) + { + CClientPlayer* pPlayer = m_Mimics.back(); + CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); + if (pVehicle) + delete pVehicle; + + delete pPlayer; + m_Mimics.pop_back(); + } +} + +#endif + +void CClientGame::DoVehicleInKeyCheck(void) +{ + // Grab the controller state + CControllerState cs; + g_pGame->GetPad()->GetCurrentControllerState(&cs); + static bool bButtonTriangleWasDown = false; + if (cs.ButtonTriangle) + { + if (!bButtonTriangleWasDown) + { + bButtonTriangleWasDown = true; + + // Process the hit + ProcessVehicleInOutKey(false); + } + } + else + { + bButtonTriangleWasDown = false; + } +} + +void CClientGame::UpdateVehicleInOut(void) +{ + // We got told by the server to animate into a certain vehicle? + if (m_VehicleInOutID != INVALID_ELEMENT_ID) + { + // Grab the vehicle we're getting in/out of + CDeathmatchVehicle* pInOutVehicle = static_cast(m_pVehicleManager->Get(m_VehicleInOutID)); + + // In or out? + if (m_bIsGettingOutOfVehicle) + { + // If we aren't working on leaving the car (he's eiter finished or cancelled/failed leaving) + if (!m_pLocalPlayer->IsLeavingVehicle()) + { + // Are we outside the car? + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + if (!pVehicle) + { + // Tell the server that we successfully left the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction = VEHICLE_NOTIFY_OUT; + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself out (so we're sure the records are correct) + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it, and damagable if we're syncing it + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + }*/ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + + // Reset the vehicle in out stuff so we're ready for another car entry/leave. + // Don't allow a new entry/leave until we've gotten the notify return packet + ElementID ReasonVehicleID = m_VehicleInOutID; + g_pClientGame->ResetVehicleInOut(); + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = ReasonVehicleID; + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_out"); +#endif + } + // Are we still inside the car? + else + { + // Warp us out now to keep in sync with the server + m_pLocalPlayer->RemoveFromVehicle(); + } + } + } + + // Are we getting into a vehicle? + else if (m_bIsGettingIntoVehicle) + { + // If we aren't working on entering the car (he's either finished or cancelled) + if (!m_pLocalPlayer->IsEnteringVehicle()) + { + // Is he in a vehicle now? + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + if (pVehicle) + { + // Tell the server that we successfully entered the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction; + + if (m_bIsJackingVehicle) + { + ucAction = static_cast(VEHICLE_NOTIFY_JACK); +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack"); +#endif + } + else + { + ucAction = static_cast(VEHICLE_NOTIFY_IN); +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in"); +#endif + } + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself in (so we're sure the records are correct) + pVehicle->AllowDoorRatioSetting(m_pLocalPlayer->m_ucEnteringDoor, true); + m_pLocalPlayer->WarpIntoVehicle(pVehicle, m_ucVehicleInOutSeat); + + /* + // Make it damagable + if ( pInOutVehicle ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + */ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + } + else + { + // Tell the server that we aborted entered the car + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write the car id and the action id (enter complete) + pBitStream->Write(m_VehicleInOutID); + unsigned char ucAction; + if (m_bIsJackingVehicle) + { + ucAction = static_cast(VEHICLE_NOTIFY_JACK_ABORT); + pBitStream->WriteBits(&ucAction, 4); + + // Did we start jacking them? + bool bAlreadyStartedJacking = false; + CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); + if (pVehicle) + { + CClientPed* pJackedPlayer = pVehicle->GetOccupant(); + if (pJackedPlayer) + { + // Jax: have we already started to jack the other player? + if (pJackedPlayer->IsGettingJacked()) + { + bAlreadyStartedJacking = true; + } + } + unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; + pBitStream->WriteBits(&ucDoor, 3); + SDoorOpenRatioSync door; + door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); + pBitStream->Write(&door); + } + pBitStream->WriteBit(bAlreadyStartedJacking); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_jack_abort"); +#endif + } + else + { + ucAction = static_cast(VEHICLE_NOTIFY_IN_ABORT); + pBitStream->WriteBits(&ucAction, 4); + CClientVehicle* pVehicle = DynamicCast(CElementIDs::GetElement(m_VehicleInOutID)); + if (pVehicle) + { + unsigned char ucDoor = m_pLocalPlayer->m_ucEnteringDoor - 2; + pBitStream->WriteBits(&ucDoor, 3); + SDoorOpenRatioSync door; + door.data.fRatio = pVehicle->GetDoorOpenRatio(m_pLocalPlayer->m_ucEnteringDoor); + pBitStream->Write(&door); + } + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_in_abort"); +#endif + } + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + + // Warp ourself out again (so we're sure the records are correct) + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it, and damagable if we're syncing it + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + } + */ + if (pInOutVehicle) + { + pInOutVehicle->CalcAndUpdateCanBeDamagedFlag(); + pInOutVehicle->CalcAndUpdateTyresCanBurstFlag(); + } + } + + // Reset + // Don't allow a new entry/leave until we've gotten the notify return packet + ElementID ReasonID = m_VehicleInOutID; + ResetVehicleInOut(); + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = ReasonID; + } + } + } + else + { + // If we aren't getting jacked + if (!m_bIsGettingJacked) + { + CClientVehicle* pVehicle = m_pLocalPlayer->GetRealOccupiedVehicle(); + CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + + // Jax: this was commented, re-comment if it was there for a reason (..and give the reason!) + // Are we in a vehicle we aren't supposed to be in? + if (pVehicle && !pOccupiedVehicle) + { + g_pCore->GetConsole()->Print("You shouldn't be in this vehicle"); + m_pLocalPlayer->RemoveFromVehicle(); + } + + // Are we supposed to be in a vehicle? But aren't? + if (pOccupiedVehicle && !pVehicle) + { + // Jax: this happens when we try to warp into a streamed out vehicle, including when we use CClientVehicle::StreamInNow + // ..maybe we need a different way to detect bike falls? + + // Tell the server + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Vehicle id + pBitStream->Write(pOccupiedVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_NOTIFY_FELL_OFF); + pBitStream->WriteBits(&ucAction, 4); + + // Send it and destroy the packet + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're not allowed to enter any vehicle before we get a confirm + m_bNoNewVehicleTask = true; + m_NoNewVehicleTaskReasonID = pOccupiedVehicle->GetID(); + + // Remove him from the vehicle + m_pLocalPlayer->RemoveFromVehicle(); + + /* + // Make it undamagable if we're not syncing it + CDeathmatchVehicle* pInOutVehicle = static_cast < CDeathmatchVehicle* > ( pOccupiedVehicle ); + if ( pInOutVehicle ) + { + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } + } + */ + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_notify_fell_off"); +#endif + } + } + } + } +} + +void CClientGame::UpdatePlayerTarget(void) +{ + CControllerState ControllerState; + m_pLocalPlayer->GetControllerState(ControllerState); + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + + // Ignore the local player so we don't get hit + m_pLocalPlayer->WorldIgnore(true); + + // Run a process line of sight and look for an entity we target + CEntity* pColEntity = NULL; + CColPoint* pColPoint = NULL; + g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pColEntity); + + // Unignore the local player again + m_pLocalPlayer->WorldIgnore(false); + + // Kill the colpoint or we get a severe memoryleak + if (pColPoint) + pColPoint->Destroy(); + + if (pColEntity != m_pTargetedGameEntity) + { + m_pTargetedGameEntity = pColEntity; + + if (pColEntity) + { + m_pTargetedEntity = m_pManager->FindEntity(pColEntity); + } + else + m_pTargetedEntity = NULL; + + // Store the last targeted player's id + if (m_pTargetedEntity && m_pTargetedEntity->GetType() == CCLIENTPLAYER) + { + m_TargetedPlayerID = m_pTargetedEntity->GetID(); + } + else + m_TargetedPlayerID = INVALID_ELEMENT_ID; + + // Send the target + ElementID TargetID = INVALID_ELEMENT_ID; + if (m_pTargetedEntity && !m_pTargetedEntity->IsLocalEntity()) + { + TargetID = m_pTargetedEntity->GetID(); + } + + CBitStream bitStream; + bitStream.pBitStream->Write(TargetID); + m_pNetAPI->RPC(PLAYER_TARGET, bitStream.pBitStream); + + // Call our onClientPlayerTarget event + CLuaArguments Arguments; + if (m_pTargetedEntity) + Arguments.PushElement(m_pTargetedEntity); + else + Arguments.PushBoolean(false); + m_pLocalPlayer->CallEvent("onClientPlayerTarget", Arguments, true); + } +} + +void CClientGame::UpdatePlayerWeapons(void) +{ + // Check whether we changed weapon slots + eWeaponSlot currentSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + if (currentSlot != m_lastWeaponSlot) + { + CLuaArguments Arguments; + Arguments.PushNumber(m_lastWeaponSlot); + Arguments.PushNumber(currentSlot); + bool bCancelled = !m_pLocalPlayer->CallEvent("onClientPlayerWeaponSwitch", Arguments, true); + + if (bCancelled) + { + // Save the current ammo in clip + unsigned short usAmmoInClip = 0; + CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); + if (pWeapon) + usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); + + // Force it back to the old slot + m_pLocalPlayer->SetCurrentWeaponSlot(m_lastWeaponSlot); + + // Restore the ammo in clip that there was in that slot + if (usAmmoInClip > 0) + m_pLocalPlayer->GetWeapon()->SetAmmoInClip(usAmmoInClip); + } + else + { + CBitStream bitStream; + CWeapon* pWeapon = m_pLocalPlayer->GetWeapon(); + NetBitStreamInterface& BitStream = *(bitStream.pBitStream); + SWeaponSlotSync slot; + + // Always send bit in case server is not in sync + if ((BitStream.Version() >= 0x44 && m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN) || BitStream.Version() >= 0x4D) + { + CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); + if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && + (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || + (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) + BitStream.WriteBit(true); + else + BitStream.WriteBit(false); + } + + if (pWeapon) + { + /* Send a packet to the server with info about the new weapon, + so the server stays in sync reliably */ + unsigned int uiSlot = static_cast(pWeapon->GetSlot()); + slot.data.uiSlot = uiSlot; + BitStream.Write(&slot); + + if (CWeaponNames::DoesSlotHaveAmmo(uiSlot)) + { + SWeaponAmmoSync ammo(pWeapon->GetType(), true, true); + ammo.data.usAmmoInClip = static_cast(pWeapon->GetAmmoInClip()); + ammo.data.usTotalAmmo = static_cast(pWeapon->GetAmmoTotal()); + BitStream.Write(&ammo); + } + } + else + { + slot.data.uiSlot = 0; + BitStream.Write(&slot); + } + + m_pNetAPI->RPC(PLAYER_WEAPON, bitStream.pBitStream); + m_lastWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + } + } +} + +void CClientGame::UpdateTrailers(void) +{ + // This function is here to re-attach trailers if they fall off + + unsigned long ulCurrentTime = GetTickCount32(); + + CClientVehicle * pVehicle = NULL, *pTrailer = NULL; + CVehicle * pGameVehicle = NULL, *pGameTrailer = NULL; + unsigned long ulIllegalTowBreakTime; + vector::const_iterator iterVehicles = m_pVehicleManager->StreamedBegin(); + for (; iterVehicles != m_pVehicleManager->StreamedEnd(); iterVehicles++) + { + pVehicle = *iterVehicles; + ulIllegalTowBreakTime = pVehicle->GetIllegalTowBreakTime(); + + // Do we have an illegal break? + if (ulIllegalTowBreakTime != 0) + { + // Has it been atleast 1 second since the break + if (ulCurrentTime > (ulIllegalTowBreakTime + 1000)) + { + // Try to re-attach them + CClientVehicle* pTowedBy = pVehicle->GetTowedByVehicle(); + if (pTowedBy) + { + // Little hack to keep illegaly detached trailers close to their tower + CVector vecPosition; + pVehicle->GetPosition(vecPosition); + pVehicle->SetPosition(vecPosition); + + pGameVehicle = pTowedBy->GetGameVehicle(); + pGameTrailer = pVehicle->GetGameVehicle(); + if (pGameVehicle && pGameTrailer) + { + // pGameTrailer->SetTowLink ( pGameVehicle ); + CVector vecRotation; + pTowedBy->GetRotationRadians(vecRotation); + pVehicle->SetRotationRadians(vecRotation); + pTowedBy->InternalSetTowLink(pVehicle); + } + } + + // Reset the break time, even if we couldnt re-attach it + pVehicle->SetIllegalTowBreakTime(0); + } + } + } +} + +void CClientGame::UpdateFireKey(void) +{ + if (m_pLocalPlayer) + { + SBindableGTAControl* pControl = g_pCore->GetKeyBinds()->GetBindableFromControl("fire"); + + // Is our 'fire' control enabled? + if (pControl->bEnabled) + { + // ** Satchel charge detonation ** + { + // Do we have a detonator in our hand? + if (m_pLocalPlayer->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_DETONATOR) + { + // Planted any satchels? + if (m_pLocalPlayer->CountProjectiles(WEAPONTYPE_REMOTE_SATCHEL_CHARGE) > 0) + { + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + + // Tell the server we want to detonate our satchels + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + g_pNet->SendPacket(PACKET_ID_DETONATE_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } + // Remove the detonator if we dont have any satchels planted + else + { + m_pLocalPlayer->RemoveWeapon(WEAPONTYPE_DETONATOR); + } + } + } + + // Has our control state been cut short? + if (!pControl->bState) + return; + + // ** Stealth kill ** + { + if (m_pLocalPlayer->IsStealthAiming()) + { + // Do we have a target ped? + CClientPed* pTargetPed = m_pLocalPlayer->GetTargetedPed(); + if (pTargetPed) + { + // Do we have a target player? + if (IS_PLAYER(pTargetPed)) + { + CClientPlayer* pTargetPlayer = static_cast(pTargetPed); + + // Is the targetted player on a team + CClientTeam* pTeam = pTargetPlayer->GetTeam(); + if (pTeam) + { + // Is this friendly-fire? + if (pTargetPlayer->IsOnMyTeam(m_pLocalPlayer) && !pTeam->GetFriendlyFire()) + { + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + return; + } + } + } + CPlayerPed* pGameTarget = static_cast(pTargetPed)->GetGamePlayer(); + if (pGameTarget) + { + // Would GTA let us stealth kill now? + if (m_pLocalPlayer->GetGamePlayer()->GetPedIntelligence()->TestForStealthKill(pGameTarget, false)) + { + // Grab our local position + CVector vecLocalPosition; + m_pLocalPlayer->GetPosition(vecLocalPosition); + + // Grab the target's position + CVector vecTargetPosition; + pTargetPed->GetPosition(vecTargetPosition); + + // Work out an angle between the players, and set this as we initiate our knife kill + float fAngle = AngleBetweenPoints2D(vecLocalPosition, vecTargetPosition); + m_pLocalPlayer->SetCurrentRotation(fAngle); + + // Change the state back to false so this press doesn't do anything else + pControl->bState = false; + CLuaArguments Arguments; + Arguments.PushElement(pTargetPed); + if (m_pLocalPlayer->CallEvent("onClientPlayerStealthKill", Arguments, false)) + { + if (pTargetPed->IsLocalEntity()) + { + CStaticFunctionDefinitions::KillPed(*pTargetPed, m_pLocalPlayer, 4 /*WEAPONTYPE_KNIFE*/, 9 /*BODYPART_HEAD*/, true); + return; + } + + // Lets request a stealth kill + CBitStream bitStream; + bitStream.pBitStream->Write(pTargetPed->GetID()); + m_pNetAPI->RPC(REQUEST_STEALTH_KILL, bitStream.pBitStream); + } + else + { + return; + } + } + } + } + } + } + } + } +} + +void CClientGame::UpdateStunts(void) +{ + // * Two wheeler * + static unsigned long ulLastCarTwoWheelCounter = 0; + static float fLastCarTwoWheelDist = 0.0f; + unsigned long ulTemp = g_pGame->GetPlayerInfo()->GetCarTwoWheelCounter(); + // Did we start a stunt? + if (ulLastCarTwoWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("2wheeler"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastCarTwoWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("2wheeler"); + Arguments.PushNumber(ulLastCarTwoWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastCarTwoWheelCounter = ulTemp; + fLastCarTwoWheelDist = g_pGame->GetPlayerInfo()->GetCarTwoWheelDist(); + + // * Wheelie * + static unsigned long ulLastBikeRearWheelCounter = 0; + static float fLastBikeRearWheelDist = 0.0f; + ulTemp = g_pGame->GetPlayerInfo()->GetBikeRearWheelCounter(); + // Did we start a stunt? + if (ulLastBikeRearWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("wheelie"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastBikeRearWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("wheelie"); + Arguments.PushNumber(ulLastBikeRearWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastBikeRearWheelCounter = ulTemp; + fLastBikeRearWheelDist = g_pGame->GetPlayerInfo()->GetBikeRearWheelDist(); + + // * Stoppie * + static unsigned long ulLastBikeFrontWheelCounter = 0; + static float fLastBikeFrontWheelDist = 0.0f; + ulTemp = g_pGame->GetPlayerInfo()->GetBikeFrontWheelCounter(); + // Did we start a stunt? + if (ulLastBikeFrontWheelCounter == 0 && ulTemp != 0) + { + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("stoppie"); + m_pLocalPlayer->CallEvent("onClientPlayerStuntStart", Arguments, true); + } + // Did we finish a stunt? + else if (ulLastBikeFrontWheelCounter != 0 && ulTemp == 0) + { + float fDistance = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); + + // Call our stunt event + CLuaArguments Arguments; + Arguments.PushString("stoppie"); + Arguments.PushNumber(ulLastBikeFrontWheelCounter); + Arguments.PushNumber(fDistance); + m_pLocalPlayer->CallEvent("onClientPlayerStuntFinish", Arguments, true); + } + ulLastBikeFrontWheelCounter = ulTemp; + fLastBikeFrontWheelDist = g_pGame->GetPlayerInfo()->GetBikeFrontWheelDist(); +} + +void CClientGame::StaticUpdateFireKey(CControlFunctionBind* pBind) +{ + g_pClientGame->UpdateFireKey(); +} + +void CClientGame::ChangeVehicleWeapon(bool bNext) +{ + if (m_pLocalPlayer && m_pLocalPlayer->GetRealOccupiedVehicle()) + { + eWeaponSlot currentWeaponSlot = m_pLocalPlayer->GetCurrentWeaponSlot(); + eWeaponSlot weaponSlot = currentWeaponSlot; + CWeapon* pWeapon = NULL; + while (!pWeapon || pWeapon->GetType() == WEAPONTYPE_UNARMED) + { + if (bNext) + { + if (weaponSlot == WEAPONSLOT_TYPE_DETONATOR) + { + weaponSlot = WEAPONSLOT_TYPE_UNARMED; + break; + } + + weaponSlot = (eWeaponSlot)(weaponSlot + 1); + + if (weaponSlot == currentWeaponSlot) + break; + + pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); + } + else + { + if (weaponSlot == WEAPONSLOT_TYPE_UNARMED) + { + if (weaponSlot != currentWeaponSlot) + break; + weaponSlot = WEAPONSLOT_TYPE_DETONATOR; + } + + weaponSlot = (eWeaponSlot)(weaponSlot - 1); + + if (weaponSlot == currentWeaponSlot) + break; + + pWeapon = m_pLocalPlayer->GetWeapon(weaponSlot); + } + } + if (pWeapon || weaponSlot == WEAPONSLOT_TYPE_UNARMED) + { + m_pLocalPlayer->SetCurrentWeaponSlot(weaponSlot); + } + } +} + +void CClientGame::ResetVehicleInOut(void) +{ + m_ulLastVehicleInOutTime = 0; + m_bIsGettingOutOfVehicle = false; + m_bIsGettingIntoVehicle = false; + m_bIsJackingVehicle = false; + m_bIsGettingJacked = false; + m_VehicleInOutID = INVALID_ELEMENT_ID; + m_ucVehicleInOutSeat = 0xFF; + m_bNoNewVehicleTask = false; + m_NoNewVehicleTaskReasonID = INVALID_ELEMENT_ID; + m_pGettingJackedBy = NULL; +} + +void CClientGame::SetAllDimensions(unsigned short usDimension) +{ + m_pManager->GetMarkerStreamer()->SetDimension(usDimension); + m_pManager->GetObjectStreamer()->SetDimension(usDimension); + m_pManager->GetObjectLodStreamer()->SetDimension(usDimension); + m_pManager->GetPickupStreamer()->SetDimension(usDimension); + m_pManager->GetPlayerStreamer()->SetDimension(usDimension); + m_pManager->GetRadarAreaManager()->SetDimension(usDimension); + m_pManager->GetVehicleStreamer()->SetDimension(usDimension); + m_pManager->GetRadarMarkerManager()->SetDimension(usDimension); + m_pManager->GetSoundManager()->SetDimension(usDimension); + m_pManager->GetPointLightsManager()->SetDimension(usDimension); + m_pManager->GetWaterManager()->SetDimension(usDimension); + m_pNametags->SetDimension(usDimension); + m_pCamera->SetDimension(usDimension); +} + +bool CClientGame::StaticKeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) +{ + return g_pClientGame->KeyStrokeHandler(strKey, bState, bIsConsoleInputKey); +} + +bool CClientGame::KeyStrokeHandler(const SString& strKey, bool bState, bool bIsConsoleInputKey) +{ + // Do we have a root yet? + if (m_pRootEntity) + { + // Ignore keydown/up pair if main menu is displayed, or console input will use the character + bool bIgnore = false; + if (bState) + { + auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; + bool isMouseKey = strKey.substr(0, 5) == "mouse"; + + if (g_pCore->IsMenuVisible() || (g_pCore->GetConsole()->IsInputActive() && bIsConsoleInputKey) || + (pFocusedBrowser && !pFocusedBrowser->IsLocal() && !isMouseKey)) + + bIgnore = true; // Ignore this keydown and the matching keyup + else + MapInsert(m_AllowKeyUpMap, strKey); // Use this keydown and the matching keyup + } + else + { + if (!MapContains(m_AllowKeyUpMap, strKey)) + bIgnore = true; // Ignore this keyup + else + MapRemove(m_AllowKeyUpMap, strKey); // Use this keyup + } + + if (!bIgnore) + { + bool bAllow = true; + // Call our key-stroke event + CLuaArguments Arguments; + Arguments.PushString(strKey); + Arguments.PushBoolean(bState); + bAllow = m_pRootEntity->CallEvent("onClientKey", Arguments, false); + if (bState == true) + { + if (bAllow == false && strKey == "escape") + { + if (m_bLastKeyWasEscapeCancelled) + { + // Escape cannot be skipped twice + bAllow = true; + m_bLastKeyWasEscapeCancelled = false; + } + else + m_bLastKeyWasEscapeCancelled = true; + } + else + m_bLastKeyWasEscapeCancelled = false; + } + return bAllow; + } + } + m_bLastKeyWasEscapeCancelled = false; + return true; +} + +bool CClientGame::StaticCharacterKeyHandler(WPARAM wChar) +{ + return g_pClientGame->CharacterKeyHandler(wChar); +} + +bool CClientGame::CharacterKeyHandler(WPARAM wChar) +{ + // Do we have a root yet? + if (m_pRootEntity && g_pCore->IsMenuVisible() == false && g_pCore->GetConsole()->IsInputActive() == false) + { + // Cancel event if remote browser is focused + auto pFocusedBrowser = g_pCore->IsWebCoreLoaded() ? g_pCore->GetWebCore()->GetFocusedWebView() : nullptr; + if (pFocusedBrowser && !pFocusedBrowser->IsLocal()) + return false; + + // Safe character? + if (wChar >= 32) + { + // Generate a null-terminating string for our character + wchar_t wUNICODE[2] = { wChar, '\0' }; + + // Convert our UTF character into an ANSI string + SString strANSI = UTF16ToMbUTF8(wUNICODE); + + // Call our character event + CLuaArguments Arguments; + Arguments.PushString(strANSI); + m_pRootEntity->CallEvent("onClientCharacter", Arguments, false); + } + } + + return false; +} + +void CClientGame::StaticProcessClientKeyBind(CKeyFunctionBind* pBind) +{ + g_pClientGame->ProcessClientKeyBind(pBind); +} + +void CClientGame::ProcessClientKeyBind(CKeyFunctionBind* pBind) +{ + m_pScriptKeyBinds->ProcessKey(pBind->boundKey->szKey, pBind->bHitState, SCRIPT_KEY_BIND_FUNCTION); +} + +void CClientGame::StaticProcessClientControlBind(CControlFunctionBind* pBind) +{ + g_pClientGame->ProcessClientControlBind(pBind); +} + +void CClientGame::ProcessClientControlBind(CControlFunctionBind* pBind) +{ + m_pScriptKeyBinds->ProcessKey(pBind->control->szControl, pBind->bHitState, SCRIPT_KEY_BIND_CONTROL_FUNCTION); +} + +void CClientGame::StaticProcessServerKeyBind(CKeyFunctionBind* pBind) +{ + g_pClientGame->ProcessServerKeyBind(pBind); +} + +void CClientGame::ProcessServerKeyBind(CKeyFunctionBind* pBind) +{ + const char* szName = pBind->boundKey->szKey; + unsigned char ucNameLength = (unsigned char)strlen(szName); + CBitStream bitStream; + bitStream.pBitStream->WriteBit(false); + bitStream.pBitStream->WriteBit(pBind->bHitState); + bitStream.pBitStream->Write(szName, ucNameLength); + m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); +} + +void CClientGame::StaticProcessServerControlBind(CControlFunctionBind* pBind) +{ + g_pClientGame->ProcessServerControlBind(pBind); +} + +void CClientGame::ProcessServerControlBind(CControlFunctionBind* pBind) +{ + const char* szName = pBind->control->szControl; + unsigned char ucNameLength = (unsigned char)strlen(szName); + CBitStream bitStream; + bitStream.pBitStream->WriteBit(true); + bitStream.pBitStream->WriteBit(pBind->bHitState); + bitStream.pBitStream->Write(szName, ucNameLength); + m_pNetAPI->RPC(KEY_BIND, bitStream.pBitStream); +} + +bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + bool bCursorForcedVisible = g_pCore->IsCursorForcedVisible(); + bool bMenuVisible = g_pCore->IsMenuVisible(); + bool bConsoleVisible = g_pCore->GetConsole()->IsVisible(); + + if (bCursorForcedVisible) + { + if (!bMenuVisible && !bConsoleVisible) + { + if (m_bCursorEventsEnabled) + { + unsigned char ucButtonHit = 0xFF; + switch (uMsg) + { + case WM_LBUTTONDOWN: + ucButtonHit = 0; + break; + case WM_LBUTTONUP: + ucButtonHit = 1; + break; + case WM_MBUTTONDOWN: + ucButtonHit = 2; + break; + case WM_MBUTTONUP: + ucButtonHit = 3; + break; + case WM_RBUTTONDOWN: + ucButtonHit = 4; + break; + case WM_RBUTTONUP: + ucButtonHit = 5; + break; + } + if (ucButtonHit != 0xFF) + { + int iX = LOWORD(lParam); + int iY = HIWORD(lParam); + + CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); + + /* + // (IJs) why are these relative? it doesn't make sense + CVector2D vecCursorPosition ( ( ( float ) iX ) / vecResolution.fX, + ( ( float ) iY ) / vecResolution.fY ); + */ + + CVector2D vecCursorPosition((float)iX, (float)iY); + + CVector vecOrigin, vecTarget, vecScreen((float)iX, (float)iY, 300.0f); + g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); + + // Grab the camera position + CCamera* pCamera = g_pGame->GetCamera(); + CCam* pCam = pCamera->GetCam(pCamera->GetActiveCam()); + CMatrix matCamera; + pCamera->GetMatrix(&matCamera); + vecOrigin = matCamera.vPos; + + CColPoint* pColPoint = NULL; + CEntity* pGameEntity = NULL; + + // Grab the collision point/entity + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pColPoint, &pGameEntity); + + CVector vecCollision; + ElementID CollisionEntityID = INVALID_ELEMENT_ID; + CClientEntity* pCollisionEntity = NULL; + if (bCollision && pColPoint) + { + vecCollision = pColPoint->GetPosition(); + if (pGameEntity) + { + CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity); + if (pEntity) + { + pCollisionEntity = pEntity; + if (!pEntity->IsLocalEntity()) + CollisionEntityID = pEntity->GetID(); + } + } + } + else + { + vecCollision = vecTarget; + } + + // Destroy the colpoint so we don't get a leak + if (pColPoint) + { + pColPoint->Destroy(); + } + + const char* szButton = NULL; + const char* szState = NULL; + switch (ucButtonHit) + { + case 0: + szButton = "left"; + szState = "down"; + break; + case 1: + szButton = "left"; + szState = "up"; + break; + case 2: + szButton = "middle"; + szState = "down"; + break; + case 3: + szButton = "middle"; + szState = "up"; + break; + case 4: + szButton = "right"; + szState = "down"; + break; + case 5: + szButton = "right"; + szState = "up"; + break; + } + if (szButton && szState) + { + if (std::isnan(vecCollision.fX)) + vecCollision.fX = 0; + if (std::isnan(vecCollision.fY)) + vecCollision.fY = 0; + if (std::isnan(vecCollision.fZ)) + vecCollision.fZ = 0; + + // Call the event for the client + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(vecCursorPosition.fX); + Arguments.PushNumber(vecCursorPosition.fY); + Arguments.PushNumber(vecCollision.fX); + Arguments.PushNumber(vecCollision.fY); + Arguments.PushNumber(vecCollision.fZ); + if (pCollisionEntity) + Arguments.PushElement(pCollisionEntity); + else + Arguments.PushBoolean(false); + m_pRootEntity->CallEvent("onClientClick", Arguments, false); + + // Send the button, cursor position, 3d position and the entity collided with + CBitStream bitStream; + + SMouseButtonSync button; + button.data.ucButton = ucButtonHit; + bitStream.pBitStream->Write(&button); + + bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fX)); + bitStream.pBitStream->WriteCompressed(static_cast(vecCursorPosition.fY)); + + SPositionSync position(false); + position.data.vecPosition = vecCollision; + bitStream.pBitStream->Write(&position); + + if (CollisionEntityID != INVALID_ELEMENT_ID) + { + bitStream.pBitStream->WriteBit(true); + bitStream.pBitStream->Write(CollisionEntityID); + } + else + bitStream.pBitStream->WriteBit(false); + + m_pNetAPI->RPC(CURSOR_EVENT, bitStream.pBitStream); + + if (strcmp(szState, "down") == 0) + { + CVector2D vecDelta = m_vecLastCursorPosition - vecCursorPosition; + + if ((GetTickCount32() - m_ulLastClickTick) < DOUBLECLICK_TIMEOUT && vecDelta.Length() <= DOUBLECLICK_MOVE_THRESHOLD) + { + // Call the event for the client + CLuaArguments DoubleClickArguments; + DoubleClickArguments.PushString(szButton); + DoubleClickArguments.PushNumber(vecCursorPosition.fX); + DoubleClickArguments.PushNumber(vecCursorPosition.fY); + DoubleClickArguments.PushNumber(vecCollision.fX); + DoubleClickArguments.PushNumber(vecCollision.fY); + DoubleClickArguments.PushNumber(vecCollision.fZ); + if (pCollisionEntity) + DoubleClickArguments.PushElement(pCollisionEntity); + else + DoubleClickArguments.PushBoolean(false); + m_pRootEntity->CallEvent("onClientDoubleClick", DoubleClickArguments, false); + } + + m_ulLastClickTick = GetTickCount32(); + m_vecLastCursorPosition = vecCursorPosition; + } + + return true; + } + } + } + } + } + switch (uMsg) + { + case WM_MOUSEMOVE: + { + int iX = LOWORD(lParam), iY = HIWORD(lParam); + static int iPreviousX = 0, iPreviousY = 0; + if (iX != iPreviousX || iY != iPreviousY) + { + iPreviousX = iX, iPreviousY = iY; + + CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); + CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); + + CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); + g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); + + // Call the onClientCursorMove event + CLuaArguments Arguments; + Arguments.PushNumber((double)vecCursorPosition.fX); + Arguments.PushNumber((double)vecCursorPosition.fY); + Arguments.PushNumber((double)iX); + Arguments.PushNumber((double)iY); + Arguments.PushNumber((double)vecTarget.fX); + Arguments.PushNumber((double)vecTarget.fY); + Arguments.PushNumber((double)vecTarget.fZ); + m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); + } + break; + } + } + return false; +} + +CClientPlayer* CClientGame::GetClosestRemotePlayer(const CVector& vecPosition, float fMaxDistance) +{ + CClientPlayer* pClosest = NULL; + float fDistance = 0.0f, fTemp; + CVector vecTemp; + CClientPlayer* pPlayer; + vector::const_iterator iter = m_pPlayerManager->IterBegin(); + for (; iter != m_pPlayerManager->IterEnd(); ++iter) + { + pPlayer = *iter; + if (!pPlayer->IsLocalPlayer() && !pPlayer->IsDeadOnNetwork() && pPlayer->GetHealth() > 0) + { + // Ensure remote player is alive and sending position updates + ulong ulTimeSinceLastPuresync = CClientTime::GetTime() - pPlayer->GetLastPuresyncTime(); + if (ulTimeSinceLastPuresync < static_cast(g_TickRateSettings.iPureSync) * 2) + { + pPlayer->GetPosition(vecTemp); + fTemp = DistanceBetweenPoints3D(vecPosition, vecTemp); + if (fTemp < fMaxDistance) + { + if (!pClosest || fTemp < fDistance) + { + pClosest = pPlayer; + fDistance = fTemp; + } + } + } + } + } + return pClosest; +} + +void CClientGame::SetGameSpeed(float fSpeed) +{ + g_pGame->SetGameSpeed(fSpeed); + m_fGameSpeed = fSpeed; +} + +void CClientGame::SetMinuteDuration(unsigned long ulDelay) +{ + g_pGame->SetMinuteDuration(ulDelay); + m_ulMinuteDuration = ulDelay; +} + +void CClientGame::SetMoney(long lMoney, bool bInstant) +{ + g_pGame->GetPlayerInfo()->SetPlayerMoney(lMoney, bInstant); + m_lMoney = lMoney; +} + +void CClientGame::SetWanted(DWORD dwWanted) +{ + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(dwWanted); + m_dwWanted = dwWanted; +} + +void CClientGame::AddBuiltInEvents(void) +{ + // Resource events + m_Events.AddEvent("onClientResourceStart", "resource", NULL, false); + m_Events.AddEvent("onClientResourceStop", "resource", NULL, false); + + // Element events + m_Events.AddEvent("onClientElementDataChange", "name", NULL, false); + m_Events.AddEvent("onClientElementStreamIn", "", NULL, false); + m_Events.AddEvent("onClientElementStreamOut", "", NULL, false); + m_Events.AddEvent("onClientElementDestroy", "", NULL, false); + + // Player events + m_Events.AddEvent("onClientPlayerJoin", "", NULL, false); + m_Events.AddEvent("onClientPlayerQuit", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerTarget", "target", NULL, false); + m_Events.AddEvent("onClientPlayerSpawn", "team", NULL, false); + m_Events.AddEvent("onClientPlayerChangeNick", "oldNick", NULL, false); + m_Events.AddEvent("onClientPlayerVehicleEnter", "vehicle, seat", NULL, false); + m_Events.AddEvent("onClientPlayerVehicleExit", "vehicle, seat", NULL, false); + m_Events.AddEvent("onClientPlayerTask", "priority, slot, name", NULL, false); + m_Events.AddEvent("onClientPlayerWeaponSwitch", "previous, current", NULL, false); + m_Events.AddEvent("onClientPlayerStuntStart", "type", NULL, false); + m_Events.AddEvent("onClientPlayerStuntFinish", "type, time, distance", NULL, false); + m_Events.AddEvent("onClientPlayerRadioSwitch", "", NULL, false); + m_Events.AddEvent("onClientPlayerDamage", "attacker, weapon, bodypart", NULL, false); + m_Events.AddEvent("onClientPlayerWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPlayerWasted", "", NULL, false); + m_Events.AddEvent("onClientPlayerChoke", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceStart", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceStop", "", NULL, false); + m_Events.AddEvent("onClientPlayerVoicePause", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerVoiceResumed", "reason", NULL, false); + m_Events.AddEvent("onClientPlayerStealthKill", "target", NULL, false); + m_Events.AddEvent("onClientPlayerHitByWaterCannon", "vehicle", NULL, false); + m_Events.AddEvent("onClientPlayerHeliKilled", "heli", NULL, false); + m_Events.AddEvent("onClientPlayerPickupHit", "pickup, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPlayerPickupLeave", "pickup, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPlayerNetworkStatus", "type, ticks", NULL, false); + + // Ped events + m_Events.AddEvent("onClientPedDamage", "attacker, weapon, bodypart", NULL, false); + m_Events.AddEvent("onClientPedWeaponFire", "weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement", NULL, false); + m_Events.AddEvent("onClientPedWasted", "", NULL, false); + m_Events.AddEvent("onClientPedChoke", "", NULL, false); + m_Events.AddEvent("onClientPedHeliKilled", "heli", NULL, false); + m_Events.AddEvent("onClientPedHitByWaterCannon", "vehicle", NULL, false); + + // Vehicle events + m_Events.AddEvent("onClientVehicleRespawn", "", NULL, false); + m_Events.AddEvent("onClientVehicleEnter", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleExit", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleStartEnter", "player, seat", NULL, false); + m_Events.AddEvent("onClientVehicleStartExit", "player, seat", NULL, false); + m_Events.AddEvent("onClientTrailerAttach", "towedBy", NULL, false); + m_Events.AddEvent("onClientTrailerDetach", "towedBy", NULL, false); + m_Events.AddEvent("onClientVehicleExplode", "", NULL, false); + m_Events.AddEvent("onClientVehicleCollision", "collidedelement, damageImpulseMag, bodypart, x, y, z, velX, velY, velZ", NULL, false); + m_Events.AddEvent("onClientVehicleDamage", "attacker, weapon, loss, x, y, z, tyre", NULL, false); + m_Events.AddEvent("onClientVehicleNitroStateChange", "activated", NULL, false); + + // GUI events + m_Events.AddEvent("onClientGUIClick", "button, state, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIDoubleClick", "button, state, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIMouseDown", "button, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIMouseUp", "button, absoluteX, absoluteY", NULL, false); + m_Events.AddEvent("onClientGUIScroll", "element", NULL, false); + m_Events.AddEvent("onClientGUIChanged", "element", NULL, false); + m_Events.AddEvent("onClientGUIAccepted", "element", NULL, false); + // m_Events.AddEvent ( "onClientGUIClose", "element", NULL, false ); + // m_Events.AddEvent ( "onClientGUIKeyDown", "element", NULL, false ); + m_Events.AddEvent("onClientGUITabSwitched", "element", NULL, false); + m_Events.AddEvent("onClientGUIComboBoxAccepted", "element", NULL, false); + + // Input events + m_Events.AddEvent("onClientDoubleClick", "button, screenX, screenY, worldX, worldY, worldZ, element", NULL, false); + m_Events.AddEvent("onClientMouseMove", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseEnter", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseLeave", "screenX, screenY", NULL, false); + m_Events.AddEvent("onClientMouseWheel", "", NULL, false); + m_Events.AddEvent("onClientGUIMove", "", NULL, false); + m_Events.AddEvent("onClientGUISize", "", NULL, false); + m_Events.AddEvent("onClientGUIFocus", "", NULL, false); + m_Events.AddEvent("onClientGUIBlur", "", NULL, false); + m_Events.AddEvent("onClientKey", "key, state", NULL, false); + m_Events.AddEvent("onClientCharacter", "character", NULL, false); + + // Console events + m_Events.AddEvent("onClientConsole", "text", NULL, false); + + // Chat events + m_Events.AddEvent("onClientChatMessage", "test, r, g, b", NULL, false); + + // Debug events + m_Events.AddEvent("onClientDebugMessage", "message, level, file, line", NULL, false); + + // Game events + m_Events.AddEvent("onClientPreRender", "", NULL, false); + m_Events.AddEvent("onClientHUDRender", "", NULL, false); + m_Events.AddEvent("onClientRender", "", NULL, false); + m_Events.AddEvent("onClientMinimize", "", NULL, false); + m_Events.AddEvent("onClientRestore", "", NULL, false); + + // Cursor events + m_Events.AddEvent("onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false); + m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); + + // Transfer box event + m_Events.AddEvent("onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false); + + // Marker events + m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); + + // Marker events + m_Events.AddEvent("onClientPickupHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientPickupLeave", "entity, matchingDimension", NULL, false); + + // Col-shape events + m_Events.AddEvent("onClientColShapeHit", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientColShapeLeave", "entity, matchingDimension", NULL, false); + m_Events.AddEvent("onClientElementColShapeHit", "colShape, matchingDimension", NULL, false); + m_Events.AddEvent("onClientElementColShapeLeave", "colShape, matchingDimension", NULL, false); + + // Explosion events + m_Events.AddEvent("onClientExplosion", "x, y, z, type", NULL, false); + + // Projectile events + m_Events.AddEvent("onClientProjectileCreation", "creator", NULL, false); + + // Sound events + m_Events.AddEvent("onClientSoundStream", "success, length, streamName, error", NULL, false); + m_Events.AddEvent("onClientSoundFinishedDownload", "length", NULL, false); + m_Events.AddEvent("onClientSoundChangedMeta", "streamTitle", NULL, false); + m_Events.AddEvent("onClientSoundStarted", "reason", NULL, false); + m_Events.AddEvent("onClientSoundStopped", "reason", NULL, false); + m_Events.AddEvent("onClientSoundBeat", "time", NULL, false); + + // Object events + m_Events.AddEvent("onClientObjectDamage", "loss, attacker", NULL, false); + m_Events.AddEvent("onClientObjectBreak", "attacker", NULL, false); + + // Web events + m_Events.AddEvent("onClientBrowserWhitelistChange", "newPages", NULL, false); + m_Events.AddEvent("onClientBrowserCreated", "", NULL, false); + m_Events.AddEvent("onClientBrowserLoadingStart", "url, mainframe", NULL, false); + m_Events.AddEvent("onClientBrowserDocumentReady", "url", NULL, false); + m_Events.AddEvent("onClientBrowserLoadingFailed", "url, errorcode, errordescription", NULL, false); + m_Events.AddEvent("onClientBrowserNavigate", "url, isblocked", NULL, false); + m_Events.AddEvent("onClientBrowserPopup", "targeturl, openerurl, ispopup", NULL, false); + m_Events.AddEvent("onClientBrowserCursorChange", "cursor", NULL, false); + m_Events.AddEvent("onClientBrowserTooltip", "text", NULL, false); + m_Events.AddEvent("onClientBrowserInputFocusChanged", "gainedfocus", NULL, false); + m_Events.AddEvent("onClientBrowserResourceBlocked", "url, domain, reason", NULL, false); + + // Misc events + m_Events.AddEvent("onClientFileDownloadComplete", "fileName, success", NULL, false); + + m_Events.AddEvent("onClientWeaponFire", "ped, x, y, z", NULL, false); +} + +void CClientGame::DrawFPS(void) +{ + // Draw the background + float fResWidth = static_cast(g_pCore->GetGraphics()->GetViewportWidth()); + float fResHeight = static_cast(g_pCore->GetGraphics()->GetViewportHeight()); + g_pCore->GetGraphics()->DrawRectangle(0.75f * fResWidth, 0.22f * fResHeight, 0.25f * fResWidth, 0.04f * fResHeight, 0x78000000); + + static char x = 0; + static float fDisp = 0.0f; + if (x == 20) + { + x = 0; + fDisp = g_pGame->GetFPS(); + } + else + x++; + SString strBuffer("FrameRate: %4.2f\n", fDisp); + + // Print it + m_pDisplayManager->DrawText2D(strBuffer, CVector(0.76f, 0.23f, 0), 1.0f, 0xFFFFFFFF); +} + +#ifdef MTA_DEBUG + +void CClientGame::DrawTasks(CClientPlayer* pPlayer) +{ + CTask* pTask = NULL; + CTask* pSubTask = NULL; + + // Got a local player model + if (pPlayer) + { + CTaskManager* man = pPlayer->GetTaskManager(); + if (man == NULL) + return; + if ((unsigned long)man == 0xDDDDDDDD) + { + m_pDisplayManager->DrawText2D("HELP! MANAGER FUCKED", CVector(0.05f, 0.5f, 0), 1.0f); + return; + } + + // Grab the current task + SString strOutput; + SString strSubOutput; + + pTask = man->GetTask(TASK_PRIORITY_PHYSICAL_RESPONSE); + strOutput += SString("Physical Response: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_TEMP); + strOutput += SString("Event Response Temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_EVENT_RESPONSE_NONTEMP); + strOutput += SString("Event Response Non-temp: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_PRIMARY); + strOutput += SString("Primary: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTask(TASK_PRIORITY_DEFAULT); + strOutput += SString("Default: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_ATTACK); + strOutput += SString("Secondary Attack: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_DUCK); + strOutput += SString("Secondary Duck: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_SAY); + strOutput += SString("Secondary Say: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_FACIAL_COMPLEX); + strOutput += SString("Secondary Facial Complex: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM); + strOutput += SString("Secondary Partial Anim: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + pTask = man->GetTaskSecondary(TASK_SECONDARY_IK); + strOutput += SString("Secondary IK: %s\n", pTask ? (pTask->GetTaskName()) : ("N/A")); + strSubOutput += SString("%s\n", pTask && pTask->GetSubTask() ? (pTask->GetSubTask()->GetTaskName()) : ("N/A")); + + m_pDisplayManager->DrawText2D(strOutput, CVector(0.05f, 0.5f, 0), 1.0f); + m_pDisplayManager->DrawText2D(strSubOutput, CVector(0.5f, 0.5f, 0), 1.0f); + } +} + +int iPlayerTask = 0; +void CClientGame::DrawPlayerDetails(CClientPlayer* pPlayer) +{ + // Get the info + CControllerState cs; + + pPlayer->GetControllerState(cs); + + CVector vecPosition; + pPlayer->GetPosition(vecPosition); + + float fRotation = pPlayer->GetCurrentRotation(); + float fCameraRotation = pPlayer->GetCameraRotation(); + float fHealth = pPlayer->GetHealth(); + bool bIsDucked = pPlayer->IsDucked(); + bool bWearingGoggles = pPlayer->IsWearingGoggles(); + bool bInVehicle = pPlayer->GetOccupiedVehicle() != NULL; + float fWeaponRange = 0.0f; + + unsigned char ucWeapon = 0; + unsigned char ucWeaponState = 0; + unsigned short usWeaponAmmo = 0; + CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); + if (pWeapon) + { + ucWeapon = static_cast(pWeapon->GetType()); + ucWeaponState = static_cast(pWeapon->GetState()); + usWeaponAmmo = static_cast(pWeapon->GetAmmoInClip()); + float fSkill = pPlayer->GetStat(g_pGame->GetStats()->GetSkillStatIndex(pWeapon->GetType())); + CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStatsFromSkillLevel(pWeapon->GetType(), fSkill); + fWeaponRange = pWeaponInfo->GetWeaponRange(); + } + + float fAimX, fAimY; + pPlayer->GetAim(fAimX, fAimY); + const CVector& vecAimSource = pPlayer->GetAimSource(); + const CVector& vecAimTarget = pPlayer->GetAimTarget(); + unsigned char ucDrivebyAim = pPlayer->GetVehicleAimAnim(); + + g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x10DE1212, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecAimSource, vecAimTarget, 1.0f, 0x90DE1212, false); + + CTask* pPrimaryTask = pPlayer->GetCurrentPrimaryTask(); + int iPrimaryTask = pPrimaryTask ? pPrimaryTask->GetTaskType() : -1; + + // Copy the stuff + SString strBuffer( + "Orient:\n" + "Position: %f %f %f\n" + "Rotation/camera: %f %f\n" + "Health: %f\n" + "\n" + "Keys:\n" + "LeftShoulder1: %hi\n" + "RightShoulder1: %hi\n" + "ButtonSquare: %hi\n" + "ButtonCross: %hi\n" + "ButtonCircle: %hi\n" + "ShockButtonL: %hi\n" + "PedWalk: %hi\n" + "VehicleMouseLook: %hi\n" + "LeftStickX: %hi\n" + "LeftStickY: %hi\n" + "\n" + "Misc:\n" + "Primary task: %d\n" + "Ducked: %u\n" + "Goggles: %u\n" + "In vehicle: %u\n" + "Weapon: %u\n" + "Weapon state: %u\n" + "Weapon ammo: %u\n" + "Weapon range: %f\n" + "Aim: %f %f\n" + "Aim source: %f %f %f\n" + "Aim target: %f %f %f\n" + "Driveby aim: %u\n" + "Frozen: %u\n", + vecPosition.fX, vecPosition.fY, vecPosition.fZ, fRotation, fCameraRotation, fHealth, cs.LeftShoulder1, cs.RightShoulder1, cs.ButtonSquare, + cs.ButtonCross, cs.ButtonCircle, cs.ShockButtonL, cs.m_bPedWalk, cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, iPrimaryTask, bIsDucked, + bWearingGoggles, bInVehicle, ucWeapon, ucWeaponState, usWeaponAmmo, fWeaponRange, fAimX, fAimY, vecAimSource.fX, vecAimSource.fY, vecAimSource.fZ, + vecAimTarget.fX, vecAimTarget.fY, vecAimTarget.fZ, ucDrivebyAim, pPlayer->IsFrozen()); + + // Draw it + m_pDisplayManager->DrawText2D(strBuffer, CVector(0.45f, 0.05f, 0), 1.0f, 0xFFFFFFFF); +} + +void CClientGame::DrawWeaponsyncData(CClientPlayer* pPlayer) +{ + CWeapon* pWeapon = pPlayer->GetWeapon(pPlayer->GetCurrentWeaponSlot()); + + if (pWeapon) + { + CVector vecSource; + CVector vecTarget; + + // red line: Draw their synced aim line + pPlayer->GetShotData(&vecSource, &vecTarget); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x10DE1212, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 2.0f, 0x90DE1212, false); + + // green line: Set muzzle as origin and perform a collision test for the target + CColPoint* pCollision; + CVector vecTemp; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecSource, &vecTarget, &pCollision, NULL); + if (pCollision) + { + if (bCollision) + { + CVector vecBullet = pCollision->GetPosition() - vecSource; + vecBullet.Normalize(); + CVector vecTarget = vecSource + (vecBullet * 200); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x1012DE12, true); + g_pCore->GetGraphics()->DrawLine3DQueued(vecSource, vecTarget, 0.5f, 0x9012DE12, false); + } + pCollision->Destroy(); + } + + if (m_pLocalPlayer != pPlayer) + { + // Draw information about their weapon state, total ammo and ammo in clip + CVector vecScreenPosition; + CVector vecPosition; + + pPlayer->GetPosition(vecPosition); + + vecPosition.fZ += 1.0f; + g_pCore->GetGraphics()->CalcScreenCoors(&vecPosition, &vecScreenPosition); + + SString strTemp; + int yoffset; + + yoffset = 0; + strTemp.Format("Ammo in clip: %d", pWeapon->GetAmmoInClip()); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + + yoffset = 15; + strTemp.Format("State: %d", pWeapon->GetState()); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); + g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + } + } +} + +void CClientGame::UpdateMimics(void) +{ + // Got a local player? + if (m_pLocalPlayer) + { + unsigned char ucWeaponType = 0; + unsigned char ucWeaponState = 0; + unsigned long ulWeaponAmmoInClip = 0; + eWeaponSlot weaponSlot = WEAPONSLOT_TYPE_UNARMED; + + CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(m_pLocalPlayer->GetCurrentWeaponSlot()); + if (pPlayerWeapon) + { + ucWeaponType = static_cast(pPlayerWeapon->GetType()); + ucWeaponState = static_cast(pPlayerWeapon->GetState()); + weaponSlot = pPlayerWeapon->GetSlot(); + ulWeaponAmmoInClip = pPlayerWeapon->GetAmmoInClip(); + } + + // Simulate lag (or not) + if (!m_bMimicLag || CClientTime::GetTime() >= m_ulLastMimicLag + 200) // TICK_RATE ) + { + m_ulLastMimicLag = CClientTime::GetTime(); + + // Grab the local data + CControllerState Controller; + m_pLocalPlayer->GetControllerState(Controller); + CVector vecPosition; + m_pLocalPlayer->GetPosition(vecPosition); + float fRotation = m_pLocalPlayer->GetCurrentRotation(); + CVector vecMoveSpeed; + m_pLocalPlayer->GetMoveSpeed(vecMoveSpeed); + float fHealth = m_pLocalPlayer->GetHealth(); + float fArmor = m_pLocalPlayer->GetArmor(); + float fCameraRotation = g_pGame->GetCamera()->GetCameraRotation(); + bool bDucked = m_pLocalPlayer->IsDucked(); + bool bWearingGoggles = m_pLocalPlayer->IsWearingGoggles(true); + bool bHasJetpack = m_pLocalPlayer->HasJetPack(); + bool bChoking = m_pLocalPlayer->IsChoking(); + bool bSunbathing = m_pLocalPlayer->IsSunbathing(); + bool bDoingDriveby = m_pLocalPlayer->IsDoingGangDriveby(); + bool bStealthAiming = m_pLocalPlayer->IsStealthAiming(); + + // Is the current weapon goggles (44 or 45) or a camera (43), or a detonator (40), don't apply the fire key + if (weaponSlot == 11 || weaponSlot == 12 || ucWeaponType == 43) + Controller.ButtonCircle = 0; + + CClientVehicle* pVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + unsigned int uiSeat = m_pLocalPlayer->GetOccupiedVehicleSeat(); + + CShotSyncData* pShotSync = g_pMultiplayer->GetLocalShotSyncData(); + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + float fAimX = pShotSync->m_fArmDirectionX; + float fAimY = pShotSync->m_fArmDirectionY; + char cVehicleAimDirection = pShotSync->m_cInVehicleAimDirection; + bool bAkimboUp = g_pMultiplayer->GetAkimboTargetUp(); + + /* + static CClientMarker *pOriginCorona = NULL, *pTargetCorona = NULL; + if ( pOriginCorona == NULL ) + { + pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); + pOriginCorona->SetColor ( 0, 255, 0, 255 ); + pOriginCorona->SetSize ( 0.5f ); + } + else + pOriginCorona->SetPosition ( vecOrigin ); + + if ( pTargetCorona == NULL ) + { + pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); + pTargetCorona->SetColor ( 255, 0, 0, 255 ); + pTargetCorona->SetSize ( 0.5f ); + } + else + pTargetCorona->SetPosition ( vecTarget );*/ + + // Apply this to each of our mimic players + unsigned int uiMimicIndex = 0; + list::const_iterator iterMimics = m_Mimics.begin(); + for (; iterMimics != m_Mimics.end(); ++iterMimics, ++uiMimicIndex) + { + vecPosition.fX += 4.0f; + vecOrigin.fX += 4.0f; + vecTarget.fX += 4.0f; + + CClientPlayer* pMimic = *iterMimics; + + pMimic->SetHealth(fHealth); + pMimic->LockHealth(fHealth); + pMimic->SetArmor(fArmor); + pMimic->LockArmor(fArmor); + pMimic->SetWearingGoggles(bWearingGoggles); + pMimic->SetHasJetPack(bHasJetpack); + pMimic->SetChoking(bChoking); + pMimic->SetSunbathing(bSunbathing); + pMimic->SetDoingGangDriveby(bDoingDriveby); + pMimic->SetStealthAiming(bStealthAiming); + + Controller.ShockButtonL = 0; + + if (m_bMimicLag) + { + pMimic->SetTargetPosition(vecPosition, TICK_RATE); + pMimic->SetMoveSpeed(vecMoveSpeed); + pMimic->SetControllerState(Controller); + pMimic->SetTargetRotation(fRotation); + pMimic->SetCameraRotation(fCameraRotation); + pMimic->Duck(bDucked); + } + else + { + pMimic->SetPosition(vecPosition); + pMimic->SetMoveSpeed(vecMoveSpeed); + pMimic->SetTargetRotation(fRotation); + pMimic->SetCameraRotation(fCameraRotation); + pMimic->SetControllerState(Controller); + pMimic->Duck(bDucked); + } + + if (ucWeaponType != 0) + { + if (ucWeaponType == 44 || ucWeaponType == 45) + { + Controller.ButtonCircle = 0; + } + + if (m_bMimicLag) + { + pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); + pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); + + pMimic->AddChangeWeapon(TICK_RATE, weaponSlot, (unsigned char)ulWeaponAmmoInClip); + } + else + { + CWeapon* pPlayerWeapon = pMimic->GetWeapon(); + eWeaponType eCurrentWeapon = static_cast(ucWeaponType); + if ((pPlayerWeapon && pPlayerWeapon->GetType() != eCurrentWeapon) || !pPlayerWeapon) + { + pPlayerWeapon = pMimic->GiveWeapon(eCurrentWeapon, ulWeaponAmmoInClip); + if (pPlayerWeapon) + { + pPlayerWeapon->SetAsCurrentWeapon(); + } + } + + if (pPlayerWeapon) + { + pPlayerWeapon->SetAmmoTotal(9999); + pPlayerWeapon->SetAmmoInClip(ulWeaponAmmoInClip); + pPlayerWeapon->SetState(static_cast(ucWeaponState)); + } + pMimic->SetAimInterpolated(TICK_RATE, fAimX, fAimY, bAkimboUp, cVehicleAimDirection); + pMimic->SetTargetTarget(TICK_RATE, vecOrigin, vecTarget); + } + } + else + { + pMimic->SetCurrentWeaponSlot(WEAPONSLOT_TYPE_UNARMED); + } + + CClientVehicle* pMimicVehicle = pMimic->GetOccupiedVehicle(); + if (pVehicle) + { + unsigned int uiModel; + CVector vecPosition, vecRotationDegrees; + CVector vecMoveSpeed, vecMoveSpeedMeters, vecTurnSpeed, vecVelocity; + float fHealth; + + uiModel = pVehicle->GetModel(); + pVehicle->GetPosition(vecPosition); + pVehicle->GetRotationDegrees(vecRotationDegrees); + pVehicle->GetMoveSpeed(vecMoveSpeed); + pVehicle->GetTurnSpeed(vecTurnSpeed); + fHealth = pVehicle->GetHealth(); + + if (pMimicVehicle && pMimicVehicle->GetModel() != uiModel) + { + delete pMimicVehicle; + pMimicVehicle = NULL; + } + + vecPosition.fX += ((float)(uiMimicIndex + 1) * 10.0f); + + if (pMimicVehicle == NULL) + { + pMimicVehicle = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, INVALID_ELEMENT_ID, uiModel, 0, 0); + pMimicVehicle->SetPosition(vecPosition); + + const SSlotStates& usUpgrades = pVehicle->GetUpgrades()->GetSlotStates(); + for (unsigned char uc = 0; uc < VEHICLE_UPGRADE_SLOTS; uc++) + { + if (usUpgrades[uc]) + { + pMimicVehicle->GetUpgrades()->AddUpgrade(usUpgrades[uc], true); + } + } + + m_vecLastMimicPos = vecPosition; + } + + if (m_bMimicLag) + { + pMimicVehicle->SetTargetPosition(vecPosition, TICK_RATE); + pMimicVehicle->SetTargetRotation(vecRotationDegrees, TICK_RATE); + pMimicVehicle->SetMoveSpeed(vecMoveSpeed); + pMimicVehicle->SetTurnSpeed(vecTurnSpeed); + } + else + { + pMimicVehicle->SetPosition(vecPosition); + pMimicVehicle->SetRotationDegrees(vecRotationDegrees); + pMimicVehicle->SetMoveSpeed(vecMoveSpeed); + pMimicVehicle->SetTurnSpeed(vecTurnSpeed); + } + pMimicVehicle->SetHealth(fHealth); + if (pMimic->GetOccupiedVehicle() != pMimicVehicle) + pMimic->WarpIntoVehicle(pMimicVehicle, uiSeat); + + unsigned int uiTrailerLoop = 0; + CClientVehicle* pTrailer = pVehicle->GetTowedVehicle(); + CClientVehicle* pMimicTrailer = NULL; + while (pTrailer) + { + uiModel = pTrailer->GetModel(); + pTrailer->GetPosition(vecPosition); + pTrailer->GetRotationDegrees(vecRotationDegrees); + pTrailer->GetMoveSpeed(vecMoveSpeed); + pTrailer->GetTurnSpeed(vecTurnSpeed); + fHealth = pTrailer->GetHealth(); + + pMimicTrailer = DynamicCast(CElementIDs::GetElement(static_cast(450 + uiMimicIndex + uiTrailerLoop))); + + if (pMimicTrailer && pMimicTrailer->GetModel() != uiModel) + { + delete pMimicTrailer; + pMimicTrailer = NULL; + } + + if (!pMimicTrailer) + { + pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, + static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); + pMimicVehicle->SetTowedVehicle(pMimicTrailer); + } + + pTrailer = pTrailer->GetTowedVehicle(); + pMimicTrailer = pMimicTrailer->GetTowedVehicle(); + uiTrailerLoop++; + } + if (pMimicTrailer) + { + if (pMimicTrailer->GetTowedByVehicle()) + { + pMimicTrailer->GetTowedByVehicle()->SetTowedVehicle(NULL); + } + } + } + else if (pMimicVehicle) + { + pMimic->RemoveFromVehicle(); + delete pMimicVehicle; + } + } + } + } +} + +void CClientGame::DoPaintballs(void) +{ + if (m_pLocalPlayer) + { + CVector vecOrigin, vecTarget; + m_pLocalPlayer->GetShotData(&vecOrigin, &vecTarget); + + CColPoint* pCollision = NULL; + CEntity* pCollisionEntity = NULL; + m_pLocalPlayer->WorldIgnore(true); + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionEntity); + m_pLocalPlayer->WorldIgnore(false); + + static list paintBalls; + if (paintBalls.size() >= 5) + { + CClientMarker* pCorona = paintBalls.back(); + delete pCorona; + paintBalls.pop_back(); + } + + CClientMarker* pCorona = new CClientMarker(m_pManager, INVALID_ELEMENT_ID, CClientMarker::MARKER_CORONA); + paintBalls.push_front(pCorona); + pCorona->SetSize(0.2f); + if (bCollision && pCollision) + { + pCorona->SetPosition(pCollision->GetPosition()); + pCorona->SetColor(SColorRGBA(255, 0, 0, 255)); + } + else + { + pCorona->SetPosition(vecTarget); + pCorona->SetColor(SColorRGBA(255, 255, 0, 255)); + } + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + } +} + +#endif + +void CClientGame::QuitPlayer(CClientPlayer* pPlayer, eQuitReason Reason) +{ + // Get the nick pointer and echo the quit message to the chat + const char* szNick = pPlayer->GetNick(); + const char* szReason = "Unknown"; + switch (Reason) + { + case QUIT_QUIT: + szReason = "Quit"; + break; + case QUIT_KICK: + szReason = "Kicked"; + break; + case QUIT_BAN: + szReason = "Banned"; + break; + case QUIT_CONNECTION_DESYNC: + szReason = "Bad Connection"; + break; + case QUIT_TIMEOUT: + szReason = "Timed Out"; + break; + } + + // In debug, make sure we don't look at this player's details +#ifdef MTA_DEBUG + if (m_pShowPlayer == pPlayer) + { + m_pShowPlayer = NULL; + } +#endif + + // Call our onClientPlayerQuit event + CLuaArguments Arguments; + Arguments.PushString(szReason); + pPlayer->CallEvent("onClientPlayerQuit", Arguments, true); + + // Detach the camera from this player if we're watching them + m_pManager->GetCamera()->UnreferencePlayer(pPlayer); + + // Was this player jacking us? + if (m_bIsGettingJacked && m_pGettingJackedBy == pPlayer) + { + ResetVehicleInOut(); + m_pLocalPlayer->RemoveFromVehicle(false); + m_pLocalPlayer->SetVehicleInOutState(VEHICLE_INOUT_NONE); + } + + // Delete the player + delete pPlayer; +} + +void CClientGame::Event_OnIngame(void) +{ + // Unpause the game + g_pGame->Pause(false); + + // Disable parts of the Hud + CHud* pHud = g_pGame->GetHud(); + pHud->SetComponentVisible(HUD_HELP_TEXT, false); + pHud->SetComponentVisible(HUD_VITAL_STATS, false); + pHud->SetComponentVisible(HUD_AREA_NAME, false); + + g_pMultiplayer->DeleteAndDisableGangTags(); + + // Switch off peds and traffic + SFixedArray vecs = { CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), + CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0) }; + g_pGame->GetPathFind()->SwitchRoadsOffInArea(&vecs[0], &vecs[1]); + g_pGame->GetPathFind()->SwitchPedRoadsOffInArea(&vecs[2], &vecs[3]); + g_pGame->GetPathFind()->SetPedDensity(0.0f); + g_pGame->GetPathFind()->SetVehicleDensity(0.0f); + + g_pGame->GetWorld()->ClearRemovedBuildingLists(); + g_pGame->GetWorld()->SetOcclusionsEnabled(true); + + g_pGame->ResetModelLodDistances(); + g_pGame->ResetAlphaTransparencies(); + + // Make sure we can access all areas + g_pGame->GetStats()->ModifyStat(CITIES_PASSED, 2.0); + + // This is to prevent the 'white arrows in checkpoints' bug (#274) + g_pGame->Get3DMarkers()->CreateMarker(87654, (e3DMarkerType)5, &vecs[4], 1, 0.2f, 0, 0, 0, 0); + + // Stop us getting 4 stars if we visit the SF or LV + // g_pGame->GetPlayerInfo()->GetWanted()->SetMaximumWantedLevel ( 0 ); + g_pGame->GetPlayerInfo()->GetWanted()->SetWantedLevel(0); + + // Reset anything from last game + ResetMapInfo(); + g_pGame->GetWaterManager()->Reset(); // Deletes all custom water elements, ResetMapInfo only reverts changes to water level + g_pGame->GetWaterManager()->SetWaterDrawnLast(true); + m_pCamera->SetCameraClip(true, true); + + // Create a local player for us + m_pLocalPlayer = new CClientPlayer(m_pManager, m_LocalID, true); + if (m_pLocalPlayer) + { + // Set our parent the root entity + m_pLocalPlayer->SetParent(m_pRootEntity); + + // Give the local player our nickname + m_pLocalPlayer->SetNick(m_strLocalNick); + + // Freeze the player at some location we won't see + m_pLocalPlayer->SetHealth(100); + m_pLocalPlayer->SetPosition(CVector(0, 0, 0)); + m_pLocalPlayer->SetFrozen(true); + m_pLocalPlayer->ResetInterpolation(); + + // Reset him + m_pLocalPlayer->ResetStats(); + } + else + { + RaiseFatalError(2); + } + + // Make sure we never get tired + g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true); + + // Tell doggy we got the game running + WatchDogCompletedSection("L1"); +} + +void CClientGame::Event_OnIngameAndConnected(void) +{ + m_ulVerifyTimeStart = CClientTime::GetTime(); + + // Keep criminal records of how many times they've connected to servers + SetApplicationSettingInt("times-connected", GetApplicationSettingInt("times-connected") + 1); + if (m_ServerType == SERVER_TYPE_EDITOR) + SetApplicationSettingInt("times-connected-editor", GetApplicationSettingInt("times-connected-editor") + 1); + + // Notify the server telling we're ingame + m_pNetAPI->RPC(PLAYER_INGAME_NOTICE); +} + +bool CClientGame::StaticBreakTowLinkHandler(CVehicle* pTowingVehicle) +{ + return g_pClientGame->BreakTowLinkHandler(pTowingVehicle); +} + +void CClientGame::StaticDrawRadarAreasHandler(void) +{ + g_pClientGame->DrawRadarAreasHandler(); +} + +bool CClientGame::StaticDamageHandler(CPed* pDamagePed, CEventDamage* pEvent) +{ + return g_pClientGame->DamageHandler(pDamagePed, pEvent); +} + +void CClientGame::StaticDeathHandler(CPed* pKilledPed, unsigned char ucDeathReason, unsigned char ucBodyPart) +{ + g_pClientGame->DeathHandler(pKilledPed, ucDeathReason, ucBodyPart); +} + +void CClientGame::StaticFireHandler(CFire* pFire) +{ + g_pClientGame->FireHandler(pFire); +} + +void CClientGame::StaticRender3DStuffHandler(void) +{ + g_pClientGame->Render3DStuffHandler(); +} + +void CClientGame::StaticPreRenderSkyHandler(void) +{ + g_pClientGame->PreRenderSkyHandler(); +} + +void CClientGame::StaticRenderHeliLightHandler() +{ + g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); +} + +bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) +{ + return g_pClientGame->ChokingHandler(ucWeaponType); +} + +void CClientGame::StaticCAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) +{ + g_pClientGame->CAnimBlendAssocDestructorHandler(pThis); +} + +CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) +{ + return g_pClientGame->AddAnimationHandler(pClump, animGroup, animID); +} + +CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, + AssocGroupId animGroup, AnimationId animID) +{ + return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); +} + +bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) +{ + return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); +} + +bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, + int* pFlags, RpClump* pClump) +{ + return g_pClientGame->BlendAnimationHierarchyHandler(pAnimAssoc, pOutAnimHierarchy, pFlags, pClump); +} + +void CClientGame::StaticPreWorldProcessHandler(void) +{ + g_pClientGame->PreWorldProcessHandler(); +} + +void CClientGame::StaticPostWorldProcessHandler(void) +{ + g_pClientGame->PostWorldProcessHandler(); +} + +void CClientGame::StaticPreFxRenderHandler(void) +{ + g_pCore->OnPreFxRender(); +} + +void CClientGame::StaticPreHudRenderHandler(void) +{ + g_pCore->OnPreHUDRender(); +} + +bool CClientGame::StaticProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) +{ + return g_pClientGame->ProcessCollisionHandler(pThisInterface, pOtherInterface); +} + +bool CClientGame::StaticVehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, + float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, + CVector vecCollisionVelocity) +{ + return g_pClientGame->VehicleCollisionHandler(pCollidingVehicle, pCollidedVehicle, iModelIndex, fDamageImpulseMag, fCollidingDamageImpulseMag, usPieceType, + vecCollisionPos, vecCollisionVelocity); +} + +bool CClientGame::StaticVehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, + const CVector& vecDamagePos, uchar ucTyre) +{ + return g_pClientGame->VehicleDamageHandler(pVehicleInterface, fLoss, pAttackerInterface, weaponType, vecDamagePos, ucTyre); +} + +bool CClientGame::StaticHeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) +{ + return g_pClientGame->HeliKillHandler(pHeliInterface, pHitInterface); +} + +bool CClientGame::StaticObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) +{ + return g_pClientGame->ObjectDamageHandler(pObjectInterface, fLoss, pAttackerInterface); +} + +bool CClientGame::StaticObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) +{ + return g_pClientGame->ObjectBreakHandler(pObjectInterface, pAttackerInterface); +} + +bool CClientGame::StaticWaterCannonHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) +{ + return g_pClientGame->WaterCannonHitHandler(pCannonVehicle, pHitPed); +} + +bool CClientGame::StaticVehicleFellThroughMapHandler(CVehicleSAInterface* pVehicle) +{ + return g_pClientGame->VehicleFellThroughMapHandler(pVehicle); +} + +void CClientGame::StaticGameObjectDestructHandler(CEntitySAInterface* pObject) +{ + g_pClientGame->GameObjectDestructHandler(pObject); +} + +void CClientGame::StaticGameVehicleDestructHandler(CEntitySAInterface* pVehicle) +{ + g_pClientGame->GameVehicleDestructHandler(pVehicle); +} + +void CClientGame::StaticGamePlayerDestructHandler(CEntitySAInterface* pPlayer) +{ + g_pClientGame->GamePlayerDestructHandler(pPlayer); +} + +void CClientGame::StaticGameProjectileDestructHandler(CEntitySAInterface* pProjectile) +{ + g_pClientGame->GameProjectileDestructHandler(pProjectile); +} + +void CClientGame::StaticGameModelRemoveHandler(ushort usModelId) +{ + g_pClientGame->GameModelRemoveHandler(usModelId); +} + +void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) +{ + if (pGameEntity) + { + // Map to client entity and pass to the texture replacer + CClientEntity* pClientEntity = g_pClientGame->GetGameEntityXRefManager()->FindClientEntity(pGameEntity); + if (pClientEntity) + { + int iTypeMask; + ushort usModelId = 0xFFFF; + switch (pClientEntity->GetType()) + { + case CCLIENTPED: + case CCLIENTPLAYER: + iTypeMask = TYPE_MASK_PED; + usModelId = (ushort) static_cast(pClientEntity)->GetModel(); + break; + case CCLIENTVEHICLE: + iTypeMask = TYPE_MASK_VEHICLE; + break; + case CCLIENTOBJECT: + iTypeMask = TYPE_MASK_OBJECT; + break; + default: + iTypeMask = TYPE_MASK_OTHER; + break; + } + g_pGame->GetRenderWare()->SetRenderingClientEntity(pClientEntity, usModelId, iTypeMask); + return; + } + } + + g_pGame->GetRenderWare()->SetRenderingClientEntity(NULL, 0xFFFF, TYPE_MASK_WORLD); +} + +void CClientGame::StaticTaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) +{ + g_pClientGame->TaskSimpleBeHitHandler(pPedAttacker, hitBodyPart, hitBodySide, weaponId); +} + +void CClientGame::StaticFxSystemDestructionHandler(void* pFxSAInterface) +{ + g_pClientGame->GetManager()->GetEffectManager()->SAEffectDestroyed(pFxSAInterface); +} + +AnimationId CClientGame::StaticDrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId) +{ + return g_pClientGame->DrivebyAnimationHandler(animGroup, animId); +} + +void CClientGame::DrawRadarAreasHandler(void) +{ + m_pRadarAreaManager->DoPulse(); +} + +bool CClientGame::BreakTowLinkHandler(CVehicle* pTowedVehicle) +{ + CClientVehicle* pVehicle = m_pVehicleManager->Get(pTowedVehicle, false); + if (pVehicle) + { + // Check if this is a legal break + bool bLegal = ((pVehicle->GetControllingPlayer() == m_pLocalPlayer) || (m_pUnoccupiedVehicleSync->Exists(static_cast(pVehicle)))); + + // Not a legal break? + if (!bLegal) + { + // Save the time it broke (used in UpdateTrailers) + pVehicle->SetIllegalTowBreakTime(GetTickCount32()); + } + } + + // Allow it to break + return true; +} + +void CClientGame::FireHandler(CFire* pFire) +{ + // Disable spreading fires + pFire->SetNumGenerationsAllowed(0); +} + +void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile) +{ + if (pProjectile->IsLocal()) + { + // Did the local player create this projectile? + if (m_pLocalPlayer && pProjectile->GetCreator() == m_pLocalPlayer) + { + // Physics says our projectile should start off at our velocity + CVector vecVelocity, vecPlayerVelocity; + pProjectile->GetVelocity(vecVelocity); + m_pLocalPlayer->GetMoveSpeed(vecPlayerVelocity); + vecVelocity += vecPlayerVelocity; + pProjectile->SetVelocity(vecVelocity); + } + + SendProjectileSync(pProjectile); + } + + // Renew the interior and dimension + if (pProjectile->GetCreator()) + { + pProjectile->SetInterior(pProjectile->GetCreator()->GetInterior()); + pProjectile->SetDimension(pProjectile->GetCreator()->GetDimension()); + } + + // Validate the projectile for our element tree + pProjectile->SetParent(m_pRootEntity); + + // Call our creation event + CLuaArguments Arguments; + Arguments.PushElement(pProjectile->GetCreator()); + pProjectile->CallEvent("onClientProjectileCreation", Arguments, true); +} + +void CClientGame::Render3DStuffHandler(void) +{ +} + +void CClientGame::PreRenderSkyHandler(void) +{ + g_pCore->GetGraphics()->GetRenderItemManager()->PreDrawWorld(); +} + +void CClientGame::PreWorldProcessHandler(void) +{ +} + +void CClientGame::PostWorldProcessHandler(void) +{ + m_pManager->GetMarkerManager()->DoPulse(); + m_pManager->GetPointLightsManager()->DoPulse(); + m_pManager->GetObjectManager()->DoPulse(); + + // Update frame time slice + uint uiCurrentTick = GetTickCount32(); + if (m_uiLastFrameTick) + { + m_uiFrameTimeSlice = uiCurrentTick - m_uiLastFrameTick; + m_uiFrameCount++; + + // Call onClientPreRender LUA event + CLuaArguments Arguments; + Arguments.PushNumber(m_uiFrameTimeSlice); + m_pRootEntity->CallEvent("onClientPreRender", Arguments, false); + } + m_uiLastFrameTick = uiCurrentTick; +} + +void CClientGame::IdleHandler(void) +{ + // If we are minimized we do the pulsing here + if (g_pCore->IsWindowMinimized()) + { + if (!m_bWasMinimized) + { + m_bWasMinimized = true; + // Call onClientMinimize LUA event + CLuaArguments Arguments; + m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); + + bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); + + // Apply mute on minimize options + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) + g_pGame->GetAudio()->SetMusicMasterVolume(0); + + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) + g_pGame->GetAudio()->SetEffectsMasterVolume(0); + + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) + m_pManager->GetSoundManager()->SetMinimizeMuted(true); + } + } + + // Ensure dummy progress graphic will be displayed when using alt pulse order + g_pCore->SetDummyProgressUpdateAlways(true); + + // Extrapolation test - Change the pulse order to reduce latency (Has side effects for peds) + DoPulses2(true); + + g_pCore->SetDummyProgressUpdateAlways(false); +} + +bool CClientGame::ChokingHandler(unsigned char ucWeaponType) +{ + if (!m_pLocalPlayer) + return true; + CLuaArguments Arguments; + Arguments.PushNumber(ucWeaponType); + return m_pLocalPlayer->CallEvent("onClientPlayerChoke", Arguments, true); +} + +void CClientGame::CAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis) +{ + // printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID); + RemoveAnimationAssociationFromMap(pThis); +} + +CAnimBlendAssociationSAInterface* CClientGame::AddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID) +{ + // printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); + return nullptr; +} + +CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, + AssocGroupId animGroup, AnimationId animID) +{ + // printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); + return nullptr; +} + +bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) +{ + bool isCustomAnimationToPlay = false; + CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); + auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); + auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); + auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); + auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); + + CClientPed* pClientPed = GetClientPedByClump(*pClump); + if (pClientPed != nullptr) + { + auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); + if (pReplacedAnimation != nullptr) + { + std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); + InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); + + // Play our custom animation instead of default + auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); + pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); + pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); + pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); + isCustomAnimationToPlay = true; + } + } + + if (!isCustomAnimationToPlay) + { + auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); + + // Play default internal animation + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); + } + return isCustomAnimationToPlay; +} + +bool CClientGame::BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags, + RpClump* pClump) +{ + bool isCustomAnimationToPlay = false; + CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); + CClientPed* pClientPed = GetClientPedByClump(*pClump); + if (pClientPed != nullptr) + { + if (pClientPed->IsNextAnimationCustom()) + { + std::shared_ptr pIFP = pClientPed->GetCustomAnimationIFP(); + if (pIFP) + { + const SString& strAnimationName = pClientPed->GetNextAnimationCustomName(); + auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy(strAnimationName); + if (pCustomAnimBlendHierarchy != nullptr) + { + std::shared_ptr pIFPAnimations = pIFP->GetIFPAnimationsPointer(); + InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); + + pClientPed->SetCurrentAnimationCustom(true); + pClientPed->SetNextAnimationNormal(); + + if (pIFP->IsUnloading()) + { + pClientPed->DereferenceCustomAnimationBlock(); + } + *pOutAnimHierarchy = pCustomAnimBlendHierarchy; + isCustomAnimationToPlay = true; + return isCustomAnimationToPlay; + } + } + } + + pClientPed->SetCurrentAnimationCustom(false); + pClientPed->SetNextAnimationNormal(); + } + return isCustomAnimationToPlay; +} + +bool CClientGame::ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface) +{ + if (pThisInterface == pOtherInterface) + return true; + + if (!m_BuiltCollisionMapThisFrame) + { + // Build a map of CPhysicalSAInterface*/CClientEntity*'s that have collision disabled + m_BuiltCollisionMapThisFrame = true; + m_CachedCollisionMap.clear(); + + std::map::iterator iter = m_AllDisabledCollisions.begin(); + for (; iter != m_AllDisabledCollisions.end(); ++iter) + { + CClientEntity* pEntity = iter->first; + CEntity* pGameEntity = pEntity->GetGameEntity(); + CEntitySAInterface* pInterface = pGameEntity ? pGameEntity->GetInterface() : NULL; + + if (pInterface) + m_CachedCollisionMap[pInterface] = pEntity; + } + } + + // Check both elements appear in the cached map before doing extra processing + std::map::iterator iter1 = m_CachedCollisionMap.find((CEntitySAInterface*)pThisInterface); + if (iter1 != m_CachedCollisionMap.end()) + { + std::map::iterator iter2 = m_CachedCollisionMap.find((CEntitySAInterface*)pOtherInterface); + if (iter2 != m_CachedCollisionMap.end()) + { + // Re-get the entity pointers using a safer method + CEntity* pGameEntity = g_pGame->GetPools()->GetEntity((DWORD*)pThisInterface); + CEntity* pGameColEntity = g_pGame->GetPools()->GetEntity((DWORD*)pOtherInterface); + + if (pGameEntity && pGameColEntity) + { + CClientEntity* pEntity = m_pManager->FindEntity(pGameEntity, true); + CClientEntity* pColEntity = m_pManager->FindEntity(pGameColEntity, true); + + if (pEntity && pColEntity) + { +#if MTA_DEBUG + CClientEntity* ppThisEntity2 = iter1->second; + CClientEntity* ppOtherEntity2 = iter2->second; + // These should match, but its not essential. + assert(ppThisEntity2 == pEntity); + assert(ppOtherEntity2 == pColEntity); +#endif + if (!pEntity->IsCollidableWith(pColEntity)) + return false; + } + } + } + } + + return true; +} + +// +// On demand files +// +void CClientGame::DownloadSingularResourceFiles(void) +{ + if (!IsTransferringSingularFiles()) + return; + + if (!g_pNet->IsConnected()) + return; + + CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES); + if (!pHTTP->ProcessQueuedFiles()) + { + // Downloading + } + else + { + // Can't clear list until all files have been processed + if (m_pSingularFileDownloadManager->AllComplete()) + { + SetTransferringSingularFiles(false); + m_pSingularFileDownloadManager->ClearList(); + } + } +} + +// Get relevant death anim for animation purposes during death situation +void GetDeathAnim(CClientPed* pDamagedPed, CEventDamage* pEvent, AssocGroupId& outAnimGroup, AnimationId& outAnimID) +{ + if (pEvent) + { + pEvent->ComputeDeathAnim(pDamagedPed->GetGamePlayer(), false); + outAnimGroup = pEvent->GetAnimGroup(); + outAnimID = pEvent->GetAnimId(); + } + else + { + // Using same numbers as CClientGame::DoWastedCheck defaults + outAnimGroup = 0; + outAnimID = 15; + } +} + +// +// DamageHandler seems to be called 3 times for each bit of damage: +// +// pass 1 - preApplyDamage +// is pass 1 if: fDamage == zero && fCurrentHealth == fPreviousHealth +// returning false stops any damage being inflicted +// returning true applies damage and allows pass 2 +// pass 2 - postApplyDamage/preApplyAnim +// is pass 2 if: fDamage > zero && fCurrentHealth != fPreviousHealth +// returning false stops damage anim +// returning true allows damage anim and allows pass 3 +// pass 3 - postApplyAnim +// is pass 3 if: fDamage > zero && fCurrentHealth == fPreviousHealth +// returning false ?? +// returning true ?? +// +bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) +{ + // CEventDamage::AffectsPed: This is/can be called more than once for each bit of damage (and may not actually take any more health (even if we return + // true)) + + // Grab some data from the event + CEntity* pInflictor = pEvent->GetInflictingEntity(); + eWeaponType weaponUsed = pEvent->GetWeaponUsed(); + ePedPieceTypes hitZone = pEvent->GetPedPieceType(); + CWeaponInfo* pWeaponInfo = g_pGame->GetWeaponInfo(weaponUsed); + float fDamage = pEvent->GetDamageApplied(); + EDamageReasonType damageReason = pEvent->GetDamageReason(); + + /* Causes too much desync right now + // Is this shotgun damage? + if ( weaponUsed == WEAPONTYPE_SHOTGUN || weaponUsed == WEAPONTYPE_SPAS12_SHOTGUN ) + { + // Make the ped fall down + pEvent->MakePedFallDown (); + } */ + + // Grab the damaged ped + CClientPed* pDamagedPed = NULL; + if (pDamagePed) + pDamagedPed = m_pPedManager->Get(dynamic_cast(pDamagePed), true, true); + + // Grab the inflictor + CClientEntity* pInflictingEntity = NULL; + if (pInflictor) + pInflictingEntity = m_pManager->FindEntity(pInflictor, true); + + // If the damage was caused by an explosion + if (weaponUsed == WEAPONTYPE_EXPLOSION) + { + CClientEntity* pLastExplosionCreator = m_pManager->GetExplosionManager()->m_pLastCreator; + + // If we don't have an inflictor, look for the last explosion creator + if (!pInflictor && pLastExplosionCreator) + pInflictingEntity = pLastExplosionCreator; + + // Change the weapon used to whatever created the explosion + weaponUsed = m_pManager->GetExplosionManager()->m_LastWeaponType; + } + + // Do we have a damaged ped? + if (pDamagedPed) + { + /////////////////////////////////////////////////////////////////////////// + // + // Pass 1 stuff + // + // return false to stop any damage being inflicted + // + /////////////////////////////////////////////////////////////////////////// + + // Pass 1 checks for double shots + if (fDamage == 0.0f && damageReason != EDamageReason::PISTOL_WHIP) + { + // Only check for remote players + CClientPlayer* pInflictingPlayer = DynamicCast(pInflictingEntity); + if (pInflictingPlayer && !pInflictingPlayer->IsLocalPlayer()) + { + bool bBulletSyncShot = (g_iDamageEventLimit != -1); // Called from discharge weapon + bool bBulletSyncWeapon = GetWeaponTypeUsesBulletSync(weaponUsed); + + if (bBulletSyncShot) + { + if (g_iDamageEventLimit == 0) + { + AddReportLog(5501, SString("2nd pass 1 for BulletSyncShot damage. weaponUsed:%d", weaponUsed)); + return false; + } + g_iDamageEventLimit--; + if (!bBulletSyncWeapon) + { + AddReportLog(5502, SString("BulletSyncShot but not bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); + return false; + } + } + else + { + if (bBulletSyncWeapon) + { + AddReportLog(5503, SString("not BulletSyncShot but bBulletSyncWeapon. weaponUsed:%d", weaponUsed)); + return false; + } + } + } + } + + // Is the damaged ped a player? + if (IS_PLAYER(pDamagedPed)) + { + CClientPlayer* pDamagedPlayer = static_cast(pDamagedPed); + + // Do we have an inflicting entity? + if (pInflictingEntity) + { + // Grab the inflicting player + CClientPlayer* pInflictingPlayer = NULL; + + switch (pInflictingEntity->GetType()) + { + case CCLIENTPLAYER: + { + pInflictingPlayer = static_cast(pInflictingEntity); + break; + } + case CCLIENTVEHICLE: + { + CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); + if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) + { + CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); + if (pPed && pPed->GetType() == CCLIENTPLAYER) + pInflictingPlayer = static_cast(pPed); + } + break; + } + default: + break; + } + if (pInflictingPlayer) + { + // Is the damaged player on a team + CClientTeam* pTeam = pDamagedPlayer->GetTeam(); + if (pTeam) + { + // Is this friendly-fire from a team-mate? + if (pDamagedPlayer->IsOnMyTeam(pInflictingPlayer) && !pTeam->GetFriendlyFire() && pDamagedPlayer != pInflictingPlayer) + return false; + } + } + } + } + /////////////////////////////////////////////////////////////////////////// + // Pass 1 end + /////////////////////////////////////////////////////////////////////////// + + return ApplyPedDamageFromGame(weaponUsed, fDamage, hitZone, pDamagedPed, pInflictingEntity, pEvent); + } + + // No damage anim for fire + if (weaponUsed == WEAPONTYPE_FLAMETHROWER) + return false; + + // Allow the damage processing to continue + return true; +} + +// +// Check GTA stored health with our stored health and do stuff +// +bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, uchar hitZone, CClientPed* pDamagedPed, CClientEntity* pInflictingEntity, + CEventDamage* pEvent) +{ + float fPreviousHealth = pDamagedPed->m_fHealth; + float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); + float fPreviousArmor = pDamagedPed->m_fArmor; + float fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); + + // Have we taken any damage here? + if ((fPreviousHealth != fCurrentHealth || fPreviousArmor != fCurrentArmor) && fDamage != 0.0f) + { + /////////////////////////////////////////////////////////////////////////// + /// + // Pass 2 stuff - (GTA has applied the damage) + // + // return false to stop damage anim (incl. death task) + // + /////////////////////////////////////////////////////////////////////////// + + g_fApplyDamageLastAmount = fDamage; + g_ucApplyDamageLastHitZone = hitZone; + g_pApplyDamageLastDamagedPed = pDamagedPed; + + CLuaArguments Arguments; + if (pInflictingEntity) + Arguments.PushElement(pInflictingEntity); + else + Arguments.PushBoolean(false); + Arguments.PushNumber(static_cast(weaponUsed)); + Arguments.PushNumber(static_cast(hitZone)); + Arguments.PushNumber(fDamage); + + // Call our event + if ((IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPlayerDamage", Arguments, true)) || + (!IS_PLAYER(pDamagedPed) && !pDamagedPed->CallEvent("onClientPedDamage", Arguments, true))) + { + // Stop here if they cancelEvent it + if (pDamagedPed->IsLocalPlayer()) + { + // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) + fPreviousHealth = pDamagedPed->m_fHealth; + fPreviousArmor = pDamagedPed->m_fArmor; + } + pDamagedPed->GetGamePlayer()->SetHealth(fPreviousHealth); + pDamagedPed->GetGamePlayer()->SetArmor(fPreviousArmor); + return false; + } + + if (pDamagedPed->IsLocalPlayer()) + { + // Reget values in case they have been changed during onClientPlayerDamage event (Avoid AC#1 kick) + fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); + fCurrentArmor = pDamagedPed->GetGamePlayer()->GetArmor(); + } + + bool bIsBeingShotWhilstAiming = (weaponUsed >= WEAPONTYPE_PISTOL && weaponUsed <= WEAPONTYPE_MINIGUN && pDamagedPed->IsUsingGun()); + bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); + + bool bAllowChoke = true; + // Is this is a remote player? + if (!pDamagedPed->IsLocalPlayer()) + { + // Don't allow GTA to start the choking task + if (weaponUsed == WEAPONTYPE_TEARGAS || weaponUsed == WEAPONTYPE_SPRAYCAN || weaponUsed == WEAPONTYPE_EXTINGUISHER) + bAllowChoke = false; + } + + // Check if their health or armor is locked, and if so prevent applying the damage locally + if (pDamagedPed->IsHealthLocked() || pDamagedPed->IsArmorLocked()) + { + // Restore health+armor + pDamagedPed->GetGamePlayer()->SetHealth(pDamagedPed->GetHealth()); + pDamagedPed->GetGamePlayer()->SetArmor(pDamagedPed->GetArmor()); + + if (bOldBehaviour) + { + // Don't play the animation if it's going to be a death one, or if it's going to interrupt aiming + if (fCurrentHealth == 0.0f || bIsBeingShotWhilstAiming) + return false; + + // Allow animation for remote players (if currently we don't need block choke) + return bAllowChoke; + } + + // No hit animation for remote players + return false; + } + + // Update our stored health/armor + pDamagedPed->m_fHealth = fCurrentHealth; + pDamagedPed->m_fArmor = fCurrentArmor; + + ElementID damagerID = INVALID_ELEMENT_ID; + if (pInflictingEntity && !pInflictingEntity->IsLocalEntity()) + damagerID = pInflictingEntity->GetID(); + + // Is it the local player? + if (pDamagedPed->IsLocalPlayer()) + { + // Update our stored damage stuff + m_ucDamageWeapon = static_cast(weaponUsed); + m_ucDamageBodyPiece = static_cast(hitZone); + m_pDamageEntity = pInflictingEntity; + m_ulDamageTime = CClientTime::GetTime(); + m_DamagerID = damagerID; + m_bDamageSent = false; + } + // Does this damage kill the player? + if (fCurrentHealth == 0.0f) + { + if (pDamagedPed->GetType() == CCLIENTPLAYER) + { + // Is the local player dying? + if (pDamagedPed->IsLocalPlayer() && fPreviousHealth > 0.0f) + { + // Grab our death animation + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + + // Check if we're dead + DoWastedCheck(damagerID, weaponUsed, hitZone, animGroup, animID); + } + + // Allow GTA to kill us if we've fell to our death + if (pDamagedPed->IsLocalPlayer() && weaponUsed == WEAPONTYPE_FALL) + return true; + + // Don't let GTA start the death task + return false; + } + else + { + if (pDamagedPed->IsLocalEntity() && fPreviousHealth > 0.0f) + { + // Client-side ped + pDamagedPed->CallEvent("onClientPedWasted", Arguments, true); + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + pDamagedPed->Kill(weaponUsed, hitZone, false, false, animGroup, animID); + return true; + } + if (fPreviousHealth > 0.0f) + { + // Grab our death animation + AssocGroupId animGroup; + AnimationId animID; + GetDeathAnim(pDamagedPed, pEvent, animGroup, animID); + + SendPedWastedPacket(pDamagedPed, damagerID, weaponUsed, hitZone, animGroup, animID); + } + } + } + + // Disallow choke task if it's necessary + if (!bAllowChoke) + return false; + + // Inhibit hit-by-gun animation for local player if required + if (bOldBehaviour) + if (pDamagedPed->IsLocalPlayer() && bIsBeingShotWhilstAiming) + return false; + + /////////////////////////////////////////////////////////////////////////// + // Pass 2 end + /////////////////////////////////////////////////////////////////////////// + } + + // No damage anim for fire + if (weaponUsed == WEAPONTYPE_FLAMETHROWER) + return false; + + // Allow the damage processing to continue + return true; +} + +void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, unsigned char ucBodyPart) +{ + CClientPed* pKilledPed = m_pPedManager->Get(dynamic_cast(pKilledPedSA), true, true); + + if (!pKilledPed) + return; + + // Not required for remote players. Local player is handled in DoPulses->DoWastedCheck + if (IS_PLAYER(pKilledPed)) + return; + + // Set the health to zero (this is safe as GTA will do it anyway in a few ticks) + pKilledPed->SetHealth(0.0f); + + // Call Lua + CLuaArguments Arguments; + Arguments.PushBoolean(false); + Arguments.PushNumber(ucDeathReason); + Arguments.PushNumber(ucBodyPart); + + pKilledPed->CallEvent("onClientPedWasted", Arguments, true); + + // Notify the server + SendPedWastedPacket(pKilledPed, INVALID_ELEMENT_ID, ucDeathReason, ucBodyPart); +} + +bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, + float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) +{ + if (pCollidingVehicle && pCollidedWith) + { + CVehicle* pColliderVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidingVehicle); + CClientEntity* pVehicleClientEntity = m_pManager->FindEntity(pColliderVehicle, true); + if (pVehicleClientEntity) + { + CClientVehicle* pClientVehicle = static_cast(pVehicleClientEntity); + + CEntity* pCollidedWithEntity = g_pGame->GetPools()->GetEntity((DWORD*)pCollidedWith); + CClientEntity* pCollidedWithClientEntity = NULL; + if (pCollidedWithEntity) + { + if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pCollidedWithVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithVehicle, true); + } + else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_OBJECT) + { + CObject* pCollidedWithObject = g_pGame->GetPools()->GetObject((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithObject, true); + } + else if (pCollidedWithEntity->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pCollidedWithPed = g_pGame->GetPools()->GetPed((DWORD*)pCollidedWith); + pCollidedWithClientEntity = m_pManager->FindEntity(pCollidedWithPed, true); + } + } + CLuaArguments Arguments; + if (pCollidedWithClientEntity) + { + Arguments.PushElement(pCollidedWithClientEntity); + } + else + { + Arguments.PushNil(); + } + Arguments.PushNumber(fDamageImpulseMag); + Arguments.PushNumber(usPieceType); + Arguments.PushNumber(vecCollisionPos.fX); + Arguments.PushNumber(vecCollisionPos.fY); + Arguments.PushNumber(vecCollisionPos.fZ); + Arguments.PushNumber(vecCollisionVelocity.fX); + Arguments.PushNumber(vecCollisionVelocity.fY); + Arguments.PushNumber(vecCollisionVelocity.fZ); + Arguments.PushNumber(fCollidingDamageImpulseMag); + Arguments.PushNumber(iModelIndex); + + pVehicleClientEntity->CallEvent("onClientVehicleCollision", Arguments, true); + // Alocate a BitStream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + // Make sure it created + if (pBitStream) + { + if (pBitStream->Version() >= 0x028) + { + // Sync Stuff + // if it's not a local vehicle + it collided with the local player + if (pVehicleClientEntity->IsLocalEntity() == false && pCollidedWithClientEntity == g_pClientGame->GetLocalPlayer()) + { + // is it below the anti spam threshold? + if (pClientVehicle->GetTimeSinceLastPush() >= MIN_PUSH_ANTISPAM_RATE) + { + // if there is no controlling player + if (!pClientVehicle->GetControllingPlayer()) + { + CDeathmatchVehicle* Vehicle = static_cast(pVehicleClientEntity); + // if We aren't already syncing the vehicle + if (GetUnoccupiedVehicleSync()->Exists(Vehicle) == false) + { + // Write the vehicle ID + pBitStream->Write(pVehicleClientEntity->GetID()); + // Send! + g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, + PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); + // Reset our push time + pClientVehicle->ResetLastPushTime(); + } + } + } + } + } + g_pNet->DeallocateNetBitStream(pBitStream); + } + return true; + } + } + return false; +} + +bool CClientGame::HeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySAInterface* pHitInterface) +{ + if (pHeliInterface && pHitInterface) + { + // Get our heli and client heli + CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); + CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); + if (pHeli && pClientHeli && pClientHeli->AreHeliBladeCollisionsEnabled()) + { + // Get our ped and client ped + CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitInterface); + CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); + // Was our client ped valid + if (pClientPed) + { + // Get our heli and client heli + CVehicle* pHeli = g_pGame->GetPools()->GetVehicle((DWORD*)pHeliInterface); + CClientVehicle* pClientHeli = m_pManager->GetVehicleManager()->GetSafe(pHeli); + + // Iterate our "stored" cancel state and find the heli in question + std::pair::iterator, std::multimap::iterator> iterators = + m_HeliCollisionsMap.equal_range(pClientHeli); + std::multimap::const_iterator iter = iterators.first; + for (; iter != iterators.second; ++iter) + { + // If the Heli and ped collided within the clear rate return false + if ((*iter).first == pClientHeli && (*iter).second == pClientPed) + return false; + } + + CLuaArguments Arguments; + if (pClientHeli) + { + // Push our heli + Arguments.PushElement(pClientHeli); + } + else + { + Arguments.PushNil(); + } + + // Trigger our event + bool bContinue; + if (IS_PLAYER(pClientPed)) + bContinue = pClientPed->CallEvent("onClientPlayerHeliKilled", Arguments, true); + else + bContinue = pClientPed->CallEvent("onClientPedHeliKilled", Arguments, true); + + // Was our event cancelled + if (!bContinue) + { + // Add our heli and ped pair to the list + std::pair pair = std::pair(pClientHeli, pClientPed); + m_HeliCollisionsMap.insert(pair); + } + // Return if it was cancelled + return bContinue; + } + } + else + { + return false; + } + } + return true; +} + +bool CClientGame::VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, + const CVector& vecDamagePos, uchar ucTyre) +{ + bool bAllowDamage = true; + CClientVehicle* pClientVehicle = GetGameEntityXRefManager()->FindClientVehicle(pVehicleInterface); + if (pClientVehicle) + { + CClientEntity* pClientAttacker = GetGameEntityXRefManager()->FindClientEntity(pAttackerInterface); + + // Compose arguments + // attacker, weapon, loss, damagepos, tyreIdx + CLuaArguments Arguments; + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + if (weaponType != WEAPONTYPE_INVALID) + Arguments.PushNumber(weaponType); + else + Arguments.PushNil(); + Arguments.PushNumber(fLoss); + Arguments.PushNumber(vecDamagePos.fX); + Arguments.PushNumber(vecDamagePos.fY); + Arguments.PushNumber(vecDamagePos.fZ); + if (ucTyre != UCHAR_INVALID_INDEX) + Arguments.PushNumber(ucTyre); + else + Arguments.PushNil(); + + if (!pClientVehicle->CallEvent("onClientVehicleDamage", Arguments, true)) + { + bAllowDamage = false; + } + } + + return bAllowDamage; +} + +bool CClientGame::ObjectDamageHandler(CObjectSAInterface* pObjectInterface, float fLoss, CEntitySAInterface* pAttackerInterface) +{ + if (pObjectInterface) + { + // Get our object and client object + CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); + CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); + + // Is our client vehicle valid? + if (pClientObject) + { + CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); + CClientEntity* pClientAttacker = NULL; + if (pAttacker) + { + if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); + } + else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerPed); + } + } + + CLuaArguments Arguments; + Arguments.PushNumber(fLoss); + + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + + return pClientObject->CallEvent("onClientObjectDamage", Arguments, true); + } + } + return true; +} + +bool CClientGame::ObjectBreakHandler(CObjectSAInterface* pObjectInterface, CEntitySAInterface* pAttackerInterface) +{ + if (pObjectInterface) + { + // Get our object and client object + CObject* pObject = g_pGame->GetPools()->GetObjectA((DWORD*)pObjectInterface); + CClientObject* pClientObject = m_pManager->GetObjectManager()->GetSafe(pObject); + + // Is our client vehicle valid? + if (pClientObject) + { + if (!pClientObject->IsBreakable(false)) + return false; + + // Apply to MTA's "internal storage", too + pClientObject->SetHealth(0.0f); + + CEntity* pAttacker = g_pGame->GetPools()->GetEntity((DWORD*)pAttackerInterface); + CClientEntity* pClientAttacker = NULL; + if (pAttacker) + { + if (pAttacker->GetEntityType() == ENTITY_TYPE_VEHICLE) + { + CVehicle* pAttackerVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerVehicle); + } + else if (pAttacker->GetEntityType() == ENTITY_TYPE_PED) + { + CPed* pAttackerPed = g_pGame->GetPools()->GetPed((DWORD*)pAttackerInterface); + pClientAttacker = m_pManager->FindEntity(pAttackerPed); + } + } + + CLuaArguments Arguments; + + if (pClientAttacker) + Arguments.PushElement(pClientAttacker); + else + Arguments.PushNil(); + + return pClientObject->CallEvent("onClientObjectBreak", Arguments, true); + } + } + return true; +} + +bool CClientGame::WaterCannonHitHandler(CVehicleSAInterface* pCannonVehicle, CPedSAInterface* pHitPed) +{ + if (pCannonVehicle && pHitPed) + { + // Get our vehicle and client vehicle + CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pCannonVehicle); + CClientVehicle* pCannonClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); + // Was our client vehicle valid + if (pCannonClientVehicle) + { + // Get our ped and client ped + CPed* pPed = g_pGame->GetPools()->GetPed((DWORD*)pHitPed); + CClientPed* pClientPed = m_pManager->GetPedManager()->GetSafe(pPed, true); + + CLuaArguments Arguments; + if (pClientPed) + { + // Push our ped + Arguments.PushElement(pClientPed); + } + else + { + Arguments.PushNil(); + } + + // Trigger our event + bool bContinue = true; + if (!IS_PLAYER(pClientPed)) + bContinue = pCannonClientVehicle->CallEvent("onClientPedHitByWaterCannon", Arguments, true); + else + bContinue = pCannonClientVehicle->CallEvent("onClientPlayerHitByWaterCannon", Arguments, true); + + // Return if it was cancelled + return bContinue; + } + } + return false; +} + +bool CClientGame::VehicleFellThroughMapHandler(CVehicleSAInterface* pVehicleInterface) +{ + if (pVehicleInterface) + { + // Get our vehicle and client vehicle + CVehicle* pVehicle = g_pGame->GetPools()->GetVehicle((DWORD*)pVehicleInterface); + CClientVehicle* pClientVehicle = m_pManager->GetVehicleManager()->GetSafe(pVehicle); + if (pClientVehicle) + { + // handle or don't + return pClientVehicle->OnVehicleFallThroughMap(); + } + } + // unhandled + return false; +} + +// Validate known objects +void CClientGame::GameObjectDestructHandler(CEntitySAInterface* pObject) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pObject); +} + +void CClientGame::GameVehicleDestructHandler(CEntitySAInterface* pVehicle) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pVehicle); +} + +void CClientGame::GamePlayerDestructHandler(CEntitySAInterface* pPlayer) +{ + m_pGameEntityXRefManager->OnGameEntityDestruct(pPlayer); +} + +void CClientGame::GameProjectileDestructHandler(CEntitySAInterface* pProjectile) +{ + CClientProjectile* pClientProjectile = m_pManager->GetProjectileManager()->Get(pProjectile); + // Happens when destroyElement is called rather than letting the projectile expire + // Normal code path is destruction from CProjectileSAInterface -> CProjectileSA -> CClientProjectile + // destroyElement is CClientProjectile -> CProjectileSA -> CProjectileSAInterface + // which means the CClientProjectile element is deleted when we get here + if (pClientProjectile) + CStaticFunctionDefinitions::DestroyElement(*pClientProjectile); +} + +void CClientGame::GameModelRemoveHandler(ushort usModelId) +{ + m_pGameEntityXRefManager->OnGameModelRemove(usModelId); +} + +void CClientGame::TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId) +{ + bool bOldBehaviour = !IsGlitchEnabled(GLITCH_HITANIM); + if (bOldBehaviour) + return; + + CClientPed* pClientPedAttacker = DynamicCast(GetGameEntityXRefManager()->FindClientEntity((CEntitySAInterface*)pPedAttacker)); + + // Make sure cause was networked ped + if (pClientPedAttacker && !pClientPedAttacker->IsLocalEntity()) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write((ushort)TASK_SIMPLE_BE_HIT); + pBitStream->Write(pClientPedAttacker->GetID()); + pBitStream->Write((uchar)hitBodyPart); + pBitStream->Write((uchar)hitBodySide); + pBitStream->Write((uchar)weaponId); + g_pNet->SendPacket(PACKET_ID_PED_TASK, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +bool CClientGame::StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (g_pClientGame) + { + return g_pClientGame->ProcessMessage(hwnd, uMsg, wParam, lParam); + } + + return false; +} + +bool CClientGame::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (ProcessMessageForCursorEvents(hwnd, uMsg, wParam, lParam)) + { + return true; + } + + return false; +} + +void CClientGame::ProcessVehicleInOutKey(bool bPassenger) +{ + // Are we already sending an in/out request or not allowed to create a new in/out? + if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle? + || m_VehicleInOutID != INVALID_ELEMENT_ID // Make sure we're not already processing a vehicle enter (would refer to valid ID if we were) + || m_bIsGettingJacked // Make sure we're not currently getting carjacked && + || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... + || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... + || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon + ) + { + return; + } + + // Reset the "is jacking" bit + m_bIsJackingVehicle = false; + + // Got a local player model? + if (!m_pLocalPlayer) + { + // No local player. Stop. + return; + } + + // If the player is in a vehicle we need to leave the vehicle. + CClientVehicle* pOccupiedVehicle = m_pLocalPlayer->GetOccupiedVehicle(); + if (pOccupiedVehicle) + { + // Only let us leave the vehicle if: + // - we press F (as driver) + // - we press either F or G as a passenger + if (bPassenger && m_pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + // Driver pressed G, so stop. + return; + } + + // We're about to exit a vehicle + // Send an in request + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!pBitStream) + { + return; + } + + // Write the vehicle id to it and that we're requesting to get out of it + pBitStream->Write(pOccupiedVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_REQUEST_OUT); + pBitStream->WriteBits(&ucAction, 4); + + unsigned char ucDoor = g_pGame->GetCarEnterExit()->ComputeTargetDoorToExit(m_pLocalPlayer->GetGamePlayer(), pOccupiedVehicle->GetGameVehicle()); + if (ucDoor >= 2 && ucDoor <= 5) + { + ucDoor -= 2; + pBitStream->WriteBits(&ucDoor, 2); + } + + // Send and destroy it + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're now exiting a vehicle + m_bIsGettingOutOfVehicle = true; + m_ulLastVehicleInOutTime = CClientTime::GetTime(); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_out"); +#endif + return; + } + + // + // We're going to enter a vehicle + // + + // If the Jump task is playing and we are in water - I know right + // Kill the task. + // + CTask* pTask = m_pLocalPlayer->GetCurrentPrimaryTask(); + if (pTask && pTask->GetTaskType() == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter + { + CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, nullptr, nullptr, 20.0f); + if (pVehicle && + (pVehicle->IsInWater() || + m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) + { + m_pLocalPlayer->KillTask(3, true); // Kill jump task if we are about to warp in + } + } + + // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle' + // task will replace it and fuck it up! + // + if (m_pLocalPlayer->GetCurrentPrimaryTask()) + { + // We already have a primary task, so stop. + return; + } + + // Are we holding the aim_weapon key? + SBindableGTAControl* pBind = g_pCore->GetKeyBinds()->GetBindableFromControl("aim_weapon"); + if (pBind && pBind->bState) + { + // Stop because the player is probably using rshift + f/g + return; + } + + if (m_pLocalPlayer->IsClimbing() // Make sure we're not currently climbing + || m_pLocalPlayer->HasJetPack() // Make sure we don't have a jetpack + || m_pLocalPlayer->IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway + || m_pLocalPlayer->IsRunningAnimation() // Make sure we aren't running an animation + ) + { + return; + } + + // Grab the closest vehicle + unsigned int uiDoor = 0; + CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, &uiDoor, nullptr, 20.0f); + unsigned int uiSeat = uiDoor; + + if (bPassenger && uiDoor == 0) + { + // We're trying to enter as a passenger, yet our closest door + // is the driver's door. Force an enter for the passenger seat. + uiSeat = 1; + } + else if (!bPassenger) + { + // We want to drive. Force our seat to the driver's seat. + uiSeat = 0; + } + + if (!pVehicle || !pVehicle->IsEnterable()) + { + // Stop if there isn't a vehicle, or the vehicle is not enterable + return; + } + + // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly) + if (pVehicle->GetVehicleType() == CLIENTVEHICLE_BOAT && m_pLocalPlayer->GetContactEntity() != pVehicle) + { + return; + } + + // Call the onClientVehicleStartEnter event for remote players + // Local player triggered before sending packet in CClientGame + CLuaArguments Arguments; + Arguments.PushElement(m_pLocalPlayer); // player + Arguments.PushNumber(uiSeat); // seat + Arguments.PushNumber(uiDoor); // Door + + if (!pVehicle->CallEvent("onClientVehicleStartEnter", Arguments, true)) + { + // Event has been cancelled + return; + } + + // Send an in request + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!pBitStream) + { + return; + } + + // Write the vehicle id to it and that we're requesting to get into it + pBitStream->Write(pVehicle->GetID()); + unsigned char ucAction = static_cast(VEHICLE_REQUEST_IN); + unsigned char ucSeat = static_cast(uiSeat); + bool bIsOnWater = pVehicle->IsOnWater(); + unsigned char ucDoor = static_cast(uiDoor); + pBitStream->WriteBits(&ucAction, 4); + pBitStream->WriteBits(&ucSeat, 4); + pBitStream->WriteBit(bIsOnWater); + pBitStream->WriteBits(&ucDoor, 3); + + // Send and destroy it + g_pNet->SendPacket(PACKET_ID_VEHICLE_INOUT, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + + // We're now entering a vehicle + m_bIsGettingIntoVehicle = true; + m_ulLastVehicleInOutTime = CClientTime::GetTime(); + +#ifdef MTA_DEBUG + g_pCore->GetConsole()->Printf("* Sent_InOut: vehicle_request_in"); +#endif +} + +// Shot compensation (Jax): +// Positions the local player where he should of been on the shooting player's screen when he +// fired remotely. (the position we !reported! around the time he shot) +bool bShotCompensation = true; + +// Temporary pointers for pre- and post-functions +CVector vecWeaponFirePosition, vecRemoteWeaponFirePosition; +CPlayerPed* pWeaponFirePed = NULL; + +bool CClientGame::PreWeaponFire(CPlayerPed* pPlayerPed, bool bStopIfUsingBulletSync) +{ + pWeaponFirePed = pPlayerPed; + + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pWeaponFirePed) + { + CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); + + // Get the CClientNetPlayer class with the specified player ped + CClientPlayer* pPlayer = g_pClientGame->m_pPlayerManager->Get(pWeaponFirePed, true); + + // Move both players to where they should be for shot compensation + if (pPlayer && !pPlayer->IsLocalPlayer()) + { + if (bStopIfUsingBulletSync && pPlayer->IsCurrentWeaponUsingBulletSync()) + return false; // Don't apply shot compensation & tell caller to not do bullet trace + + if (bShotCompensation) + { + if (!pVehicle || pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + // Warp back in time to where we were when this player shot (their latency) + + // We don't account for interpolation here, +250ms seems to work better + // ** Changed ajustment to +125ms as the position of this clients player on the firers screen + // has been changed. See CClientPed::UpdateTargetPosition() ** + CVector vecPosition; + unsigned short usLatency = (pPlayer->GetLatency() + 125); + g_pClientGame->m_pNetAPI->GetInterpolation(vecPosition, usLatency); + + // Move the entity back + if (pVehicle) + { + pVehicle->GetPosition(vecWeaponFirePosition); + pVehicle->SetPosition(vecPosition, false, false); + } + else + { + pLocalPlayer->GetPosition(vecWeaponFirePosition); + pLocalPlayer->SetPosition(vecPosition, false, false); + } + } + } + } + } + return true; +} + +void CClientGame::PostWeaponFire(void) +{ + // Send bullet sync with local damage info + if (g_bBulletFireVectorsValid) + { + g_bBulletFireVectorsValid = false; + CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer) + { + eWeaponType weaponType = pLocalPlayer->GetCurrentWeaponType(); + if (g_pClientGame->GetWeaponTypeUsesBulletSync(weaponType)) + { + g_pClientGame->GetNetAPI()->SendBulletSyncFire(weaponType, g_vecBulletFireStartPosition, g_vecBulletFireEndPosition, g_fApplyDamageLastAmount, + g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); + } + } + } + + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pWeaponFirePed) + { + CClientPed* pPed = g_pClientGame->GetPedManager()->Get(pWeaponFirePed, true, true); + if (pPed) + { + if (pPed->GetType() == CCLIENTPLAYER) + { + if (bShotCompensation) + { + // Restore compensated positions + if (!pPed->IsLocalPlayer()) + { + CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle(); + if (!pVehicle) + { + pLocalPlayer->SetPosition(vecWeaponFirePosition, false, false); + } + else if (pLocalPlayer->GetOccupiedVehicleSeat() == 0) + { + pVehicle->SetPosition(vecWeaponFirePosition, false, false); + } + } + } + } + + // Call some events + CWeapon* pWeapon = pPed->GetWeapon(); + if (pWeapon) + { + CVector vecCollision; + CClientEntity* pCollisionEntity = NULL; + + if (pPed->GetBulletImpactData(&pCollisionEntity, &vecCollision) == false) + { + CShotSyncData* pShotsyncData = pPed->m_shotSyncData; + CVector vecOrigin, vecTarget; + pPed->GetShotData(&vecOrigin, &vecTarget); + + CColPoint* pCollision = NULL; + CEntity* pCollisionGameEntity = NULL; + vecCollision = vecTarget; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecOrigin, &vecTarget, &pCollision, &pCollisionGameEntity); + if (bCollision && pCollision) + vecCollision = pCollision->GetPosition(); + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + + if (pCollisionGameEntity) + pCollisionEntity = g_pClientGame->m_pManager->FindEntity(pCollisionGameEntity); + } + else + { + pPed->ClearBulletImpactData(); + } + + // Call our lua event + CLuaArguments Arguments; + Arguments.PushNumber((double)pWeapon->GetType()); + Arguments.PushNumber((double)pWeapon->GetAmmoTotal()); + Arguments.PushNumber((double)pWeapon->GetAmmoInClip()); + Arguments.PushNumber((double)vecCollision.fX); + Arguments.PushNumber((double)vecCollision.fY); + Arguments.PushNumber((double)vecCollision.fZ); + if (pCollisionEntity) + Arguments.PushElement(pCollisionEntity); + else + Arguments.PushNil(); + + if (IS_PLAYER(pPed)) + { + CVector vecOrigin; + pPed->GetShotData(&vecOrigin); + Arguments.PushNumber((double)vecOrigin.fX); + Arguments.PushNumber((double)vecOrigin.fY); + Arguments.PushNumber((double)vecOrigin.fZ); + pPed->CallEvent("onClientPlayerWeaponFire", Arguments, true); + } + else + pPed->CallEvent("onClientPedWeaponFire", Arguments, true); + } + pPed->PostWeaponFire(); +#ifdef MTA_DEBUG + if (pPed->IsLocalPlayer() && g_pClientGame->m_bDoPaintballs) + { + g_pClientGame->DoPaintballs(); + } +#endif + } + } + pWeaponFirePed = NULL; +} + +void CClientGame::BulletImpact(CPed* pInitiator, CEntity* pVictim, const CVector* pStartPosition, const CVector* pEndPosition) +{ + // Got a local player model? + CClientPed* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pInitiator) + { + // Find the client ped that initiated the bullet impact + CClientPed* pInitiatorPed = g_pClientGame->GetPedManager()->Get(dynamic_cast(pInitiator), true, true); + + if (pInitiatorPed) + { + // Calculate the collision of the bullet + CVector vecCollision; + CColPoint* pCollision = NULL; + bool bCollision = g_pGame->GetWorld()->ProcessLineOfSight(pStartPosition, pEndPosition, &pCollision, NULL); + if (bCollision && pCollision) + { + vecCollision = pCollision->GetPosition(); + } + else + { + // If we don't have a collision, use the end of the ray that the bullet is tracing. + vecCollision = *pEndPosition; + } + + // Destroy the colpoint + if (pCollision) + { + pCollision->Destroy(); + } + + // Find the client entity for the victim. + CClientEntity* pClientVictim = NULL; + if (pVictim) + { + pClientVictim = g_pClientGame->m_pManager->FindEntity(pVictim); + } + + // Store the data in the bullet fire initiator. + pInitiatorPed->SetBulletImpactData(pClientVictim, vecCollision); + } + } +} + +void CClientGame::BulletFire(CPed* pInitiator, const CVector* pStartPosition, const CVector* pEndPosition) +{ + g_bBulletFireVectorsValid = false; + g_fApplyDamageLastAmount = 0; + g_ucApplyDamageLastHitZone = 0; + g_pApplyDamageLastDamagedPed = NULL; + + // Got a local player model? + CClientPlayer* pLocalPlayer = g_pClientGame->m_pLocalPlayer; + if (pLocalPlayer && pLocalPlayer->GetGamePlayer() == pInitiator) + { + g_bBulletFireVectorsValid = true; + g_vecBulletFireStartPosition = *pStartPosition; + g_vecBulletFireEndPosition = *pEndPosition; + } +} + +bool CClientGame::StaticProcessPacket(unsigned char ucPacketID, NetBitStreamInterface& bitStream) +{ + if (g_pClientGame) + { + g_pCore->UpdateDummyProgress(); + g_pClientGame->GetManager()->GetPacketRecorder()->RecordPacket(ucPacketID, bitStream); + return g_pClientGame->m_pPacketHandler->ProcessPacket(ucPacketID, bitStream); + } + + return false; +} + +void CClientGame::SendExplosionSync(const CVector& vecPosition, eExplosionType Type, CClientEntity* pOrigin) +{ + SPositionSync position(false); + position.data.vecPosition = vecPosition; + + // Create the bitstream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write our origin id + if (pOrigin) + { + pBitStream->WriteBit(true); + pBitStream->Write(pOrigin->GetID()); + + // Convert position + CVector vecTemp; + pOrigin->GetPosition(vecTemp); + position.data.vecPosition -= vecTemp; + } + else + pBitStream->WriteBit(false); + + // Write the position and the type + pBitStream->Write(&position); + + SExplosionTypeSync explosionType; + explosionType.data.uiType = Type; + pBitStream->Write(&explosionType); + + // Destroy it + g_pNet->SendPacket(PACKET_ID_EXPLOSION, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +void CClientGame::SendFireSync(CFire* pFire) +{ +#ifdef MTA_DEBUG + CVector* vecPos = pFire->GetPosition(); + if (vecPos) + g_pCore->GetConsole()->Printf("we're sending fire: %f %f %f %f", pFire->GetStrength(), vecPos->fX, vecPos->fY, vecPos->fZ); + else + g_pCore->GetConsole()->Printf("we're sending a fire!"); +#endif +} + +void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) +{ + // Create the bitstream + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + SPositionSync origin(false); + CClientEntity* pOriginSource = NULL; + eWeaponType weaponType = pProjectile->GetWeaponType(); + CClientEntity* pTarget = pProjectile->GetTargetEntity(); + origin.data.vecPosition = *pProjectile->GetOrigin(); + + // Is this a heatseaking missile with a target? sync it relative to the target + if (weaponType == WEAPONTYPE_ROCKET_HS && pTarget && !pTarget->IsLocalEntity()) + pOriginSource = pTarget; + + // Write the source of the projectile, if it has + if (pOriginSource) + { + CVector vecTemp; + pOriginSource->GetPosition(vecTemp); + origin.data.vecPosition -= vecTemp; + + pBitStream->WriteBit(true); + pBitStream->Write(pOriginSource->GetID()); + } + else + pBitStream->WriteBit(false); + + // Write the origin position + pBitStream->Write(&origin); + + // Write the creator weapon type + SWeaponTypeSync weaponTypeSync; + weaponTypeSync.data.ucWeaponType = static_cast(weaponType); + pBitStream->Write(&weaponTypeSync); + + // Write the projectile's model + if (pBitStream->Version() >= 0x4F) + if (pBitStream->Version() >= 0x52 || pOriginSource) // Fix possible error for 0x51 server + pBitStream->Write(pProjectile->GetModel()); + + switch (weaponType) + { + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_TEARGAS: + case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: + { + SFloatSync<7, 17> projectileForce; + projectileForce.data.fValue = pProjectile->GetForce(); + pBitStream->Write(&projectileForce); + + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); + + break; + } + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKET_HS: + { + if (pTarget) + { + pBitStream->WriteBit(true); + pBitStream->Write(pTarget->GetID()); + } + else + pBitStream->WriteBit(false); + + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); + + SRotationRadiansSync rotation(true); + pProjectile->GetRotationRadians(rotation.data.vecRotation); + pBitStream->Write(&rotation); + + break; + } + case WEAPONTYPE_FLARE: + case WEAPONTYPE_FREEFALL_BOMB: + break; + } + g_pNet->SendPacket(PACKET_ID_PROJECTILE, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + + // Destroy it + g_pNet->DeallocateNetBitStream(pBitStream); + } +} + +void CClientGame::ResetAmmoInClip(void) +{ + memset(&m_wasWeaponAmmoInClip[0], 0, sizeof(m_wasWeaponAmmoInClip)); +} + +void CClientGame::ResetMapInfo(void) +{ + // Restore some game stuff + // Keybinds + g_pCore->GetKeyBinds()->SetAllControlsEnabled(true, true, true); + + // Radarmap + m_pRadarMap->SetForcedState(false); + + // Camera + m_pCamera->FadeOut(0.0f, 0, 0, 0); + g_pGame->GetWorld()->SetCurrentArea(0); + m_pCamera->SetFocusToLocalPlayer(); + g_pGame->GetSettings()->ResetFieldOfViewFromScript(); + + // Dimension + SetAllDimensions(0); + + // Hud + g_pGame->GetHud()->SetComponentVisible(HUD_ALL, true); + // Disable area names as they are on load until camera unfades + g_pGame->GetHud()->SetComponentVisible(HUD_AREA_NAME, false); + g_pGame->GetHud()->SetComponentVisible(HUD_VITAL_STATS, false); + + m_bHudAreaNameDisabled = false; + + // Gravity + g_pMultiplayer->SetLocalPlayerGravity(DEFAULT_GRAVITY); + g_pMultiplayer->SetGlobalGravity(DEFAULT_GRAVITY); + g_pGame->SetGravity(DEFAULT_GRAVITY); + + // Gamespeed + SetGameSpeed(DEFAULT_GAME_SPEED); + + // Game minute duration + SetMinuteDuration(DEFAULT_MINUTE_DURATION); + + // Wanted-level + SetWanted(0); + + // Money + SetMoney(0, true); + + // Weather + m_pBlendedWeather->SetWeather(0); + + // Rain + g_pGame->GetWeather()->ResetAmountOfRain(); + + // Wind + g_pMultiplayer->RestoreWindVelocity(); + + // Far clip distance + g_pMultiplayer->RestoreFarClipDistance(); + + // Near clip distance + g_pMultiplayer->RestoreNearClipDistance(); + + // Fog distance + g_pMultiplayer->RestoreFogDistance(); + + // Vehicles LOD distance + g_pGame->GetSettings()->ResetVehiclesLODDistance(); + + // Peds LOD distance + g_pGame->GetSettings()->ResetPedsLODDistance(); + + // Sun color + g_pMultiplayer->ResetSunColor(); + + // Sun size + g_pMultiplayer->ResetSunSize(); + + // Sky-gradient + g_pMultiplayer->ResetSky(); + + // Heat haze + g_pMultiplayer->ResetHeatHaze(); + + // Water-colour + g_pMultiplayer->ResetWater(); + + // Water + GetManager()->GetWaterManager()->ResetWorldWaterLevel(); + + // Re-enable interior sounds and furniture + g_pMultiplayer->SetInteriorSoundsEnabled(true); + for (int i = 0; i <= 4; ++i) + g_pMultiplayer->SetInteriorFurnitureEnabled(i, true); + + // Clouds + g_pMultiplayer->SetCloudsEnabled(true); + g_pClientGame->SetCloudsEnabled(true); + + // Birds + g_pMultiplayer->DisableBirds(false); + g_pClientGame->SetBirdsEnabled(true); + + // Ambient sounds + g_pGame->GetAudio()->ResetAmbientSounds(); + + // World sounds + g_pGame->GetAudio()->ResetWorldSounds(); + + // Cheats + g_pGame->ResetCheats(); + + // Players + m_pPlayerManager->ResetAll(); + + // Jetpack max height + g_pGame->GetWorld()->SetJetpackMaxHeight(DEFAULT_JETPACK_MAXHEIGHT); + + // Aircraft max height + g_pGame->GetWorld()->SetAircraftMaxHeight(DEFAULT_AIRCRAFT_MAXHEIGHT); + + // Aircraft max velocity + g_pGame->GetWorld()->SetAircraftMaxVelocity(DEFAULT_AIRCRAFT_MAXVELOCITY); + + // Moon size + g_pMultiplayer->ResetMoonSize(); + + // Disable the change of any player stats + g_pMultiplayer->SetLocalStatsStatic(true); + + // Restore blur +#ifdef MTA_DEBUG + g_pGame->SetBlurLevel(0); +#else + g_pGame->SetBlurLevel(DEFAULT_BLUR_LEVEL); +#endif + + // Close all garages + CGarage* pGarage = NULL; + CGarages* pGarages = g_pCore->GetGame()->GetGarages(); + + for (unsigned char i = 0; (pGarage = pGarages->GetGarage(i)) != NULL; i++) + { + pGarage->SetOpen(false); + } + + // Player specific stuff + if (m_pLocalPlayer) + { + // Interior + m_pLocalPlayer->SetInterior(0); + + // Headless state + m_pLocalPlayer->SetHeadless(false); + + // Frozen state + m_pLocalPlayer->SetFrozen(false); + + // Voice + short sVoiceType, sVoiceID; + m_pLocalPlayer->GetModelInfo()->GetVoice(&sVoiceType, &sVoiceID); + m_pLocalPlayer->SetVoice(sVoiceType, sVoiceID); + + m_pLocalPlayer->DestroySatchelCharges(false, true); + // Tell the server we want to destroy our satchels + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + g_pNet->SendPacket(PACKET_ID_DESTROY_SATCHELS, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, + AnimationId animID) +{ + if (Ped && Ped->GetHealth() == 0.0f) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + // Write some death info + pBitStream->WriteCompressed(animGroup); + pBitStream->WriteCompressed(animID); + + pBitStream->Write(damagerID); + + SWeaponTypeSync weapon; + weapon.data.ucWeaponType = ucWeapon; + pBitStream->Write(&weapon); + + SBodypartSync bodyPart; + bodyPart.data.uiBodypart = ucBodyPiece; + pBitStream->Write(&bodyPart); + + // Write the position we died in + SPositionSync pos(false); + Ped->GetPosition(pos.data.vecPosition); + pBitStream->Write(&pos); + + pBitStream->Write(Ped->GetID()); + + // The ammo in our weapon and write the ammo total + CWeapon* pPlayerWeapon = Ped->GetWeapon(); + SWeaponAmmoSync ammo(ucWeapon, true, false); + ammo.data.usTotalAmmo = 0; + if (pPlayerWeapon) + ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); + pBitStream->Write(&ammo); + + // Send the packet + g_pNet->SendPacket(PACKET_ID_PED_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, AnimationId animID) +{ + // Are we not already marked as dead? and have we run out of health? + if (!m_pLocalPlayer->IsDeadOnNetwork() && m_pLocalPlayer->GetHealth() == 0.0f) + { + // Send the "i am dead" packet + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (pBitStream) + { + m_pLocalPlayer->SetDeadOnNetwork(true); + + // Call the onClientPlayerWasted event + CClientEntity* pKiller = (damagerID != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(damagerID) : NULL; + CLuaArguments Arguments; + if (pKiller) + Arguments.PushElement(pKiller); + else + Arguments.PushBoolean(false); + if (ucWeapon != 0xFF) + Arguments.PushNumber(ucWeapon); + else + Arguments.PushBoolean(false); + if (ucBodyPiece != 0xFF) + Arguments.PushNumber(ucBodyPiece); + else + Arguments.PushBoolean(false); + Arguments.PushBoolean(false); + m_pLocalPlayer->CallEvent("onClientPlayerWasted", Arguments, true); + + // Write some death info + pBitStream->WriteCompressed(animGroup); + pBitStream->WriteCompressed(animID); + + pBitStream->Write(damagerID); + + SWeaponTypeSync weapon; + weapon.data.ucWeaponType = ucWeapon; + pBitStream->Write(&weapon); + + SBodypartSync bodyPart; + bodyPart.data.uiBodypart = ucBodyPiece; + pBitStream->Write(&bodyPart); + + // Write the position we died in + SPositionSync pos(false); + m_pLocalPlayer->GetPosition(pos.data.vecPosition); + pBitStream->Write(&pos); + + // The ammo in our weapon and write the ammo total + CWeapon* pPlayerWeapon = m_pLocalPlayer->GetWeapon(); + SWeaponAmmoSync ammo(ucWeapon, true, false); + ammo.data.usTotalAmmo = 0; + if (pPlayerWeapon) + ammo.data.usTotalAmmo = static_cast(pPlayerWeapon->GetAmmoTotal()); + pBitStream->Write(&ammo); + + // Send the packet + g_pNet->SendPacket(PACKET_ID_PLAYER_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(pBitStream); + } + } +} + +bool CClientGame::OnKeyDown(CGUIKeyEventArgs Args) +{ + return true; +} + +bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + const char* szState = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIClick", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseDoubleClick(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + const char* szState = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushString(szState); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIDoubleClick", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIMouseDown", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseButtonUp(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + const char* szButton = NULL; + switch (Args.button) + { + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; + } + + if (szButton) + { + CLuaArguments Arguments; + Arguments.PushString(szButton); + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + { + pGUIElement->CallEvent("onClientGUIMouseUp", Arguments, true); + } + } + + return true; +} + +bool CClientGame::OnMouseMove(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseMove", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseEnter(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + if (Args.pSwitchedWindow) + { + CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); + if (GetGUIManager()->Exists(pGUISwitchedElement)) + Arguments.PushElement(pGUISwitchedElement); + } + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseEnter", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseLeave(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.position.fX); + Arguments.PushNumber(Args.position.fY); + if (Args.pSwitchedWindow) + { + CClientGUIElement* pGUISwitchedElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pSwitchedWindow); + if (GetGUIManager()->Exists(pGUISwitchedElement)) + Arguments.PushElement(pGUISwitchedElement); + } + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseLeave", Arguments, true); + + return true; +} + +bool CClientGame::OnMouseWheel(CGUIMouseEventArgs Args) +{ + if (!Args.pWindow) + return false; + + CLuaArguments Arguments; + Arguments.PushNumber(Args.wheelChange); + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pWindow); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientMouseWheel", Arguments, true); + + return true; +} + +bool CClientGame::OnMove(CGUIElement* pElement) +{ + if (!pElement) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); + if (pGUIElement && GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientGUIMove", Arguments, true); + + return true; +} + +bool CClientGame::OnSize(CGUIElement* pElement) +{ + if (!pElement) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pGUIElement = CGUI_GET_CCLIENTGUIELEMENT(pElement); + if (GetGUIManager()->Exists(pGUIElement)) + pGUIElement->CallEvent("onClientGUISize", Arguments, true); + + return true; +} + +bool CClientGame::OnFocusGain(CGUIFocusEventArgs Args) +{ + if (!Args.pActivatedWindow) + return false; + + CLuaArguments Arguments; + + CClientGUIElement* pActivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pActivatedWindow); + + if (Args.pDeactivatedWindow) + { + CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); + if (GetGUIManager()->Exists(pDeactivatedGUIElement)) + pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); + } + + if (GetGUIManager()->Exists(pActivatedGUIElement)) + pActivatedGUIElement->CallEvent("onClientGUIFocus", Arguments, true); + + return true; +} + +bool CClientGame::OnFocusLoss(CGUIFocusEventArgs Args) +{ + if (!Args.pDeactivatedWindow) + return false; + + CLuaArguments Arguments; + + if (Args.pActivatedWindow) + { + // pDeactivatedWindow looses focus but an other window is now gaining it so we let CClientGame::OnFocusGain trigger both events in the right order + return true; + } + + CClientGUIElement* pDeactivatedGUIElement = CGUI_GET_CCLIENTGUIELEMENT(Args.pDeactivatedWindow); + if (GetGUIManager()->Exists(pDeactivatedGUIElement)) + pDeactivatedGUIElement->CallEvent("onClientGUIBlur", Arguments, true); + + return true; +} + +// +// Display a progress dialog if a big packet is coming in +// +void CClientGame::NotifyBigPacketProgress(unsigned long ulBytesReceived, unsigned long ulTotalSize) +{ + // Should display progress box? + if (ulBytesReceived >= ulTotalSize || ulTotalSize < 50000) + { + if (m_bReceivingBigPacket) + { + // Switch off progress box + m_bReceivingBigPacket = false; + m_pBigPacketTransferBox->Hide(); + } + return; + } + + // Update progress box + if (!m_bReceivingBigPacket || m_ulBigPacketSize != ulTotalSize) + { + m_bReceivingBigPacket = true; + m_ulBigPacketSize = ulTotalSize; + m_pBigPacketTransferBox->Hide(); + m_pBigPacketTransferBox->AddToTotalSize(ulTotalSize); + m_pBigPacketTransferBox->Show(); + } + + m_pBigPacketTransferBox->DoPulse(); + m_pBigPacketTransferBox->SetInfo(std::min(ulTotalSize, ulBytesReceived), CTransferBox::PACKET); +} + +bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled) +{ + if (ucGlitch < NUM_GLITCHES && bEnabled != m_Glitches[ucGlitch]) + { + m_Glitches[ucGlitch] = bEnabled; + if (ucGlitch == GLITCH_QUICKRELOAD) + g_pMultiplayer->DisableQuickReload(!bEnabled); + if (ucGlitch == GLITCH_CLOSEDAMAGE) + g_pMultiplayer->DisableCloseRangeDamage(!bEnabled); + return true; + } + return false; +} + +bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) +{ + return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; +} + +bool CClientGame::SetCloudsEnabled(bool bEnabled) +{ + m_bCloudsEnabled = bEnabled; + return true; +} +bool CClientGame::GetCloudsEnabled(void) +{ + return m_bCloudsEnabled; +} + +bool CClientGame::SetBirdsEnabled(bool bEnabled) +{ + m_bBirdsEnabled = bEnabled; + return true; +} +bool CClientGame::GetBirdsEnabled(void) +{ + return m_bBirdsEnabled; +} + +#pragma code_seg(".text") +bool CClientGame::VerifySADataFiles(int iEnableClientChecks) +{ + int& iCheckStatus = g_pGame->GetCheckStatus(); + + if (!g_pGame->VerifySADataFileNames()) + iCheckStatus |= (1 << 11); + + __declspec(allocate(".text")) static char szVerifyData[][32] = { "data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", + "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", + "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", + "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", + "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", + "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", + "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", + "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", + "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", + "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", + "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", + "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74" }; + + CMD5Hasher hasher; + for (int i = 0; i < NUMELMS(szVerifyData); i += 2) + { + MD5 md5; + if (!hasher.Calculate(szVerifyData[i], md5) || memcmp(md5.data, szVerifyData[i + 1], 0x10)) + { + iCheckStatus |= (1 << i); + } + } + + if (iCheckStatus & iEnableClientChecks) + { + g_pCore->InitiateDataFilesFix(); + g_pCore->GetModManager()->RequestUnload(); + return false; + } + + return true; +} + +void CClientGame::InitVoice(bool bEnabled, unsigned int uiServerSampleRate, unsigned char ucQuality, unsigned int uiBitrate) +{ + if (m_pVoiceRecorder) + { + m_pVoiceRecorder->Init(bEnabled, uiServerSampleRate, ucQuality, uiBitrate); + } +} + +// +// If debug render mode is on, allow each element in range to draw some stuff +// +void CClientGame::DebugElementRender(void) +{ + if (!GetDevelopmentMode() || !GetShowCollision()) + return; + + CVector vecCameraPos; + m_pCamera->GetPosition(vecCameraPos); + float fDrawRadius = 200.f; + + // Get all entities within range + CClientEntityResult result; + GetClientSpatialDatabase()->SphereQuery(result, CSphere(vecCameraPos, fDrawRadius)); + + // For each entity found + for (CClientEntityResult::const_iterator it = result.begin(); it != result.end(); ++it) + { + CClientEntity* pEntity = *it; + if (pEntity->GetParent()) + pEntity->DebugRender(vecCameraPos, fDrawRadius); + } +} + +////////////////////////////////////////////////////////////////// +// Click +// +void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString& strTag, uint uiQuality, uint uiMaxBandwidth, uint uiMaxPacketSize, + CResource* pResource, uint uiServerSentTime) +{ + if (!pResource) + return; + + bool bAllowScreenUploadEnabled = 1; + g_pCore->GetCVars()->Get("allow_screen_upload", bAllowScreenUploadEnabled); + bool bWindowMinimized = g_pCore->IsWindowMinimized(); + + if (bWindowMinimized || !bAllowScreenUploadEnabled) + { + // If alt-tabbed or opt-out + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + if (!bAllowScreenUploadEnabled) + pBitStream->Write((uchar)EPlayerScreenShotResult::DISABLED); + else + pBitStream->Write((uchar)EPlayerScreenShotResult::MINIMIZED); + pBitStream->Write(uiServerSentTime); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); + g_pNet->DeallocateNetBitStream(pBitStream); + } + else + { + // Do grab and send + SScreenShotArgs screenShotArgs; + screenShotArgs.uiMaxBandwidth = uiMaxBandwidth; + screenShotArgs.uiMaxPacketSize = uiMaxPacketSize; + screenShotArgs.usResourceNetId = pResource->GetNetID(); + screenShotArgs.strTag = strTag; + screenShotArgs.uiServerSentTime = uiServerSentTime; + m_ScreenShotArgList.push_back(screenShotArgs); + g_pCore->GetGraphics()->GetScreenGrabber()->QueueScreenShot(uiSizeX, uiSizeY, uiQuality, &CClientGame::StaticGottenPlayerScreenShot); + } +} + +////////////////////////////////////////////////////////////////// +// Callback from TakePlayerScreendsShot +// +void CClientGame::StaticGottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strError) +{ + if (g_pClientGame) + g_pClientGame->GottenPlayerScreenShot(pBuffer, uiTimeSpentInQueue, strError); +} + +////////////////////////////////////////////////////////////////// +// Break data into packets and put into delayed send list +// +void CClientGame::GottenPlayerScreenShot(const CBuffer* pBuffer, uint uiTimeSpentInQueue, const SString& strInError) +{ + SString strError = strInError; + + // Pop saved args + if (m_ScreenShotArgList.empty()) + return; + + SScreenShotArgs screenShotArgs = m_ScreenShotArgList.front(); + m_ScreenShotArgList.pop_front(); + const uint uiMaxBandwidth = Clamp(100, screenShotArgs.uiMaxBandwidth, 1000000); + const uint uiMaxPacketSize = Clamp(100, screenShotArgs.uiMaxPacketSize, 100000); + const ushort usResourceNetId = screenShotArgs.usResourceNetId; + const SString strTag = screenShotArgs.strTag; + const uint uiServerGrabTime = screenShotArgs.uiServerSentTime + uiTimeSpentInQueue; + + // Silently ignore if resource has been stopped + CResource* pResource = GetResourceManager()->GetResourceFromNetID(usResourceNetId); + if (!pResource) + return; + + // Validate buffer + if (strError.empty()) + { + if (!pBuffer || pBuffer->GetSize() == 0) + strError = "Buffer empty"; + } + + // Handle error + if (!strError.empty()) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->Write((uchar)EPlayerScreenShotResult::ERROR_); + pBitStream->Write(uiServerGrabTime); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + if (pBitStream->Version() >= 0x053) + pBitStream->WriteString(strError); + g_pNet->SendPacket(PACKET_ID_PLAYER_SCREENSHOT, pBitStream, PACKET_PRIORITY_LOW, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_DATA_TRANSFER); + g_pNet->DeallocateNetBitStream(pBitStream); + return; + } + + // Calc constants stuff + const uint uiSendRate = Clamp(5, uiMaxBandwidth / uiMaxPacketSize, 20); + const long long llPacketInterval = 1000 / uiSendRate; + const uint uiTotalByteSize = pBuffer->GetSize(); + const char* pData = pBuffer->GetData(); + const uint uiBytesPerPart = std::min(std::min(std::max(100U, uiMaxBandwidth / uiSendRate), uiTotalByteSize), 30000U); + const uint uiNumParts = std::max(1U, (uiTotalByteSize + uiBytesPerPart - 1) / uiBytesPerPart); + + // Calc variables stuff + CTickCount tickCount = CTickCount::Now() + CTickCount(llPacketInterval); + uint uiBytesRemaining = uiTotalByteSize; + m_usNextScreenShotId++; + + // Make each packet + for (uint i = 0; i < uiNumParts; i++) + { + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + + ushort usPartNumber = i; + ushort usBytesThisPart = std::min(uiBytesRemaining, uiBytesPerPart); + assert(usBytesThisPart != 0); + + pBitStream->Write((uchar)EPlayerScreenShotResult::SUCCESS); + pBitStream->Write(m_usNextScreenShotId); + pBitStream->Write(usPartNumber); + pBitStream->Write(usBytesThisPart); + pBitStream->Write(pData, usBytesThisPart); + + // Write more info if first part + if (usPartNumber == 0) + { + pBitStream->Write(uiServerGrabTime); + pBitStream->Write(uiTotalByteSize); + pBitStream->Write((ushort)uiNumParts); + if (pBitStream->Version() >= 0x053) + pBitStream->Write(pResource->GetNetID()); + else + pBitStream->WriteString(pResource->GetName()); + pBitStream->WriteString(strTag); + } + + // Add to delay send list + SDelayedPacketInfo delayedPacketInfo; + delayedPacketInfo.useTickCount = tickCount; + delayedPacketInfo.ucPacketID = PACKET_ID_PLAYER_SCREENSHOT; + delayedPacketInfo.pBitStream = pBitStream; + delayedPacketInfo.packetPriority = PACKET_PRIORITY_LOW; + delayedPacketInfo.packetReliability = PACKET_RELIABILITY_RELIABLE_ORDERED; + delayedPacketInfo.packetOrdering = PACKET_ORDERING_DATA_TRANSFER; + m_DelayedSendList.push_back(delayedPacketInfo); + + // Increment stuff + pData += usBytesThisPart; + uiBytesRemaining -= usBytesThisPart; + tickCount += CTickCount(llPacketInterval); + } + + assert(uiBytesRemaining == 0); +} + +////////////////////////////////////////////////////////////////// +// Process delay send list +// +void CClientGame::ProcessDelayedSendList(void) +{ + CTickCount tickCount = CTickCount::Now(); + + while (!m_DelayedSendList.empty()) + { + SDelayedPacketInfo& info = m_DelayedSendList.front(); + if (info.useTickCount > tickCount) + break; + + g_pNet->SendPacket(info.ucPacketID, info.pBitStream, info.packetPriority, info.packetReliability, info.packetOrdering); + g_pNet->DeallocateNetBitStream(info.pBitStream); + m_DelayedSendList.pop_front(); + } +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetWeaponTypesUsingBulletSync +// +// Set whether the local player will send bulletsync messages for the supplied weapon type +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetWeaponTypesUsingBulletSync(const std::set& weaponTypesUsingBulletSync) +{ + m_weaponTypesUsingBulletSync = weaponTypesUsingBulletSync; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::GetWeaponTypeUsesBulletSync +// +// Get whether the local player should send bulletsync messages for the supplied weapon type +// +////////////////////////////////////////////////////////////////// +bool CClientGame::GetWeaponTypeUsesBulletSync(eWeaponType weaponType) +{ + return MapContains(m_weaponTypesUsingBulletSync, weaponType); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetDevelopmentMode +// +// Special mode which enables commands such as showcol and showsound +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetDevelopmentMode(bool bEnable, bool bEnableWeb) +{ + m_bDevelopmentMode = bEnable; + + if (m_bDevelopmentMode) + g_pGame->GetAudio()->SetWorldSoundHandler(CClientGame::StaticWorldSoundHandler); + else + g_pGame->GetAudio()->SetWorldSoundHandler(NULL); + + if (g_pCore->IsWebCoreLoaded()) + g_pCore->GetWebCore()->SetTestModeEnabled(bEnableWeb); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::StaticWorldSoundHandler +// +// Handle callback from CAudioSA when a world sound is played +// +////////////////////////////////////////////////////////////////// +void CClientGame::StaticWorldSoundHandler(uint uiGroup, uint uiIndex) +{ + g_pClientGame->WorldSoundHandler(uiGroup, uiIndex); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::WorldSoundHandler +// +// Handle callback from CAudioSA when a world sound is played +// +////////////////////////////////////////////////////////////////// +void CClientGame::WorldSoundHandler(uint uiGroup, uint uiIndex) +{ + if (m_bShowSound) + m_pScriptDebugging->LogInformation(NULL, "%s - World sound group:%d index:%d", *GetLocalTimeString(false, true), uiGroup, uiIndex); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::IsUsingAlternatePulseOrder +// +// Returns true if should be using alternate pulse order +// +////////////////////////////////////////////////////////////////// +bool CClientGame::IsUsingAlternatePulseOrder(bool bAdvanceDelayCounter) +{ + if (m_MiscGameSettings.bUseAltPulseOrder) + { + // Only actually start using alternate pulse order after 100 frames + if (m_uiAltPulseOrderCounter >= 100) + return true; + else if (bAdvanceDelayCounter) + m_uiAltPulseOrderCounter++; + } + + return false; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::OutputServerInfo +// +// Output info about the connected server for player +// +////////////////////////////////////////////////////////////////// +void CClientGame::OutputServerInfo(void) +{ + SString strTotalOutput; + strTotalOutput += SString("Server info for %s", g_pNet->GetConnectedServer(true)); + strTotalOutput += "\n"; + strTotalOutput += SString("Ver: %s\n", *GetServerVersionSortable()); + strTotalOutput += SString("AC: %s\n", *m_strACInfo); + + { + SString strVoice; + if (m_pVoiceRecorder && m_pVoiceRecorder->IsEnabled()) + strVoice += SString("Enabled - Sample rate:%d Quality:%d", m_pVoiceRecorder->GetSampleRate(), m_pVoiceRecorder->GetSampleQuality()); + else + strVoice += "Disabled"; + + strTotalOutput += SString("Voice: %s\n", *strVoice); + } + + { + SString strEnabledGlitches; + const char* szGlitchNames[] = { "Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", + "Bad driveby hitboxes", "Quick stand" }; + for (uint i = 0; i < NUM_GLITCHES; i++) + { + if (IsGlitchEnabled(i)) + { + if (!strEnabledGlitches.empty()) + strEnabledGlitches += ", "; + if (i < NUMELMS(szGlitchNames)) + strEnabledGlitches += szGlitchNames[i]; + else + strEnabledGlitches += SString("Unknown(#%d)", i + 1); + } + } + if (strEnabledGlitches.empty()) + strEnabledGlitches = "None"; + strTotalOutput += SString("Glitches: %s\n", *strEnabledGlitches); + } + + { + SString strEnabledBulletSync; + for (std::set::iterator iter = m_weaponTypesUsingBulletSync.begin(); iter != m_weaponTypesUsingBulletSync.end(); ++iter) + { + eWeaponType weaponType = *iter; + if (!strEnabledBulletSync.empty()) + strEnabledBulletSync += ","; + strEnabledBulletSync += SString("%d", weaponType); + } + if (strEnabledBulletSync.empty()) + strEnabledBulletSync = "None"; + strTotalOutput += SString("Bullet sync weapons: %s\n", *strEnabledBulletSync); + } + + { + SString strVehExtrapolate; + if (m_VehExtrapolateSettings.bEnabled) + strVehExtrapolate += SString("Amount:%d%% (LimitMs:%d)", m_VehExtrapolateSettings.iScalePercent, m_VehExtrapolateSettings.iMaxMs); + else + strVehExtrapolate += "Disabled"; + + strTotalOutput += SString("Vehicle extrapolation: %s\n", *strVehExtrapolate); + } + + { + SString strTickRates; + strTickRates += SString("Plr:%d Cam:%d Ped:%d UnocVeh:%d KeyRot:%d KeyJoy:%d", g_TickRateSettings.iPureSync, g_TickRateSettings.iCamSync, + g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, + g_TickRateSettings.iKeySyncAnalogMove); + + strTotalOutput += SString("Tick rates: %s\n", *strTickRates); + } + + { + SString strSyncerDists; + strSyncerDists += SString("Ped:%d UnoccupiedVehicle:%d ", g_TickRateSettings.iPedSyncerDistance, g_TickRateSettings.iUnoccupiedVehicleSyncerDistance); + + strTotalOutput += SString("Syncer distances: %s\n", *strSyncerDists); + } + + g_pCore->GetConsole()->Print(strTotalOutput); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::TellServerSomethingImportant +// +// Report misc important warnings/errors to the current server +// +////////////////////////////////////////////////////////////////// +void CClientGame::TellServerSomethingImportant(uint uiId, const SString& strMessage, uint uiSendLimitForThisId) +{ + g_pCore->GetConsole()->Print(strMessage); + AddReportLog(3400 + uiId, strMessage + g_pNet->GetConnectedServer(true), 10); + + if (uiSendLimitForThisId) + { + uint& uiCount = MapGet(m_SentMessageIds, uiId); + if (uiCount++ >= uiSendLimitForThisId) + return; + } + + NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); + pBitStream->WriteString(SString("%d,%s", uiId, *strMessage)); + g_pNet->SendPacket(PACKET_ID_PLAYER_DIAGNOSTIC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE); + g_pNet->DeallocateNetBitStream(pBitStream); +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::ChangeFloatPrecision +// +// Manage the change to high floating point precision +// +////////////////////////////////////////////////////////////////// +void CClientGame::ChangeFloatPrecision(bool bHigh) +{ + if (bHigh) + { + // Switch to 53 bit floating point precision on the first call + if (m_uiPrecisionCallDepth++ == 0) + _controlfp(_PC_53, MCW_PC); + } + else + { + // Even though is should never happen, m_uiPrecisionCallDepth is sometimes zero here + dassert(m_uiPrecisionCallDepth != 0); + if (m_uiPrecisionCallDepth != 0) + m_uiPrecisionCallDepth--; + // Switch back to 24 bit floating point precision on the last call + if (m_uiPrecisionCallDepth == 0) + _controlfp(_PC_24, MCW_PC); + } +} + +bool CClientGame::IsHighFloatPrecision(void) const +{ + return m_uiPrecisionCallDepth != 0; +} + +AnimationId CClientGame::DrivebyAnimationHandler(AnimationId animId, AssocGroupId animGroupId) +{ + // Only apply if all clients support the fix + if (!GetMiscGameSettings().bAllowBadDrivebyHitboxFix) + return animId; + + // If the glitch is enabled, don't apply the fix + if (IsGlitchEnabled(GLITCH_BADDRIVEBYHITBOX)) + return animId; + + // Bad animations are 232 and 236 of assoc group 72 + if (animGroupId != 72) + return animId; + + if (animId == 232) + return 235; + else if (animId == 236) + return 231; + + return animId; +} + +////////////////////////////////////////////////////////////////// +// +// CClientGame::SetFileCacheRoot +// +// Figure out which directory to use for the client resource file cache +// +////////////////////////////////////////////////////////////////// +void CClientGame::SetFileCacheRoot(void) +{ + if (g_pCore->GetCVars()->GetValue("share_file_cache") == false) + { + // Not sharing, so use current mod directory + m_strFileCacheRoot = GetModRoot(); + AddReportLog(7410, SString("CClientGame::SetFileCacheRoot - Not shared '%s'", *m_strFileCacheRoot)); + } + else + { + // Get shared directory + SString strFileCachePath = GetCommonRegistryValue("", "File Cache Path"); + // Check exists + if (!strFileCachePath.empty() && DirectoryExists(strFileCachePath)) + { + // Check writable + SString strTestFileName = PathJoin(strFileCachePath, "resources", "_test.tmp"); + if (FileSave(strTestFileName, "x")) + { + FileDelete(strTestFileName); + strTestFileName = PathJoin(strFileCachePath, "priv", "_test.tmp"); + if (FileSave(strTestFileName, "x")) + { + FileDelete(strTestFileName); + // Use shared directory + m_strFileCacheRoot = strFileCachePath; + AddReportLog(7411, SString("CClientGame::SetFileCacheRoot - Is shared '%s'", *m_strFileCacheRoot)); + return; + } + } + } + + // Otherwise set this install mod directory as shared + m_strFileCacheRoot = GetModRoot(); + SetCommonRegistryValue("", "File Cache Path", m_strFileCacheRoot); + + if (strFileCachePath.empty()) + AddReportLog(7412, SString("CClientGame::SetFileCacheRoot - Initial setting '%s'", *m_strFileCacheRoot)); + else + AddReportLog(7413, SString("CClientGame::SetFileCacheRoot - Change shared from '%s' to '%s'", *strFileCachePath, *m_strFileCacheRoot)); + } +} + +bool CClientGame::TriggerBrowserRequestResultEvent(const std::unordered_set& newPages) +{ + CLuaArguments Arguments; + CLuaArguments LuaTable; + int i = 0; + + for (auto& domain : newPages) + { + LuaTable.PushNumber(++i); + LuaTable.PushString(domain); + } + Arguments.PushTable(&LuaTable); + + return GetRootEntity()->CallEvent("onClientBrowserWhitelistChange", Arguments, false); +} + +void CClientGame::RestreamModel(unsigned short usModel) +{ + // Is this a vehicle ID? + if (CClientVehicleManager::IsValidModel(usModel)) + { + // Stream the vehicles of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetVehicleManager()->RestreamVehicles(usModel); + } + + // Is this an object ID? + else if (CClientObjectManager::IsValidModel(usModel)) + { + if (CClientPedManager::IsValidWeaponModel(usModel)) + { + // Stream the weapon of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetPedManager()->RestreamWeapon(usModel); + m_pManager->GetPickupManager()->RestreamPickups(usModel); + } + // Stream the objects of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetObjectManager()->RestreamObjects(usModel); + g_pGame->GetModelInfo(usModel)->RestreamIPL(); + } + // Is this an ped ID? + else if (CClientPlayerManager::IsValidModel(usModel)) + { + // Stream the ped of that model out so we have no + // loaded when we do the restore. The streamer will + // eventually stream them back in with async loading. + m_pManager->GetPedManager()->RestreamPeds(usModel); + } + else + + // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect + if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) + m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); +} + +void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) +{ + m_mapOfIfpPointers[u32BlockNameHash] = pIFP; +} + +std::shared_ptr CClientGame::GetIFPPointerFromMap(const unsigned int u32BlockNameHash) +{ + auto it = m_mapOfIfpPointers.find(u32BlockNameHash); + if (it != m_mapOfIfpPointers.end()) + { + return it->second; + } + return nullptr; +} + +void CClientGame::RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash) +{ + m_mapOfIfpPointers.erase(u32BlockNameHash); +} + +void CClientGame::InsertPedPointerToSet(CClientPed* pPed) +{ + m_setOfPedPointers.insert(pPed); +} + +void CClientGame::RemovePedPointerFromSet(CClientPed* pPed) +{ + m_setOfPedPointers.erase(pPed); +} + +CClientPed* CClientGame::GetClientPedByClump(const RpClump& Clump) +{ + for (auto& pPed : m_setOfPedPointers) + { + CEntity* pEntity = pPed->GetGameEntity(); + if (pEntity != nullptr) + { + if (pEntity->GetRpClump() != nullptr) + { + const RpClump& entityClump = *pEntity->GetRpClump(); + if (std::addressof(entityClump) == std::addressof(Clump)) + { + return pPed; + } + } + } + } + return nullptr; +} + +void CClientGame::OnClientIFPUnload(const std::shared_ptr& IFP) +{ + IFP->MarkAsUnloading(); + for (auto& pPed : m_setOfPedPointers) + { + // Remove IFP animations from replaced animations of peds/players + pPed->RestoreAnimations(IFP); + + // Make sure that streamed in pulses or changing model does not accidently + // play our custom animation. We can do that by making the custom animation + // untriggerable + if (pPed->GetCustomAnimationBlockNameHash() == IFP->GetBlockNameHash()) + { + if (pPed->IsCustomAnimationPlaying()) + { + pPed->SetCustomAnimationUntriggerable(); + } + + // Important! As we are using a shared_ptr, we need to decrement the reference counter + // by setting the shared_ptr to nullptr, this will avoid memory leak + if (!pPed->IsNextAnimationCustom() && pPed->IsCurrentAnimationCustom()) + { + pPed->DereferenceCustomAnimationBlock(); + } + } + } +} + +void CClientGame::InsertAnimationAssociationToMap(CAnimBlendAssociationSAInterface* pAnimAssociation, const std::shared_ptr& pIFPAnimations) +{ + m_mapOfCustomAnimationAssociations[pAnimAssociation] = pIFPAnimations; +} + +void CClientGame::RemoveAnimationAssociationFromMap(CAnimBlendAssociationSAInterface* pAnimAssociation) +{ + m_mapOfCustomAnimationAssociations.erase(pAnimAssociation); +} From 8c8e7453fa71df6a9971df51e0bd11f644bcef2e Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 17:51:07 +0200 Subject: [PATCH 13/27] Update CClientGame.cpp --- Client/mods/deathmatch/logic/CClientGame.cpp | 768 +++++++++---------- 1 file changed, 383 insertions(+), 385 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 73852452eeb..b5b43e140f1 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -1,13 +1,13 @@ /***************************************************************************** -* -* PROJECT: Multi Theft Auto v1.0 -* LICENSE: See LICENSE in the top level directory -* FILE: mods/deathmatch/logic/CClientGame.cpp -* PURPOSE: Client game manager -* -* Multi Theft Auto is available from http://www.multitheftauto.com/ -* -*****************************************************************************/ + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CClientGame.cpp + * PURPOSE: Client game manager + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ #include "StdInc.h" #include @@ -313,17 +313,17 @@ CClientGame::CClientGame(bool bLocalPlay) m_bBeingDeleted = false; -#if defined (MTA_DEBUG) || defined (MTA_BETA) + #if defined (MTA_DEBUG) || defined (MTA_BETA) m_bShowSyncingInfo = false; -#endif + #endif -#ifdef MTA_DEBUG + #ifdef MTA_DEBUG m_pShowPlayer = m_pShowPlayerTasks = NULL; m_bMimicLag = false; m_ulLastMimicLag = 0; m_bDoPaintballs = false; m_bShowInterpolation = false; -#endif + #endif // Add our lua events AddBuiltInEvents(); @@ -369,7 +369,7 @@ CClientGame::~CClientGame(void) g_pCore->GetGUI()->ClearInputHandlers(INPUT_MOD); // Destroy mimics -#ifdef MTA_DEBUG + #ifdef MTA_DEBUG list::const_iterator iterMimics = m_Mimics.begin(); for (; iterMimics != m_Mimics.end(); iterMimics++) { @@ -380,7 +380,7 @@ CClientGame::~CClientGame(void) delete pPlayer; } -#endif + #endif // Hide the transfer box incase it is showing m_pTransferBox->Hide(); @@ -506,17 +506,17 @@ CClientGame::~CClientGame(void) /* bool CClientGame::StartGame ( void ) // for an offline game (e.g. editor) { -m_Status = STATUS_OFFLINE; -g_pCore->SetOfflineMod ( true ); // hide chatbox etc -g_pCore->SetConnected ( true ); // not sure, but its required :) -g_pCore->HideMainMenu (); // duh + m_Status = STATUS_OFFLINE; + g_pCore->SetOfflineMod ( true ); // hide chatbox etc + g_pCore->SetConnected ( true ); // not sure, but its required :) + g_pCore->HideMainMenu (); // duh -// If the game isn't started, start it -if ( g_pGame->GetSystemState () == 7 ) -{ -g_pGame->StartGame (); -} -return true; + // If the game isn't started, start it + if ( g_pGame->GetSystemState () == 7 ) + { + g_pGame->StartGame (); + } + return true; } */ @@ -600,7 +600,7 @@ bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerT pBitStream->Write(static_cast(MTA_DM_BITSTREAM_VERSION)); SString strPlayerVersion("%d.%d.%d-%d.%05d.%d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, - MTASA_VERSION_BUILD, g_pNet->GetNetRev()); + MTASA_VERSION_BUILD, g_pNet->GetNetRev()); pBitStream->WriteString(strPlayerVersion); pBitStream->WriteBit(g_pCore->IsOptionalUpdateInfoRequired(g_pNet->GetConnectedServer(true))); @@ -626,7 +626,7 @@ bool CClientGame::StartGame(const char* szNick, const char* szPassword, eServerT else { g_pCore->ShowMessageBox(_("Error") + _E("CD02"), _("Not connected; please use Quick Connect or the 'connect' command to connect to a server."), - MB_BUTTON_OK | MB_ICON_ERROR); + MB_BUTTON_OK | MB_ICON_ERROR); g_pCore->GetModManager()->RequestUnload(); } @@ -751,7 +751,7 @@ void CClientGame::DoPulsePreHUDRender(bool bDidUnminimize, bool bDidRecreateRend void CClientGame::DoPulsePostFrame(void) { TIMING_CHECKPOINT("+CClientGame::DoPulsePostFrame"); -#ifdef DEBUG_KEYSTATES + #ifdef DEBUG_KEYSTATES // Get the controller state CControllerState cs; g_pGame->GetPad()->GetCurrentControllerState(&cs); @@ -789,7 +789,7 @@ void CClientGame::DoPulsePostFrame(void) cs.m_bVehicleMouseLook, cs.LeftStickX, cs.LeftStickY, cs.RightStickX, cs.RightStickY); g_pCore->GetGraphics()->DrawTextTTF(300, 320, 1280, 800, 0xFFFFFFFF, strBuffer, 1.0f, 0); -#endif + #endif UpdateModuleTickCount64(); @@ -843,7 +843,7 @@ void CClientGame::DoPulsePostFrame(void) int iPosX = uiWidth / 2; // Half way across int iPosY = uiHeight * 45 / 100; // 45/100 down g_pCore->GetGraphics()->DrawString(iPosX, iPosY, iPosX, iPosY, COLOR_ARGB(255, 255, 0, 0), "*** NETWORK TROUBLE ***", 2.0f, 2.0f, - DT_NOCLIP | DT_CENTER); + DT_NOCLIP | DT_CENTER); } // Adjust the streaming memory limit. @@ -857,8 +857,8 @@ void CClientGame::DoPulsePostFrame(void) if (g_pMultiplayer->GetLimits()->GetStreamingMemory() != iStreamingMemoryBytes) g_pMultiplayer->GetLimits()->SetStreamingMemory(iStreamingMemoryBytes); - // If we're in debug mode and are supposed to show task data, do it -#ifdef MTA_DEBUG + // If we're in debug mode and are supposed to show task data, do it + #ifdef MTA_DEBUG if (m_pShowPlayerTasks) { DrawTasks(m_pShowPlayerTasks); @@ -876,9 +876,9 @@ void CClientGame::DoPulsePostFrame(void) if (pPlayer->IsStreamedIn() && pPlayer->IsShowingWepdata()) DrawWeaponsyncData(pPlayer); } -#endif + #endif -#if defined (MTA_DEBUG) || defined (MTA_BETA) + #if defined (MTA_DEBUG) || defined (MTA_BETA) if (m_bShowSyncingInfo) { // Draw the header boxz @@ -898,7 +898,7 @@ void CClientGame::DoPulsePostFrame(void) m_pDisplayManager->DrawText2D(strBuffer, vecPosition, 1.0f, 0xFFFFFFFF); } } -#endif + #endif // Heli Clear time if (m_LastClearTime.Get() > HeliKill_List_Clear_Rate) { @@ -988,7 +988,7 @@ void CClientGame::DoPulses(void) // Otherwise, disconnect here AddReportLog(7105, SString("Core - Kicked (%s)", *strMessageCombo)); g_pCore->ShowMessageBox(_("Error") + _E("CD05"), SString(_("You were kicked from the game ( %s )"), *strMessageCombo), - MB_BUTTON_OK | MB_ICON_ERROR); + MB_BUTTON_OK | MB_ICON_ERROR); g_pCore->GetModManager()->RequestUnload(); return; } @@ -1028,9 +1028,9 @@ void CClientGame::DoPulses(void) GetModelCacheManager()->DoPulse(); -#ifdef MTA_DEBUG + #ifdef MTA_DEBUG UpdateMimics(); -#endif + #endif // Grab the current time unsigned long ulCurrentTime = CClientTime::GetTime(); @@ -1190,42 +1190,42 @@ void CClientGame::DoPulses(void) SString strErrorCode; switch (ucError) { - case RID_RSA_PUBLIC_KEY_MISMATCH: - strError = _("Disconnected: unknown protocol error"); - strErrorCode = _E("CD10"); // encryption key mismatch - break; - case RID_REMOTE_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected remotely"); - strErrorCode = _E("CD11"); - break; - case RID_REMOTE_CONNECTION_LOST: - strError = _("Disconnected: connection lost remotely"); - strErrorCode = _E("CD12"); - break; - case RID_CONNECTION_BANNED: - strError = _("Disconnected: you are banned from this server"); - strErrorCode = _E("CD13"); - break; - case RID_NO_FREE_INCOMING_CONNECTIONS: - strError = _("Disconnected: the server is currently full"); - strErrorCode = _E("CD14"); - break; - case RID_DISCONNECTION_NOTIFICATION: - strError = _("Disconnected: disconnected from the server"); - strErrorCode = _E("CD15"); - break; - case RID_CONNECTION_LOST: - strError = _("Disconnected: connection to the server was lost"); - strErrorCode = _E("CD16"); - break; - case RID_INVALID_PASSWORD: - strError = _("Disconnected: invalid password specified"); - strErrorCode = _E("CD17"); - break; - default: - strError = _("Disconnected: connection was refused"); - strErrorCode = _E("CD18"); - break; + case RID_RSA_PUBLIC_KEY_MISMATCH: + strError = _("Disconnected: unknown protocol error"); + strErrorCode = _E("CD10"); // encryption key mismatch + break; + case RID_REMOTE_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected remotely"); + strErrorCode = _E("CD11"); + break; + case RID_REMOTE_CONNECTION_LOST: + strError = _("Disconnected: connection lost remotely"); + strErrorCode = _E("CD12"); + break; + case RID_CONNECTION_BANNED: + strError = _("Disconnected: you are banned from this server"); + strErrorCode = _E("CD13"); + break; + case RID_NO_FREE_INCOMING_CONNECTIONS: + strError = _("Disconnected: the server is currently full"); + strErrorCode = _E("CD14"); + break; + case RID_DISCONNECTION_NOTIFICATION: + strError = _("Disconnected: disconnected from the server"); + strErrorCode = _E("CD15"); + break; + case RID_CONNECTION_LOST: + strError = _("Disconnected: connection to the server was lost"); + strErrorCode = _E("CD16"); + break; + case RID_INVALID_PASSWORD: + strError = _("Disconnected: invalid password specified"); + strErrorCode = _E("CD17"); + break; + default: + strError = _("Disconnected: connection was refused"); + strErrorCode = _E("CD18"); + break; } // Display an error, reset the error status and exit @@ -1562,16 +1562,16 @@ void CClientGame::UpdateVehicleInOut(void) // Make it undamagable if we're not syncing it, and damagable if we're syncing it if ( pInOutVehicle ) { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } }*/ if (pInOutVehicle) { @@ -1646,8 +1646,8 @@ void CClientGame::UpdateVehicleInOut(void) // Make it damagable if ( pInOutVehicle ) { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); } */ if (pInOutVehicle) @@ -1727,16 +1727,16 @@ void CClientGame::UpdateVehicleInOut(void) // Make it undamagable if we're not syncing it, and damagable if we're syncing it if ( pInOutVehicle ) { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } } */ if (pInOutVehicle) @@ -1802,16 +1802,16 @@ void CClientGame::UpdateVehicleInOut(void) CDeathmatchVehicle* pInOutVehicle = static_cast < CDeathmatchVehicle* > ( pOccupiedVehicle ); if ( pInOutVehicle ) { - if ( pInOutVehicle->IsSyncing () ) - { - pInOutVehicle->SetCanBeDamaged ( true ); - pInOutVehicle->SetTyresCanBurst ( true ); - } - else - { - pInOutVehicle->SetCanBeDamaged ( false ); - pInOutVehicle->SetTyresCanBurst ( false ); - } + if ( pInOutVehicle->IsSyncing () ) + { + pInOutVehicle->SetCanBeDamaged ( true ); + pInOutVehicle->SetTyresCanBurst ( true ); + } + else + { + pInOutVehicle->SetCanBeDamaged ( false ); + pInOutVehicle->SetTyresCanBurst ( false ); + } } */ @@ -1925,7 +1925,7 @@ void CClientGame::UpdatePlayerWeapons(void) CWeapon* pLastWeapon = m_pLocalPlayer->GetWeapon(m_lastWeaponSlot); if (pLastWeapon && pLastWeapon->GetAmmoTotal() == 0 && (m_lastWeaponSlot == WEAPONSLOT_TYPE_THROWN || - (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) + (BitStream.Version() >= 0x5A && (m_lastWeaponSlot == WEAPONSLOT_TYPE_HEAVY || m_lastWeaponSlot == WEAPONSLOT_TYPE_SPECIAL)))) BitStream.WriteBit(true); else BitStream.WriteBit(false); @@ -1934,7 +1934,7 @@ void CClientGame::UpdatePlayerWeapons(void) if (pWeapon) { /* Send a packet to the server with info about the new weapon, - so the server stays in sync reliably */ + so the server stays in sync reliably */ unsigned int uiSlot = static_cast(pWeapon->GetSlot()); slot.data.uiSlot = uiSlot; BitStream.Write(&slot); @@ -2372,7 +2372,7 @@ bool CClientGame::CharacterKeyHandler(WPARAM wChar) if (wChar >= 32) { // Generate a null-terminating string for our character - wchar_t wUNICODE[2] = { wChar, '\0' }; + wchar_t wUNICODE[2] = {wChar, '\0'}; // Convert our UTF character into an ANSI string SString strANSI = UTF16ToMbUTF8(wUNICODE); @@ -2454,24 +2454,24 @@ bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wPa unsigned char ucButtonHit = 0xFF; switch (uMsg) { - case WM_LBUTTONDOWN: - ucButtonHit = 0; - break; - case WM_LBUTTONUP: - ucButtonHit = 1; - break; - case WM_MBUTTONDOWN: - ucButtonHit = 2; - break; - case WM_MBUTTONUP: - ucButtonHit = 3; - break; - case WM_RBUTTONDOWN: - ucButtonHit = 4; - break; - case WM_RBUTTONUP: - ucButtonHit = 5; - break; + case WM_LBUTTONDOWN: + ucButtonHit = 0; + break; + case WM_LBUTTONUP: + ucButtonHit = 1; + break; + case WM_MBUTTONDOWN: + ucButtonHit = 2; + break; + case WM_MBUTTONUP: + ucButtonHit = 3; + break; + case WM_RBUTTONDOWN: + ucButtonHit = 4; + break; + case WM_RBUTTONUP: + ucButtonHit = 5; + break; } if (ucButtonHit != 0xFF) { @@ -2483,7 +2483,7 @@ bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wPa /* // (IJs) why are these relative? it doesn't make sense CVector2D vecCursorPosition ( ( ( float ) iX ) / vecResolution.fX, - ( ( float ) iY ) / vecResolution.fY ); + ( ( float ) iY ) / vecResolution.fY ); */ CVector2D vecCursorPosition((float)iX, (float)iY); @@ -2536,30 +2536,30 @@ bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wPa const char* szState = NULL; switch (ucButtonHit) { - case 0: - szButton = "left"; - szState = "down"; - break; - case 1: - szButton = "left"; - szState = "up"; - break; - case 2: - szButton = "middle"; - szState = "down"; - break; - case 3: - szButton = "middle"; - szState = "up"; - break; - case 4: - szButton = "right"; - szState = "down"; - break; - case 5: - szButton = "right"; - szState = "up"; - break; + case 0: + szButton = "left"; + szState = "down"; + break; + case 1: + szButton = "left"; + szState = "up"; + break; + case 2: + szButton = "middle"; + szState = "down"; + break; + case 3: + szButton = "middle"; + szState = "up"; + break; + case 4: + szButton = "right"; + szState = "down"; + break; + case 5: + szButton = "right"; + szState = "up"; + break; } if (szButton && szState) { @@ -2642,33 +2642,33 @@ bool CClientGame::ProcessMessageForCursorEvents(HWND hwnd, UINT uMsg, WPARAM wPa } switch (uMsg) { - case WM_MOUSEMOVE: - { - int iX = LOWORD(lParam), iY = HIWORD(lParam); - static int iPreviousX = 0, iPreviousY = 0; - if (iX != iPreviousX || iY != iPreviousY) + case WM_MOUSEMOVE: { - iPreviousX = iX, iPreviousY = iY; + int iX = LOWORD(lParam), iY = HIWORD(lParam); + static int iPreviousX = 0, iPreviousY = 0; + if (iX != iPreviousX || iY != iPreviousY) + { + iPreviousX = iX, iPreviousY = iY; - CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); - CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); + CVector2D vecResolution = g_pCore->GetGUI()->GetResolution(); + CVector2D vecCursorPosition(((float)iX) / vecResolution.fX, ((float)iY) / vecResolution.fY); - CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); - g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); + CVector vecTarget, vecScreen((float)iX, (float)iY, 300.0f); + g_pCore->GetGraphics()->CalcWorldCoors(&vecScreen, &vecTarget); - // Call the onClientCursorMove event - CLuaArguments Arguments; - Arguments.PushNumber((double)vecCursorPosition.fX); - Arguments.PushNumber((double)vecCursorPosition.fY); - Arguments.PushNumber((double)iX); - Arguments.PushNumber((double)iY); - Arguments.PushNumber((double)vecTarget.fX); - Arguments.PushNumber((double)vecTarget.fY); - Arguments.PushNumber((double)vecTarget.fZ); - m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); + // Call the onClientCursorMove event + CLuaArguments Arguments; + Arguments.PushNumber((double)vecCursorPosition.fX); + Arguments.PushNumber((double)vecCursorPosition.fY); + Arguments.PushNumber((double)iX); + Arguments.PushNumber((double)iY); + Arguments.PushNumber((double)vecTarget.fX); + Arguments.PushNumber((double)vecTarget.fY); + Arguments.PushNumber((double)vecTarget.fZ); + m_pRootEntity->CallEvent("onClientCursorMove", Arguments, false); + } + break; } - break; - } } return false; } @@ -2836,9 +2836,6 @@ void CClientGame::AddBuiltInEvents(void) m_Events.AddEvent("onClientClick", "button, state, screenX, screenY, worldX, worldY, worldZ, gui_clicked", NULL, false); m_Events.AddEvent("onClientCursorMove", "relativeX, relativeX, absoluteX, absoluteY, worldX, worldY, worldZ", NULL, false); - // Transfer box event - m_Events.AddEvent("onTransferBoxProgressChange", "currentStatus, totalSize", NULL, false); - // Marker events m_Events.AddEvent("onClientMarkerHit", "entity, matchingDimension", NULL, false); m_Events.AddEvent("onClientMarkerLeave", "entity, matchingDimension", NULL, false); @@ -3119,18 +3116,18 @@ void CClientGame::DrawWeaponsyncData(CClientPlayer* pPlayer) yoffset = 0; strTemp.Format("Ammo in clip: %d", pWeapon->GetAmmoInClip()); g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); yoffset = 15; strTemp.Format("State: %d", pWeapon->GetState()); g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX + 1, (int)vecScreenPosition.fY + 1 + yoffset, (int)vecScreenPosition.fX + 1, - (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, - DT_NOCLIP | DT_CENTER); + (int)vecScreenPosition.fY + 1 + yoffset, COLOR_ARGB(255, 255, 255, 255), strTemp, 1.0f, 1.0f, + DT_NOCLIP | DT_CENTER); g_pCore->GetGraphics()->DrawString((int)vecScreenPosition.fX, (int)vecScreenPosition.fY + yoffset, (int)vecScreenPosition.fX, - (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); + (int)vecScreenPosition.fY + yoffset, COLOR_ARGB(255, 0, 0, 0), strTemp, 1.0f, 1.0f, DT_NOCLIP | DT_CENTER); } } } @@ -3197,21 +3194,21 @@ void CClientGame::UpdateMimics(void) static CClientMarker *pOriginCorona = NULL, *pTargetCorona = NULL; if ( pOriginCorona == NULL ) { - pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); - pOriginCorona->SetColor ( 0, 255, 0, 255 ); - pOriginCorona->SetSize ( 0.5f ); + pOriginCorona = new CClientMarker ( m_pManager, 1337, MARKER_CORONA ); + pOriginCorona->SetColor ( 0, 255, 0, 255 ); + pOriginCorona->SetSize ( 0.5f ); } else - pOriginCorona->SetPosition ( vecOrigin ); + pOriginCorona->SetPosition ( vecOrigin ); if ( pTargetCorona == NULL ) { - pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); - pTargetCorona->SetColor ( 255, 0, 0, 255 ); - pTargetCorona->SetSize ( 0.5f ); + pTargetCorona = new CClientMarker ( m_pManager, 1338, MARKER_CORONA ); + pTargetCorona->SetColor ( 255, 0, 0, 255 ); + pTargetCorona->SetSize ( 0.5f ); } else - pTargetCorona->SetPosition ( vecTarget );*/ + pTargetCorona->SetPosition ( vecTarget );*/ // Apply this to each of our mimic players unsigned int uiMimicIndex = 0; @@ -3379,7 +3376,7 @@ void CClientGame::UpdateMimics(void) if (!pMimicTrailer) { pMimicTrailer = new CDeathmatchVehicle(m_pManager, m_pUnoccupiedVehicleSync, - static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); + static_cast(450 + uiMimicIndex + uiTrailerLoop), uiModel, 0, 0); pMimicVehicle->SetTowedVehicle(pMimicTrailer); } @@ -3457,24 +3454,24 @@ void CClientGame::QuitPlayer(CClientPlayer* pPlayer, eQuitReason Reason) const char* szReason = "Unknown"; switch (Reason) { - case QUIT_QUIT: - szReason = "Quit"; - break; - case QUIT_KICK: - szReason = "Kicked"; - break; - case QUIT_BAN: - szReason = "Banned"; - break; - case QUIT_CONNECTION_DESYNC: - szReason = "Bad Connection"; - break; - case QUIT_TIMEOUT: - szReason = "Timed Out"; - break; - } - - // In debug, make sure we don't look at this player's details + case QUIT_QUIT: + szReason = "Quit"; + break; + case QUIT_KICK: + szReason = "Kicked"; + break; + case QUIT_BAN: + szReason = "Banned"; + break; + case QUIT_CONNECTION_DESYNC: + szReason = "Bad Connection"; + break; + case QUIT_TIMEOUT: + szReason = "Timed Out"; + break; + } + + // In debug, make sure we don't look at this player's details #ifdef MTA_DEBUG if (m_pShowPlayer == pPlayer) { @@ -3516,8 +3513,8 @@ void CClientGame::Event_OnIngame(void) g_pMultiplayer->DeleteAndDisableGangTags(); // Switch off peds and traffic - SFixedArray vecs = { CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), - CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0) }; + SFixedArray vecs = {CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), + CVector(-100000.0f, -100000.0f, -100000.0f), CVector(100000.0f, 100000.0f, 100000.0f), CVector(0, 0, 0)}; g_pGame->GetPathFind()->SwitchRoadsOffInArea(&vecs[0], &vecs[1]); g_pGame->GetPathFind()->SwitchPedRoadsOffInArea(&vecs[2], &vecs[3]); g_pGame->GetPathFind()->SetPedDensity(0.0f); @@ -3645,19 +3642,20 @@ CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationHandler(RpClump } CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) + AssocGroupId animGroup, AnimationId animID) { return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); } -bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) +bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssoc, + CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) { - return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); + return g_pClientGame->AssocGroupCopyAnimationHandler(pOutAnimStaticAssoc, pAnimAssoc, pClump, pAnimAssocGroup, animID); } bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, - int* pFlags, RpClump* pClump) + int* pFlags, RpClump* pClump) { return g_pClientGame->BlendAnimationHierarchyHandler(pAnimAssoc, pOutAnimHierarchy, pFlags, pClump); } @@ -3688,15 +3686,15 @@ bool CClientGame::StaticProcessCollisionHandler(CEntitySAInterface* pThisInterfa } bool CClientGame::StaticVehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, - float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, - CVector vecCollisionVelocity) + float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, + CVector vecCollisionVelocity) { return g_pClientGame->VehicleCollisionHandler(pCollidingVehicle, pCollidedVehicle, iModelIndex, fDamageImpulseMag, fCollidingDamageImpulseMag, usPieceType, - vecCollisionPos, vecCollisionVelocity); + vecCollisionPos, vecCollisionVelocity); } bool CClientGame::StaticVehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) + const CVector& vecDamagePos, uchar ucTyre) { return g_pClientGame->VehicleDamageHandler(pVehicleInterface, fLoss, pAttackerInterface, weaponType, vecDamagePos, ucTyre); } @@ -3763,20 +3761,20 @@ void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity) ushort usModelId = 0xFFFF; switch (pClientEntity->GetType()) { - case CCLIENTPED: - case CCLIENTPLAYER: - iTypeMask = TYPE_MASK_PED; - usModelId = (ushort) static_cast(pClientEntity)->GetModel(); - break; - case CCLIENTVEHICLE: - iTypeMask = TYPE_MASK_VEHICLE; - break; - case CCLIENTOBJECT: - iTypeMask = TYPE_MASK_OBJECT; - break; - default: - iTypeMask = TYPE_MASK_OTHER; - break; + case CCLIENTPED: + case CCLIENTPLAYER: + iTypeMask = TYPE_MASK_PED; + usModelId = (ushort) static_cast(pClientEntity)->GetModel(); + break; + case CCLIENTVEHICLE: + iTypeMask = TYPE_MASK_VEHICLE; + break; + case CCLIENTOBJECT: + iTypeMask = TYPE_MASK_OBJECT; + break; + default: + iTypeMask = TYPE_MASK_OTHER; + break; } g_pGame->GetRenderWare()->SetRenderingClientEntity(pClientEntity, usModelId, iTypeMask); return; @@ -3912,16 +3910,14 @@ void CClientGame::IdleHandler(void) CLuaArguments Arguments; m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); - bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); - // Apply mute on minimize options - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) - g_pGame->GetAudio()->SetMusicMasterVolume(0); - - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) + if (g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) g_pGame->GetAudio()->SetEffectsMasterVolume(0); - if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) + if (g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) + g_pGame->GetAudio()->SetMusicMasterVolume(0); + + if (g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) m_pManager->GetSoundManager()->SetMinimizeMuted(true); } } @@ -3957,55 +3953,49 @@ CAnimBlendAssociationSAInterface* CClientGame::AddAnimationHandler(RpClump* pClu } CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, - AssocGroupId animGroup, AnimationId animID) + AssocGroupId animGroup, AnimationId animID) { // printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID ); return nullptr; } -bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, - CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) +bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssocInterface, + CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, + CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) { bool isCustomAnimationToPlay = false; CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); - auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); - - CClientPed* pClientPed = GetClientPedByClump(*pClump); + auto pOutAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pOutAnimStaticAssocInterface); + CClientPed* pClientPed = GetClientPedByClump(*pClump); if (pClientPed != nullptr) { auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); if (pReplacedAnimation != nullptr) { std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); + InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); // Play our custom animation instead of default - auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); - pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); - pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); - pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); + pOutAnimStaticAssoc->Initialize(pClump, pReplacedAnimation->pAnimationHierarchy); isCustomAnimationToPlay = true; } } if (!isCustomAnimationToPlay) { - auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); - // Play default internal animation - pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); - pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); + pOutAnimStaticAssoc->Initialize(pClump, pOriginalAnimHierarchyInterface); } + + CopyStaticAssociationProperties(pOutAnimStaticAssoc, pOriginalAnimStaticAssoc); return isCustomAnimationToPlay; } bool CClientGame::BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags, - RpClump* pClump) + RpClump* pClump) { bool isCustomAnimationToPlay = false; CAnimManager* pAnimationManager = g_pGame->GetAnimManager(); @@ -4085,13 +4075,13 @@ bool CClientGame::ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CE if (pEntity && pColEntity) { -#if MTA_DEBUG + #if MTA_DEBUG CClientEntity* ppThisEntity2 = iter1->second; CClientEntity* ppOtherEntity2 = iter2->second; // These should match, but its not essential. assert(ppThisEntity2 == pEntity); assert(ppOtherEntity2 == pColEntity); -#endif + #endif if (!pEntity->IsCollidableWith(pColEntity)) return false; } @@ -4179,8 +4169,8 @@ bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) // Is this shotgun damage? if ( weaponUsed == WEAPONTYPE_SHOTGUN || weaponUsed == WEAPONTYPE_SPAS12_SHOTGUN ) { - // Make the ped fall down - pEvent->MakePedFallDown (); + // Make the ped fall down + pEvent->MakePedFallDown (); } */ // Grab the damaged ped @@ -4265,24 +4255,24 @@ bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) switch (pInflictingEntity->GetType()) { - case CCLIENTPLAYER: - { - pInflictingPlayer = static_cast(pInflictingEntity); - break; - } - case CCLIENTVEHICLE: - { - CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); - if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) + case CCLIENTPLAYER: { - CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); - if (pPed && pPed->GetType() == CCLIENTPLAYER) - pInflictingPlayer = static_cast(pPed); + pInflictingPlayer = static_cast(pInflictingEntity); + break; } - break; - } - default: - break; + case CCLIENTVEHICLE: + { + CClientVehicle* pInflictingVehicle = static_cast(pInflictingEntity); + if (pInflictingVehicle && pInflictingVehicle->GetControllingPlayer()) + { + CClientPed* pPed = static_cast(pInflictingVehicle->GetControllingPlayer()); + if (pPed && pPed->GetType() == CCLIENTPLAYER) + pInflictingPlayer = static_cast(pPed); + } + break; + } + default: + break; } if (pInflictingPlayer) { @@ -4316,7 +4306,7 @@ bool CClientGame::DamageHandler(CPed* pDamagePed, CEventDamage* pEvent) // Check GTA stored health with our stored health and do stuff // bool CClientGame::ApplyPedDamageFromGame(eWeaponType weaponUsed, float fDamage, uchar hitZone, CClientPed* pDamagedPed, CClientEntity* pInflictingEntity, - CEventDamage* pEvent) + CEventDamage* pEvent) { float fPreviousHealth = pDamagedPed->m_fHealth; float fCurrentHealth = pDamagedPed->GetGamePlayer()->GetHealth(); @@ -4519,7 +4509,7 @@ void CClientGame::DeathHandler(CPed* pKilledPedSA, unsigned char ucDeathReason, } bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedWith, int iModelIndex, float fDamageImpulseMag, - float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) + float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity) { if (pCollidingVehicle && pCollidedWith) { @@ -4595,7 +4585,7 @@ bool CClientGame::VehicleCollisionHandler(CVehicleSAInterface* pCollidingVehicle pBitStream->Write(pVehicleClientEntity->GetID()); // Send! g_pNet->SendPacket(PACKET_ID_VEHICLE_PUSH_SYNC, pBitStream, PACKET_PRIORITY_MEDIUM, - PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); + PACKET_RELIABILITY_UNRELIABLE_SEQUENCED); // Reset our push time pClientVehicle->ResetLastPushTime(); } @@ -4679,7 +4669,7 @@ bool CClientGame::HeliKillHandler(CVehicleSAInterface* pHeliInterface, CEntitySA } bool CClientGame::VehicleDamageHandler(CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, - const CVector& vecDamagePos, uchar ucTyre) + const CVector& vecDamagePos, uchar ucTyre) { bool bAllowDamage = true; CClientVehicle* pClientVehicle = GetGameEntityXRefManager()->FindClientVehicle(pVehicleInterface); @@ -4942,7 +4932,7 @@ void CClientGame::ProcessVehicleInOutKey(bool bPassenger) || m_bIsGettingIntoVehicle // We can't enter a vehicle we're currently entering... || m_bIsGettingOutOfVehicle // We can't enter a vehicle we're currently leaving... || CClientTime::GetTime() < m_ulLastVehicleInOutTime + VEHICLE_INOUT_DELAY // We are trying to enter the vehicle to soon - ) + ) { return; } @@ -5017,7 +5007,7 @@ void CClientGame::ProcessVehicleInOutKey(bool bPassenger) CClientVehicle* pVehicle = m_pLocalPlayer->GetClosestVehicleInRange(true, !bPassenger, bPassenger, false, nullptr, nullptr, 20.0f); if (pVehicle && (pVehicle->IsInWater() || - m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) + m_pLocalPlayer->IsInWater())) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle) { m_pLocalPlayer->KillTask(3, true); // Kill jump task if we are about to warp in } @@ -5044,7 +5034,7 @@ void CClientGame::ProcessVehicleInOutKey(bool bPassenger) || m_pLocalPlayer->HasJetPack() // Make sure we don't have a jetpack || m_pLocalPlayer->IsUsingGun() // Make sure we're not using a gun (have the gun task active) - we stop it in UpdatePlayerTasks anyway || m_pLocalPlayer->IsRunningAnimation() // Make sure we aren't running an animation - ) + ) { return; } @@ -5194,7 +5184,7 @@ void CClientGame::PostWeaponFire(void) if (g_pClientGame->GetWeaponTypeUsesBulletSync(weaponType)) { g_pClientGame->GetNetAPI()->SendBulletSyncFire(weaponType, g_vecBulletFireStartPosition, g_vecBulletFireEndPosition, g_fApplyDamageLastAmount, - g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); + g_ucApplyDamageLastHitZone, DynamicCast(g_pApplyDamageLastDamagedPed)); } } } @@ -5461,45 +5451,45 @@ void CClientGame::SendProjectileSync(CClientProjectile* pProjectile) switch (weaponType) { - case WEAPONTYPE_GRENADE: - case WEAPONTYPE_TEARGAS: - case WEAPONTYPE_MOLOTOV: - case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: - { - SFloatSync<7, 17> projectileForce; - projectileForce.data.fValue = pProjectile->GetForce(); - pBitStream->Write(&projectileForce); + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_TEARGAS: + case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_REMOTE_SATCHEL_CHARGE: + { + SFloatSync<7, 17> projectileForce; + projectileForce.data.fValue = pProjectile->GetForce(); + pBitStream->Write(&projectileForce); - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); - break; - } - case WEAPONTYPE_ROCKET: - case WEAPONTYPE_ROCKET_HS: - { - if (pTarget) - { - pBitStream->WriteBit(true); - pBitStream->Write(pTarget->GetID()); + break; } - else - pBitStream->WriteBit(false); + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_ROCKET_HS: + { + if (pTarget) + { + pBitStream->WriteBit(true); + pBitStream->Write(pTarget->GetID()); + } + else + pBitStream->WriteBit(false); - SVelocitySync velocity; - pProjectile->GetVelocity(velocity.data.vecVelocity); - pBitStream->Write(&velocity); + SVelocitySync velocity; + pProjectile->GetVelocity(velocity.data.vecVelocity); + pBitStream->Write(&velocity); - SRotationRadiansSync rotation(true); - pProjectile->GetRotationRadians(rotation.data.vecRotation); - pBitStream->Write(&rotation); + SRotationRadiansSync rotation(true); + pProjectile->GetRotationRadians(rotation.data.vecRotation); + pBitStream->Write(&rotation); - break; - } - case WEAPONTYPE_FLARE: - case WEAPONTYPE_FREEFALL_BOMB: - break; + break; + } + case WEAPONTYPE_FLARE: + case WEAPONTYPE_FREEFALL_BOMB: + break; } g_pNet->SendPacket(PACKET_ID_PROJECTILE, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); @@ -5577,9 +5567,6 @@ void CClientGame::ResetMapInfo(void) // Vehicles LOD distance g_pGame->GetSettings()->ResetVehiclesLODDistance(); - // Peds LOD distance - g_pGame->GetSettings()->ResetPedsLODDistance(); - // Sun color g_pMultiplayer->ResetSunColor(); @@ -5683,7 +5670,7 @@ void CClientGame::ResetMapInfo(void) } void CClientGame::SendPedWastedPacket(CClientPed* Ped, ElementID damagerID, unsigned char ucWeapon, unsigned char ucBodyPiece, AssocGroupId animGroup, - AnimationId animID) + AnimationId animID) { if (Ped && Ped->GetHealth() == 0.0f) { @@ -5803,18 +5790,18 @@ bool CClientGame::OnMouseClick(CGUIMouseEventArgs Args) const char* szState = NULL; switch (Args.button) { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; } if (szButton) @@ -5844,18 +5831,18 @@ bool CClientGame::OnMouseDoubleClick(CGUIMouseEventArgs Args) const char* szState = NULL; switch (Args.button) { - case CGUIMouse::LeftButton: - szButton = "left"; - szState = "up"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - szState = "up"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - szState = "up"; - break; + case CGUIMouse::LeftButton: + szButton = "left"; + szState = "up"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + szState = "up"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + szState = "up"; + break; } if (szButton) @@ -5884,15 +5871,15 @@ bool CClientGame::OnMouseButtonDown(CGUIMouseEventArgs Args) const char* szButton = NULL; switch (Args.button) { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; } if (szButton) @@ -5920,15 +5907,15 @@ bool CClientGame::OnMouseButtonUp(CGUIMouseEventArgs Args) const char* szButton = NULL; switch (Args.button) { - case CGUIMouse::LeftButton: - szButton = "left"; - break; - case CGUIMouse::MiddleButton: - szButton = "middle"; - break; - case CGUIMouse::RightButton: - szButton = "right"; - break; + case CGUIMouse::LeftButton: + szButton = "left"; + break; + case CGUIMouse::MiddleButton: + szButton = "middle"; + break; + case CGUIMouse::RightButton: + szButton = "right"; + break; } if (szButton) @@ -6171,18 +6158,18 @@ bool CClientGame::VerifySADataFiles(int iEnableClientChecks) if (!g_pGame->VerifySADataFileNames()) iCheckStatus |= (1 << 11); - __declspec(allocate(".text")) static char szVerifyData[][32] = { "data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", - "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", - "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", - "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", - "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", - "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", - "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", - "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", - "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", - "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", - "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", - "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74" }; + __declspec(allocate(".text")) static char szVerifyData[][32] = {"data/carmods.dat", "\x6c\xbe\x84\x53\x61\xe7\x6a\xae\x35\xdd\xca\x30\x08\x67\xca\xdf", + "data/handling.cfg", "\x68\x68\xac\xce\xf9\x33\xf1\x85\x5e\xc2\x8c\xe1\x93\xa7\x81\x59", + "data/melee.dat", "\xb2\xf0\x56\x57\x98\x0e\x4a\x69\x3f\x8f\xf5\xea\xdc\xba\xd8\xf8", + "data/object.dat", "\x46\xa5\xe7\xdf\xf9\x00\x78\x84\x2e\x24\xd9\xde\x5e\x92\xcc\x3e", + "data/surface.dat", "\x9e\xb4\xe4\xe4\x74\xab\xd5\xda\x2f\x39\x61\xa5\xef\x54\x9f\x9e", + "data/surfaud.dat", "\xc3\x2c\x58\x6e\x8b\xa3\x57\x42\xe3\x56\xe6\x52\x56\x19\xf7\xc3", + "data/surfinfo.dat", "\x60\x5d\xd0\xbe\xab\xcc\xc7\x97\xce\x94\xa5\x1a\x3e\x4a\x09\xeb", + "data/vehicles.ide", "\xbd\xc3\xa0\xfc\xed\x24\x02\xc5\xbc\x61\x58\x57\x14\x45\x7d\x4b", + "data/water.dat", "\x69\x04\x00\xec\xc9\x21\x69\xd9\xea\xdd\xaa\xa9\x48\x90\x3e\xfb", + "data/water1.dat", "\x16\xfe\x5a\x3e\x8c\x57\xd0\x2e\xb6\x2a\x44\xa9\x6d\x8b\x9d\x39", + "data/weapon.dat", "\x0a\x9b\xb4\x90\x03\x68\x03\x64\xf9\xf9\x76\x8e\x9b\xce\xa9\x82", + "anim/ped.ifp", "\x47\x36\xB2\xC9\x0B\x00\x98\x12\x55\xF9\x50\x73\x08\xEE\x91\x74"}; CMD5Hasher hasher; for (int i = 0; i < NUMELMS(szVerifyData); i += 2) @@ -6241,7 +6228,7 @@ void CClientGame::DebugElementRender(void) // Click // void CClientGame::TakePlayerScreenShot(uint uiSizeX, uint uiSizeY, const SString& strTag, uint uiQuality, uint uiMaxBandwidth, uint uiMaxPacketSize, - CResource* pResource, uint uiServerSentTime) + CResource* pResource, uint uiServerSentTime) { if (!pResource) return; @@ -6535,8 +6522,8 @@ void CClientGame::OutputServerInfo(void) { SString strEnabledGlitches; - const char* szGlitchNames[] = { "Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", - "Bad driveby hitboxes", "Quick stand" }; + const char* szGlitchNames[] = {"Quick reload", "Fast fire", "Fast move", "Crouch bug", "Close damage", "Hit anim", "Fast sprint", + "Bad driveby hitboxes", "Quick stand"}; for (uint i = 0; i < NUM_GLITCHES; i++) { if (IsGlitchEnabled(i)) @@ -6581,8 +6568,8 @@ void CClientGame::OutputServerInfo(void) { SString strTickRates; strTickRates += SString("Plr:%d Cam:%d Ped:%d UnocVeh:%d KeyRot:%d KeyJoy:%d", g_TickRateSettings.iPureSync, g_TickRateSettings.iCamSync, - g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, - g_TickRateSettings.iKeySyncAnalogMove); + g_TickRateSettings.iPedSync, g_TickRateSettings.iUnoccupiedVehicle, g_TickRateSettings.iKeySyncRotation, + g_TickRateSettings.iKeySyncAnalogMove); strTotalOutput += SString("Tick rates: %s\n", *strTickRates); } @@ -6782,7 +6769,18 @@ void CClientGame::RestreamModel(unsigned short usModel) // 'Restream' upgrades after model replacement to propagate visual changes with immediate effect if (CClientObjectManager::IsValidModel(usModel) && CVehicleUpgrades::IsUpgrade(usModel)) - m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); + m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); +} + +void CClientGame::CopyStaticAssociationProperties(std::unique_ptr& pOutAnimStaticAssoc, + std::unique_ptr& pOriginalAnimStaticAssoc) +{ + pOutAnimStaticAssoc->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); + pOutAnimStaticAssoc->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); + + // Total bones in clump. GTA SA is using 32 bones for peds/players + pOutAnimStaticAssoc->SetNumBlendNodes(pOriginalAnimStaticAssoc->GetNumBlendNodes()); + pOutAnimStaticAssoc->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); } void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) From 0ce4601507e9a285e9d72f36c55c7a2eb06c878a Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 18:03:36 +0200 Subject: [PATCH 14/27] Update CClientGame.cpp --- Client/mods/deathmatch/logic/CClientGame.cpp | 54 ++++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index b5b43e140f1..010da777c88 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -3647,11 +3647,10 @@ CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler( return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); } -bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssoc, - CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, +CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) { - return g_pClientGame->AssocGroupCopyAnimationHandler(pOutAnimStaticAssoc, pAnimAssoc, pClump, pAnimAssocGroup, animID); + return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); } bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, @@ -3910,14 +3909,16 @@ void CClientGame::IdleHandler(void) CLuaArguments Arguments; m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); + bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); + // Apply mute on minimize options - if (g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) +- g_pGame->GetAudio()->SetMusicMasterVolume(0); +- +- if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) g_pGame->GetAudio()->SetEffectsMasterVolume(0); - if (g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) - g_pGame->GetAudio()->SetMusicMasterVolume(0); - - if (g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) m_pManager->GetSoundManager()->SetMinimizeMuted(true); } } @@ -3959,8 +3960,7 @@ CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClum return nullptr; } -bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssocInterface, - CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, +bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump, CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID) { bool isCustomAnimationToPlay = false; @@ -3968,29 +3968,37 @@ bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAIn auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface); auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID); auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface(); - auto pOutAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pOutAnimStaticAssocInterface); - CClientPed* pClientPed = GetClientPedByClump(*pClump); + auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation(pAnimAssocInterface); + + CClientPed* pClientPed = GetClientPedByClump(*pClump); if (pClientPed != nullptr) { auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface); if (pReplacedAnimation != nullptr) { std::shared_ptr pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer(); - InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations); + InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations); // Play our custom animation instead of default - pOutAnimStaticAssoc->Initialize(pClump, pReplacedAnimation->pAnimationHierarchy); + auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy); + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->InitializeForCustomAnimation(pClump, pAnimHierarchy->GetInterface()); + pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); + pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); + pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); isCustomAnimationToPlay = true; } } if (!isCustomAnimationToPlay) { + auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); + // Play default internal animation - pOutAnimStaticAssoc->Initialize(pClump, pOriginalAnimHierarchyInterface); + pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); + pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); } - CopyStaticAssociationProperties(pOutAnimStaticAssoc, pOriginalAnimStaticAssoc); return isCustomAnimationToPlay; } @@ -5567,6 +5575,9 @@ void CClientGame::ResetMapInfo(void) // Vehicles LOD distance g_pGame->GetSettings()->ResetVehiclesLODDistance(); + // Peds LOD distance + g_pGame->GetSettings()->ResetPedsLODDistance(); + // Sun color g_pMultiplayer->ResetSunColor(); @@ -6772,17 +6783,6 @@ void CClientGame::RestreamModel(unsigned short usModel) m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel); } -void CClientGame::CopyStaticAssociationProperties(std::unique_ptr& pOutAnimStaticAssoc, - std::unique_ptr& pOriginalAnimStaticAssoc) -{ - pOutAnimStaticAssoc->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup()); - pOutAnimStaticAssoc->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID()); - - // Total bones in clump. GTA SA is using 32 bones for peds/players - pOutAnimStaticAssoc->SetNumBlendNodes(pOriginalAnimStaticAssoc->GetNumBlendNodes()); - pOutAnimStaticAssoc->SetFlags(pOriginalAnimStaticAssoc->GetFlags()); -} - void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr& pIFP) { m_mapOfIfpPointers[u32BlockNameHash] = pIFP; From ad4ac2d5a5f4b81abebe2e74078e6cfb851ffafa Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 18:05:13 +0200 Subject: [PATCH 15/27] Update CClientGame.cpp --- Client/mods/deathmatch/logic/CClientGame.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 010da777c88..917310ae1fb 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -3647,7 +3647,7 @@ CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler( return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID); } -CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, +bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID) { return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID); @@ -3910,12 +3910,12 @@ void CClientGame::IdleHandler(void) m_pRootEntity->CallEvent("onClientMinimize", Arguments, false); bool bMuteAll = g_pCore->GetCVars()->GetValue("mute_master_when_minimized"); - + // Apply mute on minimize options if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_radio_when_minimized")) -- g_pGame->GetAudio()->SetMusicMasterVolume(0); -- -- if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) + g_pGame->GetAudio()->SetMusicMasterVolume(0); + + if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_sfx_when_minimized")) g_pGame->GetAudio()->SetEffectsMasterVolume(0); if (bMuteAll || g_pCore->GetCVars()->GetValue("mute_mta_when_minimized")) @@ -3993,12 +3993,11 @@ bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterfac if (!isCustomAnimationToPlay) { auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface); - + // Play default internal animation pAnimationManager->UncompressAnimation(pAnimHierarchy.get()); pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface()); } - return isCustomAnimationToPlay; } From 56bf4663a981a5c0393bb47a4b9b5ec5341cc4c7 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 18:09:40 +0200 Subject: [PATCH 16/27] update cluaguidefs.cpp --- .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 7602 ++++++++--------- 1 file changed, 3755 insertions(+), 3847 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index 9445398f4cb..2280bed95f9 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -1,646 +1,644 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto - * LICENSE: See LICENSE in the top level directory - * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp - * PURPOSE: Lua definitions class - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#include "StdInc.h" - -void CLuaGUIDefs::LoadFunctions(void) -{ - CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); - CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); - CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); - CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); - - CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); - CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); - CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); - CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); - CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); - CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); - - CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); +/***************************************************************************** +* +* PROJECT: Multi Theft Auto +* LICENSE: See LICENSE in the top level directory +* FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp +* PURPOSE: Lua definitions class +* +* Multi Theft Auto is available from http://www.multitheftauto.com/ +* +*****************************************************************************/ + +#include "StdInc.h" + +void CLuaGUIDefs::LoadFunctions(void) +{ + CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); + CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); + CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); + CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); + + CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); + CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); + CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); + CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); + CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); + CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); + CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); - CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); - - CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); - CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); - CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); - CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); - CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); - CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); - CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); - CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); - CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); - CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); - CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); - CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); - CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); - CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); - CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); - CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); - - CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); - CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); - CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); - CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); - CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); - - CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); - CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); - CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); - CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); - CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); - CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); - CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); - CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); - CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); - CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); - CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); - CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); - CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); - CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); - CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); - CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); - CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); - CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); - CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); - CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); - CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); - CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); - - CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); - CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); - CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); - CLuaCFunctions::AddFunction("guiSetText", GUISetText); - CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); - CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); - CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); - CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); - - CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); - CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); - - CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); - - CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); - CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); - CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); - CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); - CLuaCFunctions::AddFunction("guiGetText", GUIGetText); - CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); - CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); - CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); - CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); - CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); - - CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); - - CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); - CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); - - CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); - - CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); - CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); - CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); - CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); - CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); - CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); - - CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); - CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); - CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); - CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); - CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); - CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); - - CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); - CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); - - CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); - CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); - - CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); - - CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); - CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); - CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); - CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); - CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); - CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); - CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); -} - -void CLuaGUIDefs::AddClass(lua_State* luaVM) -{ - AddGuiElementClass(luaVM); - AddGuiFontClass(luaVM); - AddGuiWindowClass(luaVM); - AddGuiButtonClass(luaVM); - AddGuiEditClass(luaVM); - AddGuiLabelClass(luaVM); - AddGuiMemoClass(luaVM); - AddGuiImageClass(luaVM); - AddGuiComboBoxClass(luaVM); - AddGuiCheckBoxClass(luaVM); - AddGuiRadioButtonClass(luaVM); - AddGuiScrollPaneClass(luaVM); - AddGuiScrollBarClass(luaVM); - AddGuiProgressBarClass(luaVM); - AddGuiGridlistClass(luaVM); - AddGuiTabPanelClass(luaVM); - AddGuiTabClass(luaVM); -} - -// TODO: vector class -void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "bringToFront", "guiBringToFront"); - lua_classfunction(luaVM, "moveToBack", "guiMoveToBack"); - - lua_classfunction(luaVM, "isChatBoxInputActive", "isChatBoxInputActive"); - lua_classfunction(luaVM, "isConsoleActive", "isConsoleActive"); - lua_classfunction(luaVM, "isDebugViewActive", "isDebugViewActive"); - lua_classfunction(luaVM, "setDebugViewActive", "setDebugViewActive"); - lua_classfunction(luaVM, "isMainMenuActive", "isMainMenuActive"); - lua_classfunction(luaVM, "isMTAWindowActive", "isMTAWindowActive"); - lua_classfunction(luaVM, "isTransferBoxActive", "isTransferBoxActive"); - lua_classfunction(luaVM, "isInputEnabled", "guiGetInputEnabled"); - lua_classfunction(luaVM, "getInputMode", "guiGetInputMode"); - lua_classfunction(luaVM, "getCursorType", "guiGetCursorType"); - - lua_classfunction(luaVM, "getScreenSize", "guiGetScreenSize"); - lua_classfunction(luaVM, "getProperties", "guiGetProperties"); - lua_classfunction(luaVM, "getAlpha", "guiGetAlpha"); - lua_classfunction(luaVM, "getFont", "guiGetFont"); - lua_classfunction(luaVM, "getEnabled", "guiGetEnabled"); - lua_classfunction(luaVM, "getVisible", "guiGetVisible"); - lua_classfunction(luaVM, "getText", "guiGetText"); - lua_classfunction(luaVM, "getPosition", "guiGetPosition"); - lua_classfunction(luaVM, "getSize", "guiGetSize"); - lua_classfunction(luaVM, "getProperty", "guiGetProperty"); - - lua_classfunction(luaVM, "setInputEnabled", "guiSetInputEnabled"); - lua_classfunction(luaVM, "setAlpha", "guiSetAlpha"); - lua_classfunction(luaVM, "setEnabled", "guiSetEnabled"); - lua_classfunction(luaVM, "setFont", "guiSetFont"); - lua_classfunction(luaVM, "setVisible", "guiSetVisible"); - lua_classfunction(luaVM, "setText", "guiSetText"); - lua_classfunction(luaVM, "setInputMode", "guiSetInputMode"); - lua_classfunction(luaVM, "setProperty", "guiSetProperty"); - lua_classfunction(luaVM, "setPosition", "guiSetPosition"); - lua_classfunction(luaVM, "setSize", "guiSetSize"); - - lua_classvariable(luaVM, "chatBoxInputActive", NULL, "isChatBoxInputActive"); - lua_classvariable(luaVM, "consoleActive", NULL, "isConsoleActive"); - lua_classvariable(luaVM, "debugViewActive", "setDebugViewActive", "isDebugViewActive"); - lua_classvariable(luaVM, "mainMenuActive", NULL, "isMainMenuActive"); - lua_classvariable(luaVM, "mtaWindowActive", NULL, "isMTAWindowActive"); - lua_classvariable(luaVM, "transferBoxActive", NULL, "isTransferBoxActive"); - lua_classvariable(luaVM, "inputEnabled", "guiSetInputEnabled", "guiGetInputEnabled"); - lua_classvariable(luaVM, "inputMode", "guiGetInputMode", "guiSetInputMode"); - lua_classvariable(luaVM, "cursorAlpha", "setCursorAlpha", "getCursorAlpha"); - lua_classvariable(luaVM, "cursorType", NULL, "guiGetCursorType"); - lua_classvariable(luaVM, "font", "guiSetFont", "guiGetFont"); - lua_classvariable(luaVM, "visible", "guiSetVisible", "guiGetVisible"); - lua_classvariable(luaVM, "properties", NULL, "guiGetProperties"); - lua_classvariable(luaVM, "alpha", "guiSetAlpha", "guiGetAlpha"); - lua_classvariable(luaVM, "enabled", "guiSetEnabled", "guiGetEnabled"); - lua_classvariable(luaVM, "text", "guiSetText", "guiGetText"); - lua_classvariable(luaVM, "size", "guiSetSize", "guiGetSize"); - lua_classvariable(luaVM, "position", "guiSetPosition", "guiGetPosition"); - lua_classvariable(luaVM, "screenSize", NULL, "guiGetScreenSize"); - // lua_classvariable ( luaVM, "property" "guiSetProperty", "guiGetProperty" ); todo: .property[name] = value - - lua_registerclass(luaVM, "GuiElement", "Element"); -} - -void CLuaGUIDefs::AddGuiWindowClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateWindow"); - lua_classfunction(luaVM, "setMovable", "guiWindowSetMovable"); - lua_classfunction(luaVM, "setSizable", "guiWindowSetSizable"); - - lua_classvariable(luaVM, "movable", "guiWindowSetMovable", NULL); - lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", NULL); - - lua_registerclass(luaVM, "GuiWindow", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiButtonClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateButton"); - - lua_registerclass(luaVM, "GuiButton", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateEdit"); - lua_classfunction(luaVM, "getCaretIndex", "guiEditGetCaretIndex"); - lua_classfunction(luaVM, "setCaretIndex", "guiEditSetCaretIndex"); - lua_classfunction(luaVM, "setReadOnly", "guiEditSetReadOnly"); - lua_classfunction(luaVM, "setMasked", "guiEditSetMasked"); - lua_classfunction(luaVM, "setMaxLength", "guiEditSetMaxLength"); - - lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); - lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", "guiEditIsReadOnly"); - lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); - lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); - - lua_registerclass(luaVM, "GuiEdit", "GuiElement"); -} - -// TODO: specials -void CLuaGUIDefs::AddGuiLabelClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateLabel"); - - lua_classfunction(luaVM, "getFontHeight", "guiLabelGetFontHeight"); - lua_classfunction(luaVM, "getTextExtent", "guiLabelGetTextExtent"); - lua_classfunction(luaVM, "getColor", "guiLabelGetColor"); - - lua_classfunction(luaVM, "setColor", "guiLabelSetColor"); - lua_classfunction(luaVM, "setHorizontalAlign", "guiLabelSetHorizontalAlign"); - lua_classfunction(luaVM, "setVerticalAlign", "guiLabelSetVerticalAlign"); - - lua_classvariable(luaVM, "horizontalAlign", "guiLabelSetHorizontalAlign", NULL); - lua_classvariable(luaVM, "verticalAlign", "guiLabelSetVerticalAlign", NULL); - lua_classvariable(luaVM, "fontHeight", NULL, "guiLabelGetFontHeight"); - lua_classvariable(luaVM, "textExtent", NULL, "guiLabelGetTextExtent"); - // lua_classvariable ( luaVM, "color", "guiLabelGetColor", "guiLabelSetColor" ); - - lua_registerclass(luaVM, "GuiLabel", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiMemoClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateMemo"); - - lua_classfunction(luaVM, "getCaretIndex", "guiMemoGetCaretIndex"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); - - lua_classfunction(luaVM, "setCaretIndex", "guiMemoSetCaretIndex"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiMemoSetVerticalScrollPosition"); - lua_classfunction(luaVM, "setReadOnly", "guiMemoSetReadOnly"); - - lua_classvariable(luaVM, "caretIndex", "guiMemoSetCaretIndex", "guiMemoGetCaretIndex"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiMemoSetVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); - lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", "guiMemoIsReadOnly"); - - lua_registerclass(luaVM, "GuiMemo", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiImageClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateStaticImage"); - lua_classfunction(luaVM, "loadImage", "guiStaticImageLoadImage"); - - lua_classvariable(luaVM, "image", "guiStaticImageLoadImage", NULL); - - lua_registerclass(luaVM, "GuiStaticImage", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiComboBoxClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateComboBox"); - lua_classfunction(luaVM, "addItem", "guiComboBoxAddItem"); - lua_classfunction(luaVM, "clear", "guiComboBoxClear"); - lua_classfunction(luaVM, "removeItem", "guiComboBoxRemoveItem"); - - lua_classfunction(luaVM, "getSelected", "guiComboBoxGetSelected"); - lua_classfunction(luaVM, "getItemText", "guiComboBoxGetItemText"); - - lua_classfunction(luaVM, "setItemText", "guiComboBoxSetItemText"); - lua_classfunction(luaVM, "setSelected", "guiComboBoxSetSelected"); - - lua_classvariable(luaVM, "selected", "guiComboBoxSetSelected", "guiComboBoxGetSelected"); - - lua_registerclass(luaVM, "GuiComboBox", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiCheckBoxClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateCheckBox"); - - lua_classfunction(luaVM, "getSelected", "guiCheckBoxGetSelected"); - - lua_classfunction(luaVM, "setSelected", "guiCheckBoxSetSelected"); - - lua_classvariable(luaVM, "selected", "guiCheckBoxSetSelected", "guiCheckBoxGetSelected"); - - lua_registerclass(luaVM, "GuiCheckBox", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiRadioButtonClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateRadioButton"); - - lua_classfunction(luaVM, "getSelected", "guiRadioButtonGetSelected"); - - lua_classfunction(luaVM, "setSelected", "guiRadioButtonSetSelected"); - - lua_classvariable(luaVM, "selected", "guiRadioButtonSetSelected", "guiRadioButtonGetSelected"); - - lua_registerclass(luaVM, "GuiRadioButton", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiScrollPaneClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateScrollPane"); - - lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); - - lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition"); - lua_classfunction(luaVM, "setScrollBars", "guiScrollPaneSetScrollBars"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition"); - - lua_classvariable(luaVM, "horizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); - - lua_registerclass(luaVM, "GuiScrollPane", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiScrollBarClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateScrollBar"); - - lua_classfunction(luaVM, "getScrollPosition", "guiScrollBarGetScrollPosition"); - - lua_classfunction(luaVM, "setScrollPosition", "guiScrollBarSetScrollPosition"); - - lua_classvariable(luaVM, "scrollPosition", "guiScrollBarSetScrollPosition", "guiScrollBarGetScrollPosition"); - - lua_registerclass(luaVM, "GuiScrollBar", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiProgressBarClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateProgressBar"); - - lua_classfunction(luaVM, "getProgress", "guiProgressBarGetProgress"); - - lua_classfunction(luaVM, "setProgress", "guiProgressBarSetProgress"); - - lua_classvariable(luaVM, "progress", "guiProgressBarSetProgress", "guiProgressBarGetProgress"); - - lua_registerclass(luaVM, "GuiProgressBar", "GuiElement"); -} - -// TODO: special tables -void CLuaGUIDefs::AddGuiGridlistClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateGridList"); - lua_classfunction(luaVM, "addColumn", "guiGridListAddColumn"); - lua_classfunction(luaVM, "addRow", "guiGridListAddRow"); - lua_classfunction(luaVM, "autoSizeColumn", "guiGridListAutoSizeColumn"); - lua_classfunction(luaVM, "clear", "guiGridListClear"); - lua_classfunction(luaVM, "insertRowAfter", "guiGridListInsertRowAfter"); - lua_classfunction(luaVM, "removeColumn", "guiGridListRemoveColumn"); - lua_classfunction(luaVM, "removeRow", "guiGridListRemoveRow"); - - lua_classfunction(luaVM, "getItemData", "guiGridListGetItemData"); - lua_classfunction(luaVM, "getItemText", "guiGridListGetItemText"); - lua_classfunction(luaVM, "getRowCount", "guiGridListGetRowCount"); - lua_classfunction(luaVM, "getSelectedItem", "guiGridListGetSelectedItem"); - lua_classfunction(luaVM, "getItemColor", "guiGridListGetItemColor"); - lua_classfunction(luaVM, "getColumnTitle", "guiGridListGetColumnTitle"); - lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); - lua_classfunction(luaVM, "getVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); - lua_classfunction(luaVM, "getSelectedCount", "guiGridListGetSelectedCount"); - lua_classfunction(luaVM, "getSelectedItems", "guiGridListGetSelectedItems"); - lua_classfunction(luaVM, "getColumnCount", "guiGridListGetColumnCount"); - - lua_classfunction(luaVM, "setItemData", "guiGridListSetItemData"); - lua_classfunction(luaVM, "setItemText", "guiGridListSetItemText"); - lua_classfunction(luaVM, "setScrollBars", "guiGridListSetScrollBars"); - lua_classfunction(luaVM, "setSelectedItem", "guiGridListSetSelectedItem"); - lua_classfunction(luaVM, "setSelectionMode", "guiGridListSetSelectionMode"); - lua_classfunction(luaVM, "setSortingEnabled", "guiGridListSetSortingEnabled"); - lua_classfunction(luaVM, "setColumnWidth", "guiGridListSetColumnWidth"); - lua_classfunction(luaVM, "setItemColor", "guiGridListSetItemColor"); - lua_classfunction(luaVM, "setColumnTitle", "guiGridListSetColumnTitle"); - lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiGridListSetHorizontalScrollPosition"); - lua_classfunction(luaVM, "setVerticalScrollPosition", "guiGridListSetVerticalScrollPosition"); - - lua_classvariable(luaVM, "rowCount", NULL, "guiGridListGetRowCount"); - lua_classvariable(luaVM, "selectedCount", NULL, "guiGridListGetSelectedCount"); - lua_classvariable(luaVM, "selectedItems", NULL, "guiGridListGetSelectedItems"); - lua_classvariable(luaVM, "columnCount", NULL, "guiGridListGetColumnCount"); - lua_classvariable(luaVM, "selectionMode", "guiGridListSetSelectionMode", NULL); - lua_classvariable(luaVM, "sortingEnabled", "guiGridListSetSortingEnabled", NULL); - lua_classvariable(luaVM, "horizontalScrollPosition", "guiGridListSetHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); - lua_classvariable(luaVM, "verticalScrollPosition", "guiGridListGetVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); - // lua_classvariable ( luaVM, "selectedItem", NULL, "guiGridListGetSelectedItem" ); table - // lua_classvariable ( luaVM, "selectedItem", "guiGridListSetSelectedItem", NULL ); .selectedItem[column] = row (row in column) table - // lua_classvariable ( luaVM, "itemColor", "setItemColor", "getItemColor" ); table - // lua_classvariable ( luaVM, "columnTitle", "setColumnTitle", "getColumnTitle" ); table - - lua_registerclass(luaVM, "GuiGridList", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiTabPanelClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateTabPanel"); - - lua_classfunction(luaVM, "getSelectedTab", "guiGetSelectedTab"); - - lua_classfunction(luaVM, "setSelectedTab", "guiSetSelectedTab"); - - lua_classvariable(luaVM, "selectedTab", "guiSetSelectedTab", "guiGetSelectedTab"); - - lua_registerclass(luaVM, "GuiTabPanel", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiTabClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateTab"); - lua_classfunction(luaVM, "delete", "guiDeleteTab"); - - lua_registerclass(luaVM, "GuiTab", "GuiElement"); -} - -void CLuaGUIDefs::AddGuiFontClass(lua_State* luaVM) -{ - lua_newclass(luaVM); - - lua_classfunction(luaVM, "create", "guiCreateFont"); - - lua_registerclass(luaVM, "GuiFont", "Element"); -} - -int CLuaGUIDefs::GUIGetInputEnabled(lua_State* luaVM) -{ - lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIGetInputEnabled()); - return 1; -} - -int CLuaGUIDefs::GUISetInputEnabled(lua_State* luaVM) -{ - // bool guiSetInputEnabled ( bool enabled ) - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetInputMode(enabled ? INPUTMODE_NO_BINDS : INPUTMODE_ALLOW_BINDS); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetInputMode(lua_State* luaVM) -{ - // bool guiSetInputMode ( string mode ) - eInputMode mode; - - CScriptArgReader argStream(luaVM); - argStream.ReadEnumString(mode); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetInputMode(mode); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetInputMode(lua_State* luaVM) -{ - eInputMode mode = CStaticFunctionDefinitions::GUIGetInputMode(); - lua_pushstring(luaVM, EnumToString(mode)); - return 1; -} - -int CLuaGUIDefs::GUIIsChatBoxInputActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsChatInputEnabled()); - return 1; -} - -int CLuaGUIDefs::GUIIsConsoleActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->GetConsole()->IsVisible()); - return 1; -} - -int CLuaGUIDefs::GUIIsDebugViewActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsDebugVisible()); - return 1; -} - -int CLuaGUIDefs::GUISetDebugViewActive(lua_State* luaVM) -{ - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - g_pCore->SetDebugVisible(enabled); - - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIIsMainMenuActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pCore->IsMenuVisible()); - return 1; -} - -int CLuaGUIDefs::GUIIsMTAWindowActive(lua_State* luaVM) -{ - bool bActive = - (g_pCore->IsChatInputEnabled() || g_pCore->IsMenuVisible() || g_pCore->GetConsole()->IsVisible() || g_pClientGame->GetTransferBox()->IsVisible()); - - lua_pushboolean(luaVM, bActive); - return 1; -} + CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); + + CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); + CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); + CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); + CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); + CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); + CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); + CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); + CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); + CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); + CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); + CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); + CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); + CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); + CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); + CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); + CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); + + CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); + CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); + CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); + CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); + CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); + + CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); + CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); + CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); + CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); + CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); + CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); + CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); + CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); + CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); + CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); + CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); + CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); + CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); + CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); + CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); + CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); + CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); + CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); + CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); + CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); + CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); + CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); + CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); + CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); + CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); + CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); + CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); + CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); + + CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); + CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); + + CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); + CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); + CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); + CLuaCFunctions::AddFunction("guiSetText", GUISetText); + CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); + CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); + CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); + CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); + + CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); + CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); + + CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); + CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); + + CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); + CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); + CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); + CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); + CLuaCFunctions::AddFunction("guiGetText", GUIGetText); + CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); + CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); + CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); + CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); + CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); + + CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); + CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); + + CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); + CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); + + CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); + + CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); + CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); + CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); + CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); + CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); + + CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); + CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); + CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); + + CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); + CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); + CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); + CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); + + CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); + CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); + + CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); + CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); + + CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); + + CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); + CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); + CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); + CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); + CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); + CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); + CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); +} + +void CLuaGUIDefs::AddClass(lua_State* luaVM) +{ + AddGuiElementClass(luaVM); + AddGuiFontClass(luaVM); + AddGuiWindowClass(luaVM); + AddGuiButtonClass(luaVM); + AddGuiEditClass(luaVM); + AddGuiLabelClass(luaVM); + AddGuiMemoClass(luaVM); + AddGuiImageClass(luaVM); + AddGuiComboBoxClass(luaVM); + AddGuiCheckBoxClass(luaVM); + AddGuiRadioButtonClass(luaVM); + AddGuiScrollPaneClass(luaVM); + AddGuiScrollBarClass(luaVM); + AddGuiProgressBarClass(luaVM); + AddGuiGridlistClass(luaVM); + AddGuiTabPanelClass(luaVM); + AddGuiTabClass(luaVM); +} + +// TODO: vector class +void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "bringToFront", "guiBringToFront"); + lua_classfunction(luaVM, "moveToBack", "guiMoveToBack"); + + lua_classfunction(luaVM, "isChatBoxInputActive", "isChatBoxInputActive"); + lua_classfunction(luaVM, "isConsoleActive", "isConsoleActive"); + lua_classfunction(luaVM, "isDebugViewActive", "isDebugViewActive"); + lua_classfunction(luaVM, "setDebugViewActive", "setDebugViewActive"); + lua_classfunction(luaVM, "isMainMenuActive", "isMainMenuActive"); + lua_classfunction(luaVM, "isMTAWindowActive", "isMTAWindowActive"); + lua_classfunction(luaVM, "isTransferBoxActive", "isTransferBoxActive"); + lua_classfunction(luaVM, "isInputEnabled", "guiGetInputEnabled"); + lua_classfunction(luaVM, "getInputMode", "guiGetInputMode"); + lua_classfunction(luaVM, "getCursorType", "guiGetCursorType"); + + lua_classfunction(luaVM, "getScreenSize", "guiGetScreenSize"); + lua_classfunction(luaVM, "getProperties", "guiGetProperties"); + lua_classfunction(luaVM, "getAlpha", "guiGetAlpha"); + lua_classfunction(luaVM, "getFont", "guiGetFont"); + lua_classfunction(luaVM, "getEnabled", "guiGetEnabled"); + lua_classfunction(luaVM, "getVisible", "guiGetVisible"); + lua_classfunction(luaVM, "getText", "guiGetText"); + lua_classfunction(luaVM, "getPosition", "guiGetPosition"); + lua_classfunction(luaVM, "getSize", "guiGetSize"); + lua_classfunction(luaVM, "getProperty", "guiGetProperty"); + + lua_classfunction(luaVM, "setInputEnabled", "guiSetInputEnabled"); + lua_classfunction(luaVM, "setAlpha", "guiSetAlpha"); + lua_classfunction(luaVM, "setEnabled", "guiSetEnabled"); + lua_classfunction(luaVM, "setFont", "guiSetFont"); + lua_classfunction(luaVM, "setVisible", "guiSetVisible"); + lua_classfunction(luaVM, "setText", "guiSetText"); + lua_classfunction(luaVM, "setInputMode", "guiSetInputMode"); + lua_classfunction(luaVM, "setProperty", "guiSetProperty"); + lua_classfunction(luaVM, "setPosition", "guiSetPosition"); + lua_classfunction(luaVM, "setSize", "guiSetSize"); + + lua_classvariable(luaVM, "chatBoxInputActive", NULL, "isChatBoxInputActive"); + lua_classvariable(luaVM, "consoleActive", NULL, "isConsoleActive"); + lua_classvariable(luaVM, "debugViewActive", "setDebugViewActive", "isDebugViewActive"); + lua_classvariable(luaVM, "mainMenuActive", NULL, "isMainMenuActive"); + lua_classvariable(luaVM, "mtaWindowActive", NULL, "isMTAWindowActive"); + lua_classvariable(luaVM, "transferBoxActive", NULL, "isTransferBoxActive"); + lua_classvariable(luaVM, "inputEnabled", "guiSetInputEnabled", "guiGetInputEnabled"); + lua_classvariable(luaVM, "inputMode", "guiGetInputMode", "guiSetInputMode"); + lua_classvariable(luaVM, "cursorAlpha", "setCursorAlpha", "getCursorAlpha"); + lua_classvariable(luaVM, "cursorType", NULL, "guiGetCursorType"); + lua_classvariable(luaVM, "font", "guiSetFont", "guiGetFont"); + lua_classvariable(luaVM, "visible", "guiSetVisible", "guiGetVisible"); + lua_classvariable(luaVM, "properties", NULL, "guiGetProperties"); + lua_classvariable(luaVM, "alpha", "guiSetAlpha", "guiGetAlpha"); + lua_classvariable(luaVM, "enabled", "guiSetEnabled", "guiGetEnabled"); + lua_classvariable(luaVM, "text", "guiSetText", "guiGetText"); + lua_classvariable(luaVM, "size", "guiSetSize", "guiGetSize"); + lua_classvariable(luaVM, "position", "guiSetPosition", "guiGetPosition"); + lua_classvariable(luaVM, "screenSize", NULL, "guiGetScreenSize"); + // lua_classvariable ( luaVM, "property" "guiSetProperty", "guiGetProperty" ); todo: .property[name] = value + + lua_registerclass(luaVM, "GuiElement", "Element"); +} + +void CLuaGUIDefs::AddGuiWindowClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateWindow"); + lua_classfunction(luaVM, "setMovable", "guiWindowSetMovable"); + lua_classfunction(luaVM, "setSizable", "guiWindowSetSizable"); + + lua_classvariable(luaVM, "movable", "guiWindowSetMovable", NULL); + lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", NULL); + + lua_registerclass(luaVM, "GuiWindow", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiButtonClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateButton"); + + lua_registerclass(luaVM, "GuiButton", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateEdit"); + lua_classfunction(luaVM, "getCaretIndex", "guiEditGetCaretIndex"); + lua_classfunction(luaVM, "setCaretIndex", "guiEditSetCaretIndex"); + lua_classfunction(luaVM, "setReadOnly", "guiEditSetReadOnly"); + lua_classfunction(luaVM, "setMasked", "guiEditSetMasked"); + lua_classfunction(luaVM, "setMaxLength", "guiEditSetMaxLength"); + + lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); + lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", NULL); + lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); + lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); + + lua_registerclass(luaVM, "GuiEdit", "GuiElement"); +} + +// TODO: specials +void CLuaGUIDefs::AddGuiLabelClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateLabel"); + + lua_classfunction(luaVM, "getFontHeight", "guiLabelGetFontHeight"); + lua_classfunction(luaVM, "getTextExtent", "guiLabelGetTextExtent"); + lua_classfunction(luaVM, "getColor", "guiLabelGetColor"); + + lua_classfunction(luaVM, "setColor", "guiLabelSetColor"); + lua_classfunction(luaVM, "setHorizontalAlign", "guiLabelSetHorizontalAlign"); + lua_classfunction(luaVM, "setVerticalAlign", "guiLabelSetVerticalAlign"); + + lua_classvariable(luaVM, "horizontalAlign", "guiLabelSetHorizontalAlign", NULL); + lua_classvariable(luaVM, "verticalAlign", "guiLabelSetVerticalAlign", NULL); + lua_classvariable(luaVM, "fontHeight", NULL, "guiLabelGetFontHeight"); + lua_classvariable(luaVM, "textExtent", NULL, "guiLabelGetTextExtent"); + // lua_classvariable ( luaVM, "color", "guiLabelGetColor", "guiLabelSetColor" ); + + lua_registerclass(luaVM, "GuiLabel", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiMemoClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateMemo"); + + lua_classfunction(luaVM, "getCaretIndex", "guiMemoGetCaretIndex"); + + lua_classfunction(luaVM, "setCaretIndex", "guiMemoSetCaretIndex"); + lua_classfunction(luaVM, "setReadOnly", "guiMemoSetReadOnly"); + + lua_classvariable(luaVM, "caretIndex", "guiMemoSetCaretIndex", "guiMemoGetCaretIndex"); + lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", NULL); + + lua_registerclass(luaVM, "GuiMemo", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiImageClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateStaticImage"); + lua_classfunction(luaVM, "loadImage", "guiStaticImageLoadImage"); + + lua_classvariable(luaVM, "image", "guiStaticImageLoadImage", NULL); + + lua_registerclass(luaVM, "GuiStaticImage", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiComboBoxClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateComboBox"); + lua_classfunction(luaVM, "addItem", "guiComboBoxAddItem"); + lua_classfunction(luaVM, "clear", "guiComboBoxClear"); + lua_classfunction(luaVM, "removeItem", "guiComboBoxRemoveItem"); + + lua_classfunction(luaVM, "getSelected", "guiComboBoxGetSelected"); + lua_classfunction(luaVM, "getItemText", "guiComboBoxGetItemText"); + + lua_classfunction(luaVM, "setItemText", "guiComboBoxSetItemText"); + lua_classfunction(luaVM, "setSelected", "guiComboBoxSetSelected"); + + lua_classvariable(luaVM, "selected", "guiComboBoxSetSelected", "guiComboBoxGetSelected"); + + lua_registerclass(luaVM, "GuiComboBox", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiCheckBoxClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateCheckBox"); + + lua_classfunction(luaVM, "getSelected", "guiCheckBoxGetSelected"); + + lua_classfunction(luaVM, "setSelected", "guiCheckBoxSetSelected"); + + lua_classvariable(luaVM, "selected", "guiCheckBoxSetSelected", "guiCheckBoxGetSelected"); + + lua_registerclass(luaVM, "GuiCheckBox", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiRadioButtonClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateRadioButton"); + + lua_classfunction(luaVM, "getSelected", "guiRadioButtonGetSelected"); + + lua_classfunction(luaVM, "setSelected", "guiRadioButtonSetSelected"); + + lua_classvariable(luaVM, "selected", "guiRadioButtonSetSelected", "guiRadioButtonGetSelected"); + + lua_registerclass(luaVM, "GuiRadioButton", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiScrollPaneClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateScrollPane"); + + lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); + + lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition"); + lua_classfunction(luaVM, "setScrollBars", "guiScrollPaneSetScrollBars"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition"); + + lua_classvariable(luaVM, "horizontalScrollPosition", "guiScrollPaneSetHorizontalScrollPosition", "guiScrollPaneGetHorizontalScrollPosition"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiScrollPaneSetVerticalScrollPosition", "guiScrollPaneGetVerticalScrollPosition"); + + lua_registerclass(luaVM, "GuiScrollPane", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiScrollBarClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateScrollBar"); + + lua_classfunction(luaVM, "getScrollPosition", "guiScrollBarGetScrollPosition"); + + lua_classfunction(luaVM, "setScrollPosition", "guiScrollBarSetScrollPosition"); + + lua_classvariable(luaVM, "scrollPosition", "guiScrollBarSetScrollPosition", "guiScrollBarGetScrollPosition"); + + lua_registerclass(luaVM, "GuiScrollBar", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiProgressBarClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateProgressBar"); + + lua_classfunction(luaVM, "getProgress", "guiProgressBarGetProgress"); + + lua_classfunction(luaVM, "setProgress", "guiProgressBarSetProgress"); + + lua_classvariable(luaVM, "progress", "guiProgressBarSetProgress", "guiProgressBarGetProgress"); + + lua_registerclass(luaVM, "GuiProgressBar", "GuiElement"); +} + +// TODO: special tables +void CLuaGUIDefs::AddGuiGridlistClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateGridList"); + lua_classfunction(luaVM, "addColumn", "guiGridListAddColumn"); + lua_classfunction(luaVM, "addRow", "guiGridListAddRow"); + lua_classfunction(luaVM, "autoSizeColumn", "guiGridListAutoSizeColumn"); + lua_classfunction(luaVM, "clear", "guiGridListClear"); + lua_classfunction(luaVM, "insertRowAfter", "guiGridListInsertRowAfter"); + lua_classfunction(luaVM, "removeColumn", "guiGridListRemoveColumn"); + lua_classfunction(luaVM, "removeRow", "guiGridListRemoveRow"); + + lua_classfunction(luaVM, "getItemData", "guiGridListGetItemData"); + lua_classfunction(luaVM, "getItemText", "guiGridListGetItemText"); + lua_classfunction(luaVM, "getRowCount", "guiGridListGetRowCount"); + lua_classfunction(luaVM, "getSelectedItem", "guiGridListGetSelectedItem"); + lua_classfunction(luaVM, "getItemColor", "guiGridListGetItemColor"); + lua_classfunction(luaVM, "getColumnTitle", "guiGridListGetColumnTitle"); + lua_classfunction(luaVM, "getHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); + lua_classfunction(luaVM, "getSelectedCount", "guiGridListGetSelectedCount"); + lua_classfunction(luaVM, "getSelectedItems", "guiGridListGetSelectedItems"); + lua_classfunction(luaVM, "getColumnCount", "guiGridListGetColumnCount"); + + lua_classfunction(luaVM, "setItemData", "guiGridListSetItemData"); + lua_classfunction(luaVM, "setItemText", "guiGridListSetItemText"); + lua_classfunction(luaVM, "setScrollBars", "guiGridListSetScrollBars"); + lua_classfunction(luaVM, "setSelectedItem", "guiGridListSetSelectedItem"); + lua_classfunction(luaVM, "setSelectionMode", "guiGridListSetSelectionMode"); + lua_classfunction(luaVM, "setSortingEnabled", "guiGridListSetSortingEnabled"); + lua_classfunction(luaVM, "setColumnWidth", "guiGridListSetColumnWidth"); + lua_classfunction(luaVM, "setItemColor", "guiGridListSetItemColor"); + lua_classfunction(luaVM, "setColumnTitle", "guiGridListSetColumnTitle"); + lua_classfunction(luaVM, "setHorizontalScrollPosition", "guiGridListSetHorizontalScrollPosition"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiGridListSetVerticalScrollPosition"); + + lua_classvariable(luaVM, "rowCount", NULL, "guiGridListGetRowCount"); + lua_classvariable(luaVM, "selectedCount", NULL, "guiGridListGetSelectedCount"); + lua_classvariable(luaVM, "selectedItems", NULL, "guiGridListGetSelectedItems"); + lua_classvariable(luaVM, "columnCount", NULL, "guiGridListGetColumnCount"); + lua_classvariable(luaVM, "selectionMode", "guiGridListSetSelectionMode", NULL); + lua_classvariable(luaVM, "sortingEnabled", "guiGridListSetSortingEnabled", NULL); + lua_classvariable(luaVM, "horizontalScrollPosition", "guiGridListSetHorizontalScrollPosition", "guiGridListGetHorizontalScrollPosition"); + lua_classvariable(luaVM, "verticalScrollPosition", "guiGridListGetVerticalScrollPosition", "guiGridListGetVerticalScrollPosition"); + // lua_classvariable ( luaVM, "selectedItem", NULL, "guiGridListGetSelectedItem" ); table + // lua_classvariable ( luaVM, "selectedItem", "guiGridListSetSelectedItem", NULL ); .selectedItem[column] = row (row in column) table + // lua_classvariable ( luaVM, "itemColor", "setItemColor", "getItemColor" ); table + // lua_classvariable ( luaVM, "columnTitle", "setColumnTitle", "getColumnTitle" ); table + + lua_registerclass(luaVM, "GuiGridList", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiTabPanelClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateTabPanel"); + + lua_classfunction(luaVM, "getSelectedTab", "guiGetSelectedTab"); + + lua_classfunction(luaVM, "setSelectedTab", "guiSetSelectedTab"); + + lua_classvariable(luaVM, "selectedTab", "guiSetSelectedTab", "guiGetSelectedTab"); + + lua_registerclass(luaVM, "GuiTabPanel", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiTabClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateTab"); + lua_classfunction(luaVM, "delete", "guiDeleteTab"); + + lua_registerclass(luaVM, "GuiTab", "GuiElement"); +} + +void CLuaGUIDefs::AddGuiFontClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "guiCreateFont"); + + lua_registerclass(luaVM, "GuiFont", "Element"); +} + +int CLuaGUIDefs::GUIGetInputEnabled(lua_State* luaVM) +{ + lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIGetInputEnabled()); + return 1; +} + +int CLuaGUIDefs::GUISetInputEnabled(lua_State* luaVM) +{ + // bool guiSetInputEnabled ( bool enabled ) + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetInputMode(enabled ? INPUTMODE_NO_BINDS : INPUTMODE_ALLOW_BINDS); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetInputMode(lua_State* luaVM) +{ + // bool guiSetInputMode ( string mode ) + eInputMode mode; + + CScriptArgReader argStream(luaVM); + argStream.ReadEnumString(mode); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetInputMode(mode); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetInputMode(lua_State* luaVM) +{ + eInputMode mode = CStaticFunctionDefinitions::GUIGetInputMode(); + lua_pushstring(luaVM, EnumToString(mode)); + return 1; +} + +int CLuaGUIDefs::GUIIsChatBoxInputActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsChatInputEnabled()); + return 1; +} + +int CLuaGUIDefs::GUIIsConsoleActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->GetConsole()->IsVisible()); + return 1; +} + +int CLuaGUIDefs::GUIIsDebugViewActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsDebugVisible()); + return 1; +} + +int CLuaGUIDefs::GUISetDebugViewActive(lua_State* luaVM) +{ + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + g_pCore->SetDebugVisible(enabled); + + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIIsMainMenuActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pCore->IsMenuVisible()); + return 1; +} + +int CLuaGUIDefs::GUIIsMTAWindowActive(lua_State* luaVM) +{ + bool bActive = + (g_pCore->IsChatInputEnabled() || g_pCore->IsMenuVisible() || g_pCore->GetConsole()->IsVisible() || g_pClientGame->GetTransferBox()->IsVisible()); + + lua_pushboolean(luaVM, bActive); + return 1; +} + +int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); + return 1; +} int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) { @@ -680,3208 +678,3118 @@ int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) { lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); return 1; -} - -int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) -{ - // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) - CVector2D position; - CVector2D size; - SString titleBarText; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(titleBarText); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateWindow(*pLuaMain, position, size, titleBarText, relative); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateLabel(lua_State* luaVM) -{ - // element guiCreateLabel ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateLabel(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateStaticImage(lua_State* luaVM) -{ - // element guiCreateStaticImage ( float x, float y, float width, float height, string path, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString path; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(path); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CResource* pResource = pLuaMain->GetResource(); - SString strPath; - if (CResourceManager::ParseResourcePathInput(path, pResource, &strPath)) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateStaticImage(*pLuaMain, position, size, strPath, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - else - argStream.SetCustomError(path, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateButton(lua_State* luaVM) -{ - // element guiCreateButton ( float x, float y, float width, float height, string text, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateButton(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateProgressBar(lua_State* luaVM) -{ - // element guiCreateProgressBar ( float x, float y, float width, float height, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateProgressBar(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateCheckBox(lua_State* luaVM) -{ - // element guiCreateCheckBox ( float x, float y, float width, float height, string text, bool selected, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool selected; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(selected); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateCheckBox(*pLuaMain, position, size, text, selected, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateRadioButton(lua_State* luaVM) -{ - // element guiCreateRadioButton ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateRadioButton(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateEdit(lua_State* luaVM) -{ - // gui-edit guiCreateEdit ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateEdit(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateMemo(lua_State* luaVM) -{ - // gui-memo guiCreateMemo ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) - CVector2D position; - CVector2D size; - SString text; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(text); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateMemo(*pLuaMain, position, size, text, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateGridList(lua_State* luaVM) -{ - // element guiCreateGridList ( float x, float y, float width, float height, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateGridList(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateScrollPane(lua_State* luaVM) -{ - // element guiCreateScrollPane( float x, float y, float width, float height, bool relative, [gui-element parent = nil]) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollPane(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateScrollBar(lua_State* luaVM) -{ - // gui-scrollbar guiCreateScrollBar ( float x, float y, float width, float height, bool horizontal, bool relative, [gui-element parent = nil]) - CVector2D position; - CVector2D size; - bool horizontal; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(horizontal); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollBar(*pLuaMain, position, size, horizontal, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateTabPanel(lua_State* luaVM) -{ - // element guiCreateTabPanel ( float x, float y, float width, float height, bool relative, [element parent = nil ] ) - CVector2D position; - CVector2D size; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTabPanel(*pLuaMain, position, size, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIStaticImageLoadImage(lua_State* luaVM) -{ - // bool guiStaticImageLoadImage ( element theElement, string filename ) - CClientGUIElement* theElement; - SString filename; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadString(filename); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - - if (pLuaMain) - { - CResource* pResource = pLuaMain->GetResource(); - SString strPath; - if (CResourceManager::ParseResourcePathInput(filename, pResource, &strPath)) - { - if (CStaticFunctionDefinitions::GUIStaticImageLoadImage(*theElement, strPath)) - { - lua_pushboolean(luaVM, true); - return 1; - } - else - argStream.SetCustomError(filename, "Error loading image"); - } - else - argStream.SetCustomError(filename, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIStaticImageGetNativeSize(lua_State* luaVM) -{ - // bool guiStaticImageGetNativeSize ( element theElement, string filename ) - CClientGUIElement* theElement; - CVector2D vecSize; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - if (CStaticFunctionDefinitions::GUIStaticImageGetNativeSize(*theElement, vecSize)) - { - lua_pushnumber(luaVM, vecSize.fX); - lua_pushnumber(luaVM, vecSize.fY); - return 2; - } - - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateTab(lua_State* luaVM) -{ - // element guiCreateTab ( string text, element parent ) - SString text; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadString(text); - argStream.ReadUserData(parent); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTab(*pLuaMain, text, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetSelectedTab(lua_State* luaVM) -{ - // element guiGetSelectedTab ( element tabPanel ) - CClientGUIElement* tabPanel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabPanel); - - if (!argStream.HasErrors()) - { - CClientGUIElement* pTab = CStaticFunctionDefinitions::GUIGetSelectedTab(*tabPanel); - lua_pushelement(luaVM, pTab); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetSelectedTab(lua_State* luaVM) -{ - // bool guiSetSelectedTab ( element tabPanel, element theTab ) - CClientGUIElement* tabPanel; - CClientGUIElement* theTab; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabPanel); - argStream.ReadUserData(theTab); - - if (!argStream.HasErrors()) - { - if (CStaticFunctionDefinitions::GUISetSelectedTab(*tabPanel, *theTab)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIDeleteTab(lua_State* luaVM) -{ - // bool guiDeleteTab ( element tabToDelete, element tabPanel ) - CClientGUIElement* tabToDelete; - CClientGUIElement* tabPanel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(tabToDelete); - argStream.ReadUserData(tabPanel); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - if (CStaticFunctionDefinitions::GUIDeleteTab(*pLuaMain, tabToDelete, tabPanel)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetText(lua_State* luaVM) -{ - // bool guiSetText ( element guiElement, string text ) - CClientGUIElement* guiElement; - SString text; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(text); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetText(*guiElement, text); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetFont(lua_State* luaVM) -{ - // bool guiSetFont ( element guiElement, mixed font ) - CClientGUIElement* guiElement; - SString strFontName; - CClientGuiFont* pGuiFontElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - MixedReadGuiFontString(argStream, strFontName, "default-normal", pGuiFontElement); - - if (!argStream.HasErrors()) - { - if (guiElement->SetFont(strFontName, pGuiFontElement)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIBringToFront(lua_State* luaVM) -{ - // bool guiBringToFront ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - if (CStaticFunctionDefinitions::GUIBringToFront(*guiElement)) - { - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMoveToBack(lua_State* luaVM) -{ - // bool guiMoveToBack( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMoveToBack(*guiElement); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIRadioButtonSetSelected(lua_State* luaVM) -{ - // bool guiRadioButtonSetSelected ( element guiRadioButton, bool state ) - CClientGUIElement* guiRadioButton; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiRadioButton); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIRadioButtonSetSelected(*guiRadioButton, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICheckBoxSetSelected(lua_State* luaVM) -{ - // bool guiCheckBoxSetSelected ( element theCheckbox, bool state ) - CClientGUIElement* theCheckbox; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theCheckbox); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUICheckBoxSetSelected(*theCheckbox, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIRadioButtonGetSelected(lua_State* luaVM) -{ - // bool guiRadioButtonGetSelected( element guiRadioButton ) - CClientGUIElement* guiRadioButton; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiRadioButton); - - if (!argStream.HasErrors()) - { - bool bResult = static_cast(guiRadioButton->GetCGUIElement())->GetSelected(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICheckBoxGetSelected(lua_State* luaVM) -{ - // bool guiCheckBoxGetSelected ( element theCheckbox ) - CClientGUIElement* theCheckbox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theCheckbox); - - if (!argStream.HasErrors()) - { - bool bResult = static_cast(theCheckbox->GetCGUIElement())->GetSelected(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIProgressBarSetProgress(lua_State* luaVM) -{ - // bool guiProgressBarSetProgress ( progressBar theProgressbar, float progress ) - CClientGUIElement* theProgressbar; - float progress; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theProgressbar); - argStream.ReadNumber(progress); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIProgressBarSetProgress(*theProgressbar, static_cast(progress)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollBarSetScrollPosition(lua_State* luaVM) -{ - // bool guiScrollBarSetScrollPosition ( gui-scrollBar theScrollBar, float amount ) - CClientGUIElement* theScrollBar; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollBar); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollBarSetScrollPosition(*theScrollBar, static_cast(amount)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetHorizontalScrollPosition(lua_State* luaVM) -{ - // bool guiScrollPaneSetHorizontalScrollPosition ( gui-scrollPane theScrollPane, float amount ) - CClientGUIElement* theScrollPane; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetHorizontalScrollPosition(*theScrollPane, amount); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiScrollPaneSetVerticalScrollPosition ( gui-scrollPane theScrollPane, float amount ) - CClientGUIElement* theScrollPane; - float amount; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - argStream.ReadNumber(amount); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetVerticalScrollPosition(*theScrollPane, amount); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIProgressBarGetProgress(lua_State* luaVM) -{ - // float guiProgressBarGetProgress ( progressBar theProgressbar ); - CClientGUIElement* theProgressbar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theProgressbar); - - if (!argStream.HasErrors()) - { - int iProgress = (int)(static_cast(theProgressbar->GetCGUIElement())->GetProgress() * 100.0f + 0.5f); - lua_pushnumber(luaVM, iProgress); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneGetHorizontalScrollPosition(lua_State* luaVM) -{ - // float guiScrollPaneGetHorizontalScrollPosition ( gui-scrollPane theScrollPane ) - CClientGUIElement* theScrollPane; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - - if (!argStream.HasErrors()) - { - float fPos = static_cast(theScrollPane->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiScrollPaneGetVerticalScrollPosition ( gui-scrollPane theScrollPane ) - CClientGUIElement* theScrollPane; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollPane); - - if (!argStream.HasErrors()) - { - float fPos = static_cast(theScrollPane->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollBarGetScrollPosition(lua_State* luaVM) -{ - // float guiScrollBarGetScrollPosition ( gui-scrollBar theScrollBar ) - CClientGUIElement* theScrollBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theScrollBar); - - if (!argStream.HasErrors()) - { - int iPos = (int)(static_cast(theScrollBar->GetCGUIElement())->GetScrollPosition() * 100.0f); - lua_pushnumber(luaVM, iPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetText(lua_State* luaVM) -{ - // string guiGetText ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - SString strText = guiElement->GetCGUIElement()->GetText(); - lua_pushstring(luaVM, strText); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetFont(lua_State* luaVM) -{ - // string,font guiGetFont ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - CClientGuiFont* pGuiFontElement; - SString strFontName = guiElement->GetFont(&pGuiFontElement); - - if (strFontName != "") - lua_pushstring(luaVM, strFontName); - else - lua_pushnil(luaVM); - lua_pushelement(luaVM, pGuiFontElement); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetSize(lua_State* luaVM) -{ - // float float guiGetSize ( element theElement, bool relative ) - CClientGUIElement* theElement; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CVector2D Size; - theElement->GetCGUIElement()->GetSize(Size, relative); - - lua_pushnumber(luaVM, Size.fX); - lua_pushnumber(luaVM, Size.fY); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetScreenSize(lua_State* luaVM) -{ - const CVector2D Size = CStaticFunctionDefinitions::GUIGetScreenSize(); - - lua_pushnumber(luaVM, Size.fX); - lua_pushnumber(luaVM, Size.fY); - return 2; -} - -int CLuaGUIDefs::GUIGetPosition(lua_State* luaVM) -{ - // float, float guiGetPosition ( element guiElement, bool relative ) - CClientGUIElement* guiElement; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CVector2D Pos; - guiElement->GetCGUIElement()->GetPosition(Pos, relative); - - lua_pushnumber(luaVM, Pos.fX); - lua_pushnumber(luaVM, Pos.fY); - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetAlpha(lua_State* luaVM) -{ - // bool guiSetAlpha ( element guielement, float alpha ) - CClientGUIElement* guiElement; - float alpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(alpha); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetAlpha(*guiElement, Clamp(0.0f, alpha, 1.0f)); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetAlpha(lua_State* luaVM) -{ - // int guiGetAlpha ( element guiElement [, bool effectiveAlpha = false] ) - CClientGUIElement* guiElement; - bool bEffectiveAlpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(bEffectiveAlpha, false); - - if (!argStream.HasErrors()) - { - float fAlpha = !bEffectiveAlpha ? guiElement->GetCGUIElement()->GetAlpha() : guiElement->GetCGUIElement()->GetEffectiveAlpha(); - lua_pushnumber(luaVM, fAlpha); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetVisible(lua_State* luaVM) -{ - // bool guiSetVisible ( element guiElement, bool state ) - CClientGUIElement* guiElement; - bool state; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(state); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetVisible(*guiElement, state); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetEnabled(lua_State* luaVM) -{ - // bool guiSetEnabled ( element guiElement, bool enabled ) - CClientGUIElement* guiElement; - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetEnabled(*guiElement, enabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetProperty(lua_State* luaVM) -{ - // bool guiSetProperty ( element guiElement, string property, string value ) - CClientGUIElement* guiElement; - SString property; - SString value; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(property); - argStream.ReadString(value); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetProperty(*guiElement, property, value); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetVisible(lua_State* luaVM) -{ - // bool guiGetVisible ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - bool bResult = guiElement->GetCGUIElement()->IsVisible(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetEnabled(lua_State* luaVM) -{ - // bool guiGetEnabled ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - bool bResult = guiElement->GetCGUIElement()->IsEnabled(); - lua_pushboolean(luaVM, bResult); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetProperty(lua_State* luaVM) -{ - // string guiGetProperty ( element guiElement, string property ) - CClientGUIElement* guiElement; - SString property; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadString(property); - - if (!argStream.HasErrors()) - { - SString strValue = guiElement->GetCGUIElement()->GetProperty(property); - lua_pushstring(luaVM, strValue); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetProperties(lua_State* luaVM) -{ - // table guiGetProperties ( element guiElement ) - CClientGUIElement* guiElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - - if (!argStream.HasErrors()) - { - // Create a new table - lua_newtable(luaVM); - - // Add all our properties to the table on top of the given lua main's stack - unsigned int uiIndex = 0; - CGUIPropertyIter iter = guiElement->GetCGUIElement()->GetPropertiesBegin(); - CGUIPropertyIter iterEnd = guiElement->GetCGUIElement()->GetPropertiesEnd(); - for (; iter != iterEnd; iter++) - { - const char* szKey = (*iter)->strKey; - const char* szValue = (*iter)->strValue; - - // Add it to the table - lua_pushstring(luaVM, szKey); - lua_pushstring(luaVM, szValue); - lua_settable(luaVM, -3); - } - - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetSize(lua_State* luaVM) -{ - // bool guiSetSize ( element guiElement, float width, float height, bool relative ) - CClientGUIElement* guiElement; - float width; - float height; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(width); - argStream.ReadNumber(height); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetSize(*guiElement, CVector2D(width, height), relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUISetPosition(lua_State* luaVM) -{ - // bool guiSetPosition ( element guiElement, float x, float y, bool relative ) - CClientGUIElement* guiElement; - float x; - float y; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiElement); - argStream.ReadNumber(x); - argStream.ReadNumber(y); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUISetPosition(*guiElement, CVector2D(x, y), relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSortingEnabled(lua_State* luaVM) -{ - // bool guiGridListSetSortingEnabled ( element guiGridlist, bool enabled ) - CClientGUIElement* guiGridlist; - bool enabled; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadBool(enabled); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSortingEnabled(*guiGridlist, enabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAddColumn(lua_State* luaVM) -{ - // int guiGridListAddColumn ( element gridList, string title, float width ) - CClientGUIElement* guiGridlist; - SString title; - float width; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadString(title); - argStream.ReadNumber(width); - - if (!argStream.HasErrors()) - { - uint id = CStaticFunctionDefinitions::GUIGridListAddColumn(*guiGridlist, title, width); - lua_pushnumber(luaVM, id); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListRemoveColumn(lua_State* luaVM) -{ - // bool guiGridListRemoveColumn ( element guiGridlist, int columnIndex ) - CClientGUIElement* guiGridlist; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListRemoveColumn(*guiGridlist, columnIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetColumnWidth(lua_State* luaVM) -{ - // bool guiGridListSetColumnWidth ( element gridList, int columnIndex, number width, bool relative ) - CClientGUIElement* guiGridlist; - int columnIndex; - float width; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - argStream.ReadNumber(width); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetColumnWidth(*guiGridlist, columnIndex, width, relative); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnWidth(lua_State* luaVM) -{ - // float guiGridListGetColumnWidth ( element gridList, int columnIndex, bool relative ) - CClientGUIElement* pGridList; - int columnIndex; - bool relative; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pGridList); - argStream.ReadNumber(columnIndex); - argStream.ReadBool(relative); - - if (!argStream.HasErrors()) - { - float width; - if (static_cast(pGridList->GetCGUIElement())->GetColumnWidth(columnIndex, width, relative)) - { - lua_pushnumber(luaVM, width); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetColumnTitle(lua_State* luaVM) -{ - // bool guiGridListSetColumnTitle ( element guiGridlist, int columnIndex, string title ) - CClientGUIElement* guiGridlist; - int iColumnIndex; - SString sTitle; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(iColumnIndex); - argStream.ReadString(sTitle); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) - { - CStaticFunctionDefinitions::GUIGridListSetColumnTitle(*guiGridlist, iColumnIndex, sTitle); - lua_pushboolean(luaVM, true); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnTitle(lua_State* luaVM) -{ - // string guiGridListGetColumnTitle ( element guiGridlist, int columnIndex ) - CClientGUIElement* guiGridlist; - int iColumnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(iColumnIndex); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) - { - const char* szTitle = static_cast(guiGridlist->GetCGUIElement())->GetColumnTitle(iColumnIndex); - lua_pushstring(luaVM, szTitle); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAddRow(lua_State* luaVM) -{ - // int guiGridListAddRow ( element gridList ) - // int guiGridListAddRow ( element gridList, int/string itemText1, int/string itemText2 ... ) - CClientGUIElement* guiGridlist; - CLuaArguments Arguments; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadLuaArguments(Arguments); - - if (!argStream.HasErrors()) - { - int iRet = 0; - if (Arguments.Count() == 0) - iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true); - else - { - // Vector containing our string arguments. We add a bool to store whether it was originally a number. - std::vector > m_items; - std::vector::const_iterator it = Arguments.IterBegin(); - for (it; it != Arguments.IterEnd(); it++) - { - CLuaArgument* pArgument = *it; - SString strItemText; - bool bNumber = false; - - // Check the type of the argument and convert it to a string we can process - uint type = pArgument->GetType(); - if (type == LUA_TNUMBER) - { - // Grab the lua string and its size - const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); - size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); - - // Set our string - strItemText.assign(szLuaString, sizeLuaString); - bNumber = true; - } - else if (type == LUA_TSTRING) - strItemText = pArgument->GetString(); - else - continue; - - m_items.push_back(std::make_pair(strItemText, bNumber)); - } - iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true, &m_items); - } - - if (iRet >= 0) - { - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushnumber(luaVM, iRet); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListInsertRowAfter(lua_State* luaVM) -{ - // int guiGridListInsertRowAfter ( element gridList, int rowIndex ) - // int guiGridListInsertRowAfter ( element gridList, int rowIndex, int/string itemText1, int/string itemText2 ... ) - CClientGUIElement* guiGridlist; - int rowIndex; - CLuaArguments Arguments; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadLuaArguments(Arguments); - - if (!argStream.HasErrors()) - { - int iRet = 0; - if (Arguments.Count() == 0) - iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex); - else - { - // Vector containing our string arguments. We add a bool to store whether it was originally a number. - std::vector > m_items; - std::vector::const_iterator it = Arguments.IterBegin(); - for (it; it != Arguments.IterEnd(); it++) - { - CLuaArgument* pArgument = *it; - SString strItemText; - bool bNumber = false; - - // Check the type of the argument and convert it to a string we can process - uint type = pArgument->GetType(); - if (type == LUA_TNUMBER) - { - // Grab the lua string and its size - const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); - size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); - - // Set our string - strItemText.assign(szLuaString, sizeLuaString); - bNumber = true; - } - else if (type == LUA_TSTRING) - strItemText = pArgument->GetString(); - else - continue; - - m_items.push_back(std::make_pair(strItemText, bNumber)); - } - iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex, &m_items); - } - - if (iRet >= 0) - { - lua_pushnumber(luaVM, iRet); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListAutoSizeColumn(lua_State* luaVM) -{ - // bool guiGridListAutoSizeColumn ( element gridList, int columnIndex ) - CClientGUIElement* guiGridlist; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListAutoSizeColumn(*guiGridlist, columnIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListClear(lua_State* luaVM) -{ - // bool guiGridListClear ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListClear(*guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSelectionMode(lua_State* luaVM) -{ - // bool guiGridListSetSelectionMode ( guiElement gridlist, int mode ) - CClientGUIElement* guiGridlist; - int mode; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(mode); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSelectionMode(*guiGridlist, mode); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedItem(lua_State* luaVM) -{ - // int, int guiGridListGetSelectedItem ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iRow = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemRow(); - int iColumn = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemColumn(); - lua_pushnumber(luaVM, iRow); - lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 - return 2; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedItems(lua_State* luaVM) -{ - // table guiGridListGetSelectedItems ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - CGUIGridList* pList = static_cast(guiGridlist->GetCGUIElement()); - CGUIListItem* pItem = NULL; - - lua_newtable(luaVM); - - for (int i = 1; i <= pList->GetSelectedCount(); i++) - { - pItem = pList->GetNextSelectedItem(pItem); - if (!pItem) - break; - - lua_pushnumber(luaVM, i); - lua_newtable(luaVM); - - // column - lua_pushstring(luaVM, "column"); - lua_pushnumber(luaVM, pList->GetItemColumnIndex(pItem)); - lua_settable(luaVM, -3); - - // row - lua_pushstring(luaVM, "row"); - lua_pushnumber(luaVM, pList->GetItemRowIndex(pItem)); - lua_settable(luaVM, -3); - - // push to main table - lua_settable(luaVM, -3); - } - - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetSelectedCount(lua_State* luaVM) -{ - // int guiGridListGetSelectedCount ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iCount = static_cast(guiGridlist->GetCGUIElement())->GetSelectedCount(); - lua_pushnumber(luaVM, iCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetSelectedItem(lua_State* luaVM) -{ - // bool guiGridListSetSelectedItem ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - bool bReset; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadBool(bReset, true); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetSelectedItem(*guiGridlist, rowIndex, columnIndex, bReset); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListRemoveRow(lua_State* luaVM) -{ - // bool guiGridListRemoveRow ( element gridList, int rowIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListRemoveRow(*guiGridlist, rowIndex); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemText(lua_State* luaVM) -{ - // string guiGridListGetItemText ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - const char* szText = static_cast(guiGridlist->GetCGUIElement())->GetItemText(rowIndex, columnIndex); - lua_pushstring(luaVM, szText); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemData(lua_State* luaVM) -{ - // string guiGridListGetItemData ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - void* pData = static_cast(guiGridlist->GetCGUIElement())->GetItemData(rowIndex, columnIndex); - CLuaArgument* pVariable = reinterpret_cast(pData); - if (pVariable) - pVariable->Push(luaVM); - else - lua_pushnil(luaVM); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetItemColor(lua_State* luaVM) -{ - // int int int int guiGridListGetItemColor ( element gridList, int rowIndex, int columnIndex ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - - if (!argStream.HasErrors()) - { - unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255, ucAlpha = 255; - if (static_cast(guiGridlist->GetCGUIElement())->GetItemColor(rowIndex, columnIndex, ucRed, ucGreen, ucBlue, ucAlpha)) - { - lua_pushnumber(luaVM, ucRed); - lua_pushnumber(luaVM, ucGreen); - lua_pushnumber(luaVM, ucBlue); - lua_pushnumber(luaVM, ucAlpha); - return 4; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetHorizontalScrollPosition(lua_State* luaVM) -{ - // float guiGridListGetHorizontalScrollPosition ( element guiGridlist ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPosition); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiGridListGetVerticalScrollPosition ( element guiGridlist ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPosition); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemText(lua_State* luaVM) -{ - // bool guiGridListSetItemText ( element gridList, int rowIndex, int columnIndex, string text, bool section, bool number ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - SString text; - bool section; - bool number; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadString(text); - argStream.ReadBool(section); - argStream.ReadBool(number); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetItemText(*guiGridlist, rowIndex, columnIndex, text, section, number, true); - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemData(lua_State* luaVM) -{ - // bool guiGridListSetItemData ( element gridList, int rowIndex, int columnIndex, string data ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - CLuaArgument data; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadLuaArgument(data); - - if (!argStream.HasErrors()) - { - CLuaArgument* pData = new CLuaArgument(data); - CStaticFunctionDefinitions::GUIGridListSetItemData(*guiGridlist, rowIndex, columnIndex, pData); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetItemColor(lua_State* luaVM) -{ - // bool guiGridListSetItemColor ( element gridList, int rowIndex, int columnIndex, int red, int green, int blue[, int alpha = 255 ] ) - CClientGUIElement* guiGridlist; - int rowIndex; - int columnIndex; - int red; - int green; - int blue; - int alpha; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(rowIndex); - argStream.ReadNumber(columnIndex); - argStream.ReadNumber(red); - argStream.ReadNumber(green); - argStream.ReadNumber(blue); - argStream.ReadNumber(alpha, 255); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetItemColor(*guiGridlist, rowIndex, columnIndex, red, green, blue, alpha); - m_pGUIManager->QueueGridListUpdate(guiGridlist); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetScrollBars(lua_State* luaVM) -{ - // bool guiGridListSetScrollBars ( element guiGridlist, bool horizontalBar, bool verticalBar ) - CClientGUIElement* guiGridlist; - bool horizontalBar; - bool verticalBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadBool(horizontalBar); - argStream.ReadBool(verticalBar); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetScrollBars(*guiGridlist, horizontalBar, verticalBar); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetHorizontalScrollPosition(lua_State* luaVM) -{ - // bool guiGridListSetHorizontalScrollPosition ( element guiGridlist, float fPosition ) - CClientGUIElement* guiGridlist; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetHorizontalScrollPosition(*guiGridlist, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiGridListSetVerticalScrollPosition ( element guiGridlist, float fPosition ) - CClientGUIElement* guiGridlist; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIGridListSetVerticalScrollPosition(*guiGridlist, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIScrollPaneSetScrollBars(lua_State* luaVM) -{ - // bool guiScrollPaneSetScrollBars ( element scrollPane, bool horizontal, bool vertical ) - CClientGUIElement* scrollPane; - bool horizontalBar; - bool verticalBar; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(scrollPane); - argStream.ReadBool(horizontalBar); - argStream.ReadBool(verticalBar); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIScrollPaneSetScrollBars(*scrollPane, horizontalBar, verticalBar); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetRowCount(lua_State* luaVM) -{ - // int guiGridListGetRowCount ( element theList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iRowCount = static_cast(guiGridlist->GetCGUIElement())->GetRowCount(); - lua_pushnumber(luaVM, iRowCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGridListGetColumnCount(lua_State* luaVM) -{ - // int guiGridListGetColumnCount ( element gridList ) - CClientGUIElement* guiGridlist; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(guiGridlist); - - if (!argStream.HasErrors()) - { - int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); - lua_pushnumber(luaVM, iColumnCount); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) -{ - // bool guiEditSetReadOnly ( element editField, bool status ) - CClientGUIElement* editField; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetReadOnly(*editField, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) -{ - // bool guiEditIsReadOnly( element editField ) - CClientGUIElement* editField; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) -{ - // bool guiMemoSetReadOnly ( gui-memo theMemo, bool status ) - CClientGUIElement* theMemo; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetReadOnly(*theMemo, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) -{ - // bool guiMemoIsReadOnly( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) -{ - // bool guiEditSetMasked ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) -{ - // bool guiEditSetMaxLength ( element theElement, int length ) - CClientGUIElement* theElement; - int length; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(length); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetMaxLength(*theElement, length); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) -{ - // bool guiEditSetCaretIndex ( element theElement, int index ) - CClientGUIElement* theElement; - int index; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(index); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIEditSetCaretIndex(*theElement, index); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) -{ - // int guiEditGetCaretIndex ( element theElement ) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - lua_pushnumber(luaVM, static_cast(theElement->GetCGUIElement())->GetCaretIndex()); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) -{ - // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) - CClientGUIElement* theMemo; - int index; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(index); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetCaretIndex(*theMemo, index); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiMemoSetVerticalScrollPosition ( gui-memo theMemo, float fPosition ) - CClientGUIElement* theMemo; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) -{ - // bool guiMemoGetCaretIndex ( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - lua_pushnumber(luaVM, static_cast(theMemo->GetCGUIElement())->GetCaretIndex()); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiMemoGetVerticalScrollPosition ( gui-memo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); - float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) -{ - // bool guiWindowSetMovable ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIWindowSetMovable(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) -{ - // bool guiWindowSetSizable ( element theElement, bool status ) - CClientGUIElement* theElement; - bool status; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadBool(status); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIWindowSetSizable(*theElement, status); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) -{ - // float guiLabelGetTextExtent ( element theLabel ) - CClientGUIElement* theLabel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - - if (!argStream.HasErrors()) - { - float fExtent = static_cast(theLabel->GetCGUIElement())->GetTextExtent(); - lua_pushnumber(luaVM, fExtent); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetFontHeight(lua_State* luaVM) -{ - // float guiLabelGetFontHeight ( element theLabel ) - CClientGUIElement* theLabel; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - - if (!argStream.HasErrors()) - { - float fHeight = static_cast(theLabel->GetCGUIElement())->GetFontHeight(); - lua_pushnumber(luaVM, fHeight); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetColor(lua_State* luaVM) -{ - // bool guiLabelSetColor ( element theElement, int red, int green, int blue ) - CClientGUIElement* theElement; - int red; - int green; - int blue; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - argStream.ReadNumber(red); - argStream.ReadNumber(green); - argStream.ReadNumber(blue); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUILabelSetColor(*theElement, red, green, blue); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelGetColor(lua_State* luaVM) -{ - // int r, int g, int b guiLabelGetColor ( element theElement ) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255; - static_cast(theElement->GetCGUIElement())->GetTextColor(ucRed, ucGreen, ucBlue); - lua_pushnumber(luaVM, ucRed); - lua_pushnumber(luaVM, ucGreen); - lua_pushnumber(luaVM, ucBlue); - return 3; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetVerticalAlign(lua_State* luaVM) -{ - // bool guiLabelSetVerticalAlign ( element theLabel, string align ) - CClientGUIElement* theLabel; - CGUIVerticalAlign align; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - argStream.ReadEnumString(align); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUILabelSetVerticalAlign(*theLabel, align); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUILabelSetHorizontalAlign(lua_State* luaVM) -{ - // bool guiLabelSetHorizontalAlign ( element theLabel, string align, [ bool wordwrap = false ] ) - CClientGUIElement* theLabel; - CGUIHorizontalAlign align; - bool wordwrap; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theLabel); - argStream.ReadEnumString(align); - argStream.ReadBool(wordwrap, false); - - if (!argStream.HasErrors()) - { - if (wordwrap) - align = (CGUIHorizontalAlign)(align + 4); - CStaticFunctionDefinitions::GUILabelSetHorizontalAlign(*theLabel, align); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) -{ - //* chat_font - Returns the chatbox font - //* chat_lines - Returns how many lines the chatbox has - //* chat_color - Returns the background color of the chatbox - //* chat_text_color - Returns the chatbox text color - //* chat_input_color - Returns the background color of the chatbox input - //* chat_input_prefix_color - Returns the color of the input prefix text - //* chat_input_text_color - Returns the color of the text in the chatbox input - //* chat_scale - Returns the scale of the text in the chatbox - //* chat_position_offset_x - Returns the position offset of the chatbox on the x axis - //* chat_position_offset_y - Returns the position offset of the chatbox on the y axis - //* chat_position_horizontal - Returns the horizontal position of the chatbox - //* chat_position_vertical - Returns the vertical position of the chatbox - //* chat_text_alignment - Returns the horizontal alignment of the chatbox text - //* chat_width - Returns the scale of the background width - //* chat_css_style_text - Returns whether text fades out over time - //* chat_css_style_background - Returns whether the background fades out over time - //* chat_line_life - Returns how long it takes for text to start fading out - //* chat_line_fade_out - Returns how long takes for text to fade out - //* chat_use_cegui - Returns whether CEGUI is used to render the chatbox - //* text_scale - Returns text scale - - CCVarsInterface* pCVars = g_pCore->GetCVars(); - int iNumber; - float fNumber; - pCVars->Get("chat_font", fNumber); - lua_newtable(luaVM); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_font"); - pCVars->Get("chat_lines", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_lines"); - pCVars->Get("chat_width", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_width"); - pCVars->Get("chat_position_offset_x", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_x"); - pCVars->Get("chat_position_offset_y", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_y"); - pCVars->Get("chat_position_horizontal", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_horizontal"); - pCVars->Get("chat_position_vertical", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_vertical"); - pCVars->Get("chat_text_alignment", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_text_alignment"); - pCVars->Get("chat_css_style_text", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_text"); - pCVars->Get("chat_css_style_background", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_background"); - pCVars->Get("chat_line_life", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_life"); - pCVars->Get("chat_line_fade_out", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_fade_out"); - pCVars->Get("text_scale", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "text_scale"); - pCVars->Get("chat_use_cegui", fNumber); - lua_pushboolean(luaVM, fNumber ? true : false); - lua_setfield(luaVM, -2, "chat_use_cegui"); - std::string strCVar; - std::stringstream ss; - int iR, iG, iB, iA; - pCVars->Get("chat_color", strCVar); - if (!strCVar.empty()) - { - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_color"); - } - pCVars->Get("chat_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_text_color"); - } - pCVars->Get("chat_input_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_color"); - } - pCVars->Get("chat_input_prefix_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_prefix_color"); - } - pCVars->Get("chat_input_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_text_color"); - } - pCVars->Get("chat_scale", strCVar); - if (!strCVar.empty()) - { - float fX, fY; - ss.clear(); - ss.str(strCVar); - ss >> fX >> fY; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, fX); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, fY); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_scale"); - } - - return 1; -} - -int CLuaGUIDefs::GUICreateComboBox(lua_State* luaVM) -{ - // element guiCreateComboBox ( float x, float y, float width, float height, string caption, bool relative, [ element parent = nil ] ) - CVector2D position; - CVector2D size; - SString caption; - bool relative; - CClientGUIElement* parent; - - CScriptArgReader argStream(luaVM); - argStream.ReadVector2D(position); - argStream.ReadVector2D(size); - argStream.ReadString(caption); - argStream.ReadBool(relative); - argStream.ReadUserData(parent, NULL); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateComboBox(*pLuaMain, position, size, caption, relative, parent); - lua_pushelement(luaVM, pGUIElement); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxAddItem(lua_State* luaVM) -{ - // int guiComboBoxAddItem( element comboBox, string value ) - CClientGUIElement* comboBox; - SString value; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadString(value); - - if (!argStream.HasErrors()) - { - int newId = CStaticFunctionDefinitions::GUIComboBoxAddItem(*comboBox, value); - lua_pushnumber(luaVM, newId); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxRemoveItem(lua_State* luaVM) -{ - // bool guiComboBoxRemoveItem( element comboBox, int itemId ) - CClientGUIElement* comboBox; - int itemId; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxRemoveItem(*comboBox, itemId); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxClear(lua_State* luaVM) -{ - // bool guiComboBoxClear ( element comboBox ) - CClientGUIElement* comboBox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxClear(*comboBox); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxGetSelected(lua_State* luaVM) -{ - // int guiComboBoxGetSelected ( element comboBox ) - CClientGUIElement* comboBox; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - - if (!argStream.HasErrors()) - { - int selected = CStaticFunctionDefinitions::GUIComboBoxGetSelected(*comboBox); - lua_pushnumber(luaVM, selected); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxSetSelected(lua_State* luaVM) -{ - // bool guiComboBoxSetSelected ( element comboBox, int itemIndex ) - CClientGUIElement* comboBox; - int itemIndex; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemIndex); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxSetSelected(*comboBox, itemIndex); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxGetItemText(lua_State* luaVM) -{ - // string guiComboBoxGetItemText ( element comboBox, int itemId ) - CClientGUIElement* comboBox; - int itemId; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - - if (!argStream.HasErrors()) - { - SString ret = CStaticFunctionDefinitions::GUIComboBoxGetItemText(*comboBox, itemId); - lua_pushstring(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIComboBoxSetItemText(lua_State* luaVM) -{ - // bool guiComboBoxSetItemText ( element comboBox, int itemId, string text ) - CClientGUIElement* comboBox; - int itemId; - SString text; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(comboBox); - argStream.ReadNumber(itemId); - argStream.ReadString(text); - - if (!argStream.HasErrors()) - { - bool ret = CStaticFunctionDefinitions::GUIComboBoxSetItemText(*comboBox, itemId, text); - lua_pushboolean(luaVM, ret); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUICreateFont(lua_State* luaVM) -{ - // element guiCreateFont( string filepath [, int size=9 ] ) - SString strFilePath; - int iSize; - - CScriptArgReader argStream(luaVM); - argStream.ReadString(strFilePath); - argStream.ReadNumber(iSize, 9); - - if (!argStream.HasErrors()) - { - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - CResource* pParentResource = pLuaMain->GetResource(); - CResource* pFileResource = pParentResource; - SString strPath, strMetaPath; - if (CResourceManager::ParseResourcePathInput(strFilePath, pFileResource, &strPath, &strMetaPath)) - { - if (FileExists(strPath)) - { - SString strUniqueName = SString("%s*%s*%s", pParentResource->GetName(), pFileResource->GetName(), strMetaPath.c_str()).Replace("\\", "/"); - CClientGuiFont* pGuiFont = g_pClientGame->GetManager()->GetRenderElementManager()->CreateGuiFont(strPath, strUniqueName, iSize); - if (pGuiFont) - { - // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's - // ElementGroup? ** - pGuiFont->SetParent(pParentResource->GetResourceDynamicEntity()); - lua_pushelement(luaVM, pGuiFont); - return 1; - } - argStream.SetCustomError(strFilePath, "Error creating font"); - } - else - argStream.SetCustomError(strFilePath, "File not found"); - } - else - argStream.SetCustomError(strFilePath, "Bad file path"); - } - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - -int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) -{ - // string guiGetCursorType ( ) - auto eType = CStaticFunctionDefinitions::GUIGetCursorType(); - lua_pushstring(luaVM, EnumToString(eType)); - return 1; -} +} + +int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) +{ + // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) + CVector2D position; + CVector2D size; + SString titleBarText; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(titleBarText); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateWindow(*pLuaMain, position, size, titleBarText, relative); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateLabel(lua_State* luaVM) +{ + // element guiCreateLabel ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateLabel(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateStaticImage(lua_State* luaVM) +{ + // element guiCreateStaticImage ( float x, float y, float width, float height, string path, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString path; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(path); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CResource* pResource = pLuaMain->GetResource(); + SString strPath; + if (CResourceManager::ParseResourcePathInput(path, pResource, &strPath)) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateStaticImage(*pLuaMain, position, size, strPath, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + else + argStream.SetCustomError(path, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateButton(lua_State* luaVM) +{ + // element guiCreateButton ( float x, float y, float width, float height, string text, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateButton(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateProgressBar(lua_State* luaVM) +{ + // element guiCreateProgressBar ( float x, float y, float width, float height, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateProgressBar(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateCheckBox(lua_State* luaVM) +{ + // element guiCreateCheckBox ( float x, float y, float width, float height, string text, bool selected, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool selected; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(selected); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateCheckBox(*pLuaMain, position, size, text, selected, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateRadioButton(lua_State* luaVM) +{ + // element guiCreateRadioButton ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateRadioButton(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateEdit(lua_State* luaVM) +{ + // gui-edit guiCreateEdit ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateEdit(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateMemo(lua_State* luaVM) +{ + // gui-memo guiCreateMemo ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] ) + CVector2D position; + CVector2D size; + SString text; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(text); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateMemo(*pLuaMain, position, size, text, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateGridList(lua_State* luaVM) +{ + // element guiCreateGridList ( float x, float y, float width, float height, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateGridList(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateScrollPane(lua_State* luaVM) +{ + // element guiCreateScrollPane( float x, float y, float width, float height, bool relative, [gui-element parent = nil]) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollPane(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateScrollBar(lua_State* luaVM) +{ + // gui-scrollbar guiCreateScrollBar ( float x, float y, float width, float height, bool horizontal, bool relative, [gui-element parent = nil]) + CVector2D position; + CVector2D size; + bool horizontal; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(horizontal); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateScrollBar(*pLuaMain, position, size, horizontal, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateTabPanel(lua_State* luaVM) +{ + // element guiCreateTabPanel ( float x, float y, float width, float height, bool relative, [element parent = nil ] ) + CVector2D position; + CVector2D size; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTabPanel(*pLuaMain, position, size, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIStaticImageLoadImage(lua_State* luaVM) +{ + // bool guiStaticImageLoadImage ( element theElement, string filename ) + CClientGUIElement* theElement; + SString filename; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadString(filename); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + if (pLuaMain) + { + CResource* pResource = pLuaMain->GetResource(); + SString strPath; + if (CResourceManager::ParseResourcePathInput(filename, pResource, &strPath)) + { + if (CStaticFunctionDefinitions::GUIStaticImageLoadImage(*theElement, strPath)) + { + lua_pushboolean(luaVM, true); + return 1; + } + else + argStream.SetCustomError(filename, "Error loading image"); + } + else + argStream.SetCustomError(filename, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIStaticImageGetNativeSize(lua_State* luaVM) +{ + // bool guiStaticImageGetNativeSize ( element theElement, string filename ) + CClientGUIElement* theElement; + CVector2D vecSize; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + if (CStaticFunctionDefinitions::GUIStaticImageGetNativeSize(*theElement, vecSize)) + { + lua_pushnumber(luaVM, vecSize.fX); + lua_pushnumber(luaVM, vecSize.fY); + return 2; + } + + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateTab(lua_State* luaVM) +{ + // element guiCreateTab ( string text, element parent ) + SString text; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadString(text); + argStream.ReadUserData(parent); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateTab(*pLuaMain, text, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetSelectedTab(lua_State* luaVM) +{ + // element guiGetSelectedTab ( element tabPanel ) + CClientGUIElement* tabPanel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabPanel); + + if (!argStream.HasErrors()) + { + CClientGUIElement* pTab = CStaticFunctionDefinitions::GUIGetSelectedTab(*tabPanel); + lua_pushelement(luaVM, pTab); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetSelectedTab(lua_State* luaVM) +{ + // bool guiSetSelectedTab ( element tabPanel, element theTab ) + CClientGUIElement* tabPanel; + CClientGUIElement* theTab; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabPanel); + argStream.ReadUserData(theTab); + + if (!argStream.HasErrors()) + { + if (CStaticFunctionDefinitions::GUISetSelectedTab(*tabPanel, *theTab)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIDeleteTab(lua_State* luaVM) +{ + // bool guiDeleteTab ( element tabToDelete, element tabPanel ) + CClientGUIElement* tabToDelete; + CClientGUIElement* tabPanel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(tabToDelete); + argStream.ReadUserData(tabPanel); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + if (CStaticFunctionDefinitions::GUIDeleteTab(*pLuaMain, tabToDelete, tabPanel)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetText(lua_State* luaVM) +{ + // bool guiSetText ( element guiElement, string text ) + CClientGUIElement* guiElement; + SString text; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(text); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetText(*guiElement, text); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetFont(lua_State* luaVM) +{ + // bool guiSetFont ( element guiElement, mixed font ) + CClientGUIElement* guiElement; + SString strFontName; + CClientGuiFont* pGuiFontElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + MixedReadGuiFontString(argStream, strFontName, "default-normal", pGuiFontElement); + + if (!argStream.HasErrors()) + { + if (guiElement->SetFont(strFontName, pGuiFontElement)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIBringToFront(lua_State* luaVM) +{ + // bool guiBringToFront ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + if (CStaticFunctionDefinitions::GUIBringToFront(*guiElement)) + { + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMoveToBack(lua_State* luaVM) +{ + // bool guiMoveToBack( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMoveToBack(*guiElement); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIRadioButtonSetSelected(lua_State* luaVM) +{ + // bool guiRadioButtonSetSelected ( element guiRadioButton, bool state ) + CClientGUIElement* guiRadioButton; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiRadioButton); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIRadioButtonSetSelected(*guiRadioButton, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICheckBoxSetSelected(lua_State* luaVM) +{ + // bool guiCheckBoxSetSelected ( element theCheckbox, bool state ) + CClientGUIElement* theCheckbox; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theCheckbox); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUICheckBoxSetSelected(*theCheckbox, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIRadioButtonGetSelected(lua_State* luaVM) +{ + // bool guiRadioButtonGetSelected( element guiRadioButton ) + CClientGUIElement* guiRadioButton; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiRadioButton); + + if (!argStream.HasErrors()) + { + bool bResult = static_cast(guiRadioButton->GetCGUIElement())->GetSelected(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICheckBoxGetSelected(lua_State* luaVM) +{ + // bool guiCheckBoxGetSelected ( element theCheckbox ) + CClientGUIElement* theCheckbox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theCheckbox); + + if (!argStream.HasErrors()) + { + bool bResult = static_cast(theCheckbox->GetCGUIElement())->GetSelected(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIProgressBarSetProgress(lua_State* luaVM) +{ + // bool guiProgressBarSetProgress ( progressBar theProgressbar, float progress ) + CClientGUIElement* theProgressbar; + float progress; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theProgressbar); + argStream.ReadNumber(progress); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIProgressBarSetProgress(*theProgressbar, static_cast(progress)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollBarSetScrollPosition(lua_State* luaVM) +{ + // bool guiScrollBarSetScrollPosition ( gui-scrollBar theScrollBar, float amount ) + CClientGUIElement* theScrollBar; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollBar); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollBarSetScrollPosition(*theScrollBar, static_cast(amount)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetHorizontalScrollPosition(lua_State* luaVM) +{ + // bool guiScrollPaneSetHorizontalScrollPosition ( gui-scrollPane theScrollPane, float amount ) + CClientGUIElement* theScrollPane; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetHorizontalScrollPosition(*theScrollPane, amount); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiScrollPaneSetVerticalScrollPosition ( gui-scrollPane theScrollPane, float amount ) + CClientGUIElement* theScrollPane; + float amount; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + argStream.ReadNumber(amount); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetVerticalScrollPosition(*theScrollPane, amount); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIProgressBarGetProgress(lua_State* luaVM) +{ + // float guiProgressBarGetProgress ( progressBar theProgressbar ); + CClientGUIElement* theProgressbar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theProgressbar); + + if (!argStream.HasErrors()) + { + int iProgress = (int)(static_cast(theProgressbar->GetCGUIElement())->GetProgress() * 100.0f + 0.5f); + lua_pushnumber(luaVM, iProgress); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneGetHorizontalScrollPosition(lua_State* luaVM) +{ + // float guiScrollPaneGetHorizontalScrollPosition ( gui-scrollPane theScrollPane ) + CClientGUIElement* theScrollPane; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + + if (!argStream.HasErrors()) + { + float fPos = static_cast(theScrollPane->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiScrollPaneGetVerticalScrollPosition ( gui-scrollPane theScrollPane ) + CClientGUIElement* theScrollPane; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollPane); + + if (!argStream.HasErrors()) + { + float fPos = static_cast(theScrollPane->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollBarGetScrollPosition(lua_State* luaVM) +{ + // float guiScrollBarGetScrollPosition ( gui-scrollBar theScrollBar ) + CClientGUIElement* theScrollBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theScrollBar); + + if (!argStream.HasErrors()) + { + int iPos = (int)(static_cast(theScrollBar->GetCGUIElement())->GetScrollPosition() * 100.0f); + lua_pushnumber(luaVM, iPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetText(lua_State* luaVM) +{ + // string guiGetText ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + SString strText = guiElement->GetCGUIElement()->GetText(); + lua_pushstring(luaVM, strText); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetFont(lua_State* luaVM) +{ + // string,font guiGetFont ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + CClientGuiFont* pGuiFontElement; + SString strFontName = guiElement->GetFont(&pGuiFontElement); + + if (strFontName != "") + lua_pushstring(luaVM, strFontName); + else + lua_pushnil(luaVM); + lua_pushelement(luaVM, pGuiFontElement); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetSize(lua_State* luaVM) +{ + // float float guiGetSize ( element theElement, bool relative ) + CClientGUIElement* theElement; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CVector2D Size; + theElement->GetCGUIElement()->GetSize(Size, relative); + + lua_pushnumber(luaVM, Size.fX); + lua_pushnumber(luaVM, Size.fY); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetScreenSize(lua_State* luaVM) +{ + const CVector2D Size = CStaticFunctionDefinitions::GUIGetScreenSize(); + + lua_pushnumber(luaVM, Size.fX); + lua_pushnumber(luaVM, Size.fY); + return 2; +} + +int CLuaGUIDefs::GUIGetPosition(lua_State* luaVM) +{ + // float, float guiGetPosition ( element guiElement, bool relative ) + CClientGUIElement* guiElement; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CVector2D Pos; + guiElement->GetCGUIElement()->GetPosition(Pos, relative); + + lua_pushnumber(luaVM, Pos.fX); + lua_pushnumber(luaVM, Pos.fY); + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetAlpha(lua_State* luaVM) +{ + // bool guiSetAlpha ( element guielement, float alpha ) + CClientGUIElement* guiElement; + float alpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(alpha); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetAlpha(*guiElement, Clamp(0.0f, alpha, 1.0f)); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetAlpha(lua_State* luaVM) +{ + // int guiGetAlpha ( element guiElement [, bool effectiveAlpha = false] ) + CClientGUIElement* guiElement; + bool bEffectiveAlpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(bEffectiveAlpha, false); + + if (!argStream.HasErrors()) + { + float fAlpha = !bEffectiveAlpha ? guiElement->GetCGUIElement()->GetAlpha() : guiElement->GetCGUIElement()->GetEffectiveAlpha(); + lua_pushnumber(luaVM, fAlpha); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetVisible(lua_State* luaVM) +{ + // bool guiSetVisible ( element guiElement, bool state ) + CClientGUIElement* guiElement; + bool state; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetVisible(*guiElement, state); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetEnabled(lua_State* luaVM) +{ + // bool guiSetEnabled ( element guiElement, bool enabled ) + CClientGUIElement* guiElement; + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetEnabled(*guiElement, enabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetProperty(lua_State* luaVM) +{ + // bool guiSetProperty ( element guiElement, string property, string value ) + CClientGUIElement* guiElement; + SString property; + SString value; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(property); + argStream.ReadString(value); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetProperty(*guiElement, property, value); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetVisible(lua_State* luaVM) +{ + // bool guiGetVisible ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + bool bResult = guiElement->GetCGUIElement()->IsVisible(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetEnabled(lua_State* luaVM) +{ + // bool guiGetEnabled ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + bool bResult = guiElement->GetCGUIElement()->IsEnabled(); + lua_pushboolean(luaVM, bResult); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetProperty(lua_State* luaVM) +{ + // string guiGetProperty ( element guiElement, string property ) + CClientGUIElement* guiElement; + SString property; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadString(property); + + if (!argStream.HasErrors()) + { + SString strValue = guiElement->GetCGUIElement()->GetProperty(property); + lua_pushstring(luaVM, strValue); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetProperties(lua_State* luaVM) +{ + // table guiGetProperties ( element guiElement ) + CClientGUIElement* guiElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + + if (!argStream.HasErrors()) + { + // Create a new table + lua_newtable(luaVM); + + // Add all our properties to the table on top of the given lua main's stack + unsigned int uiIndex = 0; + CGUIPropertyIter iter = guiElement->GetCGUIElement()->GetPropertiesBegin(); + CGUIPropertyIter iterEnd = guiElement->GetCGUIElement()->GetPropertiesEnd(); + for (; iter != iterEnd; iter++) + { + const char* szKey = (*iter)->strKey; + const char* szValue = (*iter)->strValue; + + // Add it to the table + lua_pushstring(luaVM, szKey); + lua_pushstring(luaVM, szValue); + lua_settable(luaVM, -3); + } + + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetSize(lua_State* luaVM) +{ + // bool guiSetSize ( element guiElement, float width, float height, bool relative ) + CClientGUIElement* guiElement; + float width; + float height; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(width); + argStream.ReadNumber(height); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetSize(*guiElement, CVector2D(width, height), relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUISetPosition(lua_State* luaVM) +{ + // bool guiSetPosition ( element guiElement, float x, float y, bool relative ) + CClientGUIElement* guiElement; + float x; + float y; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiElement); + argStream.ReadNumber(x); + argStream.ReadNumber(y); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUISetPosition(*guiElement, CVector2D(x, y), relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSortingEnabled(lua_State* luaVM) +{ + // bool guiGridListSetSortingEnabled ( element guiGridlist, bool enabled ) + CClientGUIElement* guiGridlist; + bool enabled; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadBool(enabled); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSortingEnabled(*guiGridlist, enabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAddColumn(lua_State* luaVM) +{ + // int guiGridListAddColumn ( element gridList, string title, float width ) + CClientGUIElement* guiGridlist; + SString title; + float width; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadString(title); + argStream.ReadNumber(width); + + if (!argStream.HasErrors()) + { + uint id = CStaticFunctionDefinitions::GUIGridListAddColumn(*guiGridlist, title, width); + lua_pushnumber(luaVM, id); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListRemoveColumn(lua_State* luaVM) +{ + // bool guiGridListRemoveColumn ( element guiGridlist, int columnIndex ) + CClientGUIElement* guiGridlist; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListRemoveColumn(*guiGridlist, columnIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetColumnWidth(lua_State* luaVM) +{ + // bool guiGridListSetColumnWidth ( element gridList, int columnIndex, number width, bool relative ) + CClientGUIElement* guiGridlist; + int columnIndex; + float width; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + argStream.ReadNumber(width); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetColumnWidth(*guiGridlist, columnIndex, width, relative); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnWidth(lua_State* luaVM) +{ + // float guiGridListGetColumnWidth ( element gridList, int columnIndex, bool relative ) + CClientGUIElement* pGridList; + int columnIndex; + bool relative; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pGridList); + argStream.ReadNumber(columnIndex); + argStream.ReadBool(relative); + + if (!argStream.HasErrors()) + { + float width; + if (static_cast(pGridList->GetCGUIElement())->GetColumnWidth(columnIndex, width, relative)) + { + lua_pushnumber(luaVM, width); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetColumnTitle(lua_State* luaVM) +{ + // bool guiGridListSetColumnTitle ( element guiGridlist, int columnIndex, string title ) + CClientGUIElement* guiGridlist; + int iColumnIndex; + SString sTitle; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(iColumnIndex); + argStream.ReadString(sTitle); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) + { + CStaticFunctionDefinitions::GUIGridListSetColumnTitle(*guiGridlist, iColumnIndex, sTitle); + lua_pushboolean(luaVM, true); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnTitle(lua_State* luaVM) +{ + // string guiGridListGetColumnTitle ( element guiGridlist, int columnIndex ) + CClientGUIElement* guiGridlist; + int iColumnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(iColumnIndex); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + if (iColumnIndex > 0 && iColumnCount >= iColumnIndex) + { + const char* szTitle = static_cast(guiGridlist->GetCGUIElement())->GetColumnTitle(iColumnIndex); + lua_pushstring(luaVM, szTitle); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAddRow(lua_State* luaVM) +{ + // int guiGridListAddRow ( element gridList ) + // int guiGridListAddRow ( element gridList, int/string itemText1, int/string itemText2 ... ) + CClientGUIElement* guiGridlist; + CLuaArguments Arguments; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadLuaArguments(Arguments); + + if (!argStream.HasErrors()) + { + int iRet = 0; + if (Arguments.Count() == 0) + iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true); + else + { + // Vector containing our string arguments. We add a bool to store whether it was originally a number. + std::vector > m_items; + std::vector::const_iterator it = Arguments.IterBegin(); + for (it; it != Arguments.IterEnd(); it++) + { + CLuaArgument* pArgument = *it; + SString strItemText; + bool bNumber = false; + + // Check the type of the argument and convert it to a string we can process + uint type = pArgument->GetType(); + if (type == LUA_TNUMBER) + { + // Grab the lua string and its size + const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); + size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); + + // Set our string + strItemText.assign(szLuaString, sizeLuaString); + bNumber = true; + } + else if (type == LUA_TSTRING) + strItemText = pArgument->GetString(); + else + continue; + + m_items.push_back(std::make_pair(strItemText, bNumber)); + } + iRet = CStaticFunctionDefinitions::GUIGridListAddRow(*guiGridlist, true, &m_items); + } + + if (iRet >= 0) + { + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushnumber(luaVM, iRet); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListInsertRowAfter(lua_State* luaVM) +{ + // int guiGridListInsertRowAfter ( element gridList, int rowIndex ) + // int guiGridListInsertRowAfter ( element gridList, int rowIndex, int/string itemText1, int/string itemText2 ... ) + CClientGUIElement* guiGridlist; + int rowIndex; + CLuaArguments Arguments; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadLuaArguments(Arguments); + + if (!argStream.HasErrors()) + { + int iRet = 0; + if (Arguments.Count() == 0) + iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex); + else + { + // Vector containing our string arguments. We add a bool to store whether it was originally a number. + std::vector > m_items; + std::vector::const_iterator it = Arguments.IterBegin(); + for (it; it != Arguments.IterEnd(); it++) + { + CLuaArgument* pArgument = *it; + SString strItemText; + bool bNumber = false; + + // Check the type of the argument and convert it to a string we can process + uint type = pArgument->GetType(); + if (type == LUA_TNUMBER) + { + // Grab the lua string and its size + const char* szLuaString = lua_tostring(luaVM, pArgument->GetIndex()); + size_t sizeLuaString = lua_strlen(luaVM, pArgument->GetIndex()); + + // Set our string + strItemText.assign(szLuaString, sizeLuaString); + bNumber = true; + } + else if (type == LUA_TSTRING) + strItemText = pArgument->GetString(); + else + continue; + + m_items.push_back(std::make_pair(strItemText, bNumber)); + } + iRet = CStaticFunctionDefinitions::GUIGridListInsertRowAfter(*guiGridlist, rowIndex, &m_items); + } + + if (iRet >= 0) + { + lua_pushnumber(luaVM, iRet); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListAutoSizeColumn(lua_State* luaVM) +{ + // bool guiGridListAutoSizeColumn ( element gridList, int columnIndex ) + CClientGUIElement* guiGridlist; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListAutoSizeColumn(*guiGridlist, columnIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListClear(lua_State* luaVM) +{ + // bool guiGridListClear ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListClear(*guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSelectionMode(lua_State* luaVM) +{ + // bool guiGridListSetSelectionMode ( guiElement gridlist, int mode ) + CClientGUIElement* guiGridlist; + int mode; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(mode); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSelectionMode(*guiGridlist, mode); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedItem(lua_State* luaVM) +{ + // int, int guiGridListGetSelectedItem ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iRow = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemRow(); + int iColumn = static_cast(guiGridlist->GetCGUIElement())->GetSelectedItemColumn(); + lua_pushnumber(luaVM, iRow); + lua_pushnumber(luaVM, iColumn + 1); // columns start at 1 + return 2; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedItems(lua_State* luaVM) +{ + // table guiGridListGetSelectedItems ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + CGUIGridList* pList = static_cast(guiGridlist->GetCGUIElement()); + CGUIListItem* pItem = NULL; + + lua_newtable(luaVM); + + for (int i = 1; i <= pList->GetSelectedCount(); i++) + { + pItem = pList->GetNextSelectedItem(pItem); + if (!pItem) + break; + + lua_pushnumber(luaVM, i); + lua_newtable(luaVM); + + // column + lua_pushstring(luaVM, "column"); + lua_pushnumber(luaVM, pList->GetItemColumnIndex(pItem)); + lua_settable(luaVM, -3); + + // row + lua_pushstring(luaVM, "row"); + lua_pushnumber(luaVM, pList->GetItemRowIndex(pItem)); + lua_settable(luaVM, -3); + + // push to main table + lua_settable(luaVM, -3); + } + + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetSelectedCount(lua_State* luaVM) +{ + // int guiGridListGetSelectedCount ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iCount = static_cast(guiGridlist->GetCGUIElement())->GetSelectedCount(); + lua_pushnumber(luaVM, iCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetSelectedItem(lua_State* luaVM) +{ + // bool guiGridListSetSelectedItem ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + bool bReset; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadBool(bReset, true); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetSelectedItem(*guiGridlist, rowIndex, columnIndex, bReset); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListRemoveRow(lua_State* luaVM) +{ + // bool guiGridListRemoveRow ( element gridList, int rowIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListRemoveRow(*guiGridlist, rowIndex); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemText(lua_State* luaVM) +{ + // string guiGridListGetItemText ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + const char* szText = static_cast(guiGridlist->GetCGUIElement())->GetItemText(rowIndex, columnIndex); + lua_pushstring(luaVM, szText); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemData(lua_State* luaVM) +{ + // string guiGridListGetItemData ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + void* pData = static_cast(guiGridlist->GetCGUIElement())->GetItemData(rowIndex, columnIndex); + CLuaArgument* pVariable = reinterpret_cast(pData); + if (pVariable) + pVariable->Push(luaVM); + else + lua_pushnil(luaVM); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetItemColor(lua_State* luaVM) +{ + // int int int int guiGridListGetItemColor ( element gridList, int rowIndex, int columnIndex ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + + if (!argStream.HasErrors()) + { + unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255, ucAlpha = 255; + if (static_cast(guiGridlist->GetCGUIElement())->GetItemColor(rowIndex, columnIndex, ucRed, ucGreen, ucBlue, ucAlpha)) + { + lua_pushnumber(luaVM, ucRed); + lua_pushnumber(luaVM, ucGreen); + lua_pushnumber(luaVM, ucBlue); + lua_pushnumber(luaVM, ucAlpha); + return 4; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetHorizontalScrollPosition(lua_State* luaVM) +{ + // float guiGridListGetHorizontalScrollPosition ( element guiGridlist ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetHorizontalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPosition); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiGridListGetVerticalScrollPosition ( element guiGridlist ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + float fPosition = static_cast(guiGridlist->GetCGUIElement())->GetVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPosition); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemText(lua_State* luaVM) +{ + // bool guiGridListSetItemText ( element gridList, int rowIndex, int columnIndex, string text, bool section, bool number ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + SString text; + bool section; + bool number; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadString(text); + argStream.ReadBool(section); + argStream.ReadBool(number); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetItemText(*guiGridlist, rowIndex, columnIndex, text, section, number, true); + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemData(lua_State* luaVM) +{ + // bool guiGridListSetItemData ( element gridList, int rowIndex, int columnIndex, string data ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + CLuaArgument data; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadLuaArgument(data); + + if (!argStream.HasErrors()) + { + CLuaArgument* pData = new CLuaArgument(data); + CStaticFunctionDefinitions::GUIGridListSetItemData(*guiGridlist, rowIndex, columnIndex, pData); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetItemColor(lua_State* luaVM) +{ + // bool guiGridListSetItemColor ( element gridList, int rowIndex, int columnIndex, int red, int green, int blue[, int alpha = 255 ] ) + CClientGUIElement* guiGridlist; + int rowIndex; + int columnIndex; + int red; + int green; + int blue; + int alpha; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(rowIndex); + argStream.ReadNumber(columnIndex); + argStream.ReadNumber(red); + argStream.ReadNumber(green); + argStream.ReadNumber(blue); + argStream.ReadNumber(alpha, 255); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetItemColor(*guiGridlist, rowIndex, columnIndex, red, green, blue, alpha); + m_pGUIManager->QueueGridListUpdate(guiGridlist); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetScrollBars(lua_State* luaVM) +{ + // bool guiGridListSetScrollBars ( element guiGridlist, bool horizontalBar, bool verticalBar ) + CClientGUIElement* guiGridlist; + bool horizontalBar; + bool verticalBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadBool(horizontalBar); + argStream.ReadBool(verticalBar); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetScrollBars(*guiGridlist, horizontalBar, verticalBar); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetHorizontalScrollPosition(lua_State* luaVM) +{ + // bool guiGridListSetHorizontalScrollPosition ( element guiGridlist, float fPosition ) + CClientGUIElement* guiGridlist; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetHorizontalScrollPosition(*guiGridlist, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiGridListSetVerticalScrollPosition ( element guiGridlist, float fPosition ) + CClientGUIElement* guiGridlist; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIGridListSetVerticalScrollPosition(*guiGridlist, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIScrollPaneSetScrollBars(lua_State* luaVM) +{ + // bool guiScrollPaneSetScrollBars ( element scrollPane, bool horizontal, bool vertical ) + CClientGUIElement* scrollPane; + bool horizontalBar; + bool verticalBar; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(scrollPane); + argStream.ReadBool(horizontalBar); + argStream.ReadBool(verticalBar); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIScrollPaneSetScrollBars(*scrollPane, horizontalBar, verticalBar); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetRowCount(lua_State* luaVM) +{ + // int guiGridListGetRowCount ( element theList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iRowCount = static_cast(guiGridlist->GetCGUIElement())->GetRowCount(); + lua_pushnumber(luaVM, iRowCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGridListGetColumnCount(lua_State* luaVM) +{ + // int guiGridListGetColumnCount ( element gridList ) + CClientGUIElement* guiGridlist; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(guiGridlist); + + if (!argStream.HasErrors()) + { + int iColumnCount = static_cast(guiGridlist->GetCGUIElement())->GetColumnCount(); + lua_pushnumber(luaVM, iColumnCount); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) +{ + // bool guiEditSetReadOnly ( element editField, bool status ) + CClientGUIElement* editField; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(editField); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetReadOnly(*editField, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) +{ + // bool guiMemoSetReadOnly ( gui-memo theMemo, bool status ) + CClientGUIElement* theMemo; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetReadOnly(*theMemo, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) +{ + // bool guiEditSetMasked ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) +{ + // bool guiEditSetMaxLength ( element theElement, int length ) + CClientGUIElement* theElement; + int length; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(length); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetMaxLength(*theElement, length); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) +{ + // bool guiEditSetCaretIndex ( element theElement, int index ) + CClientGUIElement* theElement; + int index; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(index); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIEditSetCaretIndex(*theElement, index); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) +{ + // int guiEditGetCaretIndex ( element theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, static_cast(theElement->GetCGUIElement())->GetCaretIndex()); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) +{ + // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) + CClientGUIElement* theMemo; + int index; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadNumber(index); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetCaretIndex(*theMemo, index); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) +{ + // bool guiMemoGetCaretIndex ( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, static_cast(theMemo->GetCGUIElement())->GetCaretIndex()); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) +{ + // bool guiWindowSetMovable ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIWindowSetMovable(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) +{ + // bool guiWindowSetSizable ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIWindowSetSizable(*theElement, status); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) +{ + // float guiLabelGetTextExtent ( element theLabel ) + CClientGUIElement* theLabel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + + if (!argStream.HasErrors()) + { + float fExtent = static_cast(theLabel->GetCGUIElement())->GetTextExtent(); + lua_pushnumber(luaVM, fExtent); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetFontHeight(lua_State* luaVM) +{ + // float guiLabelGetFontHeight ( element theLabel ) + CClientGUIElement* theLabel; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + + if (!argStream.HasErrors()) + { + float fHeight = static_cast(theLabel->GetCGUIElement())->GetFontHeight(); + lua_pushnumber(luaVM, fHeight); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetColor(lua_State* luaVM) +{ + // bool guiLabelSetColor ( element theElement, int red, int green, int blue ) + CClientGUIElement* theElement; + int red; + int green; + int blue; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + argStream.ReadNumber(red); + argStream.ReadNumber(green); + argStream.ReadNumber(blue); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUILabelSetColor(*theElement, red, green, blue); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelGetColor(lua_State* luaVM) +{ + // int r, int g, int b guiLabelGetColor ( element theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + unsigned char ucRed = 255, ucGreen = 255, ucBlue = 255; + static_cast(theElement->GetCGUIElement())->GetTextColor(ucRed, ucGreen, ucBlue); + lua_pushnumber(luaVM, ucRed); + lua_pushnumber(luaVM, ucGreen); + lua_pushnumber(luaVM, ucBlue); + return 3; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetVerticalAlign(lua_State* luaVM) +{ + // bool guiLabelSetVerticalAlign ( element theLabel, string align ) + CClientGUIElement* theLabel; + CGUIVerticalAlign align; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + argStream.ReadEnumString(align); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUILabelSetVerticalAlign(*theLabel, align); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUILabelSetHorizontalAlign(lua_State* luaVM) +{ + // bool guiLabelSetHorizontalAlign ( element theLabel, string align, [ bool wordwrap = false ] ) + CClientGUIElement* theLabel; + CGUIHorizontalAlign align; + bool wordwrap; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theLabel); + argStream.ReadEnumString(align); + argStream.ReadBool(wordwrap, false); + + if (!argStream.HasErrors()) + { + if (wordwrap) + align = (CGUIHorizontalAlign)(align + 4); + CStaticFunctionDefinitions::GUILabelSetHorizontalAlign(*theLabel, align); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) +{ + //* chat_font - Returns the chatbox font + //* chat_lines - Returns how many lines the chatbox has + //* chat_color - Returns the background color of the chatbox + //* chat_text_color - Returns the chatbox text color + //* chat_input_color - Returns the background color of the chatbox input + //* chat_input_prefix_color - Returns the color of the input prefix text + //* chat_input_text_color - Returns the color of the text in the chatbox input + //* chat_scale - Returns the scale of the text in the chatbox + //* chat_position_offset_x - Returns the position offset of the chatbox on the x axis + //* chat_position_offset_y - Returns the position offset of the chatbox on the y axis + //* chat_position_horizontal - Returns the horizontal position of the chatbox + //* chat_position_vertical - Returns the vertical position of the chatbox + //* chat_text_alignment - Returns the horizontal alignment of the chatbox text + //* chat_width - Returns the scale of the background width + //* chat_css_style_text - Returns whether text fades out over time + //* chat_css_style_background - Returns whether the background fades out over time + //* chat_line_life - Returns how long it takes for text to start fading out + //* chat_line_fade_out - Returns how long takes for text to fade out + //* chat_use_cegui - Returns whether CEGUI is used to render the chatbox + //* text_scale - Returns text scale + + CCVarsInterface* pCVars = g_pCore->GetCVars(); + int iNumber; + float fNumber; + pCVars->Get("chat_font", fNumber); + lua_newtable(luaVM); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_font"); + pCVars->Get("chat_lines", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_lines"); + pCVars->Get("chat_width", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_width"); + pCVars->Get("chat_position_offset_x", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_position_offset_x"); + pCVars->Get("chat_position_offset_y", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_position_offset_y"); + pCVars->Get("chat_position_horizontal", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_position_horizontal"); + pCVars->Get("chat_position_vertical", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_position_vertical"); + pCVars->Get("chat_text_alignment", iNumber); + lua_pushnumber(luaVM, iNumber); + lua_setfield(luaVM, -2, "chat_text_alignment"); + pCVars->Get("chat_css_style_text", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_css_style_text"); + pCVars->Get("chat_css_style_background", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_css_style_background"); + pCVars->Get("chat_line_life", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_line_life"); + pCVars->Get("chat_line_fade_out", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "chat_line_fade_out"); + pCVars->Get("text_scale", fNumber); + lua_pushnumber(luaVM, fNumber); + lua_setfield(luaVM, -2, "text_scale"); + pCVars->Get("chat_use_cegui", fNumber); + lua_pushboolean(luaVM, fNumber ? true : false); + lua_setfield(luaVM, -2, "chat_use_cegui"); + std::string strCVar; + std::stringstream ss; + int iR, iG, iB, iA; + pCVars->Get("chat_color", strCVar); + if (!strCVar.empty()) + { + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_color"); + } + pCVars->Get("chat_text_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_text_color"); + } + pCVars->Get("chat_input_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_color"); + } + pCVars->Get("chat_input_prefix_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_prefix_color"); + } + pCVars->Get("chat_input_text_color", strCVar); + if (!strCVar.empty()) + { + ss.clear(); + ss.str(strCVar); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_input_text_color"); + } + pCVars->Get("chat_scale", strCVar); + if (!strCVar.empty()) + { + float fX, fY; + ss.clear(); + ss.str(strCVar); + ss >> fX >> fY; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, fX); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, fY); + lua_settable(luaVM, -3); + lua_setfield(luaVM, -2, "chat_scale"); + } + + return 1; +} + +int CLuaGUIDefs::GUICreateComboBox(lua_State* luaVM) +{ + // element guiCreateComboBox ( float x, float y, float width, float height, string caption, bool relative, [ element parent = nil ] ) + CVector2D position; + CVector2D size; + SString caption; + bool relative; + CClientGUIElement* parent; + + CScriptArgReader argStream(luaVM); + argStream.ReadVector2D(position); + argStream.ReadVector2D(size); + argStream.ReadString(caption); + argStream.ReadBool(relative); + argStream.ReadUserData(parent, NULL); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CClientGUIElement* pGUIElement = CStaticFunctionDefinitions::GUICreateComboBox(*pLuaMain, position, size, caption, relative, parent); + lua_pushelement(luaVM, pGUIElement); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxAddItem(lua_State* luaVM) +{ + // int guiComboBoxAddItem( element comboBox, string value ) + CClientGUIElement* comboBox; + SString value; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadString(value); + + if (!argStream.HasErrors()) + { + int newId = CStaticFunctionDefinitions::GUIComboBoxAddItem(*comboBox, value); + lua_pushnumber(luaVM, newId); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxRemoveItem(lua_State* luaVM) +{ + // bool guiComboBoxRemoveItem( element comboBox, int itemId ) + CClientGUIElement* comboBox; + int itemId; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxRemoveItem(*comboBox, itemId); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxClear(lua_State* luaVM) +{ + // bool guiComboBoxClear ( element comboBox ) + CClientGUIElement* comboBox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxClear(*comboBox); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxGetSelected(lua_State* luaVM) +{ + // int guiComboBoxGetSelected ( element comboBox ) + CClientGUIElement* comboBox; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + int selected = CStaticFunctionDefinitions::GUIComboBoxGetSelected(*comboBox); + lua_pushnumber(luaVM, selected); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushnil(luaVM); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxSetSelected(lua_State* luaVM) +{ + // bool guiComboBoxSetSelected ( element comboBox, int itemIndex ) + CClientGUIElement* comboBox; + int itemIndex; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemIndex); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxSetSelected(*comboBox, itemIndex); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxGetItemText(lua_State* luaVM) +{ + // string guiComboBoxGetItemText ( element comboBox, int itemId ) + CClientGUIElement* comboBox; + int itemId; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + + if (!argStream.HasErrors()) + { + SString ret = CStaticFunctionDefinitions::GUIComboBoxGetItemText(*comboBox, itemId); + lua_pushstring(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxSetItemText(lua_State* luaVM) +{ + // bool guiComboBoxSetItemText ( element comboBox, int itemId, string text ) + CClientGUIElement* comboBox; + int itemId; + SString text; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadNumber(itemId); + argStream.ReadString(text); + + if (!argStream.HasErrors()) + { + bool ret = CStaticFunctionDefinitions::GUIComboBoxSetItemText(*comboBox, itemId, text); + lua_pushboolean(luaVM, ret); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUICreateFont(lua_State* luaVM) +{ + // element guiCreateFont( string filepath [, int size=9 ] ) + SString strFilePath; + int iSize; + + CScriptArgReader argStream(luaVM); + argStream.ReadString(strFilePath); + argStream.ReadNumber(iSize, 9); + + if (!argStream.HasErrors()) + { + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + CResource* pParentResource = pLuaMain->GetResource(); + CResource* pFileResource = pParentResource; + SString strPath, strMetaPath; + if (CResourceManager::ParseResourcePathInput(strFilePath, pFileResource, &strPath, &strMetaPath)) + { + if (FileExists(strPath)) + { + SString strUniqueName = SString("%s*%s*%s", pParentResource->GetName(), pFileResource->GetName(), strMetaPath.c_str()).Replace("\\", "/"); + CClientGuiFont* pGuiFont = g_pClientGame->GetManager()->GetRenderElementManager()->CreateGuiFont(strPath, strUniqueName, iSize); + if (pGuiFont) + { + // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's + // ElementGroup? ** + pGuiFont->SetParent(pParentResource->GetResourceDynamicEntity()); + lua_pushelement(luaVM, pGuiFont); + return 1; + } + argStream.SetCustomError(strFilePath, "Error creating font"); + } + else + argStream.SetCustomError(strFilePath, "File not found"); + } + else + argStream.SetCustomError(strFilePath, "Bad file path"); + } + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) +{ + // string guiGetCursorType ( ) + auto eType = CStaticFunctionDefinitions::GUIGetCursorType(); + lua_pushstring(luaVM, EnumToString(eType)); + return 1; +} From ac4f1515eae3eae7e77a11d1aafc98b74625765a Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 18:15:50 +0200 Subject: [PATCH 17/27] updated CLuaGUIDefs --- .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 117 ++++++++++++++++-- 1 file changed, 107 insertions(+), 10 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index 2280bed95f9..c6138b2e286 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -1,12 +1,12 @@ /***************************************************************************** -* -* PROJECT: Multi Theft Auto -* LICENSE: See LICENSE in the top level directory -* FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp -* PURPOSE: Lua definitions class -* -* Multi Theft Auto is available from http://www.multitheftauto.com/ -* + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp + * PURPOSE: Lua definitions class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * *****************************************************************************/ #include "StdInc.h" @@ -130,10 +130,14 @@ void CLuaGUIDefs::LoadFunctions(void) CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); + CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); + CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); + CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); + CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); @@ -278,7 +282,7 @@ void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) lua_classfunction(luaVM, "setMaxLength", "guiEditSetMaxLength"); lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); - lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", NULL); + lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", "guiEditIsReadOnly"); lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); @@ -316,12 +320,15 @@ void CLuaGUIDefs::AddGuiMemoClass(lua_State* luaVM) lua_classfunction(luaVM, "create", "guiCreateMemo"); lua_classfunction(luaVM, "getCaretIndex", "guiMemoGetCaretIndex"); + lua_classfunction(luaVM, "getVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); lua_classfunction(luaVM, "setCaretIndex", "guiMemoSetCaretIndex"); + lua_classfunction(luaVM, "setVerticalScrollPosition", "guiMemoSetVerticalScrollPosition"); lua_classfunction(luaVM, "setReadOnly", "guiMemoSetReadOnly"); lua_classvariable(luaVM, "caretIndex", "guiMemoSetCaretIndex", "guiMemoGetCaretIndex"); - lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", NULL); + lua_classvariable(luaVM, "verticalScrollPosition", "guiMemoSetVerticalScrollPosition", "guiMemoGetVerticalScrollPosition"); + lua_classvariable(luaVM, "readOnly", "guiMemoSetReadOnly", "guiMemoIsReadOnly"); lua_registerclass(luaVM, "GuiMemo", "GuiElement"); } @@ -2987,6 +2994,28 @@ int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) +{ + // bool guiEditIsReadOnly( element editField ) + CClientGUIElement* editField; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(editField); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(editField>GetCGUIElement())>IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) { // bool guiMemoSetReadOnly ( gui-memo theMemo, bool status ) @@ -3011,6 +3040,28 @@ int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) +{ + // bool guiMemoIsReadOnly( guimemo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(theMemo>GetCGUIElement())>IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) { // bool guiEditSetMasked ( element theElement, bool status ) @@ -3083,6 +3134,29 @@ int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiMemoSetVerticalScrollPosition ( guimemo theMemo, float fPosition ) + CClientGUIElement* theMemo; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) { // int guiEditGetCaretIndex ( element theElement ) @@ -3104,6 +3178,29 @@ int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiMemoGetVerticalScrollPosition ( guimemo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + CGUIMemo* guiMemo = static_cast(theMemo>GetCGUIElement()); + float fPos = guiMemo>GetVerticalScrollPosition() / guiMemo>GetMaxVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) { // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) From 252445055808cf6837f58545caa03c6a5ae706b5 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 18:22:03 +0200 Subject: [PATCH 18/27] renamed transfebox to transferbox --- Client/core/CClientVariables.cpp | 2 +- Client/core/CSettings.cpp | 4 ++-- Client/mods/deathmatch/logic/CTransferBox.cpp | 1 + Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Client/core/CClientVariables.cpp b/Client/core/CClientVariables.cpp index e8b9a2245ee..ac692fc0171 100644 --- a/Client/core/CClientVariables.cpp +++ b/Client/core/CClientVariables.cpp @@ -330,7 +330,7 @@ void CClientVariables::LoadDefaults(void) DEFAULT("high_detail_vehicles", 0); // Disable rendering high detail vehicles all the time DEFAULT("fast_clothes_loading", 1); // 0-off 1-auto 2-on DEFAULT("allow_screen_upload", 1); // 0-off 1-on - DEFAULT("allow_server_control_transfebox", 1); // 0-off 1-on + DEFAULT("allow_server_control_transferbox", 1); // 0-off 1-on DEFAULT("max_clientscript_log_kb", 5000); // Max size in KB (0-No limit) DEFAULT("display_fullscreen_style", 0); // 0-standard 1-borderless 2-borderless keep res 3-borderless stretch DEFAULT("display_windowed", 0); // 0-off 1-on diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 5dab8377fa5..00ee024baf0 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -1495,7 +1495,7 @@ void CSettings::UpdateVideoTab(void) // Allow screen upload bool bAllowServerTransferBoxControl; - CVARS_GET("allow_server_control_transfebox", bAllowServerTransferBoxControl); + CVARS_GET("allow_server_control_transferbox", bAllowServerTransferBoxControl); m_pCheckBoxAllowControlTransferBox->SetSelected(bAllowServerTransferBoxControl); // Customized sa files @@ -3309,7 +3309,7 @@ void CSettings::SaveData(void) // Allow screen upload bool m_pCheckBoxAllowScreenUpload = m_pCheckBoxAllowControlTransferBox->GetSelected(); - CVARS_SET("allow_server_control_transfebox", m_pCheckBoxAllowScreenUpload); + CVARS_SET("allow_server_control_transferbox", m_pCheckBoxAllowScreenUpload); // Grass bool bGrassEnabled = m_pCheckBoxGrass->GetSelected(); diff --git a/Client/mods/deathmatch/logic/CTransferBox.cpp b/Client/mods/deathmatch/logic/CTransferBox.cpp index 626e2507fc5..bf50f3f002f 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.cpp +++ b/Client/mods/deathmatch/logic/CTransferBox.cpp @@ -109,6 +109,7 @@ void CTransferBox::Hide(void) { m_pWindow->SetVisible(false); g_pCore->GetGUI()->SetTransferBoxVisible(false); + m_dTotalSize = 0; } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index c6138b2e286..b1d29b9c0a2 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -7,7 +7,7 @@ * * Multi Theft Auto is available from http://www.multitheftauto.com/ * -*****************************************************************************/ + *****************************************************************************/ #include "StdInc.h" @@ -662,7 +662,7 @@ int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) if (!argStream.HasErrors()) { bool bAllowed = false; - g_pCore->GetCVars()->Get("allow_server_control_transfebox", bAllowed); + g_pCore->GetCVars()->Get("allow_server_control_transferbox", bAllowed); if (bAllowed) { g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); From a8b80b2ed11b6403839b1828942e51eca6f00ca1 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Mon, 23 Jul 2018 18:29:38 +0200 Subject: [PATCH 19/27] update CLuaGUIDefs --- Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index b1d29b9c0a2..64b443cb6aa 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -3004,12 +3004,12 @@ int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) if (!argStream.HasErrors()) { - bool readOnly = static_cast(editField>GetCGUIElement())>IsReadOnly(); + bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); lua_pushboolean(luaVM, readOnly); return 1; } else - m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); // error: bad arguments lua_pushnil(luaVM); @@ -3050,12 +3050,12 @@ int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) if (!argStream.HasErrors()) { - bool readOnly = static_cast(theMemo>GetCGUIElement())>IsReadOnly(); + bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); lua_pushboolean(luaVM, readOnly); return 1; } else - m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); // error: bad arguments lua_pushnil(luaVM); From 18b1b58bfc65e363a41418231395d2bd6fee5be3 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Tue, 28 Aug 2018 15:51:44 +0200 Subject: [PATCH 20/27] fix --- .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index c6138b2e286..8ff286c5647 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -645,12 +645,6 @@ int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) { lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); return 1; -} - -int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); - return 1; } int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) @@ -3004,12 +2998,12 @@ int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) if (!argStream.HasErrors()) { - bool readOnly = static_cast(editField>GetCGUIElement())>IsReadOnly(); + bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); lua_pushboolean(luaVM, readOnly); return 1; } else - m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); // error: bad arguments lua_pushnil(luaVM); @@ -3050,12 +3044,12 @@ int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) if (!argStream.HasErrors()) { - bool readOnly = static_cast(theMemo>GetCGUIElement())>IsReadOnly(); + bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); lua_pushboolean(luaVM, readOnly); return 1; } else - m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); // error: bad arguments lua_pushnil(luaVM); @@ -3151,7 +3145,7 @@ int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) return 1; } else - m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); lua_pushboolean(luaVM, false); return 1; @@ -3188,13 +3182,13 @@ int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) if (!argStream.HasErrors()) { - CGUIMemo* guiMemo = static_cast(theMemo>GetCGUIElement()); - float fPos = guiMemo>GetVerticalScrollPosition() / guiMemo>GetMaxVerticalScrollPosition() * 100.0f; + CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); + float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; lua_pushnumber(luaVM, fPos); return 1; } else - m_pScriptDebugging>LogCustom(luaVM, argStream.GetFullErrorMessage()); + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); // error: bad arguments lua_pushboolean(luaVM, false); From a8a7326da72d44d8501e19b4a4c94028698bf20e Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Tue, 28 Aug 2018 15:58:09 +0200 Subject: [PATCH 21/27] fix --- Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index 901f81b3691..ff4795ed4f1 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -2990,7 +2990,7 @@ int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) { - // bool guiEditIsReadOnly( element editField ) + // bool guiMemoIsReadOnly( gui-memo theMemo ) CClientGUIElement* editField; CScriptArgReader argStream(luaVM); From f7b26b0de7e313cf07ddc8366826fec0485a8392 Mon Sep 17 00:00:00 2001 From: Qais Patankar Date: Tue, 1 Jan 2019 07:52:14 +0100 Subject: [PATCH 22/27] Fix merge --- .../logic/CResourceFileDownloadManager.cpp | 706 +++++++++--------- 1 file changed, 353 insertions(+), 353 deletions(-) diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp index 9d8f06f83d0..ed64b8d06cd 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp @@ -1,353 +1,353 @@ -/***************************************************************************** - * - * PROJECT: Multi Theft Auto v1.0 - * LICENSE: See LICENSE in the top level directory - * FILE: mods/deathmatch/logic/CResourceFileDownloadManager.cpp - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ - -#include "StdInc.h" - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::AddServer -// -// Add http server to use. -// Assumes last one added is the internal server -// -/////////////////////////////////////////////////////////////// -void CResourceFileDownloadManager::AddServer(const SString& strUrl, int iMaxConnectionsPerClient, EDownloadModeType downloadChannel, uint uiConnectionAttempts, - uint uiConnectTimeoutMs) -{ - SHttpServerInfo serverInfo; - serverInfo.bEnabled = true; - serverInfo.downloadChannel = downloadChannel; - serverInfo.strUrl = strUrl; - serverInfo.uiConnectionAttempts = uiConnectionAttempts; - serverInfo.uiConnectTimeoutMs = uiConnectTimeoutMs; - m_HttpServerList.push_back(serverInfo); - g_pCore->GetNetwork()->GetHTTPDownloadManager(downloadChannel)->SetMaxConnections(iMaxConnectionsPerClient); -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::AddPendingFileDownload -// -// Add resource file to the list of files to be downloaded -// -/////////////////////////////////////////////////////////////// -void CResourceFileDownloadManager::AddPendingFileDownload(CDownloadableResource* pResourceFile) -{ - assert(!ListContains(m_PendingFileDownloadList, pResourceFile)); - assert(!ListContains(m_ActiveFileDownloadList, pResourceFile)); - m_PendingFileDownloadList.push_back(pResourceFile); - pResourceFile->SetIsWaitingForDownload(true); - AddDownloadSize(pResourceFile->GetDownloadSize()); -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::UpdatePendingDownloads -// -// Figure which download group should be running -// -/////////////////////////////////////////////////////////////// -void CResourceFileDownloadManager::UpdatePendingDownloads(void) -{ - // Get download group to use - int iGroup = INVALID_DOWNLOAD_PRIORITY_GROUP; - if (!m_ActiveFileDownloadList.empty()) - { - // Use active download group - iGroup = std::max(iGroup, m_ActiveFileDownloadList[0]->GetDownloadPriorityGroup()); - } - else - { - // If no resource files being downloaded, find highest pending download group - for (auto pResourceFile : m_PendingFileDownloadList) - { - iGroup = std::max(iGroup, pResourceFile->GetDownloadPriorityGroup()); - } - } - - // Start (or add to) matching group - std::vector pendingListCopy = m_PendingFileDownloadList; - for (auto pResourceFile : pendingListCopy) - { - if (pResourceFile->GetDownloadPriorityGroup() == iGroup) - { - // Move to active list and begin download - ListRemove(m_PendingFileDownloadList, pResourceFile); - m_ActiveFileDownloadList.push_back(pResourceFile); - BeginResourceFileDownload(pResourceFile, 0); - } - } -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::OnRemoveResourceFile -// -// Tidy up lists when a resource file is delected -// -/////////////////////////////////////////////////////////////// -void CResourceFileDownloadManager::OnRemoveResourceFile(CDownloadableResource* pResourceFile) -{ - ListRemove(m_PendingFileDownloadList, pResourceFile); - ListRemove(m_ActiveFileDownloadList, pResourceFile); -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::DoPulse -// -// Downloading initial resource files -// -/////////////////////////////////////////////////////////////// -void CResourceFileDownloadManager::DoPulse(void) -{ - if (!g_pNet->IsConnected()) - return; - - if (!IsTransferringInitialFiles()) - return; - - // Pulse the http downloads - uint uiDownloadSizeTotal = 0; - for (auto serverInfo : m_HttpServerList) - { - CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(serverInfo.downloadChannel); - pHTTP->ProcessQueuedFiles(); - uiDownloadSizeTotal += pHTTP->GetDownloadSizeNow(); - } - - // Handle fatal error - if (!m_strLastHTTPError.empty()) - { - // Throw the error and disconnect - g_pCore->GetConsole()->Printf(_("Download error: %s"), *m_strLastHTTPError); - AddReportLog(7106, SString("Game - HTTPError (%s)", *m_strLastHTTPError)); - - g_pCore->GetModManager()->RequestUnload(); - g_pCore->ShowMessageBox(_("Error") + _E("CD20"), *m_strLastHTTPError, MB_BUTTON_OK | MB_ICON_ERROR); // HTTP Error - m_bIsTransferingFiles = false; - return; - } - - // Update progress box - GetTransferBox()->SetInfo(uiDownloadSizeTotal); - GetTransferBox()->DoPulse(); - - CLuaArguments Arguments; - Arguments.PushNumber( uiDownloadSizeTotal ); - Arguments.PushNumber( GetTransferBox()->GetTotalSize() ); - g_pClientGame->GetLocalPlayer()->CallEvent( "onTransferBoxProgressChange", Arguments, false ); - - // Check if completed downloading current group - if (m_ActiveFileDownloadList.empty()) - { - // Hide progress box if all groups done - if (m_PendingFileDownloadList.empty()) - { - m_bIsTransferingFiles = false; - GetTransferBox()->Hide(); - } - - // Load our newly ready resources - g_pClientGame->GetResourceManager()->OnDownloadGroupFinished(); - UpdatePendingDownloads(); - } -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::AddDownloadSize -// -// Add byte count to transfer box -// -/////////////////////////////////////////////////////////////// -void CResourceFileDownloadManager::AddDownloadSize(int iSize) -{ - if (!m_bIsTransferingFiles) - { - GetTransferBox()->Show(); - m_bIsTransferingFiles = true; - for (auto serverInfo : m_HttpServerList) - { - CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(serverInfo.downloadChannel); - pHTTP->ResetDownloadSize(); - } - } - GetTransferBox()->AddToTotalSize(iSize); -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::DisableHttpServer -// -// Mark http server as unusable. -// Returns false if server cannot be disabled. -// -/////////////////////////////////////////////////////////////// -bool CResourceFileDownloadManager::DisableHttpServer(uint uiHttpServerIndex) -{ - // Can only disable if not the last one - if (uiHttpServerIndex + 1 >= m_HttpServerList.size()) - return false; - m_HttpServerList[uiHttpServerIndex].bEnabled = false; - return true; -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::BeginResourceFileDownload -// -// Return false if file could not be queued -// -/////////////////////////////////////////////////////////////// -bool CResourceFileDownloadManager::BeginResourceFileDownload(CDownloadableResource* pResourceFile, uint uiHttpServerIndex) -{ - if (uiHttpServerIndex >= m_HttpServerList.size()) - return false; - - // Find enabled server - while (m_HttpServerList[uiHttpServerIndex].bEnabled == false) - { - uiHttpServerIndex++; - if (uiHttpServerIndex >= m_HttpServerList.size()) - return false; - } - - pResourceFile->SetHttpServerIndex(uiHttpServerIndex); - - const SHttpServerInfo& serverInfo = m_HttpServerList[uiHttpServerIndex]; - CNetHTTPDownloadManagerInterface* pHTTP = g_pCore->GetNetwork()->GetHTTPDownloadManager(serverInfo.downloadChannel); - SString strHTTPDownloadURLFull("%s/%s/%s", *serverInfo.strUrl, pResourceFile->GetResource()->GetName(), pResourceFile->GetShortName()); - - SHttpRequestOptions options; - options.uiConnectionAttempts = serverInfo.uiConnectionAttempts; - options.uiConnectTimeoutMs = serverInfo.uiConnectTimeoutMs; - options.bCheckContents = true; - options.bIsLocal = g_pClientGame->IsLocalGame(); - SString* pstrContext = MakeDownloadContextString(pResourceFile); - SString strFilename = pResourceFile->GetName(); - bool bUniqueDownload = pHTTP->QueueFile(strHTTPDownloadURLFull, strFilename, pstrContext, StaticDownloadFinished, options); - if (!bUniqueDownload) - { - // TODO - If piggybacking on another matching download, then adjust progress bar - OutputDebugLine(SString("[ResourceFileDownload] Using existing download for %s", *strHTTPDownloadURLFull)); - } - return true; -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::StaticDownloadFinished -// -// Callback when file download has finished -// -/////////////////////////////////////////////////////////////// -void CResourceFileDownloadManager::StaticDownloadFinished(const SHttpDownloadResult& result) -{ - g_pClientGame->GetResourceFileDownloadManager()->DownloadFinished(result); -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::DownloadFinished -// -// Callback when file download has finished -// -/////////////////////////////////////////////////////////////// -void CResourceFileDownloadManager::DownloadFinished(const SHttpDownloadResult& result) -{ - CDownloadableResource* pResourceFile = ResolveDownloadContextString((SString*)result.pObj); - if (!pResourceFile) - return; - - assert(ListContains(m_ActiveFileDownloadList, pResourceFile)); - if (result.bSuccess) - { - CChecksum checksum = CChecksum::GenerateChecksumFromFile(pResourceFile->GetName()); - if (checksum != pResourceFile->GetServerChecksum()) - { - // Checksum failed - Try download on next server - if (BeginResourceFileDownload(pResourceFile, pResourceFile->GetHttpServerIndex() + 1)) - { - // Was re-added - Add size again to total. - AddDownloadSize(pResourceFile->GetDownloadSize()); - SString strMessage("External HTTP file mismatch (Retrying this file with internal HTTP) [%s]", *ConformResourcePath(pResourceFile->GetName())); - g_pClientGame->TellServerSomethingImportant(1011, strMessage, 3); - return; - } - } - } - else - { - // Download failed due to connection type problem - CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(m_HttpServerList[pResourceFile->GetHttpServerIndex()].downloadChannel); - SString strHTTPError = pHTTP->GetError(); - // Disable server from being used (if possible) - if (DisableHttpServer(pResourceFile->GetHttpServerIndex())) - { - // Try download on next server - if (BeginResourceFileDownload(pResourceFile, pResourceFile->GetHttpServerIndex() + 1)) - { - // Was re-added - Add size again to total. - AddDownloadSize(pResourceFile->GetDownloadSize()); - SString strMessage("External HTTP file download error:[%d] %s (Disabling External HTTP) [%s]", result.iErrorCode, *strHTTPError, - *ConformResourcePath(pResourceFile->GetName())); - g_pClientGame->TellServerSomethingImportant(1012, strMessage, 3); - return; - } - } - m_strLastHTTPError = strHTTPError; - } - - // File now done (or failed) - ListRemove(m_ActiveFileDownloadList, pResourceFile); - pResourceFile->SetIsWaitingForDownload(false); -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::MakeDownloadContextString -// -// For passing to HTTP->QueueFile -// -/////////////////////////////////////////////////////////////// -SString* CResourceFileDownloadManager::MakeDownloadContextString(CDownloadableResource* pDownloadableResource) -{ - return new SString("%d:%s", pDownloadableResource->GetResource()->GetScriptID(), pDownloadableResource->GetShortName()); -} - -/////////////////////////////////////////////////////////////// -// -// CResourceFileDownloadManager::ResolveDownloadContextString -// -// Decode previously generated context string. -// Automatically deletes the string -// -/////////////////////////////////////////////////////////////// -CDownloadableResource* CResourceFileDownloadManager::ResolveDownloadContextString(SString* pString) -{ - SString strFilename; - uint uiScriptId = atoi(pString->SplitLeft(":", &strFilename)); - delete pString; - - CResource* pResource = g_pClientGame->GetResourceManager()->GetResourceFromScriptID(uiScriptId); - if (!pResource) - return NULL; - - // Find match in active downloads - for (auto pDownloadableResource : m_ActiveFileDownloadList) - { - if (pDownloadableResource->GetResource() == pResource && pDownloadableResource->GetShortName() == strFilename) - { - return pDownloadableResource; - } - } - return NULL; -} +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CResourceFileDownloadManager.cpp + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::AddServer +// +// Add http server to use. +// Assumes last one added is the internal server +// +/////////////////////////////////////////////////////////////// +void CResourceFileDownloadManager::AddServer(const SString& strUrl, int iMaxConnectionsPerClient, EDownloadModeType downloadChannel, uint uiConnectionAttempts, + uint uiConnectTimeoutMs) +{ + SHttpServerInfo serverInfo; + serverInfo.bEnabled = true; + serverInfo.downloadChannel = downloadChannel; + serverInfo.strUrl = strUrl; + serverInfo.uiConnectionAttempts = uiConnectionAttempts; + serverInfo.uiConnectTimeoutMs = uiConnectTimeoutMs; + m_HttpServerList.push_back(serverInfo); + g_pCore->GetNetwork()->GetHTTPDownloadManager(downloadChannel)->SetMaxConnections(iMaxConnectionsPerClient); +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::AddPendingFileDownload +// +// Add resource file to the list of files to be downloaded +// +/////////////////////////////////////////////////////////////// +void CResourceFileDownloadManager::AddPendingFileDownload(CDownloadableResource* pResourceFile) +{ + assert(!ListContains(m_PendingFileDownloadList, pResourceFile)); + assert(!ListContains(m_ActiveFileDownloadList, pResourceFile)); + m_PendingFileDownloadList.push_back(pResourceFile); + pResourceFile->SetIsWaitingForDownload(true); + AddDownloadSize(pResourceFile->GetDownloadSize()); +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::UpdatePendingDownloads +// +// Figure which download group should be running +// +/////////////////////////////////////////////////////////////// +void CResourceFileDownloadManager::UpdatePendingDownloads(void) +{ + // Get download group to use + int iGroup = INVALID_DOWNLOAD_PRIORITY_GROUP; + if (!m_ActiveFileDownloadList.empty()) + { + // Use active download group + iGroup = std::max(iGroup, m_ActiveFileDownloadList[0]->GetDownloadPriorityGroup()); + } + else + { + // If no resource files being downloaded, find highest pending download group + for (auto pResourceFile : m_PendingFileDownloadList) + { + iGroup = std::max(iGroup, pResourceFile->GetDownloadPriorityGroup()); + } + } + + // Start (or add to) matching group + std::vector pendingListCopy = m_PendingFileDownloadList; + for (auto pResourceFile : pendingListCopy) + { + if (pResourceFile->GetDownloadPriorityGroup() == iGroup) + { + // Move to active list and begin download + ListRemove(m_PendingFileDownloadList, pResourceFile); + m_ActiveFileDownloadList.push_back(pResourceFile); + BeginResourceFileDownload(pResourceFile, 0); + } + } +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::OnRemoveResourceFile +// +// Tidy up lists when a resource file is delected +// +/////////////////////////////////////////////////////////////// +void CResourceFileDownloadManager::OnRemoveResourceFile(CDownloadableResource* pResourceFile) +{ + ListRemove(m_PendingFileDownloadList, pResourceFile); + ListRemove(m_ActiveFileDownloadList, pResourceFile); +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::DoPulse +// +// Downloading initial resource files +// +/////////////////////////////////////////////////////////////// +void CResourceFileDownloadManager::DoPulse(void) +{ + if (!g_pNet->IsConnected()) + return; + + if (!IsTransferringInitialFiles()) + return; + + // Pulse the http downloads + uint uiDownloadSizeTotal = 0; + for (auto serverInfo : m_HttpServerList) + { + CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(serverInfo.downloadChannel); + pHTTP->ProcessQueuedFiles(); + uiDownloadSizeTotal += pHTTP->GetDownloadSizeNow(); + } + + // Handle fatal error + if (!m_strLastHTTPError.empty()) + { + // Throw the error and disconnect + g_pCore->GetConsole()->Printf(_("Download error: %s"), *m_strLastHTTPError); + AddReportLog(7106, SString("Game - HTTPError (%s)", *m_strLastHTTPError)); + + g_pCore->GetModManager()->RequestUnload(); + g_pCore->ShowMessageBox(_("Error") + _E("CD20"), *m_strLastHTTPError, MB_BUTTON_OK | MB_ICON_ERROR); // HTTP Error + m_bIsTransferingFiles = false; + return; + } + + // Update progress box + GetTransferBox()->SetInfo(uiDownloadSizeTotal); + GetTransferBox()->DoPulse(); + + CLuaArguments Arguments; + Arguments.PushNumber(uiDownloadSizeTotal); + Arguments.PushNumber(GetTransferBox()->GetTotalSize()); + g_pClientGame->GetLocalPlayer()->CallEvent("onTransferBoxProgressChange", Arguments, false); + + // Check if completed downloading current group + if (m_ActiveFileDownloadList.empty()) + { + // Hide progress box if all groups done + if (m_PendingFileDownloadList.empty()) + { + m_bIsTransferingFiles = false; + GetTransferBox()->Hide(); + } + + // Load our newly ready resources + g_pClientGame->GetResourceManager()->OnDownloadGroupFinished(); + UpdatePendingDownloads(); + } +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::AddDownloadSize +// +// Add byte count to transfer box +// +/////////////////////////////////////////////////////////////// +void CResourceFileDownloadManager::AddDownloadSize(int iSize) +{ + if (!m_bIsTransferingFiles) + { + GetTransferBox()->Show(); + m_bIsTransferingFiles = true; + for (auto serverInfo : m_HttpServerList) + { + CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(serverInfo.downloadChannel); + pHTTP->ResetDownloadSize(); + } + } + GetTransferBox()->AddToTotalSize(iSize); +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::DisableHttpServer +// +// Mark http server as unusable. +// Returns false if server cannot be disabled. +// +/////////////////////////////////////////////////////////////// +bool CResourceFileDownloadManager::DisableHttpServer(uint uiHttpServerIndex) +{ + // Can only disable if not the last one + if (uiHttpServerIndex + 1 >= m_HttpServerList.size()) + return false; + m_HttpServerList[uiHttpServerIndex].bEnabled = false; + return true; +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::BeginResourceFileDownload +// +// Return false if file could not be queued +// +/////////////////////////////////////////////////////////////// +bool CResourceFileDownloadManager::BeginResourceFileDownload(CDownloadableResource* pResourceFile, uint uiHttpServerIndex) +{ + if (uiHttpServerIndex >= m_HttpServerList.size()) + return false; + + // Find enabled server + while (m_HttpServerList[uiHttpServerIndex].bEnabled == false) + { + uiHttpServerIndex++; + if (uiHttpServerIndex >= m_HttpServerList.size()) + return false; + } + + pResourceFile->SetHttpServerIndex(uiHttpServerIndex); + + const SHttpServerInfo& serverInfo = m_HttpServerList[uiHttpServerIndex]; + CNetHTTPDownloadManagerInterface* pHTTP = g_pCore->GetNetwork()->GetHTTPDownloadManager(serverInfo.downloadChannel); + SString strHTTPDownloadURLFull("%s/%s/%s", *serverInfo.strUrl, pResourceFile->GetResource()->GetName(), pResourceFile->GetShortName()); + + SHttpRequestOptions options; + options.uiConnectionAttempts = serverInfo.uiConnectionAttempts; + options.uiConnectTimeoutMs = serverInfo.uiConnectTimeoutMs; + options.bCheckContents = true; + options.bIsLocal = g_pClientGame->IsLocalGame(); + SString* pstrContext = MakeDownloadContextString(pResourceFile); + SString strFilename = pResourceFile->GetName(); + bool bUniqueDownload = pHTTP->QueueFile(strHTTPDownloadURLFull, strFilename, pstrContext, StaticDownloadFinished, options); + if (!bUniqueDownload) + { + // TODO - If piggybacking on another matching download, then adjust progress bar + OutputDebugLine(SString("[ResourceFileDownload] Using existing download for %s", *strHTTPDownloadURLFull)); + } + return true; +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::StaticDownloadFinished +// +// Callback when file download has finished +// +/////////////////////////////////////////////////////////////// +void CResourceFileDownloadManager::StaticDownloadFinished(const SHttpDownloadResult& result) +{ + g_pClientGame->GetResourceFileDownloadManager()->DownloadFinished(result); +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::DownloadFinished +// +// Callback when file download has finished +// +/////////////////////////////////////////////////////////////// +void CResourceFileDownloadManager::DownloadFinished(const SHttpDownloadResult& result) +{ + CDownloadableResource* pResourceFile = ResolveDownloadContextString((SString*)result.pObj); + if (!pResourceFile) + return; + + assert(ListContains(m_ActiveFileDownloadList, pResourceFile)); + if (result.bSuccess) + { + CChecksum checksum = CChecksum::GenerateChecksumFromFile(pResourceFile->GetName()); + if (checksum != pResourceFile->GetServerChecksum()) + { + // Checksum failed - Try download on next server + if (BeginResourceFileDownload(pResourceFile, pResourceFile->GetHttpServerIndex() + 1)) + { + // Was re-added - Add size again to total. + AddDownloadSize(pResourceFile->GetDownloadSize()); + SString strMessage("External HTTP file mismatch (Retrying this file with internal HTTP) [%s]", *ConformResourcePath(pResourceFile->GetName())); + g_pClientGame->TellServerSomethingImportant(1011, strMessage, 3); + return; + } + } + } + else + { + // Download failed due to connection type problem + CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(m_HttpServerList[pResourceFile->GetHttpServerIndex()].downloadChannel); + SString strHTTPError = pHTTP->GetError(); + // Disable server from being used (if possible) + if (DisableHttpServer(pResourceFile->GetHttpServerIndex())) + { + // Try download on next server + if (BeginResourceFileDownload(pResourceFile, pResourceFile->GetHttpServerIndex() + 1)) + { + // Was re-added - Add size again to total. + AddDownloadSize(pResourceFile->GetDownloadSize()); + SString strMessage("External HTTP file download error:[%d] %s (Disabling External HTTP) [%s]", result.iErrorCode, *strHTTPError, + *ConformResourcePath(pResourceFile->GetName())); + g_pClientGame->TellServerSomethingImportant(1012, strMessage, 3); + return; + } + } + m_strLastHTTPError = strHTTPError; + } + + // File now done (or failed) + ListRemove(m_ActiveFileDownloadList, pResourceFile); + pResourceFile->SetIsWaitingForDownload(false); +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::MakeDownloadContextString +// +// For passing to HTTP->QueueFile +// +/////////////////////////////////////////////////////////////// +SString* CResourceFileDownloadManager::MakeDownloadContextString(CDownloadableResource* pDownloadableResource) +{ + return new SString("%d:%s", pDownloadableResource->GetResource()->GetScriptID(), pDownloadableResource->GetShortName()); +} + +/////////////////////////////////////////////////////////////// +// +// CResourceFileDownloadManager::ResolveDownloadContextString +// +// Decode previously generated context string. +// Automatically deletes the string +// +/////////////////////////////////////////////////////////////// +CDownloadableResource* CResourceFileDownloadManager::ResolveDownloadContextString(SString* pString) +{ + SString strFilename; + uint uiScriptId = atoi(pString->SplitLeft(":", &strFilename)); + delete pString; + + CResource* pResource = g_pClientGame->GetResourceManager()->GetResourceFromScriptID(uiScriptId); + if (!pResource) + return NULL; + + // Find match in active downloads + for (auto pDownloadableResource : m_ActiveFileDownloadList) + { + if (pDownloadableResource->GetResource() == pResource && pDownloadableResource->GetShortName() == strFilename) + { + return pDownloadableResource; + } + } + return NULL; +} From 69bd0ea6d013bc5502eb6c35b527714d81cc3f16 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Wed, 2 Jan 2019 14:49:15 +0100 Subject: [PATCH 23/27] fix test --- Client/core/CSettings.cpp | 2 +- Client/core/CSettings.h | 2 +- .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 1011 +++++++++-------- 3 files changed, 569 insertions(+), 446 deletions(-) diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index 00ee024baf0..ad050062961 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -3304,7 +3304,7 @@ void CSettings::SaveData(void) CVARS_SET("show_unsafe_resolutions", bShowUnsafeResolutions); // Allow screen upload - bAllowScreenUploadEnabled = m_pCheckBoxAllowScreenUpload->GetSelected(); + bool bAllowScreenUploadEnabled = m_pCheckBoxAllowScreenUpload->GetSelected(); CVARS_SET("allow_screen_upload", bAllowScreenUploadEnabled); // Allow screen upload diff --git a/Client/core/CSettings.h b/Client/core/CSettings.h index b46dec45061..88a5c766005 100644 --- a/Client/core/CSettings.h +++ b/Client/core/CSettings.h @@ -446,5 +446,5 @@ class CSettings std::list m_pKeyBindSections; - bool bAllowScreenUploadEnabled; + bool bAllowServerTransferBoxControl; }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index ff4795ed4f1..f76879f64f8 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -1,164 +1,202 @@ /***************************************************************************** - * - * PROJECT: Multi Theft Auto - * LICENSE: See LICENSE in the top level directory - * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp - * PURPOSE: Lua definitions class - * - * Multi Theft Auto is available from http://www.multitheftauto.com/ - * - *****************************************************************************/ +* +* PROJECT: Multi Theft Auto +* LICENSE: See LICENSE in the top level directory +* FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp +* PURPOSE: Lua definitions class +* +* Multi Theft Auto is available from http://www.multitheftauto.com/ +* +*****************************************************************************/ #include "StdInc.h" +static const SFixedArray g_chatboxLayoutCVars = { { + "chat_font", + "chat_lines", + "chat_color", + "chat_text_color", + "chat_input_color", + "chat_input_prefix_color", + "chat_input_text_color", + "chat_scale", + "chat_position_offset_x", + "chat_position_offset_y", + "chat_position_horizontal", + "chat_position_vertical", + "chat_text_alignment", + "chat_width", + "chat_css_style_text", + "chat_css_style_background", + "chat_line_life", + "chat_line_fade_out", + "chat_use_cegui", + "text_scale" + } }; + void CLuaGUIDefs::LoadFunctions(void) { - CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); - CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); - CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); - CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); - - CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); - CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); - CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); - CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); - CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); - CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); - CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); - CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); - CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); - - CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); - CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); - CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); - CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); - CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); - CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); - CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); - CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); - CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); - CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); - CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); - CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); - CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); - CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); - CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); - CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); - - CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); - CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); - CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); - CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); - CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); - - CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); - CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); - CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); - CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); - CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); - CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); - CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); - CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); - CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); - CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); - CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); - CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); - CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); - CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); - CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); - CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); - CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); - CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); - CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); - CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); - CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); - CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); - - CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); - CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); - CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); - CLuaCFunctions::AddFunction("guiSetText", GUISetText); - CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); - CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); - CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); - CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); - - CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); - CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); - - CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); - - CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); - CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); - CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); - CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); - CLuaCFunctions::AddFunction("guiGetText", GUIGetText); - CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); - CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); - CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); - CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); - CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); - - CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); - - CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); - CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); - - CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); - - CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); - CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); - CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); - CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); - CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); - CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); - - CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); - CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); - CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); - CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); - CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); - CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); - - CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); - CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); - - CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); - CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); - - CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); - - CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); - CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); - CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); - CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); - CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); - CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); - CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); + std::map functions{ + { "guiGetInputEnabled", GUIGetInputEnabled }, + { "guiSetInputEnabled", GUISetInputEnabled }, + { "guiGetInputMode", GUIGetInputMode }, + { "guiSetInputMode", GUISetInputMode }, + + { "isChatBoxInputActive", GUIIsChatBoxInputActive }, + { "isConsoleActive", GUIIsConsoleActive }, + { "isDebugViewActive", GUIIsDebugViewActive }, + { "setDebugViewActive", GUISetDebugViewActive }, + { "isMainMenuActive", GUIIsMainMenuActive }, + { "isMTAWindowActive", GUIIsMTAWindowActive }, + { "isTransferBoxActive", GUIIsTransferBoxActive }, + { "isTransferBoxEnabled", GUIIsTransferBoxEnabled }, + { "setTransferBoxEnabled", GUISetTransferBoxEnabled }, + + { "guiCreateWindow", GUICreateWindow }, + { "guiCreateLabel", GUICreateLabel }, + { "guiCreateButton", GUICreateButton }, + { "guiCreateEdit", GUICreateEdit }, + { "guiCreateMemo", GUICreateMemo }, + { "guiCreateGridList", GUICreateGridList }, + { "guiCreateScrollPane", GUICreateScrollPane }, + { "guiCreateScrollBar", GUICreateScrollBar }, + { "guiCreateTabPanel", GUICreateTabPanel }, + { "guiCreateTab", GUICreateTab }, + { "guiCreateProgressBar", GUICreateProgressBar }, + { "guiCreateCheckBox", GUICreateCheckBox }, + { "guiCreateRadioButton", GUICreateRadioButton }, + { "guiCreateStaticImage", GUICreateStaticImage }, + { "guiCreateComboBox", GUICreateComboBox }, + { "guiCreateFont", GUICreateFont }, + + { "guiStaticImageLoadImage", GUIStaticImageLoadImage }, + { "guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize }, + { "guiGetSelectedTab", GUIGetSelectedTab }, + { "guiSetSelectedTab", GUISetSelectedTab }, + { "guiDeleteTab", GUIDeleteTab }, + + { "guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled }, + { "guiGridListAddColumn", GUIGridListAddColumn }, + { "guiGridListRemoveColumn", GUIGridListRemoveColumn }, + { "guiGridListSetColumnWidth", GUIGridListSetColumnWidth }, + { "guiGridListGetColumnWidth", GUIGridListGetColumnWidth }, + { "guiGridListSetColumnTitle", GUIGridListSetColumnTitle }, + { "guiGridListGetColumnTitle", GUIGridListGetColumnTitle }, + { "guiGridListSetScrollBars", GUIGridListSetScrollBars }, + { "guiGridListGetRowCount", GUIGridListGetRowCount }, + { "guiGridListGetColumnCount", GUIGridListGetColumnCount }, + { "guiGridListAddRow", GUIGridListAddRow }, + { "guiGridListInsertRowAfter", GUIGridListInsertRowAfter }, + { "guiGridListRemoveRow", GUIGridListRemoveRow }, + { "guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn }, + { "guiGridListClear", GUIGridListClear }, + { "guiGridListSetItemText", GUIGridListSetItemText }, + { "guiGridListGetItemText", GUIGridListGetItemText }, + { "guiGridListSetItemData", GUIGridListSetItemData }, + { "guiGridListGetItemData", GUIGridListGetItemData }, + { "guiGridListSetItemColor", GUIGridListSetItemColor }, + { "guiGridListGetItemColor", GUIGridListGetItemColor }, + { "guiGridListSetSelectionMode", GUIGridListSetSelectionMode }, + { "guiGridListGetSelectedItem", GUIGridListGetSelectedItem }, + { "guiGridListGetSelectedItems", GUIGridListGetSelectedItems }, + { "guiGridListGetSelectedCount", GUIGridListGetSelectedCount }, + { "guiGridListSetSelectedItem", GUIGridListSetSelectedItem }, + { "guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition }, + { "guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition }, + { "guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition }, + { "guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition }, + + { "guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars }, + { "guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition }, + { "guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition }, + { "guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition }, + { "guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition }, + + { "guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition }, + { "guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition }, + + { "guiSetEnabled", GUISetEnabled }, + { "guiSetProperty", GUISetProperty }, + { "guiSetAlpha", GUISetAlpha }, + { "guiSetText", GUISetText }, + { "guiSetFont", GUISetFont }, + { "guiSetSize", GUISetSize }, + { "guiSetPosition", GUISetPosition }, + { "guiSetVisible", GUISetVisible }, + + { "guiBringToFront", GUIBringToFront }, + { "guiMoveToBack", GUIMoveToBack }, + + { "guiCheckBoxSetSelected", GUICheckBoxSetSelected }, + { "guiRadioButtonSetSelected", GUIRadioButtonSetSelected }, + + { "guiGetEnabled", GUIGetEnabled }, + { "guiGetProperty", GUIGetProperty }, + { "guiGetProperties", GUIGetProperties }, + { "guiGetAlpha", GUIGetAlpha }, + { "guiGetText", GUIGetText }, + { "guiGetFont", GUIGetFont }, + { "guiGetSize", GUIGetSize }, + { "guiGetPosition", GUIGetPosition }, + { "guiGetVisible", GUIGetVisible }, + { "guiGetCursorType", GUIGetCursorType }, + + { "guiCheckBoxGetSelected", GUICheckBoxGetSelected }, + { "guiRadioButtonGetSelected", GUIRadioButtonGetSelected }, + + { "guiProgressBarSetProgress", GUIProgressBarSetProgress }, + { "guiProgressBarGetProgress", GUIProgressBarGetProgress }, + + { "guiGetScreenSize", GUIGetScreenSize }, + + { "guiEditSetCaretIndex", GUIEditSetCaretIndex }, + { "guiEditGetCaretIndex", GUIEditGetCaretIndex }, + { "guiEditSetMasked", GUIEditSetMasked }, + { "guiEditIsMasked", GUIEditIsMasked }, + { "guiEditSetMaxLength", GUIEditSetMaxLength }, + { "guiEditGetMaxLength", GUIEditGetMaxLength }, + { "guiEditSetReadOnly", GUIEditSetReadOnly }, + { "guiEditIsReadOnly", GUIEditIsReadOnly }, + + { "guiMemoSetCaretIndex", GUIMemoSetCaretIndex }, + { "guiMemoGetCaretIndex", GUIMemoGetCaretIndex }, + { "guiMemoSetReadOnly", GUIMemoSetReadOnly }, + { "guiMemoIsReadOnly", GUIMemoIsReadOnly }, + { "guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition }, + { "guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition }, + + { "guiLabelSetColor", GUILabelSetColor }, + { "guiLabelGetColor", GUILabelGetColor }, + { "guiLabelSetVerticalAlign", GUILabelSetVerticalAlign }, + { "guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign }, + + { "guiLabelGetTextExtent", GUILabelGetTextExtent }, + { "guiLabelGetFontHeight", GUILabelGetFontHeight }, + + { "guiWindowSetMovable", GUIWindowSetMovable }, + { "guiWindowSetSizable", GUIWindowSetSizable }, + { "guiWindowIsMovable", GUIWindowIsMovable }, + { "guiWindowIsSizable", GUIWindowIsSizable }, + + { "getChatboxLayout", GUIGetChatboxLayout }, + + { "guiComboBoxAddItem", GUIComboBoxAddItem }, + { "guiComboBoxRemoveItem", GUIComboBoxRemoveItem }, + { "guiComboBoxClear", GUIComboBoxClear }, + { "guiComboBoxGetSelected", GUIComboBoxGetSelected }, + { "guiComboBoxSetSelected", GUIComboBoxSetSelected }, + { "guiComboBoxGetItemText", GUIComboBoxGetItemText }, + { "guiComboBoxSetItemText", GUIComboBoxSetItemText }, + { "guiComboBoxGetItemCount", GUIComboBoxGetItemCount }, + { "guiComboBoxSetOpen", GUIComboBoxSetOpen }, + { "guiComboBoxIsOpen", GUIComboBoxIsOpen }, + }; + + // Add functions + for (const auto& pair : functions) + { + CLuaCFunctions::AddFunction(pair.first, pair.second); + } } void CLuaGUIDefs::AddClass(lua_State* luaVM) @@ -252,11 +290,15 @@ void CLuaGUIDefs::AddGuiWindowClass(lua_State* luaVM) lua_newclass(luaVM); lua_classfunction(luaVM, "create", "guiCreateWindow"); + lua_classfunction(luaVM, "setMovable", "guiWindowSetMovable"); lua_classfunction(luaVM, "setSizable", "guiWindowSetSizable"); - lua_classvariable(luaVM, "movable", "guiWindowSetMovable", NULL); - lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", NULL); + lua_classfunction(luaVM, "isMovable", "guiWindowIsMovable"); + lua_classfunction(luaVM, "isSizable", "guiWindowIsSizable"); + + lua_classvariable(luaVM, "movable", "guiWindowSetMovable", "guiWindowIsMovable"); + lua_classvariable(luaVM, "sizable", "guiWindowSetSizable", "guiWindowIsSizable"); lua_registerclass(luaVM, "GuiWindow", "GuiElement"); } @@ -283,8 +325,8 @@ void CLuaGUIDefs::AddGuiEditClass(lua_State* luaVM) lua_classvariable(luaVM, "caretIndex", "guiEditSetCaretIndex", "guiEditGetCaretIndex"); lua_classvariable(luaVM, "readOnly", "guiEditSetReadOnly", "guiEditIsReadOnly"); - lua_classvariable(luaVM, "masked", "guiEditSetMasked", NULL); - lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", NULL); + lua_classvariable(luaVM, "masked", "guiEditSetMasked", "guiEditIsMasked"); + lua_classvariable(luaVM, "maxLength", "guiEditSetMaxLength", "guiEditGetMaxLength"); lua_registerclass(luaVM, "GuiEdit", "GuiElement"); } @@ -356,11 +398,16 @@ void CLuaGUIDefs::AddGuiComboBoxClass(lua_State* luaVM) lua_classfunction(luaVM, "getSelected", "guiComboBoxGetSelected"); lua_classfunction(luaVM, "getItemText", "guiComboBoxGetItemText"); + lua_classfunction(luaVM, "isOpen", "guiComboBoxIsOpen"); + lua_classfunction(luaVM, "getItemCount", "guiComboBoxGetItemCount"); lua_classfunction(luaVM, "setItemText", "guiComboBoxSetItemText"); lua_classfunction(luaVM, "setSelected", "guiComboBoxSetSelected"); + lua_classfunction(luaVM, "setOpen", "guiComboBoxSetOpen"); lua_classvariable(luaVM, "selected", "guiComboBoxSetSelected", "guiComboBoxGetSelected"); + lua_classvariable(luaVM, "itemCount", nullptr, "guiComboBoxGetItemCount"); + lua_classvariable(luaVM, "open", "guiComboBoxSetOpen", "guiComboBoxIsOpen"); lua_registerclass(luaVM, "GuiComboBox", "GuiElement"); } @@ -645,40 +692,6 @@ int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) { lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsVisible()); return 1; -} - -int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) -{ - bool bEnabled; - CScriptArgReader argStream(luaVM); - argStream.ReadBool(bEnabled); - - if (!argStream.HasErrors()) - { - bool bAllowed = false; - g_pCore->GetCVars()->Get("allow_server_control_transferbox", bAllowed); - if (bAllowed) - { - g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - { - lua_pushboolean(luaVM, false); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - return 1; -} - -int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); - return 1; } int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) @@ -2988,26 +3001,26 @@ int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) return 1; } -int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) -{ - // bool guiMemoIsReadOnly( gui-memo theMemo ) - CClientGUIElement* editField; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; +int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) +{ + // bool guiEditIsReadOnly( element editField ) + CClientGUIElement* editField; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(editField); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; } int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) @@ -3034,26 +3047,26 @@ int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) return 1; } -int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) -{ - // bool guiMemoIsReadOnly( guimemo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; +int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) +{ + // bool guiMemoIsReadOnly( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); + lua_pushboolean(luaVM, readOnly); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; } int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) @@ -3080,6 +3093,28 @@ int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIEditIsMasked(lua_State* luaVM) +{ + //bool guiEditIsMasked(element theElement) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + bool masked = static_cast(theElement->GetCGUIElement())->IsMasked(); + lua_pushboolean(luaVM, masked); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) { // bool guiEditSetMaxLength ( element theElement, int length ) @@ -3104,6 +3139,27 @@ int CLuaGUIDefs::GUIEditSetMaxLength(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIEditGetMaxLength(lua_State* luaVM) +{ + // int guiEditGetMaxLength(element theElement) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, static_cast(theElement->GetCGUIElement())->GetMaxLength()); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) { // bool guiEditSetCaretIndex ( element theElement, int index ) @@ -3128,29 +3184,6 @@ int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) return 1; } -int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiMemoSetVerticalScrollPosition ( guimemo theMemo, float fPosition ) - CClientGUIElement* theMemo; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) { // int guiEditGetCaretIndex ( element theElement ) @@ -3172,29 +3205,6 @@ int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) return 1; } -int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiMemoGetVerticalScrollPosition ( guimemo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); - float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) { // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) @@ -3219,6 +3229,29 @@ int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) +{ + // bool guiMemoSetVerticalScrollPosition ( gui-memo theMemo, float fPosition ) + CClientGUIElement* theMemo; + float fPosition; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + argStream.ReadNumber(fPosition); + + if (!argStream.HasErrors()) + { + CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); + lua_pushboolean(luaVM, true); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) { // bool guiMemoGetCaretIndex ( gui-memo theMemo ) @@ -3240,6 +3273,29 @@ int CLuaGUIDefs::GUIMemoGetCaretIndex(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) +{ + // float guiMemoGetVerticalScrollPosition ( gui-memo theMemo ) + CClientGUIElement* theMemo; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theMemo); + + if (!argStream.HasErrors()) + { + CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); + float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; + lua_pushnumber(luaVM, fPos); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) { // bool guiWindowSetMovable ( element theElement, bool status ) @@ -3264,6 +3320,28 @@ int CLuaGUIDefs::GUIWindowSetMovable(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIWindowIsMovable(lua_State* luaVM) +{ + // bool guiWindowIsMovable( element theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + bool movable = static_cast(theElement->GetCGUIElement())->IsMovable(); + lua_pushboolean(luaVM, movable); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) { // bool guiWindowSetSizable ( element theElement, bool status ) @@ -3288,6 +3366,28 @@ int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIWindowIsSizable(lua_State* luaVM) +{ + // bool guiWindowIsSizable( elemen theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + bool sizable = static_cast(theElement->GetCGUIElement())->IsSizingEnabled(); + lua_pushboolean(luaVM, sizable); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) { // float guiLabelGetTextExtent ( element theLabel ) @@ -3460,176 +3560,102 @@ int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) //* chat_use_cegui - Returns whether CEGUI is used to render the chatbox //* text_scale - Returns text scale - CCVarsInterface* pCVars = g_pCore->GetCVars(); - int iNumber; - float fNumber; - pCVars->Get("chat_font", fNumber); - lua_newtable(luaVM); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_font"); - pCVars->Get("chat_lines", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_lines"); - pCVars->Get("chat_width", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_width"); - pCVars->Get("chat_position_offset_x", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_x"); - pCVars->Get("chat_position_offset_y", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_position_offset_y"); - pCVars->Get("chat_position_horizontal", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_horizontal"); - pCVars->Get("chat_position_vertical", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_position_vertical"); - pCVars->Get("chat_text_alignment", iNumber); - lua_pushnumber(luaVM, iNumber); - lua_setfield(luaVM, -2, "chat_text_alignment"); - pCVars->Get("chat_css_style_text", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_text"); - pCVars->Get("chat_css_style_background", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_css_style_background"); - pCVars->Get("chat_line_life", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_life"); - pCVars->Get("chat_line_fade_out", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "chat_line_fade_out"); - pCVars->Get("text_scale", fNumber); - lua_pushnumber(luaVM, fNumber); - lua_setfield(luaVM, -2, "text_scale"); - pCVars->Get("chat_use_cegui", fNumber); - lua_pushboolean(luaVM, fNumber ? true : false); - lua_setfield(luaVM, -2, "chat_use_cegui"); - std::string strCVar; + CScriptArgReader argStream(luaVM); + CCVarsInterface* pCVars = g_pCore->GetCVars(); + float fNumber; + SString strCVarValue; std::stringstream ss; int iR, iG, iB, iA; - pCVars->Get("chat_color", strCVar); - if (!strCVar.empty()) - { - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_color"); - } - pCVars->Get("chat_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_text_color"); - } - pCVars->Get("chat_input_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_color"); - } - pCVars->Get("chat_input_prefix_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_prefix_color"); - } - pCVars->Get("chat_input_text_color", strCVar); - if (!strCVar.empty()) - { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_input_text_color"); - } - pCVars->Get("chat_scale", strCVar); - if (!strCVar.empty()) - { - float fX, fY; - ss.clear(); - ss.str(strCVar); - ss >> fX >> fY; + SString strCVarArg; + bool bAll = argStream.NextIsNone(); + + // If we are asking for all CVars, prepare a new table + if (bAll) lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, fX); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, fY); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_scale"); + else + argStream.ReadString(strCVarArg); + + if (!argStream.HasErrors()) + { + // Loop through all CVars + for (unsigned int i = 0; i < MAX_CHATBOX_LAYOUT_CVARS; i++) + { + // If we are asking for all CVars, or we can match the requested CVar with this CVar + if (bAll || !stricmp(g_chatboxLayoutCVars[i], strCVarArg)) + { + // Push color values into a table + if (g_chatboxLayoutCVars[i] == "chat_color" || + g_chatboxLayoutCVars[i] == "chat_text_color" || + g_chatboxLayoutCVars[i] == "chat_input_color" || + g_chatboxLayoutCVars[i] == "chat_input_prefix_color" || + g_chatboxLayoutCVars[i] == "chat_input_text_color") + { + pCVars->Get(g_chatboxLayoutCVars[i], strCVarValue); + if (!strCVarValue.empty()) + { + ss.clear(); + ss.str(strCVarValue); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + } + } + // Push chat scale into a table + else if (g_chatboxLayoutCVars[i] == "chat_scale") + { + pCVars->Get(g_chatboxLayoutCVars[i], strCVarValue); + if (!strCVarValue.empty()) + { + float fX, fY; + ss.clear(); + ss.str(strCVarValue); + ss >> fX >> fY; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, fX); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, fY); + lua_settable(luaVM, -3); + } + } + else + { + pCVars->Get(g_chatboxLayoutCVars[i], fNumber); + if (g_chatboxLayoutCVars[i] == "chat_use_cegui") + lua_pushboolean(luaVM, fNumber ? true : false); + else + lua_pushnumber(luaVM, fNumber); + } + + // If we are asking for all CVars, push this into the table with its CVar name, otherwise just stop here + if (bAll) + lua_setfield(luaVM, -2, g_chatboxLayoutCVars[i]); + else + return 1; + } + } + + // We wanted all CVars and that's done so let's stop now + if (bAll) + return 1; } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + // error: bad arguments + lua_pushboolean(luaVM, false); return 1; } @@ -3828,6 +3854,69 @@ int CLuaGUIDefs::GUIComboBoxSetItemText(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIComboBoxGetItemCount(lua_State* luaVM) +{ + // int guiComboBoxGetItemCount( element comboBox ) + CClientGUIElement* comboBox; + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + int items = CStaticFunctionDefinitions::GUIComboBoxGetItemCount(*comboBox); + lua_pushnumber(luaVM, items); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxSetOpen(lua_State* luaVM) +{ + // bool guiComboBoxSetOpen( element comboBox, bool state) + CClientGUIElement* comboBox; + bool state; + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + argStream.ReadBool(state); + + if (!argStream.HasErrors()) + { + lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIComboBoxSetOpen(*comboBox, state)); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaGUIDefs::GUIComboBoxIsOpen(lua_State* luaVM) +{ + // bool guiComboBoxIsOpen( element comboBox ) + CClientGUIElement* comboBox; + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(comboBox); + + if (!argStream.HasErrors()) + { + lua_pushboolean(luaVM, CStaticFunctionDefinitions::GUIComboBoxIsOpen(*comboBox)); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + int CLuaGUIDefs::GUICreateFont(lua_State* luaVM) { // element guiCreateFont( string filepath [, int size=9 ] ) @@ -3884,3 +3973,37 @@ int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) lua_pushstring(luaVM, EnumToString(eType)); return 1; } + +int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) +{ + bool bEnabled; + CScriptArgReader argStream(luaVM); + argStream.ReadBool(bEnabled); + + if (!argStream.HasErrors()) + { + bool bAllowed = false; + g_pCore->GetCVars()->Get("allow_server_control_transferbox", bAllowed); + if (bAllowed) + { + g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); + lua_pushboolean(luaVM, true); + return 1; + } + else + { + lua_pushboolean(luaVM, false); + return 1; + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + return 1; +} + +int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) +{ + lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); + return 1; +} From 66dd5c8edc27716145f64e90d081e4adfe0f8424 Mon Sep 17 00:00:00 2001 From: CrosRoad95 Date: Wed, 2 Jan 2019 15:04:44 +0100 Subject: [PATCH 24/27] unnuke branch --- .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 863 +++--------------- 1 file changed, 145 insertions(+), 718 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index c5ee997ce5a..9c2040ad36a 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -1,166 +1,41 @@ /***************************************************************************** -* -* PROJECT: Multi Theft Auto -* LICENSE: See LICENSE in the top level directory -* FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp -* PURPOSE: Lua definitions class -* -* Multi Theft Auto is available from http://www.multitheftauto.com/ -* -*****************************************************************************/ + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/luadefs/CLuaGUIDefs.cpp + * PURPOSE: Lua definitions class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ #include "StdInc.h" +static const SFixedArray g_chatboxLayoutCVars = {{ + "chat_font", + "chat_lines", + "chat_color", + "chat_text_color", + "chat_input_color", + "chat_input_prefix_color", + "chat_input_text_color", + "chat_scale", + "chat_position_offset_x", + "chat_position_offset_y", + "chat_position_horizontal", + "chat_position_vertical", + "chat_text_alignment", + "chat_width", + "chat_css_style_text", + "chat_css_style_background", + "chat_line_life", + "chat_line_fade_out", + "chat_use_cegui", + "text_scale" +}}; + void CLuaGUIDefs::LoadFunctions(void) { -<<<<<<<<< Temporary merge branch 1 - CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); - CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); - CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); - CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); - - CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); - CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); - CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); - CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); - CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); - CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); - CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); - CLuaCFunctions::AddFunction("isTransferBoxEnabled", GUIIsTransferBoxEnabled); - CLuaCFunctions::AddFunction("setTransferBoxEnabled", GUISetTransferBoxEnabled); - - CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); - CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); - CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); - CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); - CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); - CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); - CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); - CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); - CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); - CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); - CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); - CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); - CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); - CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); - CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); - CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); - - CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); - CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); - CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); - CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); - CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); - - CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); - CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); - CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); - CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); - CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); - CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); - CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); - CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); - CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); - CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); - CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); - CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); - CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); - CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); - CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); - CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); - CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); - CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); - CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); - CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); - CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); - CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); - - CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); - CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); - CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); - CLuaCFunctions::AddFunction("guiSetText", GUISetText); - CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); - CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); - CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); - CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); - - CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); - CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); - - CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); - - CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); - CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); - CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); - CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); - CLuaCFunctions::AddFunction("guiGetText", GUIGetText); - CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); - CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); - CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); - CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); - CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); - - CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); - - CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); - CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); - - CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); - - CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); - CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); - CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); - CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); - CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); - CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); - - CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); - CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); - CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); - CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); - CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); - CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); - - CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); - CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); - - CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); - CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); - - CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); - - CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); - CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); - CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); - CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); - CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); - CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); - CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); -========= std::map functions{ {"guiGetInputEnabled", GUIGetInputEnabled}, {"guiSetInputEnabled", GUISetInputEnabled}, @@ -174,6 +49,8 @@ void CLuaGUIDefs::LoadFunctions(void) {"isMainMenuActive", GUIIsMainMenuActive}, {"isMTAWindowActive", GUIIsMTAWindowActive}, {"isTransferBoxActive", GUIIsTransferBoxActive}, + {"isTransferBoxEnabled", GUIIsTransferBoxEnabled}, + {"setTransferBoxEnabled", GUISetTransferBoxEnabled}, {"guiCreateWindow", GUICreateWindow}, {"guiCreateLabel", GUICreateLabel}, @@ -320,7 +197,6 @@ void CLuaGUIDefs::LoadFunctions(void) { CLuaCFunctions::AddFunction(pair.first, pair.second); } ->>>>>>>>> Temporary merge branch 2 } void CLuaGUIDefs::AddClass(lua_State* luaVM) @@ -818,40 +694,6 @@ int CLuaGUIDefs::GUIIsTransferBoxActive(lua_State* luaVM) return 1; } -int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) -{ - bool bEnabled; - CScriptArgReader argStream(luaVM); - argStream.ReadBool(bEnabled); - - if (!argStream.HasErrors()) - { - bool bAllowed = false; - g_pCore->GetCVars()->Get("allow_server_control_transferbox", bAllowed); - if (bAllowed) - { - g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - { - lua_pushboolean(luaVM, false); - return 1; - } - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - return 1; -} - -int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) -{ - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); - return 1; -} - int CLuaGUIDefs::GUICreateWindow(lua_State* luaVM) { // element guiCreateWindow ( float x, float y, float width, float height, string titleBarText, bool relative ) @@ -3161,7 +3003,7 @@ int CLuaGUIDefs::GUIEditSetReadOnly(lua_State* luaVM) int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) { - // bool guiMemoIsReadOnly( gui-memo theMemo ) + // bool guiEditIsReadOnly( element editField ) CClientGUIElement* editField; CScriptArgReader argStream(luaVM); @@ -3207,7 +3049,7 @@ int CLuaGUIDefs::GUIMemoSetReadOnly(lua_State* luaVM) int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) { - // bool guiMemoIsReadOnly( guimemo theMemo ) + // bool guiMemoIsReadOnly( gui-memo theMemo ) CClientGUIElement* theMemo; CScriptArgReader argStream(luaVM); @@ -3229,47 +3071,47 @@ int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) { - // bool guiMemoIsReadOnly( gui-memo theMemo ) - CClientGUIElement* theMemo; + // bool guiEditSetMasked ( element theElement, bool status ) + CClientGUIElement* theElement; + bool status; CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); + argStream.ReadUserData(theElement); + argStream.ReadBool(status); if (!argStream.HasErrors()) { - bool readOnly = static_cast(theMemo->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); + CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); + lua_pushboolean(luaVM, true); return 1; } else m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); // error: bad arguments - lua_pushnil(luaVM); + lua_pushboolean(luaVM, false); return 1; } -int CLuaGUIDefs::GUIEditSetMasked(lua_State* luaVM) +int CLuaGUIDefs::GUIEditIsMasked(lua_State* luaVM) { - // bool guiEditSetMasked ( element theElement, bool status ) + //bool guiEditIsMasked(element theElement) CClientGUIElement* theElement; - bool status; CScriptArgReader argStream(luaVM); argStream.ReadUserData(theElement); - argStream.ReadBool(status); - + if (!argStream.HasErrors()) { - CStaticFunctionDefinitions::GUIEditSetMasked(*theElement, status); - lua_pushboolean(luaVM, true); + bool masked = static_cast(theElement->GetCGUIElement())->IsMasked(); + lua_pushboolean(luaVM, masked); return 1; } else m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); // error: bad arguments - lua_pushboolean(luaVM, false); + lua_pushnil(luaVM); return 1; } @@ -3342,29 +3184,6 @@ int CLuaGUIDefs::GUIEditSetCaretIndex(lua_State* luaVM) return 1; } -int CLuaGUIDefs::GUIMemoSetVerticalScrollPosition(lua_State* luaVM) -{ - // bool guiMemoSetVerticalScrollPosition ( guimemo theMemo, float fPosition ) - CClientGUIElement* theMemo; - float fPosition; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - argStream.ReadNumber(fPosition); - - if (!argStream.HasErrors()) - { - CStaticFunctionDefinitions::GUIMemoSetVerticalScrollPosition(*theMemo, fPosition); - lua_pushboolean(luaVM, true); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; -} - int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) { // int guiEditGetCaretIndex ( element theElement ) @@ -3386,29 +3205,6 @@ int CLuaGUIDefs::GUIEditGetCaretIndex(lua_State* luaVM) return 1; } -int CLuaGUIDefs::GUIMemoGetVerticalScrollPosition(lua_State* luaVM) -{ - // float guiMemoGetVerticalScrollPosition ( guimemo theMemo ) - CClientGUIElement* theMemo; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theMemo); - - if (!argStream.HasErrors()) - { - CGUIMemo* guiMemo = static_cast(theMemo->GetCGUIElement()); - float fPos = guiMemo->GetVerticalScrollPosition() / guiMemo->GetMaxVerticalScrollPosition() * 100.0f; - lua_pushnumber(luaVM, fPos); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushboolean(luaVM, false); - return 1; -} - int CLuaGUIDefs::GUIMemoSetCaretIndex(lua_State* luaVM) { // bool guiMemoSetCaretIndex ( gui-memo theMemo, int index ) @@ -3570,6 +3366,28 @@ int CLuaGUIDefs::GUIWindowSetSizable(lua_State* luaVM) return 1; } +int CLuaGUIDefs::GUIWindowIsSizable(lua_State* luaVM) +{ + // bool guiWindowIsSizable( elemen theElement ) + CClientGUIElement* theElement; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(theElement); + + if (!argStream.HasErrors()) + { + bool sizable = static_cast(theElement->GetCGUIElement())->IsSizingEnabled(); + lua_pushboolean(luaVM, sizable); + return 1; + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // error: bad arguments + lua_pushnil(luaVM); + return 1; +} + int CLuaGUIDefs::GUILabelGetTextExtent(lua_State* luaVM) { // float guiLabelGetTextExtent ( element theLabel ) @@ -3759,23 +3577,79 @@ int CLuaGUIDefs::GUIGetChatboxLayout(lua_State* luaVM) if (!argStream.HasErrors()) { - ss.clear(); - ss.str(strCVar); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - lua_setfield(luaVM, -2, "chat_text_color"); + // Loop through all CVars + for (unsigned int i = 0; i < MAX_CHATBOX_LAYOUT_CVARS; i++) + { + // If we are asking for all CVars, or we can match the requested CVar with this CVar + if (bAll || !stricmp(g_chatboxLayoutCVars[i], strCVarArg)) + { + // Push color values into a table + if (g_chatboxLayoutCVars[i] == "chat_color" || + g_chatboxLayoutCVars[i] == "chat_text_color" || + g_chatboxLayoutCVars[i] == "chat_input_color" || + g_chatboxLayoutCVars[i] == "chat_input_prefix_color" || + g_chatboxLayoutCVars[i] == "chat_input_text_color") + { + pCVars->Get(g_chatboxLayoutCVars[i], strCVarValue); + if (!strCVarValue.empty()) + { + ss.clear(); + ss.str(strCVarValue); + ss >> iR >> iG >> iB >> iA; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, iR); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, iG); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 3); + lua_pushnumber(luaVM, iB); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 4); + lua_pushnumber(luaVM, iA); + lua_settable(luaVM, -3); + } + } + // Push chat scale into a table + else if (g_chatboxLayoutCVars[i] == "chat_scale") + { + pCVars->Get(g_chatboxLayoutCVars[i], strCVarValue); + if (!strCVarValue.empty()) + { + float fX, fY; + ss.clear(); + ss.str(strCVarValue); + ss >> fX >> fY; + lua_newtable(luaVM); + lua_pushnumber(luaVM, 1); + lua_pushnumber(luaVM, fX); + lua_settable(luaVM, -3); + lua_pushnumber(luaVM, 2); + lua_pushnumber(luaVM, fY); + lua_settable(luaVM, -3); + } + } + else + { + pCVars->Get(g_chatboxLayoutCVars[i], fNumber); + if (g_chatboxLayoutCVars[i] == "chat_use_cegui") + lua_pushboolean(luaVM, fNumber ? true : false); + else + lua_pushnumber(luaVM, fNumber); + } + + // If we are asking for all CVars, push this into the table with its CVar name, otherwise just stop here + if (bAll) + lua_setfield(luaVM, -2, g_chatboxLayoutCVars[i]); + else + return 1; + } + } + + // We wanted all CVars and that's done so let's stop now + if (bAll) + return 1; } else m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); @@ -4133,450 +4007,3 @@ int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); return 1; } - -static const SFixedArray g_chatboxLayoutCVars = { { - "chat_font", - "chat_lines", - "chat_color", - "chat_text_color", - "chat_input_color", - "chat_input_prefix_color", - "chat_input_text_color", - "chat_scale", - "chat_position_offset_x", - "chat_position_offset_y", - "chat_position_horizontal", - "chat_position_vertical", - "chat_text_alignment", - "chat_width", - "chat_css_style_text", - "chat_css_style_background", - "chat_line_life", - "chat_line_fade_out", - "chat_use_cegui", - "text_scale" - } }; - - std::map functions{ - { "guiGetInputEnabled", GUIGetInputEnabled }, - { "guiSetInputEnabled", GUISetInputEnabled }, - { "guiGetInputMode", GUIGetInputMode }, - { "guiSetInputMode", GUISetInputMode }, - { "isChatBoxInputActive", GUIIsChatBoxInputActive }, - { "isConsoleActive", GUIIsConsoleActive }, - { "isDebugViewActive", GUIIsDebugViewActive }, - { "setDebugViewActive", GUISetDebugViewActive }, - { "isMainMenuActive", GUIIsMainMenuActive }, - { "isMTAWindowActive", GUIIsMTAWindowActive }, - { "isTransferBoxActive", GUIIsTransferBoxActive }, - { "isTransferBoxEnabled", GUIIsTransferBoxEnabled }, - { "setTransferBoxEnabled", GUISetTransferBoxEnabled }, - { "guiCreateWindow", GUICreateWindow }, - { "guiCreateLabel", GUICreateLabel }, - { "guiCreateButton", GUICreateButton }, - { "guiCreateEdit", GUICreateEdit }, - { "guiCreateMemo", GUICreateMemo }, - { "guiCreateGridList", GUICreateGridList }, - { "guiCreateScrollPane", GUICreateScrollPane }, - { "guiCreateScrollBar", GUICreateScrollBar }, - { "guiCreateTabPanel", GUICreateTabPanel }, - { "guiCreateTab", GUICreateTab }, - { "guiCreateProgressBar", GUICreateProgressBar }, - { "guiCreateCheckBox", GUICreateCheckBox }, - { "guiCreateRadioButton", GUICreateRadioButton }, - { "guiCreateStaticImage", GUICreateStaticImage }, - { "guiCreateComboBox", GUICreateComboBox }, - { "guiCreateFont", GUICreateFont }, - { "guiStaticImageLoadImage", GUIStaticImageLoadImage }, - { "guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize }, - { "guiGetSelectedTab", GUIGetSelectedTab }, - { "guiSetSelectedTab", GUISetSelectedTab }, - { "guiDeleteTab", GUIDeleteTab }, - { "guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled }, - { "guiGridListAddColumn", GUIGridListAddColumn }, - { "guiGridListRemoveColumn", GUIGridListRemoveColumn }, - { "guiGridListSetColumnWidth", GUIGridListSetColumnWidth }, - { "guiGridListGetColumnWidth", GUIGridListGetColumnWidth }, - { "guiGridListSetColumnTitle", GUIGridListSetColumnTitle }, - { "guiGridListGetColumnTitle", GUIGridListGetColumnTitle }, - { "guiGridListSetScrollBars", GUIGridListSetScrollBars }, - { "guiGridListGetRowCount", GUIGridListGetRowCount }, - { "guiGridListGetColumnCount", GUIGridListGetColumnCount }, - { "guiGridListAddRow", GUIGridListAddRow }, - { "guiGridListInsertRowAfter", GUIGridListInsertRowAfter }, - { "guiGridListRemoveRow", GUIGridListRemoveRow }, - { "guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn }, - { "guiGridListClear", GUIGridListClear }, - { "guiGridListSetItemText", GUIGridListSetItemText }, - { "guiGridListGetItemText", GUIGridListGetItemText }, - { "guiGridListSetItemData", GUIGridListSetItemData }, - { "guiGridListGetItemData", GUIGridListGetItemData }, - { "guiGridListSetItemColor", GUIGridListSetItemColor }, - { "guiGridListGetItemColor", GUIGridListGetItemColor }, - { "guiGridListSetSelectionMode", GUIGridListSetSelectionMode }, - { "guiGridListGetSelectedItem", GUIGridListGetSelectedItem }, - { "guiGridListGetSelectedItems", GUIGridListGetSelectedItems }, - { "guiGridListGetSelectedCount", GUIGridListGetSelectedCount }, - { "guiGridListSetSelectedItem", GUIGridListSetSelectedItem }, - { "guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition }, - { "guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition }, - { "guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition }, - { "guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition }, - { "guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars }, - { "guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition }, - { "guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition }, - { "guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition }, - { "guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition }, - { "guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition }, - { "guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition }, - { "guiSetEnabled", GUISetEnabled }, - { "guiSetProperty", GUISetProperty }, - { "guiSetAlpha", GUISetAlpha }, - { "guiSetText", GUISetText }, - { "guiSetFont", GUISetFont }, - { "guiSetSize", GUISetSize }, - { "guiSetPosition", GUISetPosition }, - { "guiSetVisible", GUISetVisible }, - { "guiBringToFront", GUIBringToFront }, - { "guiMoveToBack", GUIMoveToBack }, - { "guiCheckBoxSetSelected", GUICheckBoxSetSelected }, - { "guiRadioButtonSetSelected", GUIRadioButtonSetSelected }, - { "guiGetEnabled", GUIGetEnabled }, - { "guiGetProperty", GUIGetProperty }, - { "guiGetProperties", GUIGetProperties }, - { "guiGetAlpha", GUIGetAlpha }, - { "guiGetText", GUIGetText }, - { "guiGetFont", GUIGetFont }, - { "guiGetSize", GUIGetSize }, - { "guiGetPosition", GUIGetPosition }, - { "guiGetVisible", GUIGetVisible }, - { "guiGetCursorType", GUIGetCursorType }, - { "guiCheckBoxGetSelected", GUICheckBoxGetSelected }, - { "guiRadioButtonGetSelected", GUIRadioButtonGetSelected }, - { "guiProgressBarSetProgress", GUIProgressBarSetProgress }, - { "guiProgressBarGetProgress", GUIProgressBarGetProgress }, - { "guiGetScreenSize", GUIGetScreenSize }, - { "guiEditSetCaretIndex", GUIEditSetCaretIndex }, - { "guiEditGetCaretIndex", GUIEditGetCaretIndex }, - { "guiEditSetMasked", GUIEditSetMasked }, - { "guiEditIsMasked", GUIEditIsMasked }, - { "guiEditSetMaxLength", GUIEditSetMaxLength }, - { "guiEditGetMaxLength", GUIEditGetMaxLength }, - { "guiEditSetReadOnly", GUIEditSetReadOnly }, - { "guiEditIsReadOnly", GUIEditIsReadOnly }, - { "guiMemoSetCaretIndex", GUIMemoSetCaretIndex }, - { "guiMemoGetCaretIndex", GUIMemoGetCaretIndex }, - { "guiMemoSetReadOnly", GUIMemoSetReadOnly }, - { "guiMemoIsReadOnly", GUIMemoIsReadOnly }, - { "guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition }, - { "guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition }, - { "guiLabelSetColor", GUILabelSetColor }, - { "guiLabelGetColor", GUILabelGetColor }, - { "guiLabelSetVerticalAlign", GUILabelSetVerticalAlign }, - { "guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign }, - { "guiLabelGetTextExtent", GUILabelGetTextExtent }, - { "guiLabelGetFontHeight", GUILabelGetFontHeight }, - { "guiWindowSetMovable", GUIWindowSetMovable }, - { "guiWindowSetSizable", GUIWindowSetSizable }, - { "guiWindowIsMovable", GUIWindowIsMovable }, - { "guiWindowIsSizable", GUIWindowIsSizable }, - { "getChatboxLayout", GUIGetChatboxLayout }, - { "guiComboBoxAddItem", GUIComboBoxAddItem }, - { "guiComboBoxRemoveItem", GUIComboBoxRemoveItem }, - { "guiComboBoxClear", GUIComboBoxClear }, - { "guiComboBoxGetSelected", GUIComboBoxGetSelected }, - { "guiComboBoxSetSelected", GUIComboBoxSetSelected }, - { "guiComboBoxGetItemText", GUIComboBoxGetItemText }, - { "guiComboBoxSetItemText", GUIComboBoxSetItemText }, - { "guiComboBoxGetItemCount", GUIComboBoxGetItemCount }, - { "guiComboBoxSetOpen", GUIComboBoxSetOpen }, - { "guiComboBoxIsOpen", GUIComboBoxIsOpen }, - }; - - // Add functions - for (const auto& pair : functions) - { - CLuaCFunctions::AddFunction(pair.first, pair.second); - } -int CLuaGUIDefs::GUIEditIsMasked(lua_State* luaVM) -{ - //bool guiEditIsMasked(element theElement) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - bool masked = static_cast(theElement->GetCGUIElement())->IsMasked(); - lua_pushboolean(luaVM, masked); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - -int CLuaGUIDefs::GUIWindowIsSizable(lua_State* luaVM) -{ - // bool guiWindowIsSizable( elemen theElement ) - CClientGUIElement* theElement; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(theElement); - - if (!argStream.HasErrors()) - { - bool sizable = static_cast(theElement->GetCGUIElement())->IsSizingEnabled(); - lua_pushboolean(luaVM, sizable); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -} - - // Loop through all CVars - for (unsigned int i = 0; i < MAX_CHATBOX_LAYOUT_CVARS; i++) - { - // If we are asking for all CVars, or we can match the requested CVar with this CVar - if (bAll || !stricmp(g_chatboxLayoutCVars[i], strCVarArg)) - { - // Push color values into a table - if (g_chatboxLayoutCVars[i] == "chat_color" || - g_chatboxLayoutCVars[i] == "chat_text_color" || - g_chatboxLayoutCVars[i] == "chat_input_color" || - g_chatboxLayoutCVars[i] == "chat_input_prefix_color" || - g_chatboxLayoutCVars[i] == "chat_input_text_color") - { - pCVars->Get(g_chatboxLayoutCVars[i], strCVarValue); - if (!strCVarValue.empty()) - { - ss.clear(); - ss.str(strCVarValue); - ss >> iR >> iG >> iB >> iA; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, iR); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, iG); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 3); - lua_pushnumber(luaVM, iB); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 4); - lua_pushnumber(luaVM, iA); - lua_settable(luaVM, -3); - } - } - // Push chat scale into a table - else if (g_chatboxLayoutCVars[i] == "chat_scale") - { - pCVars->Get(g_chatboxLayoutCVars[i], strCVarValue); - if (!strCVarValue.empty()) - { - float fX, fY; - ss.clear(); - ss.str(strCVarValue); - ss >> fX >> fY; - lua_newtable(luaVM); - lua_pushnumber(luaVM, 1); - lua_pushnumber(luaVM, fX); - lua_settable(luaVM, -3); - lua_pushnumber(luaVM, 2); - lua_pushnumber(luaVM, fY); - lua_settable(luaVM, -3); - } - } - else - { - pCVars->Get(g_chatboxLayoutCVars[i], fNumber); - if (g_chatboxLayoutCVars[i] == "chat_use_cegui") - lua_pushboolean(luaVM, fNumber ? true : false); - else - lua_pushnumber(luaVM, fNumber); - } - - // If we are asking for all CVars, push this into the table with its CVar name, otherwise just stop here - if (bAll) - lua_setfield(luaVM, -2, g_chatboxLayoutCVars[i]); - else - return 1; - } - } - - // We wanted all CVars and that's done so let's stop now - if (bAll) - return 1; - CLuaCFunctions::AddFunction("guiGetInputEnabled", GUIGetInputEnabled); - CLuaCFunctions::AddFunction("guiSetInputEnabled", GUISetInputEnabled); - CLuaCFunctions::AddFunction("guiGetInputMode", GUIGetInputMode); - CLuaCFunctions::AddFunction("guiSetInputMode", GUISetInputMode); - - CLuaCFunctions::AddFunction("isChatBoxInputActive", GUIIsChatBoxInputActive); - CLuaCFunctions::AddFunction("isConsoleActive", GUIIsConsoleActive); - CLuaCFunctions::AddFunction("isDebugViewActive", GUIIsDebugViewActive); - CLuaCFunctions::AddFunction("setDebugViewActive", GUISetDebugViewActive); - CLuaCFunctions::AddFunction("isMainMenuActive", GUIIsMainMenuActive); - CLuaCFunctions::AddFunction("isMTAWindowActive", GUIIsMTAWindowActive); - CLuaCFunctions::AddFunction("isTransferBoxActive", GUIIsTransferBoxActive); - - CLuaCFunctions::AddFunction("guiCreateWindow", GUICreateWindow); - CLuaCFunctions::AddFunction("guiCreateLabel", GUICreateLabel); - CLuaCFunctions::AddFunction("guiCreateButton", GUICreateButton); - CLuaCFunctions::AddFunction("guiCreateEdit", GUICreateEdit); - CLuaCFunctions::AddFunction("guiCreateMemo", GUICreateMemo); - CLuaCFunctions::AddFunction("guiCreateGridList", GUICreateGridList); - CLuaCFunctions::AddFunction("guiCreateScrollPane", GUICreateScrollPane); - CLuaCFunctions::AddFunction("guiCreateScrollBar", GUICreateScrollBar); - CLuaCFunctions::AddFunction("guiCreateTabPanel", GUICreateTabPanel); - CLuaCFunctions::AddFunction("guiCreateTab", GUICreateTab); - CLuaCFunctions::AddFunction("guiCreateProgressBar", GUICreateProgressBar); - CLuaCFunctions::AddFunction("guiCreateCheckBox", GUICreateCheckBox); - CLuaCFunctions::AddFunction("guiCreateRadioButton", GUICreateRadioButton); - CLuaCFunctions::AddFunction("guiCreateStaticImage", GUICreateStaticImage); - CLuaCFunctions::AddFunction("guiCreateComboBox", GUICreateComboBox); - CLuaCFunctions::AddFunction("guiCreateFont", GUICreateFont); - - CLuaCFunctions::AddFunction("guiStaticImageLoadImage", GUIStaticImageLoadImage); - CLuaCFunctions::AddFunction("guiStaticImageGetNativeSize", GUIStaticImageGetNativeSize); - CLuaCFunctions::AddFunction("guiGetSelectedTab", GUIGetSelectedTab); - CLuaCFunctions::AddFunction("guiSetSelectedTab", GUISetSelectedTab); - CLuaCFunctions::AddFunction("guiDeleteTab", GUIDeleteTab); - - CLuaCFunctions::AddFunction("guiGridListSetSortingEnabled", GUIGridListSetSortingEnabled); - CLuaCFunctions::AddFunction("guiGridListAddColumn", GUIGridListAddColumn); - CLuaCFunctions::AddFunction("guiGridListRemoveColumn", GUIGridListRemoveColumn); - CLuaCFunctions::AddFunction("guiGridListSetColumnWidth", GUIGridListSetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListGetColumnWidth", GUIGridListGetColumnWidth); - CLuaCFunctions::AddFunction("guiGridListSetColumnTitle", GUIGridListSetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListGetColumnTitle", GUIGridListGetColumnTitle); - CLuaCFunctions::AddFunction("guiGridListSetScrollBars", GUIGridListSetScrollBars); - CLuaCFunctions::AddFunction("guiGridListGetRowCount", GUIGridListGetRowCount); - CLuaCFunctions::AddFunction("guiGridListGetColumnCount", GUIGridListGetColumnCount); - CLuaCFunctions::AddFunction("guiGridListAddRow", GUIGridListAddRow); - CLuaCFunctions::AddFunction("guiGridListInsertRowAfter", GUIGridListInsertRowAfter); - CLuaCFunctions::AddFunction("guiGridListRemoveRow", GUIGridListRemoveRow); - CLuaCFunctions::AddFunction("guiGridListAutoSizeColumn", GUIGridListAutoSizeColumn); - CLuaCFunctions::AddFunction("guiGridListClear", GUIGridListClear); - CLuaCFunctions::AddFunction("guiGridListSetItemText", GUIGridListSetItemText); - CLuaCFunctions::AddFunction("guiGridListGetItemText", GUIGridListGetItemText); - CLuaCFunctions::AddFunction("guiGridListSetItemData", GUIGridListSetItemData); - CLuaCFunctions::AddFunction("guiGridListGetItemData", GUIGridListGetItemData); - CLuaCFunctions::AddFunction("guiGridListSetItemColor", GUIGridListSetItemColor); - CLuaCFunctions::AddFunction("guiGridListGetItemColor", GUIGridListGetItemColor); - CLuaCFunctions::AddFunction("guiGridListSetSelectionMode", GUIGridListSetSelectionMode); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItem", GUIGridListGetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListGetSelectedItems", GUIGridListGetSelectedItems); - CLuaCFunctions::AddFunction("guiGridListGetSelectedCount", GUIGridListGetSelectedCount); - CLuaCFunctions::AddFunction("guiGridListSetSelectedItem", GUIGridListSetSelectedItem); - CLuaCFunctions::AddFunction("guiGridListSetHorizontalScrollPosition", GUIGridListSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetHorizontalScrollPosition", GUIGridListGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListSetVerticalScrollPosition", GUIGridListSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiGridListGetVerticalScrollPosition", GUIGridListGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollPaneSetScrollBars", GUIScrollPaneSetScrollBars); - CLuaCFunctions::AddFunction("guiScrollPaneSetHorizontalScrollPosition", GUIScrollPaneSetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetHorizontalScrollPosition", GUIScrollPaneGetHorizontalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneSetVerticalScrollPosition", GUIScrollPaneSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiScrollPaneGetVerticalScrollPosition", GUIScrollPaneGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiScrollBarSetScrollPosition", GUIScrollBarSetScrollPosition); - CLuaCFunctions::AddFunction("guiScrollBarGetScrollPosition", GUIScrollBarGetScrollPosition); - - CLuaCFunctions::AddFunction("guiSetEnabled", GUISetEnabled); - CLuaCFunctions::AddFunction("guiSetProperty", GUISetProperty); - CLuaCFunctions::AddFunction("guiSetAlpha", GUISetAlpha); - CLuaCFunctions::AddFunction("guiSetText", GUISetText); - CLuaCFunctions::AddFunction("guiSetFont", GUISetFont); - CLuaCFunctions::AddFunction("guiSetSize", GUISetSize); - CLuaCFunctions::AddFunction("guiSetPosition", GUISetPosition); - CLuaCFunctions::AddFunction("guiSetVisible", GUISetVisible); - - CLuaCFunctions::AddFunction("guiBringToFront", GUIBringToFront); - CLuaCFunctions::AddFunction("guiMoveToBack", GUIMoveToBack); - - CLuaCFunctions::AddFunction("guiCheckBoxSetSelected", GUICheckBoxSetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonSetSelected", GUIRadioButtonSetSelected); - - CLuaCFunctions::AddFunction("guiGetEnabled", GUIGetEnabled); - CLuaCFunctions::AddFunction("guiGetProperty", GUIGetProperty); - CLuaCFunctions::AddFunction("guiGetProperties", GUIGetProperties); - CLuaCFunctions::AddFunction("guiGetAlpha", GUIGetAlpha); - CLuaCFunctions::AddFunction("guiGetText", GUIGetText); - CLuaCFunctions::AddFunction("guiGetFont", GUIGetFont); - CLuaCFunctions::AddFunction("guiGetSize", GUIGetSize); - CLuaCFunctions::AddFunction("guiGetPosition", GUIGetPosition); - CLuaCFunctions::AddFunction("guiGetVisible", GUIGetVisible); - CLuaCFunctions::AddFunction("guiGetCursorType", GUIGetCursorType); - - CLuaCFunctions::AddFunction("guiCheckBoxGetSelected", GUICheckBoxGetSelected); - CLuaCFunctions::AddFunction("guiRadioButtonGetSelected", GUIRadioButtonGetSelected); - - CLuaCFunctions::AddFunction("guiProgressBarSetProgress", GUIProgressBarSetProgress); - CLuaCFunctions::AddFunction("guiProgressBarGetProgress", GUIProgressBarGetProgress); - - CLuaCFunctions::AddFunction("guiGetScreenSize", GUIGetScreenSize); - - CLuaCFunctions::AddFunction("guiEditSetCaretIndex", GUIEditSetCaretIndex); - CLuaCFunctions::AddFunction("guiEditGetCaretIndex", GUIEditGetCaretIndex); - CLuaCFunctions::AddFunction("guiEditSetMasked", GUIEditSetMasked); - CLuaCFunctions::AddFunction("guiEditSetMaxLength", GUIEditSetMaxLength); - CLuaCFunctions::AddFunction("guiEditSetReadOnly", GUIEditSetReadOnly); - CLuaCFunctions::AddFunction("guiEditIsReadOnly", GUIEditIsReadOnly); - - CLuaCFunctions::AddFunction("guiMemoSetCaretIndex", GUIMemoSetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoGetCaretIndex", GUIMemoGetCaretIndex); - CLuaCFunctions::AddFunction("guiMemoSetReadOnly", GUIMemoSetReadOnly); - CLuaCFunctions::AddFunction("guiMemoIsReadOnly", GUIMemoIsReadOnly); - CLuaCFunctions::AddFunction("guiMemoSetVerticalScrollPosition", GUIMemoSetVerticalScrollPosition); - CLuaCFunctions::AddFunction("guiMemoGetVerticalScrollPosition", GUIMemoGetVerticalScrollPosition); - - CLuaCFunctions::AddFunction("guiLabelSetColor", GUILabelSetColor); - CLuaCFunctions::AddFunction("guiLabelGetColor", GUILabelGetColor); - CLuaCFunctions::AddFunction("guiLabelSetVerticalAlign", GUILabelSetVerticalAlign); - CLuaCFunctions::AddFunction("guiLabelSetHorizontalAlign", GUILabelSetHorizontalAlign); - - CLuaCFunctions::AddFunction("guiLabelGetTextExtent", GUILabelGetTextExtent); - CLuaCFunctions::AddFunction("guiLabelGetFontHeight", GUILabelGetFontHeight); - - CLuaCFunctions::AddFunction("guiWindowSetMovable", GUIWindowSetMovable); - CLuaCFunctions::AddFunction("guiWindowSetSizable", GUIWindowSetSizable); - - CLuaCFunctions::AddFunction("getChatboxLayout", GUIGetChatboxLayout); - - CLuaCFunctions::AddFunction("guiComboBoxAddItem", GUIComboBoxAddItem); - CLuaCFunctions::AddFunction("guiComboBoxRemoveItem", GUIComboBoxRemoveItem); - CLuaCFunctions::AddFunction("guiComboBoxClear", GUIComboBoxClear); - CLuaCFunctions::AddFunction("guiComboBoxGetSelected", GUIComboBoxGetSelected); - CLuaCFunctions::AddFunction("guiComboBoxSetSelected", GUIComboBoxSetSelected); - CLuaCFunctions::AddFunction("guiComboBoxGetItemText", GUIComboBoxGetItemText); - CLuaCFunctions::AddFunction("guiComboBoxSetItemText", GUIComboBoxSetItemText); -int CLuaGUIDefs::GUIEditIsReadOnly(lua_State* luaVM) -{ - // bool guiEditIsReadOnly( element editField ) - CClientGUIElement* editField; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(editField); - - if (!argStream.HasErrors()) - { - bool readOnly = static_cast(editField->GetCGUIElement())->IsReadOnly(); - lua_pushboolean(luaVM, readOnly); - return 1; - } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // error: bad arguments - lua_pushnil(luaVM); - return 1; -int CLuaGUIDefs::GUIMemoIsReadOnly(lua_State* luaVM) \ No newline at end of file From bcc50db6b8e05460a25f898d0db83c7323d6eb73 Mon Sep 17 00:00:00 2001 From: Patrik Juvonen Date: Sat, 23 Feb 2019 23:48:59 +0200 Subject: [PATCH 25/27] Clean up the PR, see further details * Create and use new allow_server_control_transferbox setting * Toggling between custom and native transfer box works by clicking on the checkbox mid-transfer too, unless client is hanging of course * Add onClientTransferBoxProgressChange event * Use const where possible * Use CGUI class as the base for enabled state of transfer box instead of duplicating logic over to CTransferBox (which didn't even work) * Don't reset transfer total size in Show function, it breaks when toggling the setting off, * Clean up project comments, clang format --- Client/core/CSettings.cpp | 50 ++++++++++++------- Client/core/CSettings.h | 6 +-- Client/gui/CGUI_Impl.h | 7 +-- Client/mods/deathmatch/logic/CClientGame.cpp | 2 + .../logic/CResourceFileDownloadManager.cpp | 23 ++++++--- .../logic/CResourceFileDownloadManager.h | 2 +- Client/mods/deathmatch/logic/CTransferBox.cpp | 43 +++++++++------- Client/mods/deathmatch/logic/CTransferBox.h | 23 +++------ Client/sdk/gui/CGUI.h | 20 ++++---- 9 files changed, 102 insertions(+), 74 deletions(-) diff --git a/Client/core/CSettings.cpp b/Client/core/CSettings.cpp index c306f912a8d..0302a3a525a 100644 --- a/Client/core/CSettings.cpp +++ b/Client/core/CSettings.cpp @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: core/CSettings.cpp * PURPOSE: In-game settings window @@ -14,11 +14,11 @@ using namespace std; -#define CORE_MTA_FILLER "cgui\\images\\mta_filler.png" -#define CORE_SETTINGS_UPDATE_INTERVAL 30 // Settings update interval in frames -#define CORE_SETTINGS_HEADERS 3 -#define CORE_SETTINGS_HEADER_SPACER " " -#define CORE_SETTINGS_NO_KEY " " +#define CORE_MTA_FILLER "cgui\\images\\mta_filler.png" +#define CORE_SETTINGS_UPDATE_INTERVAL 30 // Settings update interval in frames +#define CORE_SETTINGS_HEADERS 3 +#define CORE_SETTINGS_HEADER_SPACER " " +#define CORE_SETTINGS_NO_KEY " " extern CCore* g_pCore; extern SBindableGTAControl g_bcControls[]; @@ -376,10 +376,11 @@ void CSettings::CreateGUI() m_pCheckBoxAllowScreenUpload->GetPosition(vecTemp, false); m_pCheckBoxAllowScreenUpload->AutoSize(NULL, 20.0f); - m_pCheckBoxAllowControlTransferBox = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Allow server to control transfer box"), true)); - m_pCheckBoxAllowControlTransferBox->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); - m_pCheckBoxAllowControlTransferBox->GetPosition(vecTemp, false); - m_pCheckBoxAllowControlTransferBox->AutoSize(NULL, 20.0f); + m_pCheckBoxAllowTransferBoxControl = + reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Allow server to control transfer box"), true)); + m_pCheckBoxAllowTransferBoxControl->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); + m_pCheckBoxAllowTransferBoxControl->GetPosition(vecTemp, false); + m_pCheckBoxAllowTransferBoxControl->AutoSize(NULL, 20.0f); m_pCheckBoxCustomizedSAFiles = reinterpret_cast(pManager->CreateCheckBox(pTabMultiplayer, _("Use customized GTA:SA files"), true)); m_pCheckBoxCustomizedSAFiles->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f)); @@ -1096,7 +1097,7 @@ void CSettings::CreateGUI() // Hide if not Win8 if (atoi(GetApplicationSetting("real-os-version")) != 8) { -#ifndef MTA_DEBUG // Don't hide when debugging +#ifndef MTA_DEBUG // Don't hide when debugging m_pWin8Label->SetVisible(false); m_pWin8ColorCheckBox->SetVisible(false); m_pWin8MouseCheckBox->SetVisible(false); @@ -1208,6 +1209,7 @@ void CSettings::CreateGUI() m_pComboFxQuality->SetSelectionHandler(GUI_CALLBACK(&CSettings::OnFxQualityChanged, this)); m_pCheckBoxVolumetricShadows->SetClickHandler(GUI_CALLBACK(&CSettings::OnVolumetricShadowsClick, this)); m_pCheckBoxAllowScreenUpload->SetClickHandler(GUI_CALLBACK(&CSettings::OnAllowScreenUploadClick, this)); + m_pCheckBoxAllowTransferBoxControl->SetClickHandler(GUI_CALLBACK(&CSettings::OnAllowTransferBoxControl, this)); m_pCheckBoxCustomizedSAFiles->SetClickHandler(GUI_CALLBACK(&CSettings::OnCustomizedSAFilesClick, this)); m_pCheckBoxWindowed->SetClickHandler(GUI_CALLBACK(&CSettings::OnWindowedClick, this)); m_pCheckBoxShowUnsafeResolutions->SetClickHandler(GUI_CALLBACK(&CSettings::ShowUnsafeResolutionsClick, this)); @@ -1498,7 +1500,7 @@ void CSettings::UpdateVideoTab() // Allow screen upload bool bAllowServerTransferBoxControl; CVARS_GET("allow_server_control_transferbox", bAllowServerTransferBoxControl); - m_pCheckBoxAllowControlTransferBox->SetSelected(bAllowServerTransferBoxControl); + m_pCheckBoxAllowTransferBoxControl->SetSelected(bAllowServerTransferBoxControl); // Customized sa files m_pCheckBoxCustomizedSAFiles->SetSelected(GetApplicationSettingInt("customized-sa-files-request") != 0); @@ -3308,8 +3310,8 @@ void CSettings::SaveData() CVARS_SET("allow_screen_upload", bAllowScreenUploadEnabled); // Allow screen upload - bool m_pCheckBoxAllowScreenUpload = m_pCheckBoxAllowControlTransferBox->GetSelected(); - CVARS_SET("allow_server_control_transferbox", m_pCheckBoxAllowScreenUpload); + bool bAllowServerTransferBoxControl = m_pCheckBoxAllowTransferBoxControl->GetSelected(); + CVARS_SET("allow_server_control_transferbox", bAllowServerTransferBoxControl); // Grass bool bGrassEnabled = m_pCheckBoxGrass->GetSelected(); @@ -4308,6 +4310,21 @@ bool CSettings::OnAllowScreenUploadClick(CGUIElement* pElement) return true; } +// +// AllowTransferBoxControl +// +bool CSettings::OnAllowTransferBoxControl(CGUIElement* pElement) +{ + bool bAllowTransferBoxControl = m_pCheckBoxAllowTransferBoxControl->GetSelected(); + CVARS_SET("allow_server_control_transferbox", bAllowTransferBoxControl); + + // Enable default transfer box now if script control is disabled + if (!bAllowTransferBoxControl) + g_pCore->GetGUI()->SetTransferBoxEnabled(true); + + return true; +} + // // CustomizedSAFiles // @@ -4548,8 +4565,3 @@ bool CSettings::IsActive() { return m_pWindow->IsActive(); } - -bool CSettings::IsTransferBoxControlEnabled() -{ - return bAllowScreenUploadEnabled; -} diff --git a/Client/core/CSettings.h b/Client/core/CSettings.h index 907780be101..3bd3a2788da 100644 --- a/Client/core/CSettings.h +++ b/Client/core/CSettings.h @@ -117,7 +117,6 @@ class CSettings void TabSkip(bool bBackwards); bool IsActive(); - bool IsTransferBoxControlEnabled(); void SetSelectedIndex(unsigned int uiIndex); @@ -152,7 +151,7 @@ class CSettings CGUICheckBox* m_pCheckBoxDeviceSelectionDialog; CGUICheckBox* m_pCheckBoxShowUnsafeResolutions; CGUICheckBox* m_pCheckBoxAllowScreenUpload; - CGUICheckBox* m_pCheckBoxAllowControlTransferBox; + CGUICheckBox* m_pCheckBoxAllowTransferBoxControl; CGUICheckBox* m_pCheckBoxCustomizedSAFiles; CGUICheckBox* m_pCheckBoxGrass; CGUICheckBox* m_pCheckBoxHeatHaze; @@ -377,6 +376,7 @@ class CSettings bool OnFxQualityChanged(CGUIElement* pElement); bool OnVolumetricShadowsClick(CGUIElement* pElement); bool OnAllowScreenUploadClick(CGUIElement* pElement); + bool OnAllowTransferBoxControl(CGUIElement* pElement); bool OnCustomizedSAFilesClick(CGUIElement* pElement); bool ShowUnsafeResolutionsClick(CGUIElement* pElement); bool OnWindowedClick(CGUIElement* pElement); @@ -445,6 +445,4 @@ class CSettings int m_iMaxAnisotropic; std::list m_pKeyBindSections; - - bool bAllowServerTransferBoxControl; }; diff --git a/Client/gui/CGUI_Impl.h b/Client/gui/CGUI_Impl.h index 74f5ddc6c74..f5ca743d855 100644 --- a/Client/gui/CGUI_Impl.h +++ b/Client/gui/CGUI_Impl.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: gui/CGUI_Impl.h * PURPOSE: Graphical User Interface module class @@ -255,10 +255,11 @@ class CGUI_Impl : public CGUI, public CGUITabList void ClearInputHandlers(eInputChannel channel); void ClearSystemKeys(); - bool IsTransferBoxVisible() { return m_bTransferBoxVisible; }; + bool IsTransferBoxVisible() const { return m_bTransferBoxVisible; }; void SetTransferBoxVisible(bool bVisible) { m_bTransferBoxVisible = bVisible; }; + + bool IsTransferBoxEnabled() const { return m_bTransferBoxEnabled; }; void SetTransferBoxEnabled(bool bEnabled) { m_bTransferBoxEnabled = bEnabled; }; - bool IsTransferBoxEnabled() { return m_bTransferBoxEnabled; }; bool Event_CharacterKey(const CEGUI::EventArgs& e); bool Event_KeyDown(const CEGUI::EventArgs& e); diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 153b4670ea1..8a30b2b73e9 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -2901,6 +2901,8 @@ void CClientGame::AddBuiltInEvents() // Misc events m_Events.AddEvent("onClientFileDownloadComplete", "fileName, success", NULL, false); + m_Events.AddEvent("onClientTransferBoxProgressChange", "downloaded, total", NULL, false); + m_Events.AddEvent("onClientWeaponFire", "ped, x, y, z", NULL, false); m_Events.AddEvent("onClientWorldSound", "group, index, x, y, z", nullptr, false); diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp index 4066e788bc6..37bfcf89466 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp @@ -136,15 +136,26 @@ void CResourceFileDownloadManager::DoPulse() return; } + bool bAllowTransferBoxControl = g_pCore->GetCVars()->GetValue("allow_server_control_transferbox", false); + if (!bAllowTransferBoxControl && !GetTransferBox()->IsEnabled()) + GetTransferBox()->SetEnabled(true); + + if (GetTransferBox()->IsEnabled() && !GetTransferBox()->IsVisible()) + GetTransferBox()->Show(); + // Update progress box GetTransferBox()->SetInfo(uiDownloadSizeTotal); GetTransferBox()->DoPulse(); - CLuaArguments Arguments; - Arguments.PushNumber(uiDownloadSizeTotal); - Arguments.PushNumber(GetTransferBox()->GetTotalSize()); - g_pClientGame->GetLocalPlayer()->CallEvent("onTransferBoxProgressChange", Arguments, false); - + // Call onClientTransferBoxProgressChange if client allows control over it + if (bAllowTransferBoxControl) + { + CLuaArguments Arguments; + Arguments.PushNumber(uiDownloadSizeTotal); + Arguments.PushNumber(GetTransferBox()->GetTotalSize()); + g_pClientGame->GetLocalPlayer()->CallEvent("onClientTransferBoxProgressChange", Arguments, false); + } + // Check if completed downloading current group if (m_ActiveFileDownloadList.empty()) { @@ -233,7 +244,7 @@ bool CResourceFileDownloadManager::BeginResourceFileDownload(CDownloadableResour options.bIsLocal = g_pClientGame->IsLocalGame(); SString* pstrContext = MakeDownloadContextString(pResourceFile); SString strFilename = pResourceFile->GetName(); - bool bUniqueDownload = pHTTP->QueueFile(strHTTPDownloadURLFull, strFilename, pstrContext, StaticDownloadFinished, options); + bool bUniqueDownload = pHTTP->QueueFile(strHTTPDownloadURLFull, strFilename, pstrContext, StaticDownloadFinished, options); if (!bUniqueDownload) { // TODO - If piggybacking on another matching download, then adjust progress bar diff --git a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.h b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.h index 3ba041eb8e4..d57aedff6d0 100644 --- a/Client/mods/deathmatch/logic/CResourceFileDownloadManager.h +++ b/Client/mods/deathmatch/logic/CResourceFileDownloadManager.h @@ -38,7 +38,7 @@ class CResourceFileDownloadManager void DownloadFinished(const SHttpDownloadResult& result); SString* MakeDownloadContextString(CDownloadableResource* pDownloadableResource); CDownloadableResource* ResolveDownloadContextString(SString* pString); - double GetTotalSize() { return g_pClientGame->GetTransferBox()->GetTotalSize(); }; + double GetTotalSize() const { return g_pClientGame->GetTransferBox()->GetTotalSize(); }; std::vector m_PendingFileDownloadList; std::vector m_ActiveFileDownloadList; diff --git a/Client/mods/deathmatch/logic/CTransferBox.cpp b/Client/mods/deathmatch/logic/CTransferBox.cpp index ed04e26e557..14d7eb583a6 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.cpp +++ b/Client/mods/deathmatch/logic/CTransferBox.cpp @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: mods/deathmatch/logic/CTransferBox.cpp * PURPOSE: Transfer box GUI @@ -11,11 +11,11 @@ #include -#define TRANSFERBOX_HEIGHT 58 -#define TRANSFERBOX_ICONSIZE 20 -#define TRANSFERBOX_PROGRESSHEIGHT 28 -#define TRANSFERBOX_YSTART 20 -#define TRANSFERBOX_SPACER 11 +#define TRANSFERBOX_HEIGHT 58 +#define TRANSFERBOX_ICONSIZE 20 +#define TRANSFERBOX_PROGRESSHEIGHT 28 +#define TRANSFERBOX_YSTART 20 +#define TRANSFERBOX_SPACER 11 CTransferBox::CTransferBox() { @@ -83,26 +83,25 @@ CTransferBox::CTransferBox() CTransferBox::~CTransferBox() { for (unsigned int i = 0; i < TRANSFERBOX_FRAMES; i++) - { delete m_pIcon[i]; - } - if (m_pWindow != NULL) + if (m_pWindow != nullptr) delete m_pWindow; - if (m_pInfo != NULL) + + if (m_pInfo != nullptr) delete m_pInfo; - if (m_pProgress != NULL) + + if (m_pProgress != nullptr) delete m_pProgress; } void CTransferBox::Show() { - m_dTotalSize = 0; - if (IsEnabled()) - { - m_pWindow->SetVisible(true); - g_pCore->GetGUI()->SetTransferBoxVisible(true); - }; + if (!IsEnabled()) + return; + + m_pWindow->SetVisible(true); + g_pCore->GetGUI()->SetTransferBoxVisible(true); } void CTransferBox::Hide() @@ -113,6 +112,16 @@ void CTransferBox::Hide() m_dTotalSize = 0; } +bool CTransferBox::IsEnabled() const +{ + return g_pCore->GetGUI()->IsTransferBoxEnabled(); +} + +void CTransferBox::SetEnabled(bool bEnabled) const +{ + g_pCore->GetGUI()->SetTransferBoxEnabled(bEnabled); +} + void CTransferBox::SetInfo(double dDownloadSizeNow, CTransferBox::Type eTransferType) { // Convert to reasonable units diff --git a/Client/mods/deathmatch/logic/CTransferBox.h b/Client/mods/deathmatch/logic/CTransferBox.h index 9661cf46281..92104a66253 100644 --- a/Client/mods/deathmatch/logic/CTransferBox.h +++ b/Client/mods/deathmatch/logic/CTransferBox.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: mods/deathmatch/logic/CTransferBox.h * PURPOSE: Header for transfer box class @@ -11,11 +11,8 @@ #pragma once -#define TRANSFERBOX_FRAMES 10 -#define TRANSFERBOX_DELAY 50 - -#include "CClientCommon.h" -#include +#define TRANSFERBOX_FRAMES 10 +#define TRANSFERBOX_DELAY 50 class CTransferBox { @@ -34,18 +31,15 @@ class CTransferBox void Hide(); void SetInfo(double dDownloadSizeNow, CTransferBox::Type eTransferType = CTransferBox::NORMAL); - void DoPulse(); + bool IsVisible() const { return m_pWindow->IsVisible(); }; - bool OnCancelClick(CGUIElement* pElement); - - bool IsVisible() { return m_pWindow->IsVisible(); }; - bool IsEnabled() { return m_bEnabled; }; - void SetEnabled(bool bEnabled) { m_bEnabled = bEnabled; }; + bool IsEnabled() const; + void SetEnabled(bool bEnabled) const; - void AddToTotalSize(double dSize) { m_dTotalSize += dSize; }; + void AddToTotalSize(double dSize) { m_dTotalSize += dSize; }; + double GetTotalSize() const { return m_dTotalSize; }; - double GetTotalSize() { return m_dTotalSize; }; private: CGUIWindow* m_pWindow; SFixedArray m_pIcon; @@ -53,7 +47,6 @@ class CTransferBox CGUIProgressBar* m_pProgress; bool m_bMultipleDownloads; - bool m_bEnabled; unsigned int m_uiVisible; CElapsedTime m_AnimTimer; diff --git a/Client/sdk/gui/CGUI.h b/Client/sdk/gui/CGUI.h index 6906965af2b..5d6ee9ec8e2 100644 --- a/Client/sdk/gui/CGUI.h +++ b/Client/sdk/gui/CGUI.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * PROJECT: Multi Theft Auto v1.0 + * PROJECT: Multi Theft Auto * LICENSE: See LICENSE in the top level directory * FILE: sdk/gui/CGUI.h * PURPOSE: Graphical User Interface module interface @@ -38,14 +38,14 @@ class CGUI; #include "CGUITypes.h" // Path defines for CGUI -#define CGUI_ICON_MESSAGEBOX_INFO "cgui\\images\\info.png" -#define CGUI_ICON_MESSAGEBOX_QUESTION "cgui\\images\\question.png" -#define CGUI_ICON_MESSAGEBOX_WARNING "cgui\\images\\warning.png" -#define CGUI_ICON_MESSAGEBOX_ERROR "cgui\\images\\error.png" -#define CGUI_ICON_SERVER_PASSWORD "cgui\\images\\locked.png" +#define CGUI_ICON_MESSAGEBOX_INFO "cgui\\images\\info.png" +#define CGUI_ICON_MESSAGEBOX_QUESTION "cgui\\images\\question.png" +#define CGUI_ICON_MESSAGEBOX_WARNING "cgui\\images\\warning.png" +#define CGUI_ICON_MESSAGEBOX_ERROR "cgui\\images\\error.png" +#define CGUI_ICON_SERVER_PASSWORD "cgui\\images\\locked.png" #define CGUI_GetMaxTextExtent(...) GetMaxTextExtent(__VA_ARGS__, SString()) -#define CHECK_CHANNEL(channel) assert ( (channel) >= 0 && (channel) < INPUT_CHANNEL_COUNT ) +#define CHECK_CHANNEL(channel) assert((channel) >= 0 && (channel) < INPUT_CHANNEL_COUNT) class CGUI { @@ -164,9 +164,11 @@ class CGUI virtual void ClearInputHandlers(eInputChannel channel) = 0; virtual void ClearSystemKeys() = 0; - virtual bool IsTransferBoxVisible() = 0; + virtual bool IsTransferBoxVisible() const = 0; virtual void SetTransferBoxVisible(bool bVisible) = 0; - virtual bool IsTransferBoxEnabled() = 0; + + virtual bool IsTransferBoxEnabled() const = 0; + virtual void SetTransferBoxEnabled(bool bEnabled) = 0; virtual void CleanDeadPool() = 0; From db039829d6eea61e603f0844f9e3e3eda44c8851 Mon Sep 17 00:00:00 2001 From: Patrik Juvonen Date: Tue, 28 May 2019 23:32:13 +0300 Subject: [PATCH 26/27] Update make_uname.bat --- vendor/lua/src/make_uname.bat | 78 +++++++++++++++++------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/vendor/lua/src/make_uname.bat b/vendor/lua/src/make_uname.bat index 4c70b5740ce..c6e41c67d98 100644 --- a/vendor/lua/src/make_uname.bat +++ b/vendor/lua/src/make_uname.bat @@ -1,39 +1,39 @@ -@echo off -REM This builds all the libraries of the folder for 1 uname - -call tecmake %1 %2 %3 %4 %5 %6 %7 %8 - -if "%1"=="" goto luaexe -if "%1"=="vc6" goto luaexe -if "%1"=="vc8_64" goto luaexe_64 -if "%1"=="dll8_64" goto luadll8_64 -if "%1"=="dll" goto luadll -if "%1"=="all" goto luaexe -goto end - -:luaexe -call tecmake vc6 "MF=lua" %2 %3 %4 %5 %6 %7 -call tecmake vc6 "MF=luac" %2 %3 %4 %5 %6 %7 -call tecmake vc6 "MF=bin2c" %2 %3 %4 %5 %6 %7 -if "%1"=="all" goto luaexe_64 -goto end - -:luaexe_64 -call tecmake vc8_64 "MF=lua" %2 %3 %4 %5 %6 %7 -call tecmake vc8_64 "MF=luac" %2 %3 %4 %5 %6 %7 -call tecmake vc8_64 "MF=bin2c" %2 %3 %4 %5 %6 %7 -if "%1"=="all" goto luadll8_64 -goto end - -:luadll8_64 -copy /Y ..\lib\dll8_64\*.dll ..\bin\Win64 -if "%1"=="all" goto luadll -goto end - -:luadll -copy /Y ..\lib\dll\*.dll ..\bin\Win32 -call tecmake mingw3 mingw3-dll -call tecmake bc56 bc56-dll -goto end - -:end +@echo off +REM This builds all the libraries of the folder for 1 uname + +call tecmake %1 %2 %3 %4 %5 %6 %7 %8 + +if "%1"=="" goto luaexe +if "%1"=="vc6" goto luaexe +if "%1"=="vc8_64" goto luaexe_64 +if "%1"=="dll8_64" goto luadll8_64 +if "%1"=="dll" goto luadll +if "%1"=="all" goto luaexe +goto end + +:luaexe +call tecmake vc6 "MF=lua" %2 %3 %4 %5 %6 %7 +call tecmake vc6 "MF=luac" %2 %3 %4 %5 %6 %7 +call tecmake vc6 "MF=bin2c" %2 %3 %4 %5 %6 %7 +if "%1"=="all" goto luaexe_64 +goto end + +:luaexe_64 +call tecmake vc8_64 "MF=lua" %2 %3 %4 %5 %6 %7 +call tecmake vc8_64 "MF=luac" %2 %3 %4 %5 %6 %7 +call tecmake vc8_64 "MF=bin2c" %2 %3 %4 %5 %6 %7 +if "%1"=="all" goto luadll8_64 +goto end + +:luadll8_64 +copy /Y ..\lib\dll8_64\*.dll ..\bin\Win64 +if "%1"=="all" goto luadll +goto end + +:luadll +copy /Y ..\lib\dll\*.dll ..\bin\Win32 +call tecmake mingw3 mingw3-dll +call tecmake bc56 bc56-dll +goto end + +:end From 9d31838ca46e4649da569b1bfe9f780da92d1fe6 Mon Sep 17 00:00:00 2001 From: Nikita Obrekht Date: Sun, 25 Oct 2020 21:59:25 +0200 Subject: [PATCH 27/27] Use new parser --- .../deathmatch/logic/luadefs/CLuaGUIDefs.cpp | 39 ++++++------------- .../deathmatch/logic/luadefs/CLuaGUIDefs.h | 5 ++- 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp index 6e95f564708..068974667c6 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include "StdInc.h" +#include "lua/CLuaFunctionParser.h" static const SFixedArray g_chatboxLayoutCVars = {{ "chat_font", @@ -49,8 +50,8 @@ void CLuaGUIDefs::LoadFunctions() {"isMainMenuActive", GUIIsMainMenuActive}, {"isMTAWindowActive", GUIIsMTAWindowActive}, {"isTransferBoxActive", GUIIsTransferBoxActive}, - {"isTransferBoxEnabled", GUIIsTransferBoxEnabled}, - {"setTransferBoxEnabled", GUISetTransferBoxEnabled}, + {"isTransferBoxEnabled", ArgumentParser}, + {"setTransferBoxEnabled", ArgumentParser}, {"guiCreateWindow", GUICreateWindow}, {"guiCreateLabel", GUICreateLabel}, @@ -4064,36 +4065,20 @@ int CLuaGUIDefs::GUIGetCursorType(lua_State* luaVM) return 1; } -int CLuaGUIDefs::GUISetTransferBoxEnabled(lua_State* luaVM) +bool CLuaGUIDefs::GUISetTransferBoxEnabled(bool bEnabled) { - bool bEnabled; - CScriptArgReader argStream(luaVM); - argStream.ReadBool(bEnabled); - - if (!argStream.HasErrors()) + bool bAllowed = false; + g_pCore->GetCVars()->Get("allow_server_control_transferbox", bAllowed); + if (bAllowed && bEnabled != g_pClientGame->GetTransferBox()->IsEnabled()) { - bool bAllowed = false; - g_pCore->GetCVars()->Get("allow_server_control_transferbox", bAllowed); - if (bAllowed) - { - g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); - lua_pushboolean(luaVM, true); - return 1; - } - else - { - lua_pushboolean(luaVM, false); - return 1; - } + g_pClientGame->GetTransferBox()->SetEnabled(bEnabled); + return true; } - else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - return 1; + return false; } -int CLuaGUIDefs::GUIIsTransferBoxEnabled(lua_State* luaVM) +bool CLuaGUIDefs::GUIIsTransferBoxEnabled() { - lua_pushboolean(luaVM, g_pClientGame->GetTransferBox()->IsEnabled()); - return 1; + return g_pClientGame->GetTransferBox()->IsEnabled(); } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.h index ea6e20191ec..05b9a5abcb3 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.h @@ -31,8 +31,6 @@ class CLuaGUIDefs : public CLuaDefs LUA_DECLARE(GUIIsMainMenuActive); LUA_DECLARE(GUIIsMTAWindowActive); LUA_DECLARE(GUIIsTransferBoxActive); - LUA_DECLARE(GUIIsTransferBoxEnabled); - LUA_DECLARE(GUISetTransferBoxEnabled); LUA_DECLARE(GUICreateWindow); LUA_DECLARE(GUICreateLabel); LUA_DECLARE(GUICreateButton); @@ -161,6 +159,9 @@ class CLuaGUIDefs : public CLuaDefs LUA_DECLARE(GUIComboBoxIsOpen); LUA_DECLARE(GUIGetCursorType); + static bool GUIIsTransferBoxEnabled(); + static bool GUISetTransferBoxEnabled(bool bEnabled); + private: static void AddGuiElementClass(lua_State* luaVM); static void AddGuiFontClass(lua_State* luaVM);