using System; using System.Collections.Generic; using System.IO; using Cthangover.Core.Factories.Impls; using Cthangover.Core.Mods; using Cthangover.Core.Mods.Resolvers; using Godot; namespace Cthangover.Tools.Services { /// /// Static service for discovering and loading mod background resources. /// Queries for files under /// "backgrounds", strips extensions to produce IDs, and loads textures /// via . Used by the light editor, interactive /// editor, and scenario editor to populate background selection lists and /// render previews. /// public static class ModResourceService { /// /// Returns all unique background IDs (filenames without extension) from /// the "backgrounds" file collection across all installed mods, /// sorted, without the _albedo/_depth lighting masks. /// public static List GetBackgroundIds() { var ids = new List(); var files = Files.Collect("backgrounds"); var exts = GetExt(); foreach (var kvp in files) { var id = kvp.Key; var ext = Path.GetExtension(id); if (!string.IsNullOrWhiteSpace(id) && exts.Contains(ext.ToLower())) { var cleanId = id.Substring(0, id.LastIndexOf('.')); var bare = cleanId.TrimEnd('_'); if (!bare.EndsWith("_albedo") && !bare.EndsWith("_depth")) ids.Add(cleanId); } } ids.Sort(StringComparer.OrdinalIgnoreCase); return ids; } /// Ids of every sound (group sounds, path without extension): the choices for a scene's ambient. public static List GetSoundIds() { var ids = new List(); var exts = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (var ext in ModConfig.Instance.AudioExtensions) exts.Add(ext); foreach (var id in Files.Collect("sounds").Keys) { var ext = Path.GetExtension(id); if (exts.Contains(ext)) ids.Add(id.Substring(0, id.Length - ext.Length)); } ids.Sort(StringComparer.OrdinalIgnoreCase); return ids; } private static HashSet GetExt() { var set = new HashSet(); foreach (var ext in ModConfig.Instance.TextureExtensions) { if(string.IsNullOrWhiteSpace(ext)) continue; set.Add(ext.ToLower()); } return set; } /// /// Returns every texture logical name (filename without extension) from /// all configured texture groups, sorted for stable UI lists. Used by /// the map editor's marker icon picker: these are exactly the IDs that /// MapZone.Image accepts, because resolution also keys textures /// by basename. /// public static List GetTextureIds() { var ids = new List(); var textures = Textures.Collect(); if (textures == null) return ids; foreach (var kvp in textures) ids.Add(kvp.Key); ids.Sort(StringComparer.OrdinalIgnoreCase); return ids; } /// /// Texture IDs that make sense as small icons (map markers): every /// texture except backgrounds and their _depth/_albedo /// masks. Textures are keyed by file name, so backgrounds are excluded /// by the file-name part of their IDs. /// public static List GetIconIds() { var backgrounds = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (var id in GetBackgroundIds()) backgrounds.Add(id.Substring(id.LastIndexOf('/') + 1)); var result = new List(); foreach (var id in GetTextureIds()) { if (backgrounds.Contains(id) || id.EndsWith("_depth", StringComparison.OrdinalIgnoreCase) || id.EndsWith("_albedo", StringComparison.OrdinalIgnoreCase)) continue; result.Add(id); } return result; } /// /// Loads a background texture by ID via . /// Returns null on any error (missing resource, load failure). /// public static Texture2D LoadBackgroundTexture(string id) { try { return BackgroundFactory.Instance.Get(id); } catch { return null; } } } }