// One-off: walk a creature Setup -> parts -> GfxObj -> Surface ids, and walk its // ClothingBase texture/palette overrides, so we can dump the real skin textures. using System.Globalization; using DatReaderWriter; using DatReaderWriter.DBObjs; using DatReaderWriter.Options; using SysEnv = System.Environment; static uint Hex(string s) => uint.Parse(s.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? s[2..] : s, NumberStyles.HexNumber, CultureInfo.InvariantCulture); uint setupId = Hex(args[0]); string? exportPath = args.Length > 2 ? args[2] : null; uint motionTableId = args.Length > 3 ? Hex(args[3]) : 0; uint clothingId = args.Length > 1 ? Hex(args[1]) : 0; string datDir = SysEnv.GetEnvironmentVariable("ACDREAM_DAT_DIR") ?? Path.Combine(SysEnv.GetFolderPath(SysEnv.SpecialFolder.UserProfile), "Documents", "Asheron's Call"); using var dats = new DatCollection(datDir, DatAccessType.Read); if (exportPath is not null) return MosswartArt.Export.Run(dats, setupId, clothingId, exportPath, motionTableId); if (!dats.TryGet(setupId, out var setup) || setup is null) { Console.Error.WriteLine("no setup"); return 1; } Console.WriteLine($"Setup 0x{setupId:X8}: {setup.Parts.Count} parts, radius {setup.Radius:F2} height {setup.Height:F2}"); var allSurfaces = new SortedSet(); for (int i = 0; i < setup.Parts.Count; i++) { uint gid = setup.Parts[i]; if (!dats.TryGet(gid, out var g) || g is null) { Console.WriteLine($" part[{i}] gfx 0x{gid:X8} MISSING"); continue; } var surfs = string.Join(", ", g.Surfaces.Select(s => $"0x{(uint)s:X8}")); Console.WriteLine($" part[{i}] gfx 0x{gid:X8} verts={g.VertexArray?.Vertices?.Count ?? 0} surfaces=[{surfs}]"); foreach (var s in g.Surfaces) allSurfaces.Add((uint)s); } if (clothingId != 0 && dats.TryGet(clothingId, out var ct) && ct is not null) { Console.WriteLine($"\nClothingBase 0x{clothingId:X8}: {ct.ClothingBaseEffects.Count} base effects, {ct.ClothingSubPalEffects.Count} subpal effects"); foreach (var kv in ct.ClothingBaseEffects) { Console.WriteLine($" setup 0x{kv.Key:X8}:"); foreach (var ce in kv.Value.CloObjectEffects) { Console.WriteLine($" part {ce.Index} gfx 0x{ce.ModelId:X8}"); foreach (var te in ce.CloTextureEffects) { Console.WriteLine($" tex 0x{te.OldTexture:X8} -> 0x{te.NewTexture:X8}"); allSurfaces.Add((uint)te.NewTexture); } } } foreach (var kv in ct.ClothingSubPalEffects) Console.WriteLine($" subpal key {kv.Key}: icon 0x{kv.Value.Icon:X8} ranges={kv.Value.CloSubPalettes.Count}"); } Console.WriteLine("\nALL SURFACE IDS:"); Console.WriteLine(string.Join(" ", allSurfaces.Select(s => $"0x{s:X8}"))); return 0;