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());