From 440d0b91b456814cd74b66dc55039da08705df37 Mon Sep 17 00:00:00 2001 From: Jarrod Doyle Date: Thu, 19 Sep 2024 21:16:07 +0100 Subject: [PATCH] Path manager refactor --- project/code/LGS/ResourcePathManager.cs | 490 ++++++++++++------------ project/code/TMV/Context.cs | 9 +- project/code/TMV/Mission.cs | 21 +- project/code/TMV/Model.cs | 2 +- project/code/TMV/ModelLoader.cs | 16 +- project/code/TMV/TextureLoader.cs | 8 +- project/code/TMV/UI/ResourceSelector.cs | 13 +- project/code/TMV/UI/TextureBrowser.cs | 13 +- 8 files changed, 293 insertions(+), 279 deletions(-) diff --git a/project/code/LGS/ResourcePathManager.cs b/project/code/LGS/ResourcePathManager.cs index d246cf3..6a27c77 100644 --- a/project/code/LGS/ResourcePathManager.cs +++ b/project/code/LGS/ResourcePathManager.cs @@ -6,6 +6,22 @@ using System.Linq; namespace KeepersCompound.LGS; +// TODO: Make this nicer to use! +// Rather than navigating through the path manager Context should hold the current campaign resources +// Campaign resources should be lazy loaded (only get the paths when we first set it as campaign) +// Campaign resources should extend off of the base game resources and just overwrite any resource paths it needs to + +enum ConfigFile +{ + Cam, + CamExt, + CamMod, + Game, + Install, + User, + ConfigFileCount, +} + public enum ResourceType { Mission, @@ -16,21 +32,23 @@ public enum ResourceType public class ResourcePathManager { - private record CampaignResources + public record CampaignResources { - public Dictionary missionPathMap; - public Dictionary texturePathMap; - public Dictionary objectPathMap; - public Dictionary objectTexturePathMap; + public bool initialised = false; + public string name; + private readonly Dictionary _missionPathMap = []; + private readonly Dictionary _texturePathMap = []; + private readonly Dictionary _objectPathMap = []; + private readonly Dictionary _objectTexturePathMap = []; public List GetResourceNames(ResourceType type) { List keys = type switch { - ResourceType.Mission => [.. missionPathMap.Keys], - ResourceType.Object => [.. objectPathMap.Keys], - ResourceType.ObjectTexture => [.. objectTexturePathMap.Keys], - ResourceType.Texture => [.. texturePathMap.Keys], + ResourceType.Mission => [.. _missionPathMap.Keys], + ResourceType.Object => [.. _objectPathMap.Keys], + ResourceType.ObjectTexture => [.. _objectTexturePathMap.Keys], + ResourceType.Texture => [.. _texturePathMap.Keys], _ => throw new ArgumentOutOfRangeException(nameof(type)), }; keys.Sort(); @@ -41,13 +59,58 @@ public class ResourcePathManager { var map = type switch { - ResourceType.Mission => missionPathMap, - ResourceType.Object => objectPathMap, - ResourceType.ObjectTexture => objectTexturePathMap, - ResourceType.Texture => texturePathMap, + ResourceType.Mission => _missionPathMap, + ResourceType.Object => _objectPathMap, + ResourceType.ObjectTexture => _objectTexturePathMap, + ResourceType.Texture => _texturePathMap, _ => throw new ArgumentOutOfRangeException(nameof(type)), }; - return map.TryGetValue(name, out var resourcePath) ? resourcePath : null; + return map.TryGetValue(name.ToLower(), out var resourcePath) ? resourcePath : null; + } + + public void Initialise(string misPath, string resPath) + { + foreach (var path in Directory.GetFiles(misPath)) + { + var convertedPath = ConvertSeparator(path); + var ext = Path.GetExtension(convertedPath).ToLower(); + if (ext == ".mis" || ext == ".cow") + { + var baseName = Path.GetFileName(convertedPath).ToLower(); + _missionPathMap[baseName] = convertedPath; + } + } + + foreach (var (name, path) in GetTexturePaths(resPath)) + { + _texturePathMap[name] = path; + } + foreach (var (name, path) in GetObjectPaths(resPath)) + { + _objectPathMap[name] = path; + } + foreach (var (name, path) in GetObjectTexturePaths(resPath)) + { + _objectTexturePathMap[name] = path; + } + } + + public void Initialise(string misPath, string resPath, CampaignResources parent) + { + foreach (var (name, path) in parent._texturePathMap) + { + _texturePathMap[name] = path; + } + foreach (var (name, path) in parent._objectPathMap) + { + _objectPathMap[name] = path; + } + foreach (var (name, path) in parent._objectTexturePathMap) + { + _objectTexturePathMap[name] = path; + } + + Initialise(misPath, resPath); } } @@ -67,70 +130,83 @@ public class ResourcePathManager return path.Replace('\\', '/'); } - public bool Init(string installPath) + public void Init(string installPath) { - // TODO: This can be done less awkwardly with the resource paths - if (DirContainsThiefExe(installPath) && - TryGetInstallCfgPath(installPath, out var installCfgPath) && - TryBuildOmsPathMap(installPath, installCfgPath, out var omsMap) && - TryBuildFmsPathMap(installPath, out var fmsMap, out var fmsDir) && - TryGetPath(installPath, "fam.crf", out var famPath) && - TryGetPath(installPath, "obj.crf", out var objPath)) + // TODO: + // - Determine if folder is a thief install + // - Load all the (relevant) config files + // - Get base paths from configs + // - Build list of FM campaigns + // - Initialise OM campaign resource paths + // - Lazy load FM campaign resource paths (that inherit OM resources) + + if (!DirContainsThiefExe(installPath)) { - // Register OM resources - { - var famExtractPath = Path.Join(_extractionPath, "fam"); - if (Directory.Exists(famExtractPath)) - { - Directory.Delete(famExtractPath, true); - } - ZipFile.OpenRead(famPath).ExtractToDirectory(famExtractPath); - var texturePathMap = GetTexturePaths(_extractionPath); - - var objExtractPath = Path.Join(_extractionPath, "obj"); - if (Directory.Exists(objExtractPath)) - { - Directory.Delete(objExtractPath, true); - } - ZipFile.OpenRead(objPath).ExtractToDirectory(objExtractPath); - var objectPathMap = GetObjectPaths(_extractionPath); - var objectTexturePathMap = GetObjectTexturePaths(_extractionPath); - - _omResources = new CampaignResources - { - missionPathMap = omsMap, - texturePathMap = texturePathMap, - objectPathMap = objectPathMap, - objectTexturePathMap = objectTexturePathMap, - }; - } - - { - _fmResources = new Dictionary(); - foreach (var (campaign, missionPathMap) in fmsMap) - { - var root = Path.Join(fmsDir, campaign); - var texturePathMap = GetTexturePaths(root); - var objectPathMap = GetObjectPaths(root); - var objectTexturePathMap = GetObjectTexturePaths(root); - - var resource = new CampaignResources - { - missionPathMap = missionPathMap, - texturePathMap = texturePathMap, - objectPathMap = objectPathMap, - objectTexturePathMap = objectTexturePathMap, - }; - _fmResources.Add(campaign, resource); - _fmsDir = fmsDir; - } - } - - _initialised = true; - return true; + throw new ArgumentException($"No Thief installation found at {installPath}", nameof(installPath)); } - return false; + // TODO: Should these paths be stored? + if (!TryGetConfigPaths(installPath, out var configPaths)) + { + throw new InvalidOperationException("Failed to find all installation config paths."); + } + + // Get the paths of the base Fam and Obj resources so we can extract them. + var installCfgLines = File.ReadAllLines(configPaths[(int)ConfigFile.Install]); + FindConfigVar(installCfgLines, "resname_base", out var resPaths); + var baseFamPath = ""; + var baseObjPath = ""; + foreach (var resPath in resPaths.Split('+')) + { + var dir = Path.Join(installPath, ConvertSeparator(resPath)); + foreach (var path in Directory.GetFiles(dir)) + { + var name = Path.GetFileName(path).ToLower(); + if (name == "fam.crf" && baseFamPath == "") + { + baseFamPath = path; + } + else if (name == "obj.crf" && baseObjPath == "") + { + baseObjPath = path; + } + } + } + + // Do the extraction bro + (string, string)[] resources = [("fam", baseFamPath), ("obj", baseObjPath)]; + foreach (var (extractName, zipPath) in resources) + { + var extractPath = Path.Join(_extractionPath, extractName); + if (Directory.Exists(extractPath)) + { + Directory.Delete(extractPath, true); + } + ZipFile.OpenRead(zipPath).ExtractToDirectory(extractPath); + } + + FindConfigVar(installCfgLines, "load_path", out var omsPath); + omsPath = Path.Join(installPath, ConvertSeparator(omsPath)); + _omResources = new CampaignResources(); + _omResources.name = ""; + _omResources.Initialise(omsPath, _extractionPath); + + var camModLines = File.ReadAllLines(configPaths[(int)ConfigFile.CamMod]); + FindConfigVar(camModLines, "fm_path", out var fmsPath, "FMs"); + _fmsDir = Path.Join(installPath, fmsPath); + + // Build up the map of FM campaigns. These are uninitialised, we just want + // to have their name + _fmResources = new Dictionary(); + foreach (var dir in Directory.GetDirectories(_fmsDir)) + { + var name = Path.GetFileName(dir); + var fmResource = new CampaignResources(); + fmResource.name = name; + _fmResources.Add(name, fmResource); + } + + _initialised = true; } public List GetCampaignNames() @@ -142,60 +218,25 @@ public class ResourcePathManager return names; } - public List GetResourceNames(ResourceType type, string campaignName) + public CampaignResources GetCampaign(string campaignName) { - if (!_initialised) - { - throw new InvalidOperationException("Resource Path Manager hasn't been initialised."); - } - if (campaignName == null || campaignName == "") { - return _omResources.GetResourceNames(type); + return _omResources; } else if (_fmResources.TryGetValue(campaignName, out var campaign)) { - return campaign.GetResourceNames(type); + if (!campaign.initialised) + { + var fmPath = Path.Join(_fmsDir, campaignName); + campaign.Initialise(fmPath, fmPath, _omResources); + } + return campaign; } throw new ArgumentException("No campaign found with given name", nameof(campaignName)); } - // This expects resourceName to already have it's separator converted - public (string, string) GetResourcePath( - ResourceType type, - string campaignName, - string resourceName) - { - if (!_initialised) - { - throw new InvalidOperationException("Resource Path Manager hasn't been initialised."); - } - - resourceName = resourceName.ToLower(); - var omResourcePath = _omResources.GetResourcePath(type, resourceName); - - if (campaignName == null || campaignName == "" && omResourcePath != null) - { - return ("", omResourcePath); - } - else if (_fmResources.TryGetValue(campaignName, out var campaign)) - { - var fmResourcePath = campaign.GetResourcePath(type, resourceName); - if (fmResourcePath != null) - { - return (campaignName, fmResourcePath); - } - else if (omResourcePath != null) - { - return ("", omResourcePath); - } - } - - // throw new ArgumentException($"No resource found with given type and name: {type}, {resourceName}", nameof(resourceName)); - return (null, null); - } - private static Dictionary GetObjectTexturePaths(string root) { string[] validExtensions = { ".dds", ".png", ".tga", ".pcx", ".gif", ".bmp", ".cel", }; @@ -277,100 +318,11 @@ public class ResourcePathManager return pathMap; } - private static bool TryBuildOmsPathMap(string root, string cfgPath, out Dictionary map) - { - map = new Dictionary(); - - var omsPath = ""; - foreach (var line in File.ReadLines(cfgPath)) - { - if (line.StartsWith("load_path")) - { - // TODO: This can have multiple paths I think - var path = ConvertSeparator(line.Split(" ")[1]); - omsPath = Path.GetFullPath(root + path); - break; - } - } - if (omsPath == "") - { - return false; - } - - var searchOptions = new EnumerationOptions - { - MatchCasing = MatchCasing.CaseInsensitive, - }; - foreach (var path in Directory.GetFiles(omsPath, "*.mis", searchOptions)) - { - var convertedPath = ConvertSeparator(path); - var baseName = Path.GetFileName(convertedPath).ToLower(); - map.Add(baseName, convertedPath); - } - - return true; - } - - private static bool TryBuildFmsPathMap( - string root, - out Dictionary> fmsMap, - out string fmsPath) - { - fmsMap = new Dictionary>(); - fmsPath = root + "/FMs"; - - var searchOptions = new EnumerationOptions - { - MatchCasing = MatchCasing.CaseInsensitive, - RecurseSubdirectories = true - }; - - // Cam Mod tells us where any FMs are installed (alongside other things) - // If it doesn't exist then something is wrong with the install directory - if (!TryGetPath(root, "cam_mod.ini", out var camModPath)) - { - return false; - } - - // We're looking for an uncommented line defining an fm_path, but its - // find if we don't find one because there's a default path. - foreach (var line in File.ReadLines(camModPath)) - { - if (line.StartsWith("fm_path")) - { - // TODO: I think this can technically contain multiple paths - var path = ConvertSeparator(line.Split(" ")[1]); - fmsPath = Path.GetFullPath(root + path); - break; - } - } - - // Now we can iterate through all the FM directories and map their mission paths - // if they have any. - string[] extensions = { ".mis", ".cow" }; - searchOptions.RecurseSubdirectories = false; - foreach (var dir in Directory.GetDirectories(fmsPath)) - { - var campaignMap = new Dictionary(); - foreach (var path in Directory.GetFiles(dir)) - { - var convertedPath = ConvertSeparator(path); - if (extensions.Contains(Path.GetExtension(convertedPath).ToLower())) - { - var baseName = Path.GetFileName(convertedPath).ToLower(); - campaignMap.Add(baseName, ConvertSeparator(path)); - } - } - - if (campaignMap.Count != 0) - { - fmsMap.Add(Path.GetFileName(dir), campaignMap); - } - } - - return true; - } - + /// + /// Determine if the given directory contains a Thief executable at the top level. + /// + /// The directory to search + /// true if a Thief executable was found, false otherwise. private static bool DirContainsThiefExe(string dir) { var searchOptions = new EnumerationOptions @@ -390,44 +342,108 @@ public class ResourcePathManager return false; } - private static bool TryGetInstallCfgPath(string dir, out string installCfgPath) + /// + /// Get an array of of all the Dark config file paths. + /// + /// Root directory of the Thief installation. + /// Output array of config file paths + /// true if all config files were found, false otherwise. + private static bool TryGetConfigPaths(string installPath, out string[] configPaths) { + configPaths = new string[(int)ConfigFile.ConfigFileCount]; + var searchOptions = new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, - RecurseSubdirectories = true }; - foreach (var path in Directory.GetFiles(dir, "*.cfg", searchOptions)) + // `cam.cfg`, `cam_ext.cfg`, and `cam_mod.ini` are always in the root of the install. + // The first two configs will tell us if any other configs are in non-default locations. + // We can't just do a recursive search for everything else because they can potentially + // be *outside* of the Thief installation. + foreach (var path in Directory.GetFiles(installPath, "cam*", searchOptions)) { - var baseName = Path.GetFileName(path).ToLower(); - if (baseName == "install.cfg" || baseName == "darkinst.cfg") + var name = Path.GetFileName(path).ToLower(); + if (name == "cam.cfg") { - installCfgPath = path; + configPaths[(int)ConfigFile.Cam] = path; + } + else if (name == "cam_ext.cfg") + { + configPaths[(int)ConfigFile.CamExt] = path; + } + else if (name == "cam_mod.ini") + { + configPaths[(int)ConfigFile.CamMod] = path; + } + } + + var camExtLines = File.ReadAllLines(configPaths[(int)ConfigFile.CamExt]); + var camLines = File.ReadAllLines(configPaths[(int)ConfigFile.Cam]); + + bool FindCamVar(string varName, out string value, string defaultValue = "") + { + return FindConfigVar(camExtLines, varName, out value, defaultValue) || + FindConfigVar(camLines, varName, out value, defaultValue); + } + + FindCamVar("include_path", out var includePath, "./"); + FindCamVar("game", out var gameName); + FindCamVar($"{gameName}_include_install_cfg", out var installCfgName); + FindCamVar("include_user_cfg", out var userCfgName); + + // TODO: How to handle case-insensitive absolute paths? + // Fixup the include path to "work" cross-platform + includePath = ConvertSeparator(includePath); + includePath = Path.Join(installPath, includePath); + if (!Directory.Exists(includePath)) + { + return false; + } + + foreach (var path in Directory.GetFiles(includePath, "*.cfg", searchOptions)) + { + var name = Path.GetFileName(path).ToLower(); + if (name == $"{gameName}.cfg") + { + configPaths[(int)ConfigFile.Game] = path; + } + else if (name == installCfgName.ToLower()) + { + configPaths[(int)ConfigFile.Install] = path; + } + else if (name == userCfgName.ToLower()) + { + configPaths[(int)ConfigFile.User] = path; + } + } + + // Check we found everything + var i = 0; + foreach (var path in configPaths) + { + if (path == null || path == "") + { + return false; + } + i++; + } + return true; + } + + private static bool FindConfigVar(string[] lines, string varName, out string value, string defaultValue = "") + { + value = defaultValue; + + foreach (var line in lines) + { + if (line.StartsWith(varName)) + { + value = line[(line.IndexOf(' ') + 1)..]; return true; } } - installCfgPath = ""; - return false; - } - - private static bool TryGetPath(string dir, string searchPattern, out string path) - { - var searchOptions = new EnumerationOptions - { - MatchCasing = MatchCasing.CaseInsensitive, - RecurseSubdirectories = true - }; - - var paths = Directory.GetFiles(dir, searchPattern, searchOptions); - if (paths.Length > 0) - { - path = paths[0]; - return true; - } - - path = ""; return false; } } \ No newline at end of file diff --git a/project/code/TMV/Context.cs b/project/code/TMV/Context.cs index 228491e..abfe093 100644 --- a/project/code/TMV/Context.cs +++ b/project/code/TMV/Context.cs @@ -9,15 +9,20 @@ public partial class Context : Node public ResourcePathManager PathManager { get; private set; } public ModelLoader ModelLoader { get; private set; } - public string CampaignName { get; set; } + public ResourcePathManager.CampaignResources CampaignResources { get; private set; } public override void _Ready() { var extractPath = ProjectSettings.GlobalizePath($"user://extracted/tmp"); PathManager = new ResourcePathManager(extractPath); ModelLoader = new ModelLoader(); - CampaignName = ""; + CampaignResources = PathManager.GetCampaign(""); Instance = this; } + + public void SetCampaign(string campaignName) + { + CampaignResources = PathManager.GetCampaign(campaignName); + } } \ No newline at end of file diff --git a/project/code/TMV/Mission.cs b/project/code/TMV/Mission.cs index 4d71061..fb7af0f 100644 --- a/project/code/TMV/Mission.cs +++ b/project/code/TMV/Mission.cs @@ -58,15 +58,11 @@ public partial class Mission : Node3D var resourceSelector = GetNode("%ResourceSelector") as ResourceSelector; resourceSelector.ResourceSelected += (string campaign, string mission) => { - var context = Context.Instance; - context.CampaignName = campaign; _missionName = mission; - var (newCampaign, missionPath) = context.PathManager.GetResourcePath(ResourceType.Mission, campaign, mission); - if (newCampaign != campaign) - { - GD.Print($"Didn't find campaign mission: ({campaign}, {mission})"); - } - FileName = missionPath; + + var context = Context.Instance; + context.SetCampaign(campaign); + FileName = context.CampaignResources.GetResourcePath(ResourceType.Mission, mission); Build = true; }; } @@ -120,7 +116,7 @@ public partial class Mission : Node3D { ClearMap(); - _textureLoader = new TextureLoader(Context.Instance.CampaignName); + _textureLoader = new TextureLoader(); Timing.TimeStage("DbFile Parse", () => _file = new(FileName)); Timing.TimeStage("Register Textures", () => UseChunk("TXLIST", RegisterTextures)); Timing.TimeStage("Build WR", () => UseChunk("WREXT", BuildWrMeshes)); @@ -285,19 +281,18 @@ public partial class Mission : Node3D path = prop.value; - var pathManager = Context.Instance.PathManager; - var campaign = Context.Instance.CampaignName; + var campaignResources = Context.Instance.CampaignResources; if (path.StartsWith("fam", StringComparison.OrdinalIgnoreCase)) { var resType = ResourceType.Texture; - path = pathManager.GetResourcePath(resType, campaign, prop.value).Item2; + path = campaignResources.GetResourcePath(resType, prop.value); } else { var resType = ResourceType.ObjectTexture; var convertedValue = ResourcePathManager.ConvertSeparator(prop.value); var resName = Path.GetFileNameWithoutExtension(convertedValue); - path = pathManager.GetResourcePath(resType, campaign, resName).Item2; + path = campaignResources.GetResourcePath(resType, resName); } return path != null; diff --git a/project/code/TMV/Model.cs b/project/code/TMV/Model.cs index 46791b2..944e24e 100644 --- a/project/code/TMV/Model.cs +++ b/project/code/TMV/Model.cs @@ -18,7 +18,7 @@ public partial class Model : Node3D node.QueueFree(); } - Context.Instance.CampaignName = campaignName; + Context.Instance.SetCampaign(campaignName); var model = Context.Instance.ModelLoader.Load(modelPath); AddChild(model); } diff --git a/project/code/TMV/ModelLoader.cs b/project/code/TMV/ModelLoader.cs index cfff4c6..385a5af 100644 --- a/project/code/TMV/ModelLoader.cs +++ b/project/code/TMV/ModelLoader.cs @@ -5,13 +5,15 @@ using KeepersCompound.LGS; namespace KeepersCompound.TMV; +// TODO: Work out a way to share base game models again in the cache public class ModelLoader { private readonly Dictionary<(string, string), MeshInstance3D> _cache = new(); public MeshInstance3D Load(string modelName, bool forceLoad = false) { - var campaignName = Context.Instance.CampaignName; + var campaignResources = Context.Instance.CampaignResources; + var campaignName = campaignResources.name; campaignName ??= ""; if (!forceLoad) @@ -27,20 +29,20 @@ public class ModelLoader } // We don't care if this is null actually, we'll still cache that it's null lol - var model = Timing.TimeStage("Load Models", () => { return LoadModel(ref campaignName, modelName); }); + var model = Timing.TimeStage("Load Models", () => { return LoadModel(modelName); }); _cache[(campaignName, modelName)] = model; return model?.Duplicate() as MeshInstance3D; } - public static MeshInstance3D LoadModel(ref string campaignName, string modelName) + public static MeshInstance3D LoadModel(string modelName) { - var pathManager = Context.Instance.PathManager; - var (newCampaignName, modelPath) = pathManager.GetResourcePath(ResourceType.Object, campaignName, modelName); - campaignName = newCampaignName; + var campaignResources = Context.Instance.CampaignResources; + var modelPath = campaignResources.GetResourcePath(ResourceType.Object, modelName); if (modelPath == null) { return null; } + var modelFile = new ModelFile(modelPath); if (modelFile == null) { @@ -55,7 +57,7 @@ public class ModelLoader { var convertedName = ResourcePathManager.ConvertSeparator(material.Name); var resName = Path.GetFileNameWithoutExtension(convertedName); - var (_, path) = pathManager.GetResourcePath(ResourceType.ObjectTexture, campaignName, resName); + var path = campaignResources.GetResourcePath(ResourceType.ObjectTexture, resName); if (path == null) { // Might fail in exported projects diff --git a/project/code/TMV/TextureLoader.cs b/project/code/TMV/TextureLoader.cs index 7327060..a1920f0 100644 --- a/project/code/TMV/TextureLoader.cs +++ b/project/code/TMV/TextureLoader.cs @@ -7,15 +7,13 @@ namespace KeepersCompound.TMV; public partial class TextureLoader { - private readonly string _fmName; private readonly List _textureCache = new(); private readonly Dictionary _idMap = new(); private readonly Dictionary _idPathMap = new(); private readonly Dictionary _pathMap = new(); - public TextureLoader(string fmName) + public TextureLoader() { - _fmName = fmName; LoadDefaultTextures(); } @@ -35,8 +33,8 @@ public partial class TextureLoader private bool Load(int id, string path) { var loaded = false; - var pathManager = Context.Instance.PathManager; - var (_, texPath) = pathManager.GetResourcePath(ResourceType.Texture, _fmName, path); + var campaignResources = Context.Instance.CampaignResources; + var texPath = campaignResources.GetResourcePath(ResourceType.Texture, path); if (texPath != null) { diff --git a/project/code/TMV/UI/ResourceSelector.cs b/project/code/TMV/UI/ResourceSelector.cs index 8fdaea4..3232beb 100644 --- a/project/code/TMV/UI/ResourceSelector.cs +++ b/project/code/TMV/UI/ResourceSelector.cs @@ -54,10 +54,8 @@ public partial class ResourceSelector : Control private void SetInstallPath(string path) { _FolderPath.Text = path; - if (Context.Instance.PathManager.Init(path)) - { - BuildCampaignList(); - } + Context.Instance.PathManager.Init(path); + BuildCampaignList(); } private void BuildCampaignList() @@ -79,10 +77,11 @@ public partial class ResourceSelector : Control _Resources.Clear(); _LoadButton.Disabled = true; - var pathManager = Context.Instance.PathManager; var campaignName = idx == 0 ? null : _Campaigns.GetItemText((int)idx); - var resourceNammes = pathManager.GetResourceNames(ResType, campaignName); - foreach (var resource in resourceNammes) + var pathManager = Context.Instance.PathManager; + var campaignResources = pathManager.GetCampaign(campaignName); + var resourceNames = campaignResources.GetResourceNames(ResType); + foreach (var resource in resourceNames) { _Resources.AddItem(resource); } diff --git a/project/code/TMV/UI/TextureBrowser.cs b/project/code/TMV/UI/TextureBrowser.cs index 2b22992..5c56893 100644 --- a/project/code/TMV/UI/TextureBrowser.cs +++ b/project/code/TMV/UI/TextureBrowser.cs @@ -37,7 +37,7 @@ public partial class TextureBrowser : Node { // !HACK TEMP Context.Instance.PathManager.Init("/stuff/Games/thief/drive_c/GOG Games/TG ND 1.27 (MAPPING)/"); - Context.Instance.CampaignName = "TheBlackParade_1_0"; + Context.Instance.SetCampaign("TheBlackParade_1_0"); _folderTree = GetNode("%FolderTree"); _searchBar = GetNode("%SearchBar"); @@ -72,8 +72,8 @@ public partial class TextureBrowser : Node { _folderTree.Clear(); - var context = Context.Instance; - var textureNames = context.PathManager.GetResourceNames(LGS.ResourceType.Texture, context.CampaignName); + var campaignResources = Context.Instance.CampaignResources; + var textureNames = campaignResources.GetResourceNames(LGS.ResourceType.Texture); var treeItems = new Dictionary(); treeItems.Add("", _folderTree.CreateItem()); @@ -102,13 +102,12 @@ public partial class TextureBrowser : Node child.QueueFree(); } - var pathManager = Context.Instance.PathManager; - var campaign = Context.Instance.CampaignName; + var campaignResources = Context.Instance.CampaignResources; var resType = LGS.ResourceType.Texture; - var textureNames = pathManager.GetResourceNames(resType, campaign); + var textureNames = campaignResources.GetResourceNames(resType); foreach (var name in textureNames) { - var (_, path) = pathManager.GetResourcePath(resType, campaign, name); + var path = campaignResources.GetResourcePath(resType, name); var texture = TextureLoader.LoadTexture(path); var textureRect = new TextureRect();