mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
AnimeEdit 新增支持 Work
This commit is contained in:
@ -8,6 +8,8 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
using VPet.ModMaker.Models.ModModel;
|
||||||
|
using VPet_Simulator.Core;
|
||||||
|
|
||||||
namespace VPet.ModMaker.Models;
|
namespace VPet.ModMaker.Models;
|
||||||
|
|
||||||
@ -74,6 +76,11 @@ public static class Extensions
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsHasNameAnime(this GraphInfo.GraphType graphType)
|
||||||
|
{
|
||||||
|
return AnimeTypeModel.HasNameAnimes.Contains(graphType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 流内容对比
|
/// 流内容对比
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -94,20 +94,11 @@ public class ModLoader
|
|||||||
var name = lps.First().Info;
|
var name = lps.First().Info;
|
||||||
var pet = new PetLoader(lps, di);
|
var pet = new PetLoader(lps, di);
|
||||||
Pets.Add(pet);
|
Pets.Add(pet);
|
||||||
// TODO : 此方法会导致 LoadImageToStream 无法使用
|
// ! : 此方法会导致 LoadImageToStream 无法使用
|
||||||
//var graphCore = new GraphCore(0);
|
//var graphCore = new GraphCore(0);
|
||||||
//foreach (var p in pet.path)
|
//foreach (var p in pet.path)
|
||||||
// PetLoader.LoadGraph(graphCore, di, p);
|
// PetLoader.LoadGraph(graphCore, di, p);
|
||||||
//MultiGraphs.Add(pet.Name, graphCore);
|
//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;
|
break;
|
||||||
|
@ -1,523 +1,11 @@
|
|||||||
using HKW.HKWViewModels.SimpleObservable;
|
using HKW.HKWViewModels.SimpleObservable;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
using VPet_Simulator.Core;
|
using VPet_Simulator.Core;
|
||||||
using static VPet_Simulator.Core.GraphInfo;
|
|
||||||
|
|
||||||
namespace VPet.ModMaker.Models.ModModel;
|
namespace VPet.ModMaker.Models.ModModel;
|
||||||
|
|
||||||
public class AnimeTypeModel
|
|
||||||
{
|
|
||||||
public static ObservableCollection<GraphInfo.GraphType> GraphTypes { get; } =
|
|
||||||
new(Enum.GetValues(typeof(GraphInfo.GraphType)).Cast<GraphInfo.GraphType>());
|
|
||||||
public static ObservableCollection<GraphInfo.AnimatType> AnimatTypes { get; } =
|
|
||||||
new(Enum.GetValues(typeof(GraphInfo.AnimatType)).Cast<GraphInfo.AnimatType>());
|
|
||||||
public static ObservableCollection<GameSave.ModeType> ModeTypes { get; } =
|
|
||||||
new(Enum.GetValues(typeof(GameSave.ModeType)).Cast<GameSave.ModeType>());
|
|
||||||
|
|
||||||
public ObservableValue<string> Id { get; } = new();
|
|
||||||
|
|
||||||
public ObservableValue<string> Name { get; } = new();
|
|
||||||
public ObservableValue<GraphInfo.GraphType> GraphType { get; } = new();
|
|
||||||
|
|
||||||
public ObservableCollection<AnimeModel> HappyAnimes { get; } = new();
|
|
||||||
public ObservableCollection<AnimeModel> NomalAnimes { get; } = new();
|
|
||||||
public ObservableCollection<AnimeModel> PoorConditionAnimes { get; } = new();
|
|
||||||
public ObservableCollection<AnimeModel> 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<GameSave.ModeType>(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<AnimeModel> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 保存成默认样式
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path"></param>
|
|
||||||
/// <param name="animeTypeModel"></param>
|
|
||||||
static void SaveDefault(string path, AnimeTypeModel animeTypeModel)
|
|
||||||
{
|
|
||||||
var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString());
|
|
||||||
Directory.CreateDirectory(animePath);
|
|
||||||
SaveWithAnimeType(animePath, animeTypeModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 保存成多类型样式
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path"></param>
|
|
||||||
/// <param name="animeTypeModel"></param>
|
|
||||||
static void SaveMultiType(string path, AnimeTypeModel animeTypeModel)
|
|
||||||
{
|
|
||||||
var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString());
|
|
||||||
Directory.CreateDirectory(animePath);
|
|
||||||
SaveWithModeType(animePath, animeTypeModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 保存为 ModeType 划分的样式
|
|
||||||
/// <para><![CDATA[
|
|
||||||
/// Happy/A/0
|
|
||||||
/// Happy/A/1
|
|
||||||
/// Happy/B/0
|
|
||||||
/// Happy/B/1
|
|
||||||
/// Nomal/A/0
|
|
||||||
/// Nomal/A/1
|
|
||||||
/// ...
|
|
||||||
/// ]]>
|
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path"></param>
|
|
||||||
/// <param name="animeTypeModel"></param>
|
|
||||||
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<AnimeModel> 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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 保存为 AnimeType 划分的样式
|
|
||||||
/// <para><![CDATA[
|
|
||||||
/// Happy/0
|
|
||||||
/// Happy/1
|
|
||||||
/// Nomal/0
|
|
||||||
/// Nomal/1
|
|
||||||
/// ...
|
|
||||||
/// ]]>
|
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="animePath"></param>
|
|
||||||
/// <param name="animeType"></param>
|
|
||||||
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<AnimeModel> animes)
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(animePath);
|
|
||||||
var count = 0;
|
|
||||||
foreach (var anime in animes)
|
|
||||||
{
|
|
||||||
SaveImages(Path.Combine(animePath, count.ToString()), anime);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 保存图片
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="imagesPath"></param>
|
|
||||||
/// <param name="model"></param>
|
|
||||||
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 class AnimeModel
|
||||||
{
|
{
|
||||||
public ObservableValue<string> Id { get; } = new();
|
public ObservableValue<string> Id { get; } = new();
|
||||||
|
521
VPet.ModMaker/Models/ModModel/AnimeTypeModel.cs
Normal file
521
VPet.ModMaker/Models/ModModel/AnimeTypeModel.cs
Normal file
@ -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<GraphInfo.GraphType> GraphTypes { get; } =
|
||||||
|
new(Enum.GetValues(typeof(GraphInfo.GraphType)).Cast<GraphInfo.GraphType>());
|
||||||
|
public static ObservableCollection<GraphInfo.AnimatType> AnimatTypes { get; } =
|
||||||
|
new(Enum.GetValues(typeof(GraphInfo.AnimatType)).Cast<GraphInfo.AnimatType>());
|
||||||
|
public static ObservableCollection<GameSave.ModeType> ModeTypes { get; } =
|
||||||
|
new(Enum.GetValues(typeof(GameSave.ModeType)).Cast<GameSave.ModeType>());
|
||||||
|
|
||||||
|
public static HashSet<GraphInfo.GraphType> HasNameAnimes { get; } =
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
GraphInfo.GraphType.Common,
|
||||||
|
GraphInfo.GraphType.Work,
|
||||||
|
GraphInfo.GraphType.Idel,
|
||||||
|
GraphInfo.GraphType.Move
|
||||||
|
};
|
||||||
|
|
||||||
|
public ObservableValue<string> Id { get; } = new();
|
||||||
|
|
||||||
|
public ObservableValue<string> Name { get; } = new();
|
||||||
|
public ObservableValue<GraphInfo.GraphType> GraphType { get; } = new();
|
||||||
|
|
||||||
|
public ObservableCollection<AnimeModel> HappyAnimes { get; } = new();
|
||||||
|
public ObservableCollection<AnimeModel> NomalAnimes { get; } = new();
|
||||||
|
public ObservableCollection<AnimeModel> PoorConditionAnimes { get; } = new();
|
||||||
|
public ObservableCollection<AnimeModel> 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<GameSave.ModeType>(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<AnimeModel> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存成默认样式
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
/// <param name="animeTypeModel"></param>
|
||||||
|
static void SaveDefault(string path, AnimeTypeModel animeTypeModel)
|
||||||
|
{
|
||||||
|
var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString());
|
||||||
|
Directory.CreateDirectory(animePath);
|
||||||
|
SaveWithAnimeType(animePath, animeTypeModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存成多类型样式
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
/// <param name="animeTypeModel"></param>
|
||||||
|
static void SaveMultiType(string path, AnimeTypeModel animeTypeModel)
|
||||||
|
{
|
||||||
|
var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString());
|
||||||
|
Directory.CreateDirectory(animePath);
|
||||||
|
SaveWithModeType(animePath, animeTypeModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存为 ModeType 划分的样式
|
||||||
|
/// <para><![CDATA[
|
||||||
|
/// Happy/A/0
|
||||||
|
/// Happy/A/1
|
||||||
|
/// Happy/B/0
|
||||||
|
/// Happy/B/1
|
||||||
|
/// Nomal/A/0
|
||||||
|
/// Nomal/A/1
|
||||||
|
/// ...
|
||||||
|
/// ]]>
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
/// <param name="animeTypeModel"></param>
|
||||||
|
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<AnimeModel> 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存为 AnimeType 划分的样式
|
||||||
|
/// <para><![CDATA[
|
||||||
|
/// Happy/0
|
||||||
|
/// Happy/1
|
||||||
|
/// Nomal/0
|
||||||
|
/// Nomal/1
|
||||||
|
/// ...
|
||||||
|
/// ]]>
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="animePath"></param>
|
||||||
|
/// <param name="animeType"></param>
|
||||||
|
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<AnimeModel> animes)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(animePath);
|
||||||
|
var count = 0;
|
||||||
|
foreach (var anime in animes)
|
||||||
|
{
|
||||||
|
SaveImages(Path.Combine(animePath, count.ToString()), anime);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存图片
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="imagesPath"></param>
|
||||||
|
/// <param name="model"></param>
|
||||||
|
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
|
||||||
|
}
|
@ -98,7 +98,18 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
|||||||
var dirName = Path.GetFileName(animeDir);
|
var dirName = Path.GetFileName(animeDir);
|
||||||
if (Enum.TryParse<GraphInfo.GraphType>(dirName, true, out var animeType))
|
if (Enum.TryParse<GraphInfo.GraphType>(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);
|
petModel.Animes.Add(model);
|
||||||
}
|
}
|
||||||
else if (dirName.Equals("Switch", StringComparison.InvariantCultureIgnoreCase))
|
else if (dirName.Equals("Switch", StringComparison.InvariantCultureIgnoreCase))
|
||||||
@ -161,6 +172,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Load
|
||||||
private void LoadI18nData()
|
private void LoadI18nData()
|
||||||
{
|
{
|
||||||
foreach (var lang in I18nDatas)
|
foreach (var lang in I18nDatas)
|
||||||
@ -220,7 +232,8 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
#region Save
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
SaveTo(SourcePath.Value);
|
SaveTo(SourcePath.Value);
|
||||||
@ -340,7 +353,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
|||||||
new Line("pet", pet.Id.Value)
|
new Line("pet", pet.Id.Value)
|
||||||
{
|
{
|
||||||
new Sub("intor", pet.DescriptionId.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)
|
new Sub("petname", pet.PetNameId.Value)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -546,7 +559,7 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
Image.Value.CloseStream();
|
Image.Value.CloseStream();
|
||||||
|
@ -101,6 +101,7 @@
|
|||||||
<Compile Include="Converters\MarginConverter.cs" />
|
<Compile Include="Converters\MarginConverter.cs" />
|
||||||
<Compile Include="Models\EnumFlagsVM.cs" />
|
<Compile Include="Models\EnumFlagsVM.cs" />
|
||||||
<Compile Include="Models\ModModel\AnimeModel.cs" />
|
<Compile Include="Models\ModModel\AnimeModel.cs" />
|
||||||
|
<Compile Include="Models\ModModel\AnimeTypeModel.cs" />
|
||||||
<Compile Include="Models\ModModel\ClickTextModel.cs" />
|
<Compile Include="Models\ModModel\ClickTextModel.cs" />
|
||||||
<Compile Include="Models\Expansions.cs" />
|
<Compile Include="Models\Expansions.cs" />
|
||||||
<Compile Include="Models\ModModel\FoodModel.cs" />
|
<Compile Include="Models\ModModel\FoodModel.cs" />
|
||||||
|
@ -68,10 +68,16 @@ public class AnimeEditWindowVM
|
|||||||
or GraphInfo.GraphType.Touch_Head
|
or GraphInfo.GraphType.Touch_Head
|
||||||
or GraphInfo.GraphType.Sleep
|
or GraphInfo.GraphType.Sleep
|
||||||
or GraphInfo.GraphType.Common
|
or GraphInfo.GraphType.Common
|
||||||
|
or GraphInfo.GraphType.Work
|
||||||
)
|
)
|
||||||
HasMultiType.Value = true;
|
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;
|
HasAnimeName.Value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ public class AnimePageVM
|
|||||||
var vm = window.ViewModel;
|
var vm = window.ViewModel;
|
||||||
vm.CurrentPet = CurrentPet.Value;
|
vm.CurrentPet = CurrentPet.Value;
|
||||||
vm.Anime.Value.GraphType.Value = graphType;
|
vm.Anime.Value.GraphType.Value = graphType;
|
||||||
|
vm.Anime.Value.Name.Value = selectGraphTypeWindow.AnimeName.Value;
|
||||||
window.ShowDialog();
|
window.ShowDialog();
|
||||||
if (window.IsCancel)
|
if (window.IsCancel)
|
||||||
return;
|
return;
|
||||||
|
@ -3,6 +3,7 @@ using LinePutScript;
|
|||||||
using LinePutScript.Converter;
|
using LinePutScript.Converter;
|
||||||
using LinePutScript.Localization.WPF;
|
using LinePutScript.Localization.WPF;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
using Panuon.WPF.UI;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
@ -189,8 +190,10 @@ public class ModMakerWindowVM
|
|||||||
MessageBox.Show("模组载入失败".Translate());
|
MessageBox.Show("模组载入失败".Translate());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var pendingHandler = PendingBox.Show("载入中".Translate());
|
||||||
var modInfo = new ModInfoModel(mod);
|
var modInfo = new ModInfoModel(mod);
|
||||||
EditMod(modInfo);
|
EditMod(modInfo);
|
||||||
|
pendingHandler.Close();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -91,6 +91,42 @@
|
|||||||
<TextBlock Text="{ll:Str 动画类型}" />
|
<TextBlock Text="{ll:Str 动画类型}" />
|
||||||
</DataGridTextColumn.Header>
|
</DataGridTextColumn.Header>
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
|
<DataGridTextColumn
|
||||||
|
Binding="{Binding HappyAnimes.Count}"
|
||||||
|
CanUserSort="True"
|
||||||
|
IsReadOnly="True"
|
||||||
|
SortMemberPath="Id.Value">
|
||||||
|
<DataGridTextColumn.Header>
|
||||||
|
<TextBlock Text="{ll:Str 开心状态动画数量}" />
|
||||||
|
</DataGridTextColumn.Header>
|
||||||
|
</DataGridTextColumn>
|
||||||
|
<DataGridTextColumn
|
||||||
|
Binding="{Binding NomalAnimes.Count}"
|
||||||
|
CanUserSort="True"
|
||||||
|
IsReadOnly="True"
|
||||||
|
SortMemberPath="Id.Value">
|
||||||
|
<DataGridTextColumn.Header>
|
||||||
|
<TextBlock Text="{ll:Str 普通状态动画数量}" />
|
||||||
|
</DataGridTextColumn.Header>
|
||||||
|
</DataGridTextColumn>
|
||||||
|
<DataGridTextColumn
|
||||||
|
Binding="{Binding PoorConditionAnimes.Count}"
|
||||||
|
CanUserSort="True"
|
||||||
|
IsReadOnly="True"
|
||||||
|
SortMemberPath="Id.Value">
|
||||||
|
<DataGridTextColumn.Header>
|
||||||
|
<TextBlock Text="{ll:Str 不开心状态动画数量}" />
|
||||||
|
</DataGridTextColumn.Header>
|
||||||
|
</DataGridTextColumn>
|
||||||
|
<DataGridTextColumn
|
||||||
|
Binding="{Binding IllAnimes.Count}"
|
||||||
|
CanUserSort="True"
|
||||||
|
IsReadOnly="True"
|
||||||
|
SortMemberPath="Id.Value">
|
||||||
|
<DataGridTextColumn.Header>
|
||||||
|
<TextBlock Text="{ll:Str 生病状态动画数量}" />
|
||||||
|
</DataGridTextColumn.Header>
|
||||||
|
</DataGridTextColumn>
|
||||||
<!--<DataGridTextColumn
|
<!--<DataGridTextColumn
|
||||||
Binding="{Binding LocateType.EnumValue.Value}"
|
Binding="{Binding LocateType.EnumValue.Value}"
|
||||||
CanUserSort="True"
|
CanUserSort="True"
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
<RowDefinition />
|
<RowDefinition />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBlock Text="当前只支持 Default 动画" />
|
|
||||||
<Grid
|
<Grid
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
@ -29,11 +28,24 @@
|
|||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
<Label Content="{ll:Str 动画类型}" />
|
<Label Content="{ll:Str 动画类型}" />
|
||||||
<ComboBox
|
<ComboBox
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
ItemsSource="{Binding GraphTypes}"
|
ItemsSource="{Binding GraphTypes.Value}"
|
||||||
SelectedItem="{Binding GraphType.Value}" />
|
SelectedItem="{Binding GraphType.Value}" />
|
||||||
|
<Label
|
||||||
|
Grid.Row="1"
|
||||||
|
Content="{ll:Str 动画名称}"
|
||||||
|
Visibility="{Binding HasNameAnime.Value, Converter={StaticResource FalseToHiddenConverter}}" />
|
||||||
|
<TextBox
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Text="{Binding AnimeName.Value, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
Visibility="{Binding HasNameAnime.Value, Converter={StaticResource FalseToHiddenConverter}}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="2">
|
<Grid Grid.Row="2">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
@ -29,6 +29,7 @@ public partial class SelectGraphTypeWindow : Window
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
DataContext = this;
|
DataContext = this;
|
||||||
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
|
||||||
|
GraphType.ValueChanged += GraphType_ValueChanged;
|
||||||
Closed += (s, e) =>
|
Closed += (s, e) =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -39,22 +40,37 @@ public partial class SelectGraphTypeWindow : Window
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GraphType_ValueChanged(GraphInfo.GraphType oldValue, GraphInfo.GraphType newValue)
|
||||||
|
{
|
||||||
|
if (newValue.IsHasNameAnime())
|
||||||
|
HasNameAnime.Value = true;
|
||||||
|
else
|
||||||
|
HasNameAnime.Value = false;
|
||||||
|
}
|
||||||
|
|
||||||
private void CurrentPet_ValueChanged(PetModel oldValue, PetModel newValue)
|
private void CurrentPet_ValueChanged(PetModel oldValue, PetModel newValue)
|
||||||
{
|
{
|
||||||
if (CurrentPet.Value.Animes.Count == 0)
|
|
||||||
{
|
|
||||||
GraphTypes.Value.Add(GraphInfo.GraphType.Default);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GraphTypes.Value = new(
|
GraphTypes.Value = new(
|
||||||
AnimeTypeModel.GraphTypes.Except(CurrentPet.Value.Animes.Select(m => m.GraphType.Value))
|
AnimeTypeModel.GraphTypes.Except(CurrentPet.Value.Animes.Select(m => m.GraphType.Value))
|
||||||
);
|
);
|
||||||
|
// 可添加多个项的类型
|
||||||
|
if (GraphTypes.Value.Contains(GraphInfo.GraphType.Common) is false)
|
||||||
|
GraphTypes.Value.Add(GraphInfo.GraphType.Common);
|
||||||
|
if (GraphTypes.Value.Contains(GraphInfo.GraphType.Work) is false)
|
||||||
|
GraphTypes.Value.Add(GraphInfo.GraphType.Work);
|
||||||
|
if (GraphTypes.Value.Contains(GraphInfo.GraphType.Move) is false)
|
||||||
|
GraphTypes.Value.Add(GraphInfo.GraphType.Move);
|
||||||
|
if (GraphTypes.Value.Contains(GraphInfo.GraphType.Idel) is false)
|
||||||
|
GraphTypes.Value.Add(GraphInfo.GraphType.Idel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableValue<PetModel> CurrentPet { get; } = new();
|
public ObservableValue<PetModel> CurrentPet { get; } = new();
|
||||||
public ObservableValue<GraphInfo.GraphType> GraphType { get; } = new();
|
public ObservableValue<GraphInfo.GraphType> GraphType { get; } = new();
|
||||||
public ObservableValue<ObservableCollection<GraphInfo.GraphType>> GraphTypes { get; } =
|
public ObservableValue<ObservableCollection<GraphInfo.GraphType>> GraphTypes { get; } =
|
||||||
new(new());
|
new(new());
|
||||||
|
public ObservableValue<string> AnimeName { get; } = new();
|
||||||
|
|
||||||
|
public ObservableValue<bool> HasNameAnime { get; } = new();
|
||||||
|
|
||||||
public bool IsCancel { get; private set; } = true;
|
public bool IsCancel { get; private set; } = true;
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@
|
|||||||
<TabItem.Header>
|
<TabItem.Header>
|
||||||
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}{0} ({1})">
|
<MultiBinding Converter="{StaticResource StringFormatConverter}" ConverterParameter="{}{0} ({1})">
|
||||||
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}" />
|
<Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}" />
|
||||||
<Binding Path="ModEditWindow.MovePage.ViewModel.CurrentPet.Value.Animes.Count" />
|
<Binding Path="ModEditWindow.AnimePage.ViewModel.CurrentPet.Value.Animes.Count" />
|
||||||
</MultiBinding>
|
</MultiBinding>
|
||||||
</TabItem.Header>
|
</TabItem.Header>
|
||||||
<Frame Content="{Binding ModEditWindow.AnimePage}" />
|
<Frame Content="{Binding ModEditWindow.AnimePage}" />
|
||||||
|
Reference in New Issue
Block a user