diff --git a/Dalamud/Interface/Textures/Internal/SharedImmediateTextures/GamePathSharedImmediateTexture.cs b/Dalamud/Interface/Textures/Internal/SharedImmediateTextures/GamePathSharedImmediateTexture.cs index 6b3d13588..1190c9550 100644 --- a/Dalamud/Interface/Textures/Internal/SharedImmediateTextures/GamePathSharedImmediateTexture.cs +++ b/Dalamud/Interface/Textures/Internal/SharedImmediateTextures/GamePathSharedImmediateTexture.cs @@ -3,11 +3,12 @@ using System.Threading; using System.Threading.Tasks; using Dalamud.Data; -using Dalamud.Interface.Internal; using Dalamud.Interface.Textures.TextureWraps; using Lumina.Data.Files; +using Serilog; + namespace Dalamud.Interface.Textures.Internal.SharedImmediateTextures; /// Represents a sharable texture, based on a file in game resources. @@ -35,9 +36,39 @@ internal sealed class GamePathSharedImmediateTexture : SharedImmediateTexture { var dm = await Service.GetAsync(); var tm = await Service.GetAsync(); + + TexFile? file; + var substPath = tm.GetSubstitutedPath(this.path); - if (dm.GetFile(substPath) is not { } file) - throw new FileNotFoundException(); + if (!string.IsNullOrWhiteSpace(substPath) && substPath != this.path) + { + try + { + file = + Path.IsPathRooted(this.path) + ? dm.GameData.GetFileFromDisk(substPath, this.path) + : dm.GetFile(substPath) ?? + throw new FileNotFoundException("Game file not found.", substPath); + } + catch (Exception e) + { + file = dm.GetFile(this.path); + if (file is null) + throw; + + Log.Warning( + e, + "{who}: substitute path {subst} for {orig} failed to load. Using original path instead.", + nameof(GamePathSharedImmediateTexture), + substPath, + this.path); + } + } + else + { + file = dm.GetFile(this.path) ?? throw new FileNotFoundException("Game file not found.", this.path); + } + cancellationToken.ThrowIfCancellationRequested(); var wrap = tm.NoThrottleCreateFromTexFile(file); tm.BlameSetName(wrap, this.ToString());