@@ -1162,7 +1162,9 @@ namespace
11621162 return nullptr ;
11631163 }
11641164
1165- // Capture all TXD textures for restoration
1165+ // Capture all TXD textures for restoration, filtering out MTA-injected textures.
1166+ // Without filtering, MTA masters/copies still linked in the TXD get recorded as
1167+ // "originals," contaminating the baseline used by canProveNoLeaks comparisons.
11661168 void PopulateOriginalTextures (CModelTexturesInfo& info, RwTexDictionary* pTxd)
11671169 {
11681170 info.originalTextures .clear ();
@@ -1174,10 +1176,39 @@ namespace
11741176 std::vector<RwTexture*> allTextures;
11751177 CRenderWareSA::GetTxdTextures (allTextures, pTxd);
11761178
1179+ // Build a set of rasters owned by known MTA textures for fast filtering.
1180+ // Both masters and copies share the same raster, so a raster-level check
1181+ // catches both without needing separate copy tracking.
1182+ std::unordered_set<RwRaster*> mtaRasters;
1183+
1184+ for (RwTexture* pMaster : g_LeakedMasterTextures)
1185+ {
1186+ if (pMaster && pMaster->raster )
1187+ mtaRasters.insert (pMaster->raster );
1188+ }
1189+
1190+ for (const SReplacementTextures* pReplacement : info.usedByReplacements )
1191+ {
1192+ if (!pReplacement || !IsReplacementActive (pReplacement))
1193+ continue ;
1194+
1195+ for (RwTexture* pMasterTex : pReplacement->textures )
1196+ {
1197+ if (pMasterTex && pMasterTex->raster )
1198+ mtaRasters.insert (pMasterTex->raster );
1199+ }
1200+ }
1201+
11771202 for (RwTexture* pTex : allTextures)
11781203 {
1179- if (pTex)
1180- info.originalTextures .insert (pTex);
1204+ if (!pTex)
1205+ continue ;
1206+
1207+ // Reject textures whose raster belongs to an MTA master or copy
1208+ if (!mtaRasters.empty () && pTex->raster && mtaRasters.count (pTex->raster ) != 0 )
1209+ continue ;
1210+
1211+ info.originalTextures .insert (pTex);
11811212 }
11821213
11831214 // Build name map for lookup after replacements
0 commit comments