From 8746b439e1a8c0ded1d33c4a4ac7f4312748a3eb Mon Sep 17 00:00:00 2001 From: Hakoyu Date: Wed, 27 Sep 2023 18:14:29 +0800 Subject: [PATCH] =?UTF-8?q?AnimeEdit=20=E6=96=B0=E5=A2=9E=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20Work?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VPet.ModMaker/Models/Expansions.cs | 7 + VPet.ModMaker/Models/ModLoader.cs | 11 +- VPet.ModMaker/Models/ModModel/AnimeModel.cs | 512 ----------------- .../Models/ModModel/AnimeTypeModel.cs | 521 ++++++++++++++++++ VPet.ModMaker/Models/ModModel/ModInfoModel.cs | 21 +- VPet.ModMaker/VPet.ModMaker.csproj | 1 + .../ModEdit/AnimeEdit/AnimeEditWindowVM.cs | 8 +- .../ModEdit/AnimeEdit/AnimePageVM.cs | 1 + VPet.ModMaker/ViewModels/ModMakerWindowVM.cs | 3 + .../Views/ModEdit/AnimeEdit/AnimePage.xaml | 36 ++ .../AnimeEdit/SelectGraphTypeWindow.xaml | 16 +- .../AnimeEdit/SelectGraphTypeWindow.xaml.cs | 26 +- .../Views/ModEdit/ModEditWindow.xaml | 2 +- 13 files changed, 630 insertions(+), 535 deletions(-) create mode 100644 VPet.ModMaker/Models/ModModel/AnimeTypeModel.cs diff --git a/VPet.ModMaker/Models/Expansions.cs b/VPet.ModMaker/Models/Expansions.cs index 7e67544..71953f4 100644 --- a/VPet.ModMaker/Models/Expansions.cs +++ b/VPet.ModMaker/Models/Expansions.cs @@ -8,6 +8,8 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Media; using System.Windows.Media.Imaging; +using VPet.ModMaker.Models.ModModel; +using VPet_Simulator.Core; namespace VPet.ModMaker.Models; @@ -74,6 +76,11 @@ public static class Extensions return true; } + public static bool IsHasNameAnime(this GraphInfo.GraphType graphType) + { + return AnimeTypeModel.HasNameAnimes.Contains(graphType); + } + /// /// 流内容对比 /// diff --git a/VPet.ModMaker/Models/ModLoader.cs b/VPet.ModMaker/Models/ModLoader.cs index a1ac26b..5747166 100644 --- a/VPet.ModMaker/Models/ModLoader.cs +++ b/VPet.ModMaker/Models/ModLoader.cs @@ -94,20 +94,11 @@ public class ModLoader var name = lps.First().Info; var pet = new PetLoader(lps, di); Pets.Add(pet); - // TODO : 此方法会导致 LoadImageToStream 无法使用 + // ! : 此方法会导致 LoadImageToStream 无法使用 //var graphCore = new GraphCore(0); //foreach (var p in pet.path) // PetLoader.LoadGraph(graphCore, di, p); //MultiGraphs.Add(pet.Name, graphCore); - - //var p = mw.Pets.FirstOrDefault(x => x.Id == name); - //if (p == null) - // mw.Pets.Add(new PetLoader(lps, di)); - //else - //{ - // p.path.Add(di.FullName + "\\" + lps.First()["path"].Info); - // p.Config.Set(lps); - //} } } break; diff --git a/VPet.ModMaker/Models/ModModel/AnimeModel.cs b/VPet.ModMaker/Models/ModModel/AnimeModel.cs index c523bbd..3ddec24 100644 --- a/VPet.ModMaker/Models/ModModel/AnimeModel.cs +++ b/VPet.ModMaker/Models/ModModel/AnimeModel.cs @@ -1,523 +1,11 @@ using HKW.HKWViewModels.SimpleObservable; -using System; -using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Media.Imaging; using VPet_Simulator.Core; -using static VPet_Simulator.Core.GraphInfo; namespace VPet.ModMaker.Models.ModModel; -public class AnimeTypeModel -{ - public static ObservableCollection GraphTypes { get; } = - new(Enum.GetValues(typeof(GraphInfo.GraphType)).Cast()); - public static ObservableCollection AnimatTypes { get; } = - new(Enum.GetValues(typeof(GraphInfo.AnimatType)).Cast()); - public static ObservableCollection ModeTypes { get; } = - new(Enum.GetValues(typeof(GameSave.ModeType)).Cast()); - - public ObservableValue Id { get; } = new(); - - public ObservableValue Name { get; } = new(); - public ObservableValue GraphType { get; } = new(); - - public ObservableCollection HappyAnimes { get; } = new(); - public ObservableCollection NomalAnimes { get; } = new(); - public ObservableCollection PoorConditionAnimes { get; } = new(); - public ObservableCollection IllAnimes { get; } = new(); - - public AnimeTypeModel() - { - Name.ValueChanged += (_, _) => - { - Id.Value = $"{GraphType.Value}_{Name.Value}"; - }; - } - - public AnimeTypeModel(AnimeTypeModel model) - : this() - { - Id.Value = model.Id.Value; - Name.Value = model.Name.Value; - GraphType.Value = model.GraphType.Value; - foreach (var anime in model.HappyAnimes) - HappyAnimes.Add(anime.Copy()); - foreach (var anime in model.NomalAnimes) - NomalAnimes.Add(anime.Copy()); - foreach (var anime in model.PoorConditionAnimes) - PoorConditionAnimes.Add(anime.Copy()); - foreach (var anime in model.IllAnimes) - IllAnimes.Add(anime.Copy()); - } - - public static AnimeTypeModel? Create(GraphInfo.GraphType graphType, string path) - { - try - { - var model = new AnimeTypeModel(graphType, path); - return model; - } - catch - { - return null; - } - } - - public AnimeTypeModel(GraphInfo.GraphType graphType, string path) - { - Name.Value = Path.GetFileName(path); - if (graphType is GraphInfo.GraphType.Common) - Id.Value = $"{nameof(GraphInfo.GraphType.Common)}_{Name.Value}"; - else - Id.Value = graphType.ToString(); - GraphType.Value = graphType; - if ( - graphType - is GraphInfo.GraphType.Default - or GraphInfo.GraphType.Shutdown - or GraphInfo.GraphType.StartUP - or GraphInfo.GraphType.Switch_Up - or GraphInfo.GraphType.Switch_Down - or GraphInfo.GraphType.Switch_Thirsty - or GraphInfo.GraphType.Switch_Hunger - or GraphInfo.GraphType.Raised_Dynamic - ) - LoadDefault(path); - else if ( - graphType - is GraphInfo.GraphType.Touch_Head - or GraphInfo.GraphType.Touch_Body - or GraphInfo.GraphType.Sleep - or GraphInfo.GraphType.Raised_Static - or GraphInfo.GraphType.StateONE - or GraphInfo.GraphType.StateTWO - or GraphInfo.GraphType.Common - ) - LoadMultiType(path); - else - throw new Exception(); - } - - //private void LoadSingle(string path) - //{ - // foreach (var dir in Directory.EnumerateDirectories(path)) - // { - // var dirName = Path.GetFileName(dir); - // var dirInfo = dirName.Split(Utils.Separator); - // var mode = Enum.Parse(typeof(GameSave.ModeType), dirInfo[0], true); - // if (dirInfo.Length == 2) { } - // } - //} - - - private void LoadDefault(string path) - { - foreach (var dir in Directory.EnumerateDirectories(path)) - { - var dirName = Path.GetFileName(dir); - if ( - dirName.Contains( - nameof(GameSave.ModeType.Happy), - StringComparison.InvariantCultureIgnoreCase - ) - ) - { - AddAnime(HappyAnimes, dir); - } - else if ( - dirName.Contains( - nameof(GameSave.ModeType.Nomal), - StringComparison.InvariantCultureIgnoreCase - ) - ) - { - AddAnime(NomalAnimes, dir); - } - else if ( - dirName.Contains( - nameof(GameSave.ModeType.PoorCondition), - StringComparison.InvariantCultureIgnoreCase - ) - ) - { - AddAnime(PoorConditionAnimes, dir); - } - else if ( - dirName.Contains( - nameof(GameSave.ModeType.Ill), - StringComparison.InvariantCultureIgnoreCase - ) - ) - { - AddAnime(IllAnimes, dir); - } - } - if (Directory.EnumerateFiles(path).Any()) - { - AddAnime(NomalAnimes, path); - } - } - - private void LoadMultiType(string path) - { - foreach (var dir in Directory.EnumerateDirectories(path)) - { - var dirName = Path.GetFileName(dir); - var dirInfo = dirName.Split(Utils.Separator, StringSplitOptions.RemoveEmptyEntries); - if (dirInfo.Length == 2) - { - // 判断 A_Happy 类型文件夹 - var typeName = dirInfo[0]; - var modeName = dirInfo[1]; - var type = GetAnimatType(typeName[0]); - var mode = Enum.Parse(typeof(GameSave.ModeType), Path.GetFileName(modeName), true); - if (mode is GameSave.ModeType.Happy) - { - AddAnime(HappyAnimes, dir, type); - } - else if (mode is GameSave.ModeType.Nomal) - { - AddAnime(NomalAnimes, dir, type); - } - else if (mode is GameSave.ModeType.PoorCondition) - { - AddAnime(PoorConditionAnimes, dir, type); - } - else if (mode is GameSave.ModeType.Ill) - { - AddAnime(IllAnimes, dir, type); - } - } - else if (Enum.TryParse(dirName, true, out var mode)) - { - // 判断 Happy/A 型文件夹 - foreach (var typePath in Directory.EnumerateDirectories(dir)) - { - var type = GetAnimatType( - Path.GetFileName(typePath).Split(Utils.Separator).First()[0] - ); - if (mode is GameSave.ModeType.Happy) - { - AddAnime(HappyAnimes, typePath, type); - } - else if (mode is GameSave.ModeType.Nomal) - { - AddAnime(NomalAnimes, typePath, type); - } - else if (mode is GameSave.ModeType.PoorCondition) - { - AddAnime(PoorConditionAnimes, typePath, type); - } - else if (mode is GameSave.ModeType.Ill) - { - AddAnime(IllAnimes, typePath, type); - } - } - } - else - { - var type = GetAnimatType(dirName[0]); - // 判断 A/Happy 文件夹 - foreach (var modePath in Directory.EnumerateDirectories(dir)) - { - mode = (GameSave.ModeType) - Enum.Parse( - typeof(GameSave.ModeType), - Path.GetFileName(modePath).Split(Utils.Separator).First(), - true - ); - if (mode is GameSave.ModeType.Happy) - { - AddAnime(HappyAnimes, modePath, type); - } - else if (mode is GameSave.ModeType.Nomal) - { - AddAnime(NomalAnimes, modePath, type); - } - else if (mode is GameSave.ModeType.PoorCondition) - { - AddAnime(PoorConditionAnimes, modePath, type); - } - else if (mode is GameSave.ModeType.Ill) - { - AddAnime(IllAnimes, modePath, type); - } - } - } - } - } - - private static GraphInfo.AnimatType GetAnimatType(char c) - { - return c switch - { - 'A' => GraphInfo.AnimatType.A_Start, - 'B' => GraphInfo.AnimatType.B_Loop, - 'C' => GraphInfo.AnimatType.C_End, - _ => GraphInfo.AnimatType.Single, - }; - } - - private static void AddAnime( - ObservableCollection collection, - string path, - GraphInfo.AnimatType animatType = AnimatType.Single - ) - { - if (Directory.EnumerateFiles(path).Any()) - { - var animeModel = new AnimeModel(path); - animeModel.AnimeType.Value = animatType; - collection.Add(animeModel); - } - else - { - foreach (var imagesDir in Directory.EnumerateDirectories(path)) - { - var animeModel = new AnimeModel(imagesDir); - animeModel.AnimeType.Value = animatType; - collection.Add(animeModel); - } - } - } - - public void Save(string path) - { - if ( - GraphType.Value - is GraphInfo.GraphType.Default - or GraphInfo.GraphType.Shutdown - or GraphInfo.GraphType.StartUP - ) - SaveDefault(path, this); - else if ( - GraphType.Value - is GraphInfo.GraphType.Touch_Head - or GraphInfo.GraphType.Touch_Body - or GraphInfo.GraphType.Sleep - ) - SaveMultiType(path, this); - else if ( - GraphType.Value - is GraphInfo.GraphType.Switch_Up - or GraphInfo.GraphType.Switch_Down - or GraphInfo.GraphType.Switch_Thirsty - or GraphInfo.GraphType.Switch_Hunger - ) - SaveSwitch(path, this); - else if ( - GraphType.Value - is GraphInfo.GraphType.Raised_Dynamic - or GraphInfo.GraphType.Raised_Static - ) - SaveRaise(path, this); - else if (GraphType.Value is GraphInfo.GraphType.StateONE or GraphInfo.GraphType.StateTWO) - SaveState(path, this); - else if (GraphType.Value is GraphInfo.GraphType.Common) - SaveCommon(path, this); - } - - void SaveCommon(string path, AnimeTypeModel animeTypeModel) - { - var animePath = Path.Combine(path, animeTypeModel.Name.Value); - Directory.CreateDirectory(animePath); - SaveWithModeType(animePath, animeTypeModel); - } - - void SaveState(string path, AnimeTypeModel animeTypeModel) - { - var animePath = Path.Combine(path, "State"); - Directory.CreateDirectory(animePath); - SaveMultiType(animePath, animeTypeModel); - } - - void SaveRaise(string path, AnimeTypeModel animeTypeModel) - { - var animePath = Path.Combine(path, "Raise"); - Directory.CreateDirectory(animePath); - if (animeTypeModel.GraphType.Value is GraphInfo.GraphType.Raised_Dynamic) - SaveDefault(animePath, animeTypeModel); - else if (animeTypeModel.GraphType.Value is GraphInfo.GraphType.Raised_Static) - SaveMultiType(animePath, animeTypeModel); - } - - void SaveSwitch(string path, AnimeTypeModel animeTypeModel) - { - var animePath = Path.Combine(path, "Switch"); - Directory.CreateDirectory(animePath); - var switchName = animeTypeModel.GraphType.ToString().Split(Utils.Separator).Last(); - SaveWithAnimeType(Path.Combine(animePath, switchName), animeTypeModel); - } - - /// - /// 保存成默认样式 - /// - /// - /// - static void SaveDefault(string path, AnimeTypeModel animeTypeModel) - { - var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString()); - Directory.CreateDirectory(animePath); - SaveWithAnimeType(animePath, animeTypeModel); - } - - /// - /// 保存成多类型样式 - /// - /// - /// - static void SaveMultiType(string path, AnimeTypeModel animeTypeModel) - { - var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString()); - Directory.CreateDirectory(animePath); - SaveWithModeType(animePath, animeTypeModel); - } - - /// - /// 保存为 ModeType 划分的样式 - /// - /// - /// - /// - /// - static void SaveWithModeType(string path, AnimeTypeModel animeTypeModel) - { - if (animeTypeModel.HappyAnimes.Count > 0) - { - var modePath = Path.Combine(path, nameof(GameSave.ModeType.Happy)); - SaveAnimes(modePath, animeTypeModel.HappyAnimes); - } - if (animeTypeModel.NomalAnimes.Count > 0) - { - var modePath = Path.Combine(path, nameof(GameSave.ModeType.Nomal)); - SaveAnimes(modePath, animeTypeModel.NomalAnimes); - } - if (animeTypeModel.PoorConditionAnimes.Count > 0) - { - var modePath = Path.Combine(path, nameof(GameSave.ModeType.PoorCondition)); - SaveAnimes(modePath, animeTypeModel.PoorConditionAnimes); - } - if (animeTypeModel.IllAnimes.Count > 0) - { - var modePath = Path.Combine(path, nameof(GameSave.ModeType.Ill)); - SaveAnimes(modePath, animeTypeModel.IllAnimes); - } - - static void SaveAnimes(string animePath, ObservableCollection animes) - { - Directory.CreateDirectory(animePath); - var countA = 0; - var countB = 0; - var countC = 0; - foreach (var anime in animes) - { - if (anime.AnimeType.Value is GraphInfo.AnimatType.A_Start) - { - var animatTypePath = Path.Combine(animePath, "A"); - Directory.CreateDirectory(animatTypePath); - SaveImages(Path.Combine(animatTypePath, countA.ToString()), anime); - countA++; - } - else if (anime.AnimeType.Value is GraphInfo.AnimatType.B_Loop) - { - var animatTypePath = Path.Combine(animePath, "B"); - Directory.CreateDirectory(animatTypePath); - SaveImages(Path.Combine(animatTypePath, countB.ToString()), anime); - countB++; - } - else if (anime.AnimeType.Value is GraphInfo.AnimatType.C_End) - { - var animatTypePath = Path.Combine(animePath, "C"); - Directory.CreateDirectory(animatTypePath); - SaveImages(Path.Combine(animatTypePath, countC.ToString()), anime); - countC++; - } - } - } - } - - /// - /// 保存为 AnimeType 划分的样式 - /// - /// - /// - /// - /// - static void SaveWithAnimeType(string animePath, AnimeTypeModel animeType) - { - if (animeType.HappyAnimes.Count > 0) - { - var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.Happy)); - SaveAnimes(modePath, animeType.HappyAnimes); - } - if (animeType.NomalAnimes.Count > 0) - { - var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.Nomal)); - SaveAnimes(modePath, animeType.NomalAnimes); - } - if (animeType.PoorConditionAnimes.Count > 0) - { - var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.PoorCondition)); - SaveAnimes(modePath, animeType.PoorConditionAnimes); - } - if (animeType.IllAnimes.Count > 0) - { - var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.Ill)); - SaveAnimes(modePath, animeType.IllAnimes); - } - static void SaveAnimes(string animePath, ObservableCollection animes) - { - Directory.CreateDirectory(animePath); - var count = 0; - foreach (var anime in animes) - { - SaveImages(Path.Combine(animePath, count.ToString()), anime); - count++; - } - } - } - - /// - /// 保存图片 - /// - /// - /// - static void SaveImages(string imagesPath, AnimeModel model) - { - Directory.CreateDirectory(imagesPath); - var imageIndex = 0; - foreach (var image in model.Images) - { - image.Image.Value.SaveToPng( - Path.Combine( - imagesPath, - $"{model.Id.Value}_{imageIndex:000}_{image.Duration.Value}.png" - ) - ); - imageIndex++; - } - } -} - public class AnimeModel { public ObservableValue Id { get; } = new(); diff --git a/VPet.ModMaker/Models/ModModel/AnimeTypeModel.cs b/VPet.ModMaker/Models/ModModel/AnimeTypeModel.cs new file mode 100644 index 0000000..5186ecd --- /dev/null +++ b/VPet.ModMaker/Models/ModModel/AnimeTypeModel.cs @@ -0,0 +1,521 @@ +using HKW.HKWViewModels.SimpleObservable; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; +using VPet_Simulator.Core; +using static VPet_Simulator.Core.GraphInfo; + +namespace VPet.ModMaker.Models.ModModel; + +public class AnimeTypeModel +{ + public static ObservableCollection GraphTypes { get; } = + new(Enum.GetValues(typeof(GraphInfo.GraphType)).Cast()); + public static ObservableCollection AnimatTypes { get; } = + new(Enum.GetValues(typeof(GraphInfo.AnimatType)).Cast()); + public static ObservableCollection ModeTypes { get; } = + new(Enum.GetValues(typeof(GameSave.ModeType)).Cast()); + + public static HashSet HasNameAnimes { get; } = + new() + { + GraphInfo.GraphType.Common, + GraphInfo.GraphType.Work, + GraphInfo.GraphType.Idel, + GraphInfo.GraphType.Move + }; + + public ObservableValue Id { get; } = new(); + + public ObservableValue Name { get; } = new(); + public ObservableValue GraphType { get; } = new(); + + public ObservableCollection HappyAnimes { get; } = new(); + public ObservableCollection NomalAnimes { get; } = new(); + public ObservableCollection PoorConditionAnimes { get; } = new(); + public ObservableCollection IllAnimes { get; } = new(); + + public AnimeTypeModel() + { + Name.ValueChanged += (_, _) => + { + Id.Value = $"{GraphType.Value}_{Name.Value}"; + }; + } + + public AnimeTypeModel(AnimeTypeModel model) + : this() + { + Id.Value = model.Id.Value; + Name.Value = model.Name.Value; + GraphType.Value = model.GraphType.Value; + foreach (var anime in model.HappyAnimes) + HappyAnimes.Add(anime.Copy()); + foreach (var anime in model.NomalAnimes) + NomalAnimes.Add(anime.Copy()); + foreach (var anime in model.PoorConditionAnimes) + PoorConditionAnimes.Add(anime.Copy()); + foreach (var anime in model.IllAnimes) + IllAnimes.Add(anime.Copy()); + } + + public static AnimeTypeModel? Create(GraphInfo.GraphType graphType, string path) + { + try + { + var model = new AnimeTypeModel(graphType, path); + return model; + } + catch + { + return null; + } + } + + public AnimeTypeModel(GraphInfo.GraphType graphType, string path) + { + Name.Value = Path.GetFileName(path); + if (graphType is GraphInfo.GraphType.Common or GraphInfo.GraphType.Work) + Id.Value = $"{graphType}_{Name.Value}"; + else + Id.Value = graphType.ToString(); + GraphType.Value = graphType; + if ( + graphType + is GraphInfo.GraphType.Default + or GraphInfo.GraphType.Shutdown + or GraphInfo.GraphType.StartUP + or GraphInfo.GraphType.Switch_Up + or GraphInfo.GraphType.Switch_Down + or GraphInfo.GraphType.Switch_Thirsty + or GraphInfo.GraphType.Switch_Hunger + or GraphInfo.GraphType.Raised_Dynamic + ) + LoadDefault(path); + else if ( + graphType + is GraphInfo.GraphType.Touch_Head + or GraphInfo.GraphType.Touch_Body + or GraphInfo.GraphType.Sleep + or GraphInfo.GraphType.Raised_Static + or GraphInfo.GraphType.StateONE + or GraphInfo.GraphType.StateTWO + or GraphInfo.GraphType.Common + or GraphInfo.GraphType.Work + ) + LoadMultiType(path); + else + throw new Exception(); + } + + #region Load + private void LoadDefault(string path) + { + foreach (var dir in Directory.EnumerateDirectories(path)) + { + var dirName = Path.GetFileName(dir); + if ( + dirName.Contains( + nameof(GameSave.ModeType.Happy), + StringComparison.InvariantCultureIgnoreCase + ) + ) + { + AddAnime(HappyAnimes, dir); + } + else if ( + dirName.Contains( + nameof(GameSave.ModeType.Nomal), + StringComparison.InvariantCultureIgnoreCase + ) + ) + { + AddAnime(NomalAnimes, dir); + } + else if ( + dirName.Contains( + nameof(GameSave.ModeType.PoorCondition), + StringComparison.InvariantCultureIgnoreCase + ) + ) + { + AddAnime(PoorConditionAnimes, dir); + } + else if ( + dirName.Contains( + nameof(GameSave.ModeType.Ill), + StringComparison.InvariantCultureIgnoreCase + ) + ) + { + AddAnime(IllAnimes, dir); + } + } + if (Directory.EnumerateFiles(path).Any()) + { + AddAnime(NomalAnimes, path); + } + } + + private void LoadMultiType(string path) + { + foreach (var dir in Directory.EnumerateDirectories(path)) + { + var dirName = Path.GetFileName(dir); + var dirInfo = dirName.Split(Utils.Separator, StringSplitOptions.RemoveEmptyEntries); + if (dirInfo.Length == 3) + { + // 判断 A_1_Happy 类型文件夹 + var typeName = dirInfo[0]; + var modeName = dirInfo[2]; + var type = GetAnimatType(typeName[0]); + var mode = (GameSave.ModeType) + Enum.Parse(typeof(GameSave.ModeType), Path.GetFileName(modeName), true); + AddAnimeForModeType(dir, mode, type); + } + else if (dirInfo.Length == 2) + { + // 判断 A_Happy 类型文件夹 + var typeName = dirInfo[0]; + var modeName = dirInfo[1]; + var type = GetAnimatType(typeName[0]); + var mode = (GameSave.ModeType) + Enum.Parse(typeof(GameSave.ModeType), Path.GetFileName(modeName), true); + AddAnimeForModeType(dir, mode, type); + } + else if (Enum.TryParse(dirName, true, out var mode)) + { + // 判断 Happy/A 型文件夹 + foreach (var typePath in Directory.EnumerateDirectories(dir)) + { + var type = GetAnimatType( + Path.GetFileName(typePath).Split(Utils.Separator).First()[0] + ); + AddAnimeForModeType(typePath, mode, type); + } + } + else + { + var type = GetAnimatType(dirName[0]); + // 判断 A/Happy 文件夹 + foreach (var modePath in Directory.EnumerateDirectories(dir)) + { + mode = (GameSave.ModeType) + Enum.Parse( + typeof(GameSave.ModeType), + Path.GetFileName(modePath).Split(Utils.Separator).First(), + true + ); + AddAnimeForModeType(modePath, mode, type); + } + } + } + } + + private void AddAnimeForModeType( + string path, + GameSave.ModeType modeType, + GraphInfo.AnimatType animeType + ) + { + if (modeType is GameSave.ModeType.Happy) + { + AddAnime(HappyAnimes, path, animeType); + } + else if (modeType is GameSave.ModeType.Nomal) + { + AddAnime(NomalAnimes, path, animeType); + } + else if (modeType is GameSave.ModeType.PoorCondition) + { + AddAnime(PoorConditionAnimes, path, animeType); + } + else if (modeType is GameSave.ModeType.Ill) + { + AddAnime(IllAnimes, path, animeType); + } + } + + private static GraphInfo.AnimatType GetAnimatType(char c) + { + return c switch + { + 'A' => GraphInfo.AnimatType.A_Start, + 'B' => GraphInfo.AnimatType.B_Loop, + 'C' => GraphInfo.AnimatType.C_End, + _ => GraphInfo.AnimatType.Single, + }; + } + + private static void AddAnime( + ObservableCollection collection, + string path, + GraphInfo.AnimatType animatType = AnimatType.Single + ) + { + if (Directory.EnumerateFiles(path).Any()) + { + var animeModel = new AnimeModel(path); + animeModel.AnimeType.Value = animatType; + collection.Add(animeModel); + } + else + { + foreach (var imagesDir in Directory.EnumerateDirectories(path)) + { + var animeModel = new AnimeModel(imagesDir); + animeModel.AnimeType.Value = animatType; + collection.Add(animeModel); + } + } + } + #endregion + #region Save + public void Save(string path) + { + if ( + GraphType.Value + is GraphInfo.GraphType.Default + or GraphInfo.GraphType.Shutdown + or GraphInfo.GraphType.StartUP + ) + SaveDefault(path, this); + else if ( + GraphType.Value + is GraphInfo.GraphType.Touch_Head + or GraphInfo.GraphType.Touch_Body + or GraphInfo.GraphType.Sleep + ) + SaveMultiType(path, this); + else if ( + GraphType.Value + is GraphInfo.GraphType.Switch_Up + or GraphInfo.GraphType.Switch_Down + or GraphInfo.GraphType.Switch_Thirsty + or GraphInfo.GraphType.Switch_Hunger + ) + SaveSwitch(path, this); + else if ( + GraphType.Value + is GraphInfo.GraphType.Raised_Dynamic + or GraphInfo.GraphType.Raised_Static + ) + SaveRaise(path, this); + else if (GraphType.Value is GraphInfo.GraphType.StateONE or GraphInfo.GraphType.StateTWO) + SaveState(path, this); + else if (GraphType.Value is GraphInfo.GraphType.Common) + SaveCommon(path, this); + else if (GraphType.Value is GraphInfo.GraphType.Work) + SaveHasNameAnime(path, this); + } + + void SaveHasNameAnime(string path, AnimeTypeModel animeTypeModel) + { + var animeTypePath = Path.Combine(path, animeTypeModel.GraphType.Value.ToString()); + Directory.CreateDirectory(animeTypePath); + var animePath = Path.Combine(animeTypePath, animeTypeModel.Name.Value); + Directory.CreateDirectory(animePath); + SaveWithModeType(animePath, animeTypeModel); + } + + void SaveCommon(string path, AnimeTypeModel animeTypeModel) + { + var animePath = Path.Combine(path, animeTypeModel.Name.Value); + Directory.CreateDirectory(animePath); + SaveWithModeType(animePath, animeTypeModel); + } + + void SaveState(string path, AnimeTypeModel animeTypeModel) + { + var animePath = Path.Combine(path, "State"); + Directory.CreateDirectory(animePath); + SaveMultiType(animePath, animeTypeModel); + } + + void SaveRaise(string path, AnimeTypeModel animeTypeModel) + { + var animePath = Path.Combine(path, "Raise"); + Directory.CreateDirectory(animePath); + if (animeTypeModel.GraphType.Value is GraphInfo.GraphType.Raised_Dynamic) + SaveDefault(animePath, animeTypeModel); + else if (animeTypeModel.GraphType.Value is GraphInfo.GraphType.Raised_Static) + SaveMultiType(animePath, animeTypeModel); + } + + void SaveSwitch(string path, AnimeTypeModel animeTypeModel) + { + var animePath = Path.Combine(path, "Switch"); + Directory.CreateDirectory(animePath); + var switchName = animeTypeModel.GraphType.ToString().Split(Utils.Separator).Last(); + SaveWithAnimeType(Path.Combine(animePath, switchName), animeTypeModel); + } + + /// + /// 保存成默认样式 + /// + /// + /// + static void SaveDefault(string path, AnimeTypeModel animeTypeModel) + { + var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString()); + Directory.CreateDirectory(animePath); + SaveWithAnimeType(animePath, animeTypeModel); + } + + /// + /// 保存成多类型样式 + /// + /// + /// + static void SaveMultiType(string path, AnimeTypeModel animeTypeModel) + { + var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString()); + Directory.CreateDirectory(animePath); + SaveWithModeType(animePath, animeTypeModel); + } + + /// + /// 保存为 ModeType 划分的样式 + /// + /// + /// + /// + /// + static void SaveWithModeType(string path, AnimeTypeModel animeTypeModel) + { + if (animeTypeModel.HappyAnimes.Count > 0) + { + var modePath = Path.Combine(path, nameof(GameSave.ModeType.Happy)); + SaveAnimes(modePath, animeTypeModel.HappyAnimes); + } + if (animeTypeModel.NomalAnimes.Count > 0) + { + var modePath = Path.Combine(path, nameof(GameSave.ModeType.Nomal)); + SaveAnimes(modePath, animeTypeModel.NomalAnimes); + } + if (animeTypeModel.PoorConditionAnimes.Count > 0) + { + var modePath = Path.Combine(path, nameof(GameSave.ModeType.PoorCondition)); + SaveAnimes(modePath, animeTypeModel.PoorConditionAnimes); + } + if (animeTypeModel.IllAnimes.Count > 0) + { + var modePath = Path.Combine(path, nameof(GameSave.ModeType.Ill)); + SaveAnimes(modePath, animeTypeModel.IllAnimes); + } + + static void SaveAnimes(string animePath, ObservableCollection animes) + { + Directory.CreateDirectory(animePath); + var countA = 0; + var countB = 0; + var countC = 0; + foreach (var anime in animes) + { + if (anime.AnimeType.Value is GraphInfo.AnimatType.A_Start) + { + var animatTypePath = Path.Combine(animePath, "A"); + Directory.CreateDirectory(animatTypePath); + SaveImages(Path.Combine(animatTypePath, countA.ToString()), anime); + countA++; + } + else if (anime.AnimeType.Value is GraphInfo.AnimatType.B_Loop) + { + var animatTypePath = Path.Combine(animePath, "B"); + Directory.CreateDirectory(animatTypePath); + SaveImages(Path.Combine(animatTypePath, countB.ToString()), anime); + countB++; + } + else if (anime.AnimeType.Value is GraphInfo.AnimatType.C_End) + { + var animatTypePath = Path.Combine(animePath, "C"); + Directory.CreateDirectory(animatTypePath); + SaveImages(Path.Combine(animatTypePath, countC.ToString()), anime); + countC++; + } + } + } + } + + /// + /// 保存为 AnimeType 划分的样式 + /// + /// + /// + /// + /// + static void SaveWithAnimeType(string animePath, AnimeTypeModel animeType) + { + if (animeType.HappyAnimes.Count > 0) + { + var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.Happy)); + SaveAnimes(modePath, animeType.HappyAnimes); + } + if (animeType.NomalAnimes.Count > 0) + { + var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.Nomal)); + SaveAnimes(modePath, animeType.NomalAnimes); + } + if (animeType.PoorConditionAnimes.Count > 0) + { + var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.PoorCondition)); + SaveAnimes(modePath, animeType.PoorConditionAnimes); + } + if (animeType.IllAnimes.Count > 0) + { + var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.Ill)); + SaveAnimes(modePath, animeType.IllAnimes); + } + static void SaveAnimes(string animePath, ObservableCollection animes) + { + Directory.CreateDirectory(animePath); + var count = 0; + foreach (var anime in animes) + { + SaveImages(Path.Combine(animePath, count.ToString()), anime); + count++; + } + } + } + + /// + /// 保存图片 + /// + /// + /// + static void SaveImages(string imagesPath, AnimeModel model) + { + Directory.CreateDirectory(imagesPath); + var imageIndex = 0; + foreach (var image in model.Images) + { + image.Image.Value.SaveToPng( + Path.Combine( + imagesPath, + $"{model.Id.Value}_{imageIndex:000}_{image.Duration.Value}.png" + ) + ); + imageIndex++; + } + } + #endregion +} diff --git a/VPet.ModMaker/Models/ModModel/ModInfoModel.cs b/VPet.ModMaker/Models/ModModel/ModInfoModel.cs index 6aa533e..9d46271 100644 --- a/VPet.ModMaker/Models/ModModel/ModInfoModel.cs +++ b/VPet.ModMaker/Models/ModModel/ModInfoModel.cs @@ -98,7 +98,18 @@ public class ModInfoModel : I18nModel var dirName = Path.GetFileName(animeDir); if (Enum.TryParse(dirName, true, out var animeType)) { - if (AnimeTypeModel.Create(animeType, animeDir) is AnimeTypeModel model) + if (animeType is GraphInfo.GraphType.Work) + { + foreach (var dir in Directory.EnumerateDirectories(animeDir)) + { + if ( + AnimeTypeModel.Create(GraphInfo.GraphType.Work, dir) + is AnimeTypeModel model1 + ) + petModel.Animes.Add(model1); + } + } + else if (AnimeTypeModel.Create(animeType, animeDir) is AnimeTypeModel model) petModel.Animes.Add(model); } else if (dirName.Equals("Switch", StringComparison.InvariantCultureIgnoreCase)) @@ -161,6 +172,7 @@ public class ModInfoModel : I18nModel } } + #region Load private void LoadI18nData() { foreach (var lang in I18nDatas) @@ -220,7 +232,8 @@ public class ModInfoModel : I18nModel } } } - + #endregion + #region Save public void Save() { SaveTo(SourcePath.Value); @@ -340,7 +353,7 @@ public class ModInfoModel : I18nModel new Line("pet", pet.Id.Value) { new Sub("intor", pet.DescriptionId.Value), - new Sub("ModPath", pet.Id.Value), + new Sub("path", pet.Id.Value), new Sub("petname", pet.PetNameId.Value) } ); @@ -546,7 +559,7 @@ public class ModInfoModel : I18nModel } } } - + #endregion public void Close() { Image.Value.CloseStream(); diff --git a/VPet.ModMaker/VPet.ModMaker.csproj b/VPet.ModMaker/VPet.ModMaker.csproj index 69d15ba..7aff785 100644 --- a/VPet.ModMaker/VPet.ModMaker.csproj +++ b/VPet.ModMaker/VPet.ModMaker.csproj @@ -101,6 +101,7 @@ + diff --git a/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimeEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimeEditWindowVM.cs index 9859c8f..677bc2b 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimeEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimeEditWindowVM.cs @@ -68,10 +68,16 @@ public class AnimeEditWindowVM or GraphInfo.GraphType.Touch_Head or GraphInfo.GraphType.Sleep or GraphInfo.GraphType.Common + or GraphInfo.GraphType.Work ) HasMultiType.Value = true; - if (model.GraphType.Value is GraphInfo.GraphType.Idel or GraphInfo.GraphType.Common) + if ( + model.GraphType.Value + is GraphInfo.GraphType.Idel + or GraphInfo.GraphType.Common + or GraphInfo.GraphType.Work + ) HasAnimeName.Value = true; } diff --git a/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimePageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimePageVM.cs index 93aaf98..e0ee85b 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimePageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/AnimeEdit/AnimePageVM.cs @@ -72,6 +72,7 @@ public class AnimePageVM var vm = window.ViewModel; vm.CurrentPet = CurrentPet.Value; vm.Anime.Value.GraphType.Value = graphType; + vm.Anime.Value.Name.Value = selectGraphTypeWindow.AnimeName.Value; window.ShowDialog(); if (window.IsCancel) return; diff --git a/VPet.ModMaker/ViewModels/ModMakerWindowVM.cs b/VPet.ModMaker/ViewModels/ModMakerWindowVM.cs index 158e7c5..00d9946 100644 --- a/VPet.ModMaker/ViewModels/ModMakerWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModMakerWindowVM.cs @@ -3,6 +3,7 @@ using LinePutScript; using LinePutScript.Converter; using LinePutScript.Localization.WPF; using Microsoft.Win32; +using Panuon.WPF.UI; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -189,8 +190,10 @@ public class ModMakerWindowVM MessageBox.Show("模组载入失败".Translate()); return; } + var pendingHandler = PendingBox.Show("载入中".Translate()); var modInfo = new ModInfoModel(mod); EditMod(modInfo); + pendingHandler.Close(); } catch (Exception ex) { diff --git a/VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimePage.xaml b/VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimePage.xaml index c1a1960..70a0f5b 100644 --- a/VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimePage.xaml +++ b/VPet.ModMaker/Views/ModEdit/AnimeEdit/AnimePage.xaml @@ -91,6 +91,42 @@ + + + + + + + + + + + + + + + + + + + +