From 09be0c375e77ce91b1a889db26835bcee1ba779a Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Wed, 3 Dec 2025 22:23:44 +0100 Subject: [PATCH 01/10] initial commit --- Client/mods/deathmatch/logic/CClientGame.cpp | 6 + Client/mods/deathmatch/logic/CPlayerMap.cpp | 177 +++++++++++++++++- Client/mods/deathmatch/logic/CPlayerMap.h | 25 +++ Client/mods/deathmatch/logic/CResource.cpp | 8 + .../logic/CStaticFunctionDefinitions.cpp | 32 ++++ .../logic/CStaticFunctionDefinitions.h | 6 + .../logic/luadefs/CLuaPlayerDefs.cpp | 62 ++++++ .../deathmatch/logic/luadefs/CLuaPlayerDefs.h | 5 + .../MTA/cgui/images/radar/README.txt | 14 ++ .../MTA/cgui/images/{ => radar}/map_1024.png | Bin .../MTA/cgui/images/{ => radar}/map_2048.png | Bin 11 files changed, 330 insertions(+), 5 deletions(-) create mode 100644 Shared/data/MTA San Andreas/MTA/cgui/images/radar/README.txt rename Shared/data/MTA San Andreas/MTA/cgui/images/{ => radar}/map_1024.png (100%) rename Shared/data/MTA San Andreas/MTA/cgui/images/{ => radar}/map_2048.png (100%) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 0d057bf424f..0e8f9a52498 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -551,6 +551,12 @@ CClientGame::~CClientGame() discord->UpdatePresence(); } + if (m_pPlayerMap) + { + m_pPlayerMap->ResetCustomMapImage(); + m_pPlayerMap->ResetMapOpacity(); + } + // Destroy our stuff SAFE_DELETE(m_pManager); // Will trigger onClientResourceStop diff --git a/Client/mods/deathmatch/logic/CPlayerMap.cpp b/Client/mods/deathmatch/logic/CPlayerMap.cpp index fe089cd23b0..5e645fe3d69 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.cpp +++ b/Client/mods/deathmatch/logic/CPlayerMap.cpp @@ -12,6 +12,7 @@ #include "StdInc.h" using SharedUtil::CalcMTASAPath; +using SharedUtil::FileExists; using std::list; enum @@ -61,6 +62,18 @@ CPlayerMap::CPlayerMap(CClientManager* pManager) m_mapImageTexture = nullptr; m_playerMarkerTexture = nullptr; + // Custom map image variables + m_bHasCustomMapImage = false; + m_customMapImageTexture = nullptr; + m_strCustomMapImagePath = ""; + m_pCustomTextureElement = nullptr; + m_ucCustomMapOpacity = 255; + m_bHasCustomMapOpacity = false; + m_pCustomMapResource = nullptr; + m_pCustomOpacityResource = nullptr; + m_bRadarMapDisabled = false; + m_pRadarMapDisabledResource = nullptr; + // Create all map textures CreateAllTextures(); @@ -109,6 +122,8 @@ CPlayerMap::~CPlayerMap() // Delete our images SAFE_RELEASE(m_mapImageTexture); SAFE_RELEASE(m_playerMarkerTexture); + if (!m_pCustomTextureElement) + SAFE_RELEASE(m_customMapImageTexture); for (uint i = 0; i < m_markerTextureList.size(); i++) SAFE_RELEASE(m_markerTextureList[i]); m_markerTextureList.clear(); @@ -118,7 +133,7 @@ CPlayerMap::~CPlayerMap() void CPlayerMap::CreateOrUpdateMapTexture() { const std::uint32_t mapSize = MAP_IMAGE_SIZES[m_playerMapImageIndex]; - const SString fileName("MTA\\cgui\\images\\map_%d.png", mapSize); + const SString fileName("MTA\\cgui\\images\\radar\\map_%d.png", mapSize); auto* newTexture = g_pCore->GetGraphics()->GetRenderItemManager()->CreateTexture(CalcMTASAPath(fileName), nullptr, false, mapSize, mapSize, RFORMAT_DXT1); if (!newTexture) @@ -156,6 +171,7 @@ void CPlayerMap::CreateAllTextures() { // Create the map texture m_playerMapImageIndex = g_pCore->GetCVars()->GetValue("mapimage"); + m_defaultMapImageIndex = m_playerMapImageIndex; CreateOrUpdateMapTexture(); // Create the player blip texture @@ -163,6 +179,9 @@ void CPlayerMap::CreateAllTextures() // Create the other marker textures CreateMarkerTextures(); + + // Try to load a user custom map if it exists + LoadUserCustomMapIfExists(); } catch (const std::exception& e) { @@ -293,8 +312,7 @@ void CPlayerMap::DoRender() if (isMapShowing && !m_failedToLoadTextures) { // Get the alpha value from the settings - int mapAlpha; - g_pCore->GetCVars()->Get("mapalpha", mapAlpha); + uchar mapAlpha = GetMapOpacity(); const SColorARGB mapColor(mapAlpha, 255, 255, 255); // Update the image if the user changed it via a setting @@ -302,10 +320,14 @@ void CPlayerMap::DoRender() if (mapImageIndex != m_playerMapImageIndex) { UpdateOrRevertMapTexture(mapImageIndex); + if (!m_bHasCustomMapImage) + LoadUserCustomMapIfExists(); } - g_pCore->GetGraphics()->DrawTexture(m_mapImageTexture, static_cast(m_iMapMinX), static_cast(m_iMapMinY), - m_fMapSize / m_mapImageTexture->m_uiSizeX, m_fMapSize / m_mapImageTexture->m_uiSizeY, 0.0f, 0.0f, 0.0f, mapColor); + CTextureItem* pMapTexture = m_bHasCustomMapImage ? m_customMapImageTexture : m_mapImageTexture; + + g_pCore->GetGraphics()->DrawTexture(pMapTexture, static_cast(m_iMapMinX), static_cast(m_iMapMinY), + m_fMapSize / pMapTexture->m_uiSizeX, m_fMapSize / pMapTexture->m_uiSizeY, 0.0f, 0.0f, 0.0f, mapColor); // Grab the info for the local player blip CVector2D vecLocalPos; @@ -718,6 +740,9 @@ void CPlayerMap::SetAttachedToLocalPlayer(bool bIsAttachedToLocal) bool CPlayerMap::IsPlayerMapShowing() { + if (m_bRadarMapDisabled) + return false; + return ((m_bIsPlayerMapEnabled || m_bForcedState) && m_mapImageTexture && m_playerMarkerTexture && (!g_pCore->GetConsole()->IsVisible() && !g_pCore->IsMenuVisible())); } @@ -752,3 +777,145 @@ SString CPlayerMap::GetBoundKeyName(const SString& strCommand) return strCommand; return pCommandBind->boundKey->szKey; } +bool CPlayerMap::SetCustomMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource) +{ + if (uiSize != 1024 && uiSize != 2048) + return false; + + if (!pResource) + return false; + + SString strFullPath = pResource->GetResourceDirectoryPath() + strTexturePath; + + CTextureItem* pNewTexture = g_pCore->GetGraphics()->GetRenderItemManager()->CreateTexture(strFullPath, nullptr, false, uiSize, uiSize, RFORMAT_DXT1); + + if (!pNewTexture) + return false; + + if (!m_pCustomTextureElement) + SAFE_RELEASE(m_customMapImageTexture); + + m_customMapImageTexture = pNewTexture; + m_strCustomMapImagePath = strFullPath; + m_bHasCustomMapImage = true; + m_pCustomMapResource = pResource; + m_pCustomTextureElement = nullptr; + + return true; +} + +bool CPlayerMap::SetCustomMapImageFromTexture(CClientTexture* pTexture, CResource* pResource) +{ + if (!pTexture || !pResource) + return false; + + CTextureItem* pTextureItem = pTexture->GetTextureItem(); + if (!pTextureItem) + return false; + + if (!m_pCustomTextureElement) + SAFE_RELEASE(m_customMapImageTexture); + + m_customMapImageTexture = pTextureItem; + m_strCustomMapImagePath = ""; + m_bHasCustomMapImage = true; + m_pCustomMapResource = pResource; + m_pCustomTextureElement = pTexture; + + return true; +} + +void CPlayerMap::ResetCustomMapImage() +{ + if (!m_pCustomTextureElement) + SAFE_RELEASE(m_customMapImageTexture); + + m_bHasCustomMapImage = false; + m_strCustomMapImagePath = ""; + m_pCustomMapResource = nullptr; + m_pCustomTextureElement = nullptr; +} + +bool CPlayerMap::SetMapOpacity(uchar ucOpacity, CResource* pResource) +{ + m_ucCustomMapOpacity = ucOpacity; + m_bHasCustomMapOpacity = true; + m_pCustomOpacityResource = pResource; + return true; +} + +void CPlayerMap::ResetMapOpacity() +{ + m_bHasCustomMapOpacity = false; + m_ucCustomMapOpacity = 255; + m_pCustomOpacityResource = nullptr; +} + +uchar CPlayerMap::GetMapOpacity() const +{ + if (m_bHasCustomMapOpacity) + return m_ucCustomMapOpacity; + + int mapAlpha; + g_pCore->GetCVars()->Get("mapalpha", mapAlpha); + return static_cast(Clamp(0, mapAlpha, 255)); +} + +bool CPlayerMap::SetRadarMapDisabled(bool bDisabled, CResource* pResource) +{ + m_bRadarMapDisabled = bDisabled; + m_pRadarMapDisabledResource = pResource; + return true; +} + +void CPlayerMap::LoadUserCustomMapIfExists() +{ + const std::uint32_t mapSize = MAP_IMAGE_SIZES[m_playerMapImageIndex]; + const SString customFileName = CalcMTASAPath(SString("MTA\\cgui\\images\\radar\\map_%d-custom.png", mapSize)); + + if (FileExists(customFileName)) + { + CTextureItem* pCustomTexture = g_pCore->GetGraphics()->GetRenderItemManager()->CreateTexture(customFileName, nullptr, false, mapSize, mapSize, RFORMAT_DXT1); + + if (pCustomTexture) + { + if (!m_pCustomTextureElement) + SAFE_RELEASE(m_customMapImageTexture); + + m_customMapImageTexture = pCustomTexture; + m_strCustomMapImagePath = customFileName; + m_bHasCustomMapImage = true; + m_pCustomMapResource = nullptr; + m_pCustomTextureElement = nullptr; + } + } +} + +void CPlayerMap::OnResourceStopping(CResource* pResource) +{ + if (m_bHasCustomMapImage && m_pCustomMapResource == pResource) + { + if (!m_pCustomTextureElement) + SAFE_RELEASE(m_customMapImageTexture); + + m_bHasCustomMapImage = false; + m_strCustomMapImagePath = ""; + m_pCustomMapResource = nullptr; + m_pCustomTextureElement = nullptr; + + LoadUserCustomMapIfExists(); + } + + if (m_bHasCustomMapOpacity && m_pCustomOpacityResource == pResource) + { + m_bHasCustomMapOpacity = false; + m_ucCustomMapOpacity = 255; + m_pCustomOpacityResource = nullptr; + } + + if (m_bRadarMapDisabled && m_pRadarMapDisabledResource == pResource) + { + m_bRadarMapDisabled = false; + m_pRadarMapDisabledResource = nullptr; + } +} diff --git a/Client/mods/deathmatch/logic/CPlayerMap.h b/Client/mods/deathmatch/logic/CPlayerMap.h index d03f40892e0..7b9c506a095 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.h +++ b/Client/mods/deathmatch/logic/CPlayerMap.h @@ -16,6 +16,9 @@ #include #include +class CResource; +class CClientTexture; + class CPlayerMap { public: @@ -37,6 +40,16 @@ class CPlayerMap void ToggleHelpText(); + bool SetCustomMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource = nullptr); + bool SetCustomMapImageFromTexture(CClientTexture* pTexture, CResource* pResource = nullptr); + void ResetCustomMapImage(); + bool SetMapOpacity(uchar ucOpacity, CResource* pResource = nullptr); + void ResetMapOpacity(); + uchar GetMapOpacity() const; + bool HasCustomMapImage() const { return m_bHasCustomMapImage; } + void OnResourceStopping(CResource* pResource); + bool SetRadarMapDisabled(bool bDisabled, CResource* pResource); + protected: void InternalSetPlayerMapEnabled(bool bEnabled); @@ -46,6 +59,7 @@ class CPlayerMap void CreateOrUpdateMapTexture(); void UpdateOrRevertMapTexture(std::size_t imageIndex); void CreateAllTextures(); + void LoadUserCustomMapIfExists(); public: bool IsAttachedToLocalPlayer() const { return m_bIsAttachedToLocal; }; @@ -125,4 +139,15 @@ class CPlayerMap bool m_bRadarVisible; bool m_bDebugVisible; bool m_bTextVisible; + bool m_bHasCustomMapImage; + CTextureItem* m_customMapImageTexture; + std::string m_strCustomMapImagePath; + CClientTexture* m_pCustomTextureElement; + std::size_t m_defaultMapImageIndex; + uchar m_ucCustomMapOpacity; + bool m_bHasCustomMapOpacity; + CResource* m_pCustomMapResource; + CResource* m_pCustomOpacityResource; + bool m_bRadarMapDisabled; + CResource* m_pRadarMapDisabledResource; }; diff --git a/Client/mods/deathmatch/logic/CResource.cpp b/Client/mods/deathmatch/logic/CResource.cpp index d1d9be1f8ea..25024b0567c 100644 --- a/Client/mods/deathmatch/logic/CResource.cpp +++ b/Client/mods/deathmatch/logic/CResource.cpp @@ -370,6 +370,14 @@ void CResource::Stop() { m_bStarting = false; m_bStopping = true; + + if (g_pClientGame) + { + CPlayerMap* pPlayerMap = g_pClientGame->GetPlayerMap(); + if (pPlayerMap) + pPlayerMap->OnResourceStopping(this); + } + CLuaArguments Arguments; Arguments.PushResource(this); m_pResourceEntity->CallEvent("onClientResourceStop", Arguments, true); diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 6e91ea3b3a7..0d3ddbbba63 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -7997,6 +7997,38 @@ bool CStaticFunctionDefinitions::GetPlayerMapBoundingBox(CVector& vecMin, CVecto return false; } +bool CStaticFunctionDefinitions::SetPlayerMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource) +{ + return m_pPlayerMap->SetCustomMapImage(strTexturePath, uiSize, pResource); +} + +bool CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(CClientTexture* pTexture, CResource* pResource) +{ + return m_pPlayerMap->SetCustomMapImageFromTexture(pTexture, pResource); +} + +bool CStaticFunctionDefinitions::ResetPlayerMapImage() +{ + m_pPlayerMap->ResetCustomMapImage(); + return true; +} + +bool CStaticFunctionDefinitions::SetPlayerMapOpacity(uchar ucOpacity, CResource* pResource) +{ + return m_pPlayerMap->SetMapOpacity(ucOpacity, pResource); +} + +bool CStaticFunctionDefinitions::ResetPlayerMapOpacity() +{ + m_pPlayerMap->ResetMapOpacity(); + return true; +} + +bool CStaticFunctionDefinitions::DisableRadarMap(bool bDisable, CResource* pResource) +{ + return m_pPlayerMap->SetRadarMapDisabled(bDisable, pResource); +} + bool CStaticFunctionDefinitions::FxAddBlood(CVector& vecPosition, CVector& vecDirection, int iCount, float fBrightness) { g_pGame->GetFx()->AddBlood(vecPosition, vecDirection, iCount, fBrightness); diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 766a09a9ffc..9ec4144a6f3 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -724,6 +724,12 @@ class CStaticFunctionDefinitions static bool IsPlayerMapForced(bool& bForced); static bool IsPlayerMapVisible(bool& bVisible); static bool GetPlayerMapBoundingBox(CVector& vecMin, CVector& vecMax); + static bool SetPlayerMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource); + static bool SetPlayerMapImageFromTexture(CClientTexture* pTexture, CResource* pResource); + static bool ResetPlayerMapImage(); + static bool SetPlayerMapOpacity(uchar ucOpacity, CResource* pResource); + static bool ResetPlayerMapOpacity(); + static bool DisableRadarMap(bool bDisable, CResource* pResource); // Fx funcs static bool FxAddBlood(CVector& vecPosition, CVector& vecDirection, int iCount, float fBrightness); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp index b4813e21a70..d71aa799468 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp @@ -53,6 +53,11 @@ void CLuaPlayerDefs::LoadFunctions() {"isPlayerMapVisible", IsPlayerMapVisible}, {"getPlayerMapBoundingBox", GetPlayerMapBoundingBox}, {"getPlayerMapOpacity", ArgumentParser}, + {"setPlayerMapImage", ArgumentParser}, + {"resetPlayerMapImage", ArgumentParser}, + {"setPlayerMapOpacity", ArgumentParser}, + {"resetPlayerMapOpacity", ArgumentParser}, + {"disableRadarMap", ArgumentParser}, {"getPlayerHudComponentProperty", ArgumentParser}, }; @@ -78,6 +83,11 @@ void CLuaPlayerDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "forceMap", "forcePlayerMap"); lua_classfunction(luaVM, "isMapForced", "isPlayerMapForced"); lua_classfunction(luaVM, "isMapVisible", "isPlayerMapVisible"); + lua_classfunction(luaVM, "setMapImage", "setPlayerMapImage"); + lua_classfunction(luaVM, "resetMapImage", "resetPlayerMapImage"); + lua_classfunction(luaVM, "setMapOpacity", "setPlayerMapOpacity"); + lua_classfunction(luaVM, "resetMapOpacity", "resetPlayerMapOpacity"); + lua_classfunction(luaVM, "disableRadarMap", "disableRadarMap"); lua_classfunction(luaVM, "isHudComponentVisible", "isPlayerHudComponentVisible"); lua_classfunction(luaVM, "toggleControl", "toggleControl"); lua_classfunction(luaVM, "setHudComponentProperty", "setPlayerHudComponentProperty"); @@ -1053,3 +1063,55 @@ std::variant, CLuaMultiR return false; } + +bool CLuaPlayerDefs::SetPlayerMapImage(lua_State* luaVM, std::variant texturePathOrElement, std::optional size) +{ + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (!pLuaMain) + return false; + + CResource* pResource = pLuaMain->GetResource(); + + if (std::holds_alternative(texturePathOrElement)) + { + CClientTexture* pTexture = std::get(texturePathOrElement); + return CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(pTexture, pResource); + } + else + { + std::string strPath = std::get(texturePathOrElement); + if (!size.has_value()) + return false; + return CStaticFunctionDefinitions::SetPlayerMapImage(strPath, size.value(), pResource); + } +} + +bool CLuaPlayerDefs::ResetPlayerMapImage() +{ + return CStaticFunctionDefinitions::ResetPlayerMapImage(); +} + +bool CLuaPlayerDefs::SetPlayerMapOpacity(lua_State* luaVM, uchar opacity) +{ + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (!pLuaMain) + return false; + + CResource* pResource = pLuaMain->GetResource(); + return CStaticFunctionDefinitions::SetPlayerMapOpacity(opacity, pResource); +} + +bool CLuaPlayerDefs::ResetPlayerMapOpacity() +{ + return CStaticFunctionDefinitions::ResetPlayerMapOpacity(); +} + +bool CLuaPlayerDefs::DisableRadarMap(lua_State* luaVM, bool disable) +{ + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (!pLuaMain) + return false; + + CResource* pResource = pLuaMain->GetResource(); + return CStaticFunctionDefinitions::DisableRadarMap(disable, pResource); +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h index 1bc08998a47..1f188da8ed4 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h @@ -55,4 +55,9 @@ class CLuaPlayerDefs : public CLuaDefs LUA_DECLARE(IsPlayerMapVisible); LUA_DECLARE(GetPlayerMapBoundingBox); static unsigned char GetPlayerMapOpacity(); + static bool SetPlayerMapImage(lua_State* luaVM, std::variant texturePathOrElement, std::optional size); + static bool ResetPlayerMapImage(); + static bool SetPlayerMapOpacity(lua_State* luaVM, uchar opacity); + static bool ResetPlayerMapOpacity(); + static bool DisableRadarMap(lua_State* luaVM, bool disable); }; diff --git a/Shared/data/MTA San Andreas/MTA/cgui/images/radar/README.txt b/Shared/data/MTA San Andreas/MTA/cgui/images/radar/README.txt new file mode 100644 index 00000000000..f35adbc69a1 --- /dev/null +++ b/Shared/data/MTA San Andreas/MTA/cgui/images/radar/README.txt @@ -0,0 +1,14 @@ +MTA:SA F11 Radar Map - Custom Images + +You can replace the F11 map images by creating custom versions with the "-custom" suffix: + +Default files: +- map_1024.png (1024x1024) +- map_2048.png (2048x2048) + +To use custom images, create: +- map_1024-custom.png (1024x1024) +- map_2048-custom.png (2048x2048) + +Place them in this folder. MTA will use -custom files if they exist. +Server scripts can override these with setPlayerMapImage(). diff --git a/Shared/data/MTA San Andreas/MTA/cgui/images/map_1024.png b/Shared/data/MTA San Andreas/MTA/cgui/images/radar/map_1024.png similarity index 100% rename from Shared/data/MTA San Andreas/MTA/cgui/images/map_1024.png rename to Shared/data/MTA San Andreas/MTA/cgui/images/radar/map_1024.png diff --git a/Shared/data/MTA San Andreas/MTA/cgui/images/map_2048.png b/Shared/data/MTA San Andreas/MTA/cgui/images/radar/map_2048.png similarity index 100% rename from Shared/data/MTA San Andreas/MTA/cgui/images/map_2048.png rename to Shared/data/MTA San Andreas/MTA/cgui/images/radar/map_2048.png From 4e08a0791e8fa0ac31293ba20feb84d158667979 Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Wed, 3 Dec 2025 22:57:19 +0100 Subject: [PATCH 02/10] fixes etc. --- Client/mods/deathmatch/logic/CPlayerMap.cpp | 184 +++++++++++++----- Client/mods/deathmatch/logic/CPlayerMap.h | 23 ++- .../logic/CStaticFunctionDefinitions.cpp | 8 +- .../logic/CStaticFunctionDefinitions.h | 4 +- .../logic/luadefs/CLuaPlayerDefs.cpp | 17 +- .../deathmatch/logic/luadefs/CLuaPlayerDefs.h | 2 +- 6 files changed, 167 insertions(+), 71 deletions(-) diff --git a/Client/mods/deathmatch/logic/CPlayerMap.cpp b/Client/mods/deathmatch/logic/CPlayerMap.cpp index 5e645fe3d69..6b3613989f0 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.cpp +++ b/Client/mods/deathmatch/logic/CPlayerMap.cpp @@ -63,13 +63,8 @@ CPlayerMap::CPlayerMap(CClientManager* pManager) m_playerMarkerTexture = nullptr; // Custom map image variables - m_bHasCustomMapImage = false; - m_customMapImageTexture = nullptr; - m_strCustomMapImagePath = ""; - m_pCustomTextureElement = nullptr; m_ucCustomMapOpacity = 255; m_bHasCustomMapOpacity = false; - m_pCustomMapResource = nullptr; m_pCustomOpacityResource = nullptr; m_bRadarMapDisabled = false; m_pRadarMapDisabledResource = nullptr; @@ -122,8 +117,14 @@ CPlayerMap::~CPlayerMap() // Delete our images SAFE_RELEASE(m_mapImageTexture); SAFE_RELEASE(m_playerMarkerTexture); - if (!m_pCustomTextureElement) - SAFE_RELEASE(m_customMapImageTexture); + + // Release custom map textures + for (int i = 0; i < 2; i++) + { + if (!m_customMapData[i].pTextureElement && m_customMapData[i].pTexture) + SAFE_RELEASE(m_customMapData[i].pTexture); + } + for (uint i = 0; i < m_markerTextureList.size(); i++) SAFE_RELEASE(m_markerTextureList[i]); m_markerTextureList.clear(); @@ -311,6 +312,24 @@ void CPlayerMap::DoRender() // Render if showing and textures are all loaded if (isMapShowing && !m_failedToLoadTextures) { + // Check if the current size texture element is still valid + std::size_t currentIdx = m_playerMapImageIndex; + if (m_customMapData[currentIdx].bHasCustomMap && m_customMapData[currentIdx].pTextureElement) + { + if (m_customMapData[currentIdx].pTextureElement->IsBeingDeleted()) + { + // Delete the texture, reset + m_customMapData[currentIdx].pTexture = nullptr; + m_customMapData[currentIdx].bHasCustomMap = false; + m_customMapData[currentIdx].strPath = ""; + m_customMapData[currentIdx].pResource = nullptr; + m_customMapData[currentIdx].pTextureElement = nullptr; + + // Try to load a user custom map if it exists + LoadUserCustomMapIfExists(); + } + } + // Get the alpha value from the settings uchar mapAlpha = GetMapOpacity(); const SColorARGB mapColor(mapAlpha, 255, 255, 255); @@ -320,11 +339,13 @@ void CPlayerMap::DoRender() if (mapImageIndex != m_playerMapImageIndex) { UpdateOrRevertMapTexture(mapImageIndex); - if (!m_bHasCustomMapImage) + if (!m_customMapData[m_playerMapImageIndex].bHasCustomMap) LoadUserCustomMapIfExists(); } - CTextureItem* pMapTexture = m_bHasCustomMapImage ? m_customMapImageTexture : m_mapImageTexture; + CTextureItem* pMapTexture = m_customMapData[m_playerMapImageIndex].bHasCustomMap + ? m_customMapData[m_playerMapImageIndex].pTexture + : m_mapImageTexture; g_pCore->GetGraphics()->DrawTexture(pMapTexture, static_cast(m_iMapMinX), static_cast(m_iMapMinY), m_fMapSize / pMapTexture->m_uiSizeX, m_fMapSize / pMapTexture->m_uiSizeY, 0.0f, 0.0f, 0.0f, mapColor); @@ -421,6 +442,9 @@ void CPlayerMap::DoRender() void CPlayerMap::SetPlayerMapEnabled(bool show) { + if (m_bRadarMapDisabled && show) + return; + bool alreadyEnabled = (m_bIsPlayerMapEnabled || m_bForcedState); bool definitiveShow = (show || m_bForcedState); if (alreadyEnabled != definitiveShow) @@ -780,65 +804,101 @@ SString CPlayerMap::GetBoundKeyName(const SString& strCommand) bool CPlayerMap::SetCustomMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource) { if (uiSize != 1024 && uiSize != 2048) - return false; + throw std::invalid_argument("Invalid map size (must be 1024 or 2048)"); if (!pResource) return false; + std::size_t idx = (uiSize == 1024) ? 0 : 1; SString strFullPath = pResource->GetResourceDirectoryPath() + strTexturePath; CTextureItem* pNewTexture = g_pCore->GetGraphics()->GetRenderItemManager()->CreateTexture(strFullPath, nullptr, false, uiSize, uiSize, RFORMAT_DXT1); if (!pNewTexture) - return false; + throw std::invalid_argument("Failed to load texture from path: " + strTexturePath); - if (!m_pCustomTextureElement) - SAFE_RELEASE(m_customMapImageTexture); + // Release old texture if it existed and was not element-based + if (!m_customMapData[idx].pTextureElement && m_customMapData[idx].pTexture) + SAFE_RELEASE(m_customMapData[idx].pTexture); - m_customMapImageTexture = pNewTexture; - m_strCustomMapImagePath = strFullPath; - m_bHasCustomMapImage = true; - m_pCustomMapResource = pResource; - m_pCustomTextureElement = nullptr; + m_customMapData[idx].pTexture = pNewTexture; + m_customMapData[idx].strPath = strFullPath; + m_customMapData[idx].bHasCustomMap = true; + m_customMapData[idx].pResource = pResource; + m_customMapData[idx].pTextureElement = nullptr; return true; } -bool CPlayerMap::SetCustomMapImageFromTexture(CClientTexture* pTexture, CResource* pResource) +bool CPlayerMap::SetCustomMapImageFromTexture(CClientTexture* pTexture, uint uiSize, CResource* pResource) { if (!pTexture || !pResource) return false; + if (uiSize != 1024 && uiSize != 2048) + throw std::invalid_argument("Invalid map size (must be 1024 or 2048)"); + CTextureItem* pTextureItem = pTexture->GetTextureItem(); if (!pTextureItem) - return false; + throw std::invalid_argument("Invalid texture element"); - if (!m_pCustomTextureElement) - SAFE_RELEASE(m_customMapImageTexture); + std::size_t idx = (uiSize == 1024) ? 0 : 1; + + // If the current map index does not match, update it + if (idx != m_playerMapImageIndex) + { + m_playerMapImageIndex = idx; + try { + CreateOrUpdateMapTexture(); + } catch (...) { + // Ignore errors + } + } + + // Release old texture if it existed and was not element-based + if (!m_customMapData[idx].pTextureElement && m_customMapData[idx].pTexture) + SAFE_RELEASE(m_customMapData[idx].pTexture); - m_customMapImageTexture = pTextureItem; - m_strCustomMapImagePath = ""; - m_bHasCustomMapImage = true; - m_pCustomMapResource = pResource; - m_pCustomTextureElement = pTexture; + m_customMapData[idx].pTexture = pTextureItem; + m_customMapData[idx].strPath = ""; + m_customMapData[idx].bHasCustomMap = true; + m_customMapData[idx].pResource = pResource; + m_customMapData[idx].pTextureElement = pTexture; return true; } -void CPlayerMap::ResetCustomMapImage() +void CPlayerMap::ResetCustomMapImage(uint uiSize) { - if (!m_pCustomTextureElement) - SAFE_RELEASE(m_customMapImageTexture); + // If size is 0, reset both sizes + if (uiSize == 0) + { + ResetCustomMapImage(1024); + ResetCustomMapImage(2048); + return; + } - m_bHasCustomMapImage = false; - m_strCustomMapImagePath = ""; - m_pCustomMapResource = nullptr; - m_pCustomTextureElement = nullptr; + if (uiSize != 1024 && uiSize != 2048) + return; + + std::size_t idx = (uiSize == 1024) ? 0 : 1; + + if (!m_customMapData[idx].pTextureElement && m_customMapData[idx].pTexture) + SAFE_RELEASE(m_customMapData[idx].pTexture); + + m_customMapData[idx].bHasCustomMap = false; + m_customMapData[idx].strPath = ""; + m_customMapData[idx].pResource = nullptr; + m_customMapData[idx].pTextureElement = nullptr; + + // Try to load the user custom map if it exists + if (idx == m_playerMapImageIndex) + LoadUserCustomMapIfExists(); } bool CPlayerMap::SetMapOpacity(uchar ucOpacity, CResource* pResource) { - m_ucCustomMapOpacity = ucOpacity; + m_ucCustomMapOpacity = static_cast(Clamp(0, static_cast(ucOpacity), 255)); m_bHasCustomMapOpacity = true; m_pCustomOpacityResource = pResource; return true; @@ -870,7 +930,13 @@ bool CPlayerMap::SetRadarMapDisabled(bool bDisabled, CResource* pResource) void CPlayerMap::LoadUserCustomMapIfExists() { - const std::uint32_t mapSize = MAP_IMAGE_SIZES[m_playerMapImageIndex]; + std::size_t idx = m_playerMapImageIndex; + + // If already has a script-set custom map for this size, do not override + if (m_customMapData[idx].bHasCustomMap && m_customMapData[idx].pResource != nullptr) + return; + + const std::uint32_t mapSize = MAP_IMAGE_SIZES[idx]; const SString customFileName = CalcMTASAPath(SString("MTA\\cgui\\images\\radar\\map_%d-custom.png", mapSize)); if (FileExists(customFileName)) @@ -879,33 +945,45 @@ void CPlayerMap::LoadUserCustomMapIfExists() if (pCustomTexture) { - if (!m_pCustomTextureElement) - SAFE_RELEASE(m_customMapImageTexture); + // Release old texture if it existed and was not element-based + if (!m_customMapData[idx].pTextureElement && m_customMapData[idx].pTexture) + SAFE_RELEASE(m_customMapData[idx].pTexture); - m_customMapImageTexture = pCustomTexture; - m_strCustomMapImagePath = customFileName; - m_bHasCustomMapImage = true; - m_pCustomMapResource = nullptr; - m_pCustomTextureElement = nullptr; + m_customMapData[idx].pTexture = pCustomTexture; + m_customMapData[idx].strPath = customFileName; + m_customMapData[idx].bHasCustomMap = true; + m_customMapData[idx].pResource = nullptr; + m_customMapData[idx].pTextureElement = nullptr; } } } void CPlayerMap::OnResourceStopping(CResource* pResource) { - if (m_bHasCustomMapImage && m_pCustomMapResource == pResource) + // Check both size custom maps + for (int i = 0; i < 2; i++) { - if (!m_pCustomTextureElement) - SAFE_RELEASE(m_customMapImageTexture); - - m_bHasCustomMapImage = false; - m_strCustomMapImagePath = ""; - m_pCustomMapResource = nullptr; - m_pCustomTextureElement = nullptr; - - LoadUserCustomMapIfExists(); + if (m_customMapData[i].bHasCustomMap && m_customMapData[i].pResource == pResource) + { + if (!m_customMapData[i].pTextureElement && m_customMapData[i].pTexture) + { + SAFE_RELEASE(m_customMapData[i].pTexture); + } + else + { + m_customMapData[i].pTexture = nullptr; + } + + m_customMapData[i].bHasCustomMap = false; + m_customMapData[i].strPath = ""; + m_customMapData[i].pResource = nullptr; + m_customMapData[i].pTextureElement = nullptr; + } } + // If the current map size had a custom map, try to load the user custom map + LoadUserCustomMapIfExists(); + if (m_bHasCustomMapOpacity && m_pCustomOpacityResource == pResource) { m_bHasCustomMapOpacity = false; diff --git a/Client/mods/deathmatch/logic/CPlayerMap.h b/Client/mods/deathmatch/logic/CPlayerMap.h index 7b9c506a095..766838c600b 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.h +++ b/Client/mods/deathmatch/logic/CPlayerMap.h @@ -41,12 +41,15 @@ class CPlayerMap void ToggleHelpText(); bool SetCustomMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource = nullptr); - bool SetCustomMapImageFromTexture(CClientTexture* pTexture, CResource* pResource = nullptr); - void ResetCustomMapImage(); + bool SetCustomMapImageFromTexture(CClientTexture* pTexture, uint uiSize, CResource* pResource = nullptr); + void ResetCustomMapImage(uint uiSize = 0); bool SetMapOpacity(uchar ucOpacity, CResource* pResource = nullptr); void ResetMapOpacity(); uchar GetMapOpacity() const; - bool HasCustomMapImage() const { return m_bHasCustomMapImage; } + bool HasCustomMapImage(uint uiSize) const { + std::size_t idx = (uiSize == 1024) ? 0 : 1; + return m_customMapData[idx].bHasCustomMap; + } void OnResourceStopping(CResource* pResource); bool SetRadarMapDisabled(bool bDisabled, CResource* pResource); @@ -139,14 +142,18 @@ class CPlayerMap bool m_bRadarVisible; bool m_bDebugVisible; bool m_bTextVisible; - bool m_bHasCustomMapImage; - CTextureItem* m_customMapImageTexture; - std::string m_strCustomMapImagePath; - CClientTexture* m_pCustomTextureElement; + struct CustomMapData + { + bool bHasCustomMap = false; + CTextureItem* pTexture = nullptr; + std::string strPath = ""; + CClientTexture* pTextureElement = nullptr; + CResource* pResource = nullptr; + }; + CustomMapData m_customMapData[2]; // [0] = 1024, [1] = 2048 std::size_t m_defaultMapImageIndex; uchar m_ucCustomMapOpacity; bool m_bHasCustomMapOpacity; - CResource* m_pCustomMapResource; CResource* m_pCustomOpacityResource; bool m_bRadarMapDisabled; CResource* m_pRadarMapDisabledResource; diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 0d3ddbbba63..44fa3e74422 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -8002,14 +8002,14 @@ bool CStaticFunctionDefinitions::SetPlayerMapImage(const std::string& strTexture return m_pPlayerMap->SetCustomMapImage(strTexturePath, uiSize, pResource); } -bool CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(CClientTexture* pTexture, CResource* pResource) +bool CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(CClientTexture* pTexture, uint uiSize, CResource* pResource) { - return m_pPlayerMap->SetCustomMapImageFromTexture(pTexture, pResource); + return m_pPlayerMap->SetCustomMapImageFromTexture(pTexture, uiSize, pResource); } -bool CStaticFunctionDefinitions::ResetPlayerMapImage() +bool CStaticFunctionDefinitions::ResetPlayerMapImage(uint uiSize) { - m_pPlayerMap->ResetCustomMapImage(); + m_pPlayerMap->ResetCustomMapImage(uiSize); return true; } diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 9ec4144a6f3..a930ad67887 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -725,8 +725,8 @@ class CStaticFunctionDefinitions static bool IsPlayerMapVisible(bool& bVisible); static bool GetPlayerMapBoundingBox(CVector& vecMin, CVector& vecMax); static bool SetPlayerMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource); - static bool SetPlayerMapImageFromTexture(CClientTexture* pTexture, CResource* pResource); - static bool ResetPlayerMapImage(); + static bool SetPlayerMapImageFromTexture(CClientTexture* pTexture, uint uiSize, CResource* pResource); + static bool ResetPlayerMapImage(uint uiSize = 0); static bool SetPlayerMapOpacity(uchar ucOpacity, CResource* pResource); static bool ResetPlayerMapOpacity(); static bool DisableRadarMap(bool bDisable, CResource* pResource); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp index d71aa799468..d865b3bfed9 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp @@ -1075,7 +1075,9 @@ bool CLuaPlayerDefs::SetPlayerMapImage(lua_State* luaVM, std::variant(texturePathOrElement)) { CClientTexture* pTexture = std::get(texturePathOrElement); - return CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(pTexture, pResource); + if (!size.has_value()) + return false; + return CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(pTexture, size.value(), pResource); } else { @@ -1086,9 +1088,18 @@ bool CLuaPlayerDefs::SetPlayerMapImage(lua_State* luaVM, std::variant size) { - return CStaticFunctionDefinitions::ResetPlayerMapImage(); + if (size.has_value()) + { + if (*size != 1024 && *size != 2048) + throw std::invalid_argument("Invalid map size (must be 1024 or 2048)"); + return CStaticFunctionDefinitions::ResetPlayerMapImage(*size); + } + else + { + return CStaticFunctionDefinitions::ResetPlayerMapImage(0); + } } bool CLuaPlayerDefs::SetPlayerMapOpacity(lua_State* luaVM, uchar opacity) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h index 1f188da8ed4..a09c430e460 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h @@ -56,7 +56,7 @@ class CLuaPlayerDefs : public CLuaDefs LUA_DECLARE(GetPlayerMapBoundingBox); static unsigned char GetPlayerMapOpacity(); static bool SetPlayerMapImage(lua_State* luaVM, std::variant texturePathOrElement, std::optional size); - static bool ResetPlayerMapImage(); + static bool ResetPlayerMapImage(std::optional size); static bool SetPlayerMapOpacity(lua_State* luaVM, uchar opacity); static bool ResetPlayerMapOpacity(); static bool DisableRadarMap(lua_State* luaVM, bool disable); From 272d7aefcb198fa0d5c9c08059e134256b5281e6 Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Wed, 3 Dec 2025 23:04:23 +0100 Subject: [PATCH 03/10] crashfix --- Client/mods/deathmatch/logic/CPlayerMap.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Client/mods/deathmatch/logic/CPlayerMap.cpp b/Client/mods/deathmatch/logic/CPlayerMap.cpp index 6b3613989f0..b2072feb76b 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.cpp +++ b/Client/mods/deathmatch/logic/CPlayerMap.cpp @@ -122,7 +122,10 @@ CPlayerMap::~CPlayerMap() for (int i = 0; i < 2; i++) { if (!m_customMapData[i].pTextureElement && m_customMapData[i].pTexture) + { SAFE_RELEASE(m_customMapData[i].pTexture); + m_customMapData[i].pTexture = nullptr; + } } for (uint i = 0; i < m_markerTextureList.size(); i++) @@ -819,7 +822,10 @@ bool CPlayerMap::SetCustomMapImage(const std::string& strTexturePath, uint uiSiz // Release old texture if it existed and was not element-based if (!m_customMapData[idx].pTextureElement && m_customMapData[idx].pTexture) + { SAFE_RELEASE(m_customMapData[idx].pTexture); + m_customMapData[idx].pTexture = nullptr; + } m_customMapData[idx].pTexture = pNewTexture; m_customMapData[idx].strPath = strFullPath; @@ -857,7 +863,10 @@ bool CPlayerMap::SetCustomMapImageFromTexture(CClientTexture* pTexture, uint uiS // Release old texture if it existed and was not element-based if (!m_customMapData[idx].pTextureElement && m_customMapData[idx].pTexture) + { SAFE_RELEASE(m_customMapData[idx].pTexture); + m_customMapData[idx].pTexture = nullptr; + } m_customMapData[idx].pTexture = pTextureItem; m_customMapData[idx].strPath = ""; @@ -884,7 +893,10 @@ void CPlayerMap::ResetCustomMapImage(uint uiSize) std::size_t idx = (uiSize == 1024) ? 0 : 1; if (!m_customMapData[idx].pTextureElement && m_customMapData[idx].pTexture) + { SAFE_RELEASE(m_customMapData[idx].pTexture); + m_customMapData[idx].pTexture = nullptr; + } m_customMapData[idx].bHasCustomMap = false; m_customMapData[idx].strPath = ""; @@ -968,6 +980,7 @@ void CPlayerMap::OnResourceStopping(CResource* pResource) if (!m_customMapData[i].pTextureElement && m_customMapData[i].pTexture) { SAFE_RELEASE(m_customMapData[i].pTexture); + m_customMapData[i].pTexture = nullptr; } else { From 75ade17b3de9b6a01a7f74e75555a14b714e9b2f Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Wed, 3 Dec 2025 23:07:22 +0100 Subject: [PATCH 04/10] crashfix --- Client/mods/deathmatch/logic/CPlayerMap.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Client/mods/deathmatch/logic/CPlayerMap.cpp b/Client/mods/deathmatch/logic/CPlayerMap.cpp index b2072feb76b..5e8cdd58757 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.cpp +++ b/Client/mods/deathmatch/logic/CPlayerMap.cpp @@ -121,11 +121,14 @@ CPlayerMap::~CPlayerMap() // Release custom map textures for (int i = 0; i < 2; i++) { - if (!m_customMapData[i].pTextureElement && m_customMapData[i].pTexture) + if (m_customMapData[i].bHasCustomMap && m_customMapData[i].pTexture && !m_customMapData[i].pTextureElement) { SAFE_RELEASE(m_customMapData[i].pTexture); - m_customMapData[i].pTexture = nullptr; } + m_customMapData[i].pTexture = nullptr; + m_customMapData[i].pTextureElement = nullptr; + m_customMapData[i].pResource = nullptr; + m_customMapData[i].bHasCustomMap = false; } for (uint i = 0; i < m_markerTextureList.size(); i++) From 4507b5e38c71840ebcac0187b245b0a44b3e4ad7 Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Wed, 3 Dec 2025 23:36:40 +0100 Subject: [PATCH 05/10] fix --- Client/mods/deathmatch/logic/CClientGame.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 0e8f9a52498..b2d59d79425 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -555,6 +555,7 @@ CClientGame::~CClientGame() { m_pPlayerMap->ResetCustomMapImage(); m_pPlayerMap->ResetMapOpacity(); + m_pPlayerMap->SetPlayerMapEnabled(true); } // Destroy our stuff From 0a34bc022439bc2833e12f81fd90a22617e86c42 Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Wed, 3 Dec 2025 23:55:45 +0100 Subject: [PATCH 06/10] rename disableRadarMap to disablePlayerMap --- .../mods/deathmatch/logic/CStaticFunctionDefinitions.cpp | 2 +- Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h | 2 +- Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp | 8 ++++---- Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 44fa3e74422..472f99c7ae1 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -8024,7 +8024,7 @@ bool CStaticFunctionDefinitions::ResetPlayerMapOpacity() return true; } -bool CStaticFunctionDefinitions::DisableRadarMap(bool bDisable, CResource* pResource) +bool CStaticFunctionDefinitions::DisablePlayerMap(bool bDisable, CResource* pResource) { return m_pPlayerMap->SetRadarMapDisabled(bDisable, pResource); } diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h index a930ad67887..6d9c40a5acc 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -729,7 +729,7 @@ class CStaticFunctionDefinitions static bool ResetPlayerMapImage(uint uiSize = 0); static bool SetPlayerMapOpacity(uchar ucOpacity, CResource* pResource); static bool ResetPlayerMapOpacity(); - static bool DisableRadarMap(bool bDisable, CResource* pResource); + static bool DisablePlayerMap(bool bDisable, CResource* pResource); // Fx funcs static bool FxAddBlood(CVector& vecPosition, CVector& vecDirection, int iCount, float fBrightness); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp index d865b3bfed9..cebce06f593 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp @@ -57,7 +57,7 @@ void CLuaPlayerDefs::LoadFunctions() {"resetPlayerMapImage", ArgumentParser}, {"setPlayerMapOpacity", ArgumentParser}, {"resetPlayerMapOpacity", ArgumentParser}, - {"disableRadarMap", ArgumentParser}, + {"disablePlayerMap", ArgumentParser}, {"getPlayerHudComponentProperty", ArgumentParser}, }; @@ -87,7 +87,7 @@ void CLuaPlayerDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "resetMapImage", "resetPlayerMapImage"); lua_classfunction(luaVM, "setMapOpacity", "setPlayerMapOpacity"); lua_classfunction(luaVM, "resetMapOpacity", "resetPlayerMapOpacity"); - lua_classfunction(luaVM, "disableRadarMap", "disableRadarMap"); + lua_classfunction(luaVM, "disableMap", "disablePlayerMap"); lua_classfunction(luaVM, "isHudComponentVisible", "isPlayerHudComponentVisible"); lua_classfunction(luaVM, "toggleControl", "toggleControl"); lua_classfunction(luaVM, "setHudComponentProperty", "setPlayerHudComponentProperty"); @@ -1117,12 +1117,12 @@ bool CLuaPlayerDefs::ResetPlayerMapOpacity() return CStaticFunctionDefinitions::ResetPlayerMapOpacity(); } -bool CLuaPlayerDefs::DisableRadarMap(lua_State* luaVM, bool disable) +bool CLuaPlayerDefs::DisablePlayerMap(lua_State* luaVM, bool disable) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); if (!pLuaMain) return false; CResource* pResource = pLuaMain->GetResource(); - return CStaticFunctionDefinitions::DisableRadarMap(disable, pResource); + return CStaticFunctionDefinitions::DisablePlayerMap(disable, pResource); } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h index a09c430e460..fe98f868f3a 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h @@ -59,5 +59,5 @@ class CLuaPlayerDefs : public CLuaDefs static bool ResetPlayerMapImage(std::optional size); static bool SetPlayerMapOpacity(lua_State* luaVM, uchar opacity); static bool ResetPlayerMapOpacity(); - static bool DisableRadarMap(lua_State* luaVM, bool disable); + static bool DisablePlayerMap(lua_State* luaVM, bool disable); }; From fc8120f30dbeb42259938e7fb19d028e7ec0918a Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Thu, 4 Dec 2025 13:27:29 +0100 Subject: [PATCH 07/10] remove disablePlayerMap --- Client/mods/deathmatch/logic/CPlayerMap.cpp | 20 ------------------- Client/mods/deathmatch/logic/CPlayerMap.h | 2 -- .../logic/CStaticFunctionDefinitions.cpp | 5 ----- .../logic/CStaticFunctionDefinitions.h | 1 - .../logic/luadefs/CLuaPlayerDefs.cpp | 12 ----------- .../deathmatch/logic/luadefs/CLuaPlayerDefs.h | 1 - 6 files changed, 41 deletions(-) diff --git a/Client/mods/deathmatch/logic/CPlayerMap.cpp b/Client/mods/deathmatch/logic/CPlayerMap.cpp index 5e8cdd58757..b8548cd0892 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.cpp +++ b/Client/mods/deathmatch/logic/CPlayerMap.cpp @@ -66,7 +66,6 @@ CPlayerMap::CPlayerMap(CClientManager* pManager) m_ucCustomMapOpacity = 255; m_bHasCustomMapOpacity = false; m_pCustomOpacityResource = nullptr; - m_bRadarMapDisabled = false; m_pRadarMapDisabledResource = nullptr; // Create all map textures @@ -448,9 +447,6 @@ void CPlayerMap::DoRender() void CPlayerMap::SetPlayerMapEnabled(bool show) { - if (m_bRadarMapDisabled && show) - return; - bool alreadyEnabled = (m_bIsPlayerMapEnabled || m_bForcedState); bool definitiveShow = (show || m_bForcedState); if (alreadyEnabled != definitiveShow) @@ -770,9 +766,6 @@ void CPlayerMap::SetAttachedToLocalPlayer(bool bIsAttachedToLocal) bool CPlayerMap::IsPlayerMapShowing() { - if (m_bRadarMapDisabled) - return false; - return ((m_bIsPlayerMapEnabled || m_bForcedState) && m_mapImageTexture && m_playerMarkerTexture && (!g_pCore->GetConsole()->IsVisible() && !g_pCore->IsMenuVisible())); } @@ -936,13 +929,6 @@ uchar CPlayerMap::GetMapOpacity() const return static_cast(Clamp(0, mapAlpha, 255)); } -bool CPlayerMap::SetRadarMapDisabled(bool bDisabled, CResource* pResource) -{ - m_bRadarMapDisabled = bDisabled; - m_pRadarMapDisabledResource = pResource; - return true; -} - void CPlayerMap::LoadUserCustomMapIfExists() { std::size_t idx = m_playerMapImageIndex; @@ -1006,10 +992,4 @@ void CPlayerMap::OnResourceStopping(CResource* pResource) m_ucCustomMapOpacity = 255; m_pCustomOpacityResource = nullptr; } - - if (m_bRadarMapDisabled && m_pRadarMapDisabledResource == pResource) - { - m_bRadarMapDisabled = false; - m_pRadarMapDisabledResource = nullptr; - } } diff --git a/Client/mods/deathmatch/logic/CPlayerMap.h b/Client/mods/deathmatch/logic/CPlayerMap.h index 766838c600b..989f451a5f4 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.h +++ b/Client/mods/deathmatch/logic/CPlayerMap.h @@ -51,7 +51,6 @@ class CPlayerMap return m_customMapData[idx].bHasCustomMap; } void OnResourceStopping(CResource* pResource); - bool SetRadarMapDisabled(bool bDisabled, CResource* pResource); protected: void InternalSetPlayerMapEnabled(bool bEnabled); @@ -155,6 +154,5 @@ class CPlayerMap uchar m_ucCustomMapOpacity; bool m_bHasCustomMapOpacity; CResource* m_pCustomOpacityResource; - bool m_bRadarMapDisabled; CResource* m_pRadarMapDisabledResource; }; diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 472f99c7ae1..b85170c2024 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -8024,11 +8024,6 @@ bool CStaticFunctionDefinitions::ResetPlayerMapOpacity() return true; } -bool CStaticFunctionDefinitions::DisablePlayerMap(bool bDisable, CResource* pResource) -{ - return m_pPlayerMap->SetRadarMapDisabled(bDisable, pResource); -} - bool CStaticFunctionDefinitions::FxAddBlood(CVector& vecPosition, CVector& vecDirection, int iCount, float fBrightness) { g_pGame->GetFx()->AddBlood(vecPosition, vecDirection, iCount, fBrightness); diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 6d9c40a5acc..4c075c41209 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -729,7 +729,6 @@ class CStaticFunctionDefinitions static bool ResetPlayerMapImage(uint uiSize = 0); static bool SetPlayerMapOpacity(uchar ucOpacity, CResource* pResource); static bool ResetPlayerMapOpacity(); - static bool DisablePlayerMap(bool bDisable, CResource* pResource); // Fx funcs static bool FxAddBlood(CVector& vecPosition, CVector& vecDirection, int iCount, float fBrightness); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp index cebce06f593..aca8d553d78 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp @@ -57,7 +57,6 @@ void CLuaPlayerDefs::LoadFunctions() {"resetPlayerMapImage", ArgumentParser}, {"setPlayerMapOpacity", ArgumentParser}, {"resetPlayerMapOpacity", ArgumentParser}, - {"disablePlayerMap", ArgumentParser}, {"getPlayerHudComponentProperty", ArgumentParser}, }; @@ -87,7 +86,6 @@ void CLuaPlayerDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "resetMapImage", "resetPlayerMapImage"); lua_classfunction(luaVM, "setMapOpacity", "setPlayerMapOpacity"); lua_classfunction(luaVM, "resetMapOpacity", "resetPlayerMapOpacity"); - lua_classfunction(luaVM, "disableMap", "disablePlayerMap"); lua_classfunction(luaVM, "isHudComponentVisible", "isPlayerHudComponentVisible"); lua_classfunction(luaVM, "toggleControl", "toggleControl"); lua_classfunction(luaVM, "setHudComponentProperty", "setPlayerHudComponentProperty"); @@ -1116,13 +1114,3 @@ bool CLuaPlayerDefs::ResetPlayerMapOpacity() { return CStaticFunctionDefinitions::ResetPlayerMapOpacity(); } - -bool CLuaPlayerDefs::DisablePlayerMap(lua_State* luaVM, bool disable) -{ - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (!pLuaMain) - return false; - - CResource* pResource = pLuaMain->GetResource(); - return CStaticFunctionDefinitions::DisablePlayerMap(disable, pResource); -} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h index fe98f868f3a..d14072f8d17 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.h @@ -59,5 +59,4 @@ class CLuaPlayerDefs : public CLuaDefs static bool ResetPlayerMapImage(std::optional size); static bool SetPlayerMapOpacity(lua_State* luaVM, uchar opacity); static bool ResetPlayerMapOpacity(); - static bool DisablePlayerMap(lua_State* luaVM, bool disable); }; From 855f2d08bf21d7f91c6cc2390d1133567ba96c80 Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Thu, 4 Dec 2025 13:30:09 +0100 Subject: [PATCH 08/10] fix --- Client/mods/deathmatch/logic/CClientGame.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index b2d59d79425..0e8f9a52498 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -555,7 +555,6 @@ CClientGame::~CClientGame() { m_pPlayerMap->ResetCustomMapImage(); m_pPlayerMap->ResetMapOpacity(); - m_pPlayerMap->SetPlayerMapEnabled(true); } // Destroy our stuff From 41826bf02771229e8417ded7c2367cada852d7b5 Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Thu, 4 Dec 2025 13:42:59 +0100 Subject: [PATCH 09/10] use enum instead of magic numbers --- Client/mods/deathmatch/logic/CPlayerMap.cpp | 30 +++++------- Client/mods/deathmatch/logic/CPlayerMap.h | 46 +++++++++++++++---- .../logic/CStaticFunctionDefinitions.cpp | 12 ++--- .../logic/CStaticFunctionDefinitions.h | 6 +-- .../logic/luadefs/CLuaPlayerDefs.cpp | 25 ++++++---- 5 files changed, 73 insertions(+), 46 deletions(-) diff --git a/Client/mods/deathmatch/logic/CPlayerMap.cpp b/Client/mods/deathmatch/logic/CPlayerMap.cpp index b8548cd0892..f08f57b152c 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.cpp +++ b/Client/mods/deathmatch/logic/CPlayerMap.cpp @@ -800,15 +800,13 @@ SString CPlayerMap::GetBoundKeyName(const SString& strCommand) return strCommand; return pCommandBind->boundKey->szKey; } -bool CPlayerMap::SetCustomMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource) +bool CPlayerMap::SetCustomMapImage(const std::string& strTexturePath, ECustomMapResolution resolution, CResource* pResource) { - if (uiSize != 1024 && uiSize != 2048) - throw std::invalid_argument("Invalid map size (must be 1024 or 2048)"); - if (!pResource) return false; - std::size_t idx = (uiSize == 1024) ? 0 : 1; + std::size_t idx = MapResolutionToIndex(resolution); + std::uint32_t uiSize = MapResolutionToSize(resolution); SString strFullPath = pResource->GetResourceDirectoryPath() + strTexturePath; CTextureItem* pNewTexture = g_pCore->GetGraphics()->GetRenderItemManager()->CreateTexture(strFullPath, nullptr, false, uiSize, uiSize, RFORMAT_DXT1); @@ -832,19 +830,16 @@ bool CPlayerMap::SetCustomMapImage(const std::string& strTexturePath, uint uiSiz return true; } -bool CPlayerMap::SetCustomMapImageFromTexture(CClientTexture* pTexture, uint uiSize, CResource* pResource) +bool CPlayerMap::SetCustomMapImageFromTexture(CClientTexture* pTexture, ECustomMapResolution resolution, CResource* pResource) { if (!pTexture || !pResource) return false; - if (uiSize != 1024 && uiSize != 2048) - throw std::invalid_argument("Invalid map size (must be 1024 or 2048)"); - CTextureItem* pTextureItem = pTexture->GetTextureItem(); if (!pTextureItem) throw std::invalid_argument("Invalid texture element"); - std::size_t idx = (uiSize == 1024) ? 0 : 1; + std::size_t idx = MapResolutionToIndex(resolution); // If the current map index does not match, update it if (idx != m_playerMapImageIndex) @@ -873,20 +868,17 @@ bool CPlayerMap::SetCustomMapImageFromTexture(CClientTexture* pTexture, uint uiS return true; } -void CPlayerMap::ResetCustomMapImage(uint uiSize) +void CPlayerMap::ResetCustomMapImage(std::optional resolution) { - // If size is 0, reset both sizes - if (uiSize == 0) + // If resolution is not provided, reset both sizes + if (!resolution.has_value()) { - ResetCustomMapImage(1024); - ResetCustomMapImage(2048); + ResetCustomMapImage(ECustomMapResolution::Res_1024); + ResetCustomMapImage(ECustomMapResolution::Res_2048); return; } - - if (uiSize != 1024 && uiSize != 2048) - return; - std::size_t idx = (uiSize == 1024) ? 0 : 1; + std::size_t idx = MapResolutionToIndex(resolution.value()); if (!m_customMapData[idx].pTextureElement && m_customMapData[idx].pTexture) { diff --git a/Client/mods/deathmatch/logic/CPlayerMap.h b/Client/mods/deathmatch/logic/CPlayerMap.h index 989f451a5f4..1693402b9a7 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.h +++ b/Client/mods/deathmatch/logic/CPlayerMap.h @@ -19,6 +19,35 @@ class CResource; class CClientTexture; +enum class ECustomMapResolution : std::uint32_t +{ + Res_1024 = 1024, + Res_2048 = 2048 +}; + +inline std::size_t MapResolutionToIndex(ECustomMapResolution resolution) +{ + return resolution == ECustomMapResolution::Res_1024 ? 0 : 1; +} + +inline std::uint32_t MapResolutionToSize(ECustomMapResolution resolution) +{ + return static_cast(resolution); +} + +inline std::optional UIntToMapResolution(std::uint32_t value) +{ + switch (value) + { + case static_cast(ECustomMapResolution::Res_1024): + return ECustomMapResolution::Res_1024; + case static_cast(ECustomMapResolution::Res_2048): + return ECustomMapResolution::Res_2048; + default: + return std::nullopt; + } +} + class CPlayerMap { public: @@ -40,17 +69,16 @@ class CPlayerMap void ToggleHelpText(); - bool SetCustomMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource = nullptr); - bool SetCustomMapImageFromTexture(CClientTexture* pTexture, uint uiSize, CResource* pResource = nullptr); - void ResetCustomMapImage(uint uiSize = 0); - bool SetMapOpacity(uchar ucOpacity, CResource* pResource = nullptr); - void ResetMapOpacity(); + bool SetCustomMapImage(const std::string& strTexturePath, ECustomMapResolution resolution, CResource* pResource = nullptr); + bool SetCustomMapImageFromTexture(CClientTexture* pTexture, ECustomMapResolution resolution, CResource* pResource = nullptr); + void ResetCustomMapImage(std::optional resolution = std::nullopt); + bool SetMapOpacity(uchar ucOpacity, CResource* pResource = nullptr); + void ResetMapOpacity(); uchar GetMapOpacity() const; - bool HasCustomMapImage(uint uiSize) const { - std::size_t idx = (uiSize == 1024) ? 0 : 1; - return m_customMapData[idx].bHasCustomMap; + bool HasCustomMapImage(ECustomMapResolution resolution) const { + return m_customMapData[MapResolutionToIndex(resolution)].bHasCustomMap; } - void OnResourceStopping(CResource* pResource); + void OnResourceStopping(CResource* pResource); protected: void InternalSetPlayerMapEnabled(bool bEnabled); diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index b85170c2024..d76f2064e83 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -7997,19 +7997,19 @@ bool CStaticFunctionDefinitions::GetPlayerMapBoundingBox(CVector& vecMin, CVecto return false; } -bool CStaticFunctionDefinitions::SetPlayerMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource) +bool CStaticFunctionDefinitions::SetPlayerMapImage(const std::string& strTexturePath, ECustomMapResolution resolution, CResource* pResource) { - return m_pPlayerMap->SetCustomMapImage(strTexturePath, uiSize, pResource); + return m_pPlayerMap->SetCustomMapImage(strTexturePath, resolution, pResource); } -bool CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(CClientTexture* pTexture, uint uiSize, CResource* pResource) +bool CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(CClientTexture* pTexture, ECustomMapResolution resolution, CResource* pResource) { - return m_pPlayerMap->SetCustomMapImageFromTexture(pTexture, uiSize, pResource); + return m_pPlayerMap->SetCustomMapImageFromTexture(pTexture, resolution, pResource); } -bool CStaticFunctionDefinitions::ResetPlayerMapImage(uint uiSize) +bool CStaticFunctionDefinitions::ResetPlayerMapImage(std::optional resolution) { - m_pPlayerMap->ResetCustomMapImage(uiSize); + m_pPlayerMap->ResetCustomMapImage(resolution); return true; } diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 4c075c41209..d20c1b1aaca 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -724,9 +724,9 @@ class CStaticFunctionDefinitions static bool IsPlayerMapForced(bool& bForced); static bool IsPlayerMapVisible(bool& bVisible); static bool GetPlayerMapBoundingBox(CVector& vecMin, CVector& vecMax); - static bool SetPlayerMapImage(const std::string& strTexturePath, uint uiSize, CResource* pResource); - static bool SetPlayerMapImageFromTexture(CClientTexture* pTexture, uint uiSize, CResource* pResource); - static bool ResetPlayerMapImage(uint uiSize = 0); + static bool SetPlayerMapImage(const std::string& strTexturePath, ECustomMapResolution resolution, CResource* pResource); + static bool SetPlayerMapImageFromTexture(CClientTexture* pTexture, ECustomMapResolution resolution, CResource* pResource); + static bool ResetPlayerMapImage(std::optional resolution = std::nullopt); static bool SetPlayerMapOpacity(uchar ucOpacity, CResource* pResource); static bool ResetPlayerMapOpacity(); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp index aca8d553d78..49a0c25b270 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaPlayerDefs.cpp @@ -10,6 +10,8 @@ *****************************************************************************/ #include "StdInc.h" +#include "CLuaPlayerDefs.h" +#include "CPlayerMap.h" #include "lua/CLuaFunctionParser.h" void CLuaPlayerDefs::LoadFunctions() @@ -1070,19 +1072,22 @@ bool CLuaPlayerDefs::SetPlayerMapImage(lua_State* luaVM, std::variantGetResource(); + if (!size.has_value()) + return false; + + auto resolution = UIntToMapResolution(size.value()); + if (!resolution.has_value()) + throw std::invalid_argument("Invalid map size (must be 1024 or 2048)"); + if (std::holds_alternative(texturePathOrElement)) { CClientTexture* pTexture = std::get(texturePathOrElement); - if (!size.has_value()) - return false; - return CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(pTexture, size.value(), pResource); + return CStaticFunctionDefinitions::SetPlayerMapImageFromTexture(pTexture, resolution.value(), pResource); } else { std::string strPath = std::get(texturePathOrElement); - if (!size.has_value()) - return false; - return CStaticFunctionDefinitions::SetPlayerMapImage(strPath, size.value(), pResource); + return CStaticFunctionDefinitions::SetPlayerMapImage(strPath, resolution.value(), pResource); } } @@ -1090,13 +1095,15 @@ bool CLuaPlayerDefs::ResetPlayerMapImage(std::optional size) { if (size.has_value()) { - if (*size != 1024 && *size != 2048) + auto resolution = UIntToMapResolution(*size); + if (!resolution.has_value()) throw std::invalid_argument("Invalid map size (must be 1024 or 2048)"); - return CStaticFunctionDefinitions::ResetPlayerMapImage(*size); + + return CStaticFunctionDefinitions::ResetPlayerMapImage(resolution.value()); } else { - return CStaticFunctionDefinitions::ResetPlayerMapImage(0); + return CStaticFunctionDefinitions::ResetPlayerMapImage(std::nullopt); } } From 33fbfcc582a9dc76be2b3a230307a19f6c3aefec Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Thu, 4 Dec 2025 14:01:40 +0100 Subject: [PATCH 10/10] crashfix --- Client/mods/deathmatch/logic/CPlayerMap.cpp | 30 +++------------------ 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/Client/mods/deathmatch/logic/CPlayerMap.cpp b/Client/mods/deathmatch/logic/CPlayerMap.cpp index f08f57b152c..09acc7ecfc1 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.cpp +++ b/Client/mods/deathmatch/logic/CPlayerMap.cpp @@ -840,24 +840,6 @@ bool CPlayerMap::SetCustomMapImageFromTexture(CClientTexture* pTexture, ECustomM throw std::invalid_argument("Invalid texture element"); std::size_t idx = MapResolutionToIndex(resolution); - - // If the current map index does not match, update it - if (idx != m_playerMapImageIndex) - { - m_playerMapImageIndex = idx; - try { - CreateOrUpdateMapTexture(); - } catch (...) { - // Ignore errors - } - } - - // Release old texture if it existed and was not element-based - if (!m_customMapData[idx].pTextureElement && m_customMapData[idx].pTexture) - { - SAFE_RELEASE(m_customMapData[idx].pTexture); - m_customMapData[idx].pTexture = nullptr; - } m_customMapData[idx].pTexture = pTextureItem; m_customMapData[idx].strPath = ""; @@ -959,19 +941,13 @@ void CPlayerMap::OnResourceStopping(CResource* pResource) if (m_customMapData[i].bHasCustomMap && m_customMapData[i].pResource == pResource) { if (!m_customMapData[i].pTextureElement && m_customMapData[i].pTexture) - { SAFE_RELEASE(m_customMapData[i].pTexture); - m_customMapData[i].pTexture = nullptr; - } - else - { - m_customMapData[i].pTexture = nullptr; - } - + + m_customMapData[i].pTexture = nullptr; + m_customMapData[i].pTextureElement = nullptr; m_customMapData[i].bHasCustomMap = false; m_customMapData[i].strPath = ""; m_customMapData[i].pResource = nullptr; - m_customMapData[i].pTextureElement = nullptr; } }