mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
更新
This commit is contained in:
parent
ba74693de0
commit
5b602d864d
@ -2,29 +2,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
public class ObservableEnumFlagsVM<T>
|
||||
/// <summary>
|
||||
/// 可观察的枚举标签模型
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class ObservableEnumFlags<T>
|
||||
where T : Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 枚举值
|
||||
/// </summary>
|
||||
public ObservableValue<T> EnumValue { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 添加枚举命令
|
||||
/// </summary>
|
||||
public ObservableCommand<T> AddCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 删除枚举命令
|
||||
/// </summary>
|
||||
public ObservableCommand<T> RemoveCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 枚举类型
|
||||
/// </summary>
|
||||
public Type EnumType = typeof(T);
|
||||
|
||||
/// <summary>
|
||||
/// 枚举基类
|
||||
/// </summary>
|
||||
public Type UnderlyingType { get; } = Enum.GetUnderlyingType(typeof(T));
|
||||
|
||||
public ObservableEnumFlagsVM()
|
||||
public ObservableEnumFlags()
|
||||
{
|
||||
if (Attribute.IsDefined(EnumType, typeof(FlagsAttribute)) is false)
|
||||
throw new Exception("此枚举类型未使用特性 [Flags]");
|
||||
AddCommand.ExecuteEvent += AddCommand_ExecuteEvent;
|
||||
RemoveCommand.ExecuteEvent += RemoveCommand_ExecuteEvent;
|
||||
}
|
||||
|
||||
public ObservableEnumFlagsVM(T value)
|
||||
public ObservableEnumFlags(T value)
|
||||
: this()
|
||||
{
|
||||
EnumValue.Value = value;
|
||||
|
@ -13,8 +13,18 @@ using VPet_Simulator.Core;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 拓展
|
||||
/// </summary>
|
||||
public static class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="comparisonType"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Contains(this string source, string value, StringComparison comparisonType)
|
||||
{
|
||||
return source.IndexOf(value, comparisonType) >= 0;
|
||||
@ -25,6 +35,10 @@ public static class Extensions
|
||||
// return ((FileStream)image.StreamSource).Name;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭流
|
||||
/// </summary>
|
||||
/// <param name="source">图像资源</param>
|
||||
public static void CloseStream(this ImageSource source)
|
||||
{
|
||||
if (source is BitmapImage image)
|
||||
@ -33,6 +47,11 @@ public static class Extensions
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图像复制
|
||||
/// </summary>
|
||||
/// <param name="image">图像</param>
|
||||
/// <returns>复制的图像</returns>
|
||||
public static BitmapImage Copy(this BitmapImage image)
|
||||
{
|
||||
BitmapImage newImage = new();
|
||||
@ -54,6 +73,11 @@ public static class Extensions
|
||||
return newImage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存至Png图片
|
||||
/// </summary>
|
||||
/// <param name="image">图片资源</param>
|
||||
/// <param name="path">路径</param>
|
||||
public static void SaveToPng(this BitmapSource image, string path)
|
||||
{
|
||||
if (path.EndsWith(".png") is false)
|
||||
@ -64,6 +88,15 @@ public static class Extensions
|
||||
encoder.Save(fs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试添加
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">键类型</typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="dictionary"></param>
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <returns>成功为 <see langword="true"/> 失败为 <see langword="false"/></returns>
|
||||
public static bool TryAdd<TKey, TValue>(
|
||||
this IDictionary<TKey, TValue> dictionary,
|
||||
TKey key,
|
||||
@ -76,6 +109,11 @@ public static class Extensions
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是含有名称的动画
|
||||
/// </summary>
|
||||
/// <param name="graphType"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsHasNameAnime(this GraphInfo.GraphType graphType)
|
||||
{
|
||||
return AnimeTypeModel.HasNameAnimes.Contains(graphType);
|
||||
|
@ -8,10 +8,24 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// I18n助手
|
||||
/// </summary>
|
||||
public class I18nHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前数据
|
||||
/// </summary>
|
||||
public static I18nHelper Current { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前文化名称
|
||||
/// </summary>
|
||||
public ObservableValue<string> CultureName { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 文化列表
|
||||
/// </summary>
|
||||
public ObservableCollection<string> CultureNames { get; } = new();
|
||||
|
||||
public I18nHelper()
|
||||
@ -42,8 +56,19 @@ public class I18nHelper
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加文化事件
|
||||
/// </summary>
|
||||
public event CultureEventHandler AddCulture;
|
||||
|
||||
/// <summary>
|
||||
/// 删除文化事件
|
||||
/// </summary>
|
||||
public event CultureEventHandler RemoveCulture;
|
||||
|
||||
/// <summary>
|
||||
/// 修改文化事件
|
||||
/// </summary>
|
||||
public event ReplaceCultureEventHandler ReplaceCulture;
|
||||
|
||||
public delegate void CultureEventHandler(string culture);
|
||||
|
@ -7,18 +7,29 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// I18n模型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public class I18nModel<T>
|
||||
where T : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前I18n数据
|
||||
/// </summary>
|
||||
public ObservableValue<T> CurrentI18nData { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 所有I18n数据
|
||||
/// </summary>
|
||||
public Dictionary<string, T> I18nDatas { get; } = new();
|
||||
|
||||
public I18nModel()
|
||||
{
|
||||
I18nHelper.Current.CultureName.ValueChanged += LangChanged;
|
||||
I18nHelper.Current.AddCulture += AddLang;
|
||||
I18nHelper.Current.RemoveCulture += RemoveLang;
|
||||
I18nHelper.Current.ReplaceCulture += ReplaceLang;
|
||||
I18nHelper.Current.CultureName.ValueChanged += CultureChanged;
|
||||
I18nHelper.Current.AddCulture += AddCulture;
|
||||
I18nHelper.Current.RemoveCulture += RemoveCulture;
|
||||
I18nHelper.Current.ReplaceCulture += ReplaceCulture;
|
||||
if (I18nHelper.Current.CultureNames.Count == 0)
|
||||
return;
|
||||
foreach (var item in I18nHelper.Current.CultureNames)
|
||||
@ -28,27 +39,45 @@ public class I18nModel<T>
|
||||
CurrentI18nData.Value = I18nDatas[I18nHelper.Current.CultureName.Value];
|
||||
}
|
||||
|
||||
private void LangChanged(string oldValue, string newValue)
|
||||
/// <summary>
|
||||
/// 文化改变
|
||||
/// </summary>
|
||||
/// <param name="oldValue"></param>
|
||||
/// <param name="newValue"></param>
|
||||
private void CultureChanged(string oldValue, string newValue)
|
||||
{
|
||||
if (I18nDatas.TryGetValue(newValue, out var result))
|
||||
CurrentI18nData.Value = result;
|
||||
}
|
||||
|
||||
private void AddLang(string lang)
|
||||
/// <summary>
|
||||
/// 添加文化
|
||||
/// </summary>
|
||||
/// <param name="culture">文化名称</param>
|
||||
private void AddCulture(string culture)
|
||||
{
|
||||
if (I18nDatas.ContainsKey(lang) is false)
|
||||
I18nDatas.Add(lang, new());
|
||||
if (I18nDatas.ContainsKey(culture) is false)
|
||||
I18nDatas.Add(culture, new());
|
||||
}
|
||||
|
||||
private void RemoveLang(string lang)
|
||||
/// <summary>
|
||||
/// 删除文化
|
||||
/// </summary>
|
||||
/// <param name="culture">文化名称</param>
|
||||
private void RemoveCulture(string culture)
|
||||
{
|
||||
I18nDatas.Remove(lang);
|
||||
I18nDatas.Remove(culture);
|
||||
}
|
||||
|
||||
private void ReplaceLang(string oldLang, string newLang)
|
||||
/// <summary>
|
||||
/// 替换文化
|
||||
/// </summary>
|
||||
/// <param name="oldCulture">旧文化名称</param>
|
||||
/// <param name="newCulture">新文化名称</param>
|
||||
private void ReplaceCulture(string oldCulture, string newCulture)
|
||||
{
|
||||
var item = I18nDatas[oldLang];
|
||||
I18nDatas.Remove(oldLang);
|
||||
I18nDatas.Add(newLang, item);
|
||||
var item = I18nDatas[oldCulture];
|
||||
I18nDatas.Remove(oldCulture);
|
||||
I18nDatas.Add(newCulture, item);
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,19 @@ using VPet_Simulator.Windows.Interface;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 模组加载器
|
||||
/// </summary>
|
||||
public class ModLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 作者
|
||||
/// </summary>
|
||||
public string Author { get; }
|
||||
|
||||
/// <summary>
|
||||
@ -26,193 +36,231 @@ public class ModLoader
|
||||
/// 上传至Steam的ItemID
|
||||
/// </summary>
|
||||
public ulong ItemID { get; }
|
||||
public string Intro { get; }
|
||||
public DirectoryInfo ModPath { get; }
|
||||
public int GameVer { get; }
|
||||
public int Ver { get; }
|
||||
public HashSet<string> Tag { get; } = new();
|
||||
public bool SuccessLoad { get; } = true;
|
||||
public DateTime CacheDate { get; } = DateTime.MinValue;
|
||||
public List<PetLoader> Pets { get; } = new();
|
||||
public List<Food> Foods { get; } = new();
|
||||
public List<LowText> LowTexts { get; } = new();
|
||||
public List<ClickText> ClickTexts { get; } = new();
|
||||
public List<SelectText> SelectTexts { get; } = new();
|
||||
public Dictionary<string, GraphCore> MultiGraphs { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 简介
|
||||
/// </summary>
|
||||
public string Intro { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 模组路径
|
||||
/// </summary>
|
||||
public DirectoryInfo ModPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 支持的游戏版本
|
||||
/// </summary>
|
||||
public int GameVer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 版本
|
||||
/// </summary>
|
||||
public int Ver { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 标签
|
||||
/// </summary>
|
||||
public HashSet<string> Tag { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 缓存数据
|
||||
/// </summary>
|
||||
public DateTime CacheDate { get; } = DateTime.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// 宠物列表
|
||||
/// </summary>
|
||||
public List<PetLoader> Pets { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 食物列表
|
||||
/// </summary>
|
||||
public List<Food> Foods { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 低状态文本列表
|
||||
/// </summary>
|
||||
public List<LowText> LowTexts { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 点击文本列表
|
||||
/// </summary>
|
||||
public List<ClickText> ClickTexts { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 选择文本列表
|
||||
/// </summary>
|
||||
public List<SelectText> SelectTexts { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// I18n数据
|
||||
/// </summary>
|
||||
public Dictionary<string, I18nModInfoModel> I18nDatas { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 其它I18n数据
|
||||
/// </summary>
|
||||
public Dictionary<string, Dictionary<string, string>> OtherI18nDatas { get; } = new();
|
||||
|
||||
public ModLoader(DirectoryInfo path)
|
||||
{
|
||||
try
|
||||
ModPath = path;
|
||||
LpsDocument modlps = new LpsDocument(File.ReadAllText(path.FullName + @"\info.lps"));
|
||||
Name = modlps.FindLine("vupmod").Info;
|
||||
Intro = modlps.FindLine("intro").Info;
|
||||
GameVer = modlps.FindSub("gamever").InfoToInt;
|
||||
Ver = modlps.FindSub("ver").InfoToInt;
|
||||
Author = modlps.FindSub("author").Info.Split('[').First();
|
||||
if (modlps.FindLine("authorid") != null)
|
||||
AuthorID = modlps.FindLine("authorid").InfoToInt64;
|
||||
else
|
||||
AuthorID = 0;
|
||||
if (modlps.FindLine("itemid") != null)
|
||||
ItemID = Convert.ToUInt64(modlps.FindLine("itemid").info);
|
||||
else
|
||||
ItemID = 0;
|
||||
CacheDate = modlps.GetDateTime("cachedate", DateTime.MinValue);
|
||||
|
||||
//MOD未加载时支持翻译
|
||||
foreach (var line in modlps.FindAllLine("lang"))
|
||||
{
|
||||
ModPath = path;
|
||||
LpsDocument modlps = new LpsDocument(File.ReadAllText(path.FullName + @"\info.lps"));
|
||||
Name = modlps.FindLine("vupmod").Info;
|
||||
Intro = modlps.FindLine("intro").Info;
|
||||
GameVer = modlps.FindSub("gamever").InfoToInt;
|
||||
Ver = modlps.FindSub("ver").InfoToInt;
|
||||
Author = modlps.FindSub("author").Info.Split('[').First();
|
||||
if (modlps.FindLine("authorid") != null)
|
||||
AuthorID = modlps.FindLine("authorid").InfoToInt64;
|
||||
else
|
||||
AuthorID = 0;
|
||||
if (modlps.FindLine("itemid") != null)
|
||||
ItemID = Convert.ToUInt64(modlps.FindLine("itemid").info);
|
||||
else
|
||||
ItemID = 0;
|
||||
CacheDate = modlps.GetDateTime("cachedate", DateTime.MinValue);
|
||||
|
||||
//MOD未加载时支持翻译
|
||||
foreach (var line in modlps.FindAllLine("lang"))
|
||||
var i18nData = new I18nModInfoModel();
|
||||
foreach (var sub in line)
|
||||
{
|
||||
var i18nData = new I18nModInfoModel();
|
||||
foreach (var sub in line)
|
||||
{
|
||||
if (sub.Name == Name)
|
||||
i18nData.Name.Value = sub.Info;
|
||||
else if (sub.Name == Intro)
|
||||
i18nData.Description.Value = sub.Info;
|
||||
}
|
||||
I18nDatas.Add(line.Info, i18nData);
|
||||
if (sub.Name == Name)
|
||||
i18nData.Name.Value = sub.Info;
|
||||
else if (sub.Name == Intro)
|
||||
i18nData.Description.Value = sub.Info;
|
||||
}
|
||||
DirectoryInfo? langDirectory = null;
|
||||
foreach (DirectoryInfo di in path.EnumerateDirectories())
|
||||
I18nDatas.Add(line.Info, i18nData);
|
||||
}
|
||||
DirectoryInfo? langDirectory = null;
|
||||
foreach (DirectoryInfo di in path.EnumerateDirectories())
|
||||
{
|
||||
switch (di.Name.ToLower())
|
||||
{
|
||||
switch (di.Name.ToLower())
|
||||
{
|
||||
case "pet":
|
||||
//宠物模型
|
||||
Tag.Add("pet");
|
||||
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
|
||||
{
|
||||
var lps = new LpsDocument(File.ReadAllText(fi.FullName));
|
||||
if (lps.First().Name.ToLower() == "pet")
|
||||
{
|
||||
var name = lps.First().Info;
|
||||
var pet = new PetLoader(lps, di);
|
||||
Pets.Add(pet);
|
||||
// ! : 此方法会导致 LoadImageToStream 无法使用
|
||||
//var graphCore = new GraphCore(0);
|
||||
//foreach (var p in pet.path)
|
||||
// PetLoader.LoadGraph(graphCore, di, p);
|
||||
//MultiGraphs.Add(pet.Name, graphCore);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "food":
|
||||
Tag.Add("food");
|
||||
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
|
||||
{
|
||||
var tmp = new LpsDocument(File.ReadAllText(fi.FullName));
|
||||
foreach (ILine li in tmp)
|
||||
{
|
||||
var food = LPSConvert.DeserializeObject<Food>(li);
|
||||
var imagePath = $"{path.FullName}\\image\\food\\{food.Name}.png";
|
||||
if (File.Exists(imagePath))
|
||||
food.Image = imagePath;
|
||||
Foods.Add(food);
|
||||
//string tmps = li.Find("name").info;
|
||||
//mw.Foods.RemoveAll(x => x.Id == tmps);
|
||||
//mw.Foods.Add(LPSConvert.DeserializeObject<Food>(li));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "image":
|
||||
Tag.Add("image");
|
||||
break;
|
||||
case "text":
|
||||
Tag.Add("text");
|
||||
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
|
||||
{
|
||||
var tmp = new LpsDocument(File.ReadAllText(fi.FullName));
|
||||
foreach (ILine li in tmp)
|
||||
{
|
||||
switch (li.Name.ToLower())
|
||||
{
|
||||
case "lowfoodtext":
|
||||
LowTexts.Add(LPSConvert.DeserializeObject<LowText>(li));
|
||||
break;
|
||||
case "lowdrinktext":
|
||||
LowTexts.Add(LPSConvert.DeserializeObject<LowText>(li));
|
||||
break;
|
||||
case "clicktext":
|
||||
ClickTexts.Add(LPSConvert.DeserializeObject<ClickText>(li));
|
||||
break;
|
||||
case "selecttext":
|
||||
SelectTexts.Add(
|
||||
LPSConvert.DeserializeObject<SelectText>(li)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "lang":
|
||||
Tag.Add("lang");
|
||||
langDirectory = di;
|
||||
//foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
|
||||
//{
|
||||
// //LocalizeCore.AddCulture(
|
||||
// // fi.Id.Substring(0, fi.Id.Length - fi.Extension.Length),
|
||||
// // new LPS_D(File.ReadAllText(fi.FullName))
|
||||
// //);
|
||||
//}
|
||||
//foreach (DirectoryInfo dis in di.EnumerateDirectories())
|
||||
//{
|
||||
// foreach (FileInfo fi in dis.EnumerateFiles("*.lps"))
|
||||
// {
|
||||
// //LocalizeCore.AddCulture(
|
||||
// // dis.Id,
|
||||
// // new LPS_D(File.ReadAllText(fi.FullName))
|
||||
// //);
|
||||
// }
|
||||
//}
|
||||
|
||||
//if (mw.Set.Language == "null")
|
||||
//{
|
||||
// LocalizeCore.LoadDefaultCulture();
|
||||
//}
|
||||
//else
|
||||
// LocalizeCore.LoadCulture(mw.Set.Language);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (langDirectory is null)
|
||||
return;
|
||||
foreach (DirectoryInfo dis in langDirectory.EnumerateDirectories())
|
||||
{
|
||||
OtherI18nDatas.Add(dis.Name, new());
|
||||
foreach (FileInfo fi in dis.EnumerateFiles("*.lps"))
|
||||
{
|
||||
var lps = new LPS(File.ReadAllText(fi.FullName));
|
||||
foreach (var item in lps)
|
||||
case "pet":
|
||||
//宠物模型
|
||||
Tag.Add("pet");
|
||||
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
|
||||
{
|
||||
if (OtherI18nDatas[dis.Name].ContainsKey(item.Name) is false)
|
||||
OtherI18nDatas[dis.Name].TryAdd(item.Name, item.Info);
|
||||
var lps = new LpsDocument(File.ReadAllText(fi.FullName));
|
||||
if (lps.First().Name.ToLower() == "pet")
|
||||
{
|
||||
var name = lps.First().Info;
|
||||
var pet = new PetLoader(lps, di);
|
||||
Pets.Add(pet);
|
||||
// ! : 此方法会导致 LoadImageToStream 无法使用
|
||||
//var graphCore = new GraphCore(0);
|
||||
//foreach (var p in pet.path)
|
||||
// PetLoader.LoadGraph(graphCore, di, p);
|
||||
//MultiGraphs.Add(pet.Name, graphCore);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "food":
|
||||
Tag.Add("food");
|
||||
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
|
||||
{
|
||||
var tmp = new LpsDocument(File.ReadAllText(fi.FullName));
|
||||
foreach (ILine li in tmp)
|
||||
{
|
||||
var food = LPSConvert.DeserializeObject<Food>(li);
|
||||
var imagePath = $"{path.FullName}\\image\\food\\{food.Name}.png";
|
||||
if (File.Exists(imagePath))
|
||||
food.Image = imagePath;
|
||||
Foods.Add(food);
|
||||
//string tmps = li.Find("name").info;
|
||||
//mw.Foods.RemoveAll(x => x.Id == tmps);
|
||||
//mw.Foods.Add(LPSConvert.DeserializeObject<Food>(li));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "image":
|
||||
Tag.Add("image");
|
||||
break;
|
||||
case "text":
|
||||
Tag.Add("text");
|
||||
foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
|
||||
{
|
||||
var tmp = new LpsDocument(File.ReadAllText(fi.FullName));
|
||||
foreach (ILine li in tmp)
|
||||
{
|
||||
switch (li.Name.ToLower())
|
||||
{
|
||||
case "lowfoodtext":
|
||||
LowTexts.Add(LPSConvert.DeserializeObject<LowText>(li));
|
||||
break;
|
||||
case "lowdrinktext":
|
||||
LowTexts.Add(LPSConvert.DeserializeObject<LowText>(li));
|
||||
break;
|
||||
case "clicktext":
|
||||
ClickTexts.Add(LPSConvert.DeserializeObject<ClickText>(li));
|
||||
break;
|
||||
case "selecttext":
|
||||
SelectTexts.Add(LPSConvert.DeserializeObject<SelectText>(li));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "lang":
|
||||
Tag.Add("lang");
|
||||
langDirectory = di;
|
||||
//foreach (FileInfo fi in di.EnumerateFiles("*.lps"))
|
||||
//{
|
||||
// //LocalizeCore.AddCulture(
|
||||
// // fi.Id.Substring(0, fi.Id.Length - fi.Extension.Length),
|
||||
// // new LPS_D(File.ReadAllText(fi.FullName))
|
||||
// //);
|
||||
//}
|
||||
//foreach (DirectoryInfo dis in di.EnumerateDirectories())
|
||||
//{
|
||||
// foreach (FileInfo fi in dis.EnumerateFiles("*.lps"))
|
||||
// {
|
||||
// //LocalizeCore.AddCulture(
|
||||
// // dis.Id,
|
||||
// // new LPS_D(File.ReadAllText(fi.FullName))
|
||||
// //);
|
||||
// }
|
||||
//}
|
||||
|
||||
//if (mw.Set.Language == "null")
|
||||
//{
|
||||
// LocalizeCore.LoadDefaultCulture();
|
||||
//}
|
||||
//else
|
||||
// LocalizeCore.LoadCulture(mw.Set.Language);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (langDirectory is null)
|
||||
return;
|
||||
foreach (DirectoryInfo dis in langDirectory.EnumerateDirectories())
|
||||
{
|
||||
OtherI18nDatas.Add(dis.Name, new());
|
||||
foreach (FileInfo fi in dis.EnumerateFiles("*.lps"))
|
||||
{
|
||||
var lps = new LPS(File.ReadAllText(fi.FullName));
|
||||
foreach (var item in lps)
|
||||
{
|
||||
if (OtherI18nDatas[dis.Name].ContainsKey(item.Name) is false)
|
||||
OtherI18nDatas[dis.Name].TryAdd(item.Name, item.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Tag.Add("该模组已损坏");
|
||||
SuccessLoad = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteFile()
|
||||
{
|
||||
var lps = new LpsDocument(File.ReadAllText(ModPath.FullName + @"\info.lps"));
|
||||
lps.FindLine("vupmod").Info = Name;
|
||||
lps.FindLine("intro").Info = Intro;
|
||||
lps.FindSub("gamever").InfoToInt = GameVer;
|
||||
lps.FindSub("ver").InfoToInt = Ver;
|
||||
lps.FindSub("author").Info = Author;
|
||||
lps.FindorAddLine("authorid").InfoToInt64 = AuthorID;
|
||||
lps.FindorAddLine("itemid").info = ItemID.ToString();
|
||||
File.WriteAllText(ModPath.FullName + @"\info.lps", lps.ToString());
|
||||
}
|
||||
//public void WriteFile()
|
||||
//{
|
||||
// var lps = new LpsDocument(File.ReadAllText(ModPath.FullName + @"\info.lps"));
|
||||
// lps.FindLine("vupmod").Info = Name;
|
||||
// lps.FindLine("intro").Info = Intro;
|
||||
// lps.FindSub("gamever").InfoToInt = GameVer;
|
||||
// lps.FindSub("ver").InfoToInt = Ver;
|
||||
// lps.FindSub("author").Info = Author;
|
||||
// lps.FindorAddLine("authorid").InfoToInt64 = AuthorID;
|
||||
// lps.FindorAddLine("itemid").info = ItemID.ToString();
|
||||
// File.WriteAllText(ModPath.FullName + @"\info.lps", lps.ToString());
|
||||
//}
|
||||
}
|
||||
|
@ -9,15 +9,30 @@ using System.Windows.Media.Imaging;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
public class ModMakerHistory
|
||||
/// <summary>
|
||||
/// 模组制作历史
|
||||
/// </summary>
|
||||
public class ModMakeHistory
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片
|
||||
/// </summary>
|
||||
public BitmapImage Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
[Line(ignoreCase: true)]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路径
|
||||
/// </summary>
|
||||
private string _path;
|
||||
|
||||
/// <summary>
|
||||
/// 资源路径
|
||||
/// </summary>
|
||||
[Line(ignoreCase: true)]
|
||||
public string SourcePath
|
||||
{
|
||||
@ -31,8 +46,14 @@ public class ModMakerHistory
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模组信息文件
|
||||
/// </summary>
|
||||
public string InfoFile => Path.Combine(SourcePath, "info.lps");
|
||||
|
||||
/// <summary>
|
||||
/// 最后编辑时间
|
||||
/// </summary>
|
||||
[Line(ignoreCase: true)]
|
||||
public DateTime LastTime { get; set; }
|
||||
}
|
@ -6,9 +6,23 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 模组制作器信息
|
||||
/// </summary>
|
||||
public static class ModMakerInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础目录
|
||||
/// </summary>
|
||||
public const string BaseDirectory = nameof(ModMaker);
|
||||
|
||||
/// <summary>
|
||||
/// 历史文件
|
||||
/// </summary>
|
||||
public const string HistoryFile = $"{BaseDirectory}\\history.lps";
|
||||
|
||||
/// <summary>
|
||||
/// 信息文件
|
||||
/// </summary>
|
||||
public const string InfoFile = "info.lps";
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ public class ClickTextModel : I18nModel<I18nClickTextModel>
|
||||
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public ObservableValue<string> Working { get; } = new();
|
||||
public ObservableEnumFlagsVM<ClickText.ModeType> Mode { get; } = new();
|
||||
public ObservableEnumFlags<ClickText.ModeType> Mode { get; } = new();
|
||||
public ObservableValue<VPet_Simulator.Core.Main.WorkingState> WorkingState { get; } = new();
|
||||
public ObservableEnumFlagsVM<ClickText.DayTime> DayTime { get; } = new();
|
||||
public ObservableEnumFlags<ClickText.DayTime> DayTime { get; } = new();
|
||||
|
||||
public ObservableRange<double> Like { get; } = new(0, int.MaxValue);
|
||||
public ObservableRange<double> Health { get; } = new(0, int.MaxValue);
|
||||
|
@ -36,12 +36,12 @@ public class MoveModel
|
||||
public ObservableValue<int> TriggerTop { get; } = new(100);
|
||||
public ObservableValue<int> TriggerBottom { get; } = new(100);
|
||||
|
||||
public ObservableEnumFlagsVM<GraphHelper.Move.DirectionType> LocateType { get; } =
|
||||
public ObservableEnumFlags<GraphHelper.Move.DirectionType> LocateType { get; } =
|
||||
new(GraphHelper.Move.DirectionType.None);
|
||||
public ObservableEnumFlagsVM<GraphHelper.Move.DirectionType> TriggerType { get; } =
|
||||
public ObservableEnumFlags<GraphHelper.Move.DirectionType> TriggerType { get; } =
|
||||
new(GraphHelper.Move.DirectionType.None);
|
||||
|
||||
public ObservableEnumFlagsVM<GraphHelper.Move.ModeType> ModeType { get; } =
|
||||
public ObservableEnumFlags<GraphHelper.Move.ModeType> ModeType { get; } =
|
||||
new(GraphHelper.Move.ModeType.Nomal);
|
||||
|
||||
public MoveModel() { }
|
||||
|
@ -28,7 +28,7 @@ public class SelectTextModel : I18nModel<I18nSelectTextModel>
|
||||
|
||||
public ObservableValue<string> Id { get; } = new();
|
||||
public ObservableValue<string> ChooseId { get; } = new();
|
||||
public ObservableEnumFlagsVM<ClickText.ModeType> Mode { get; } = new();
|
||||
public ObservableEnumFlags<ClickText.ModeType> Mode { get; } = new();
|
||||
|
||||
//public ObservableValue<string> Working { get; } = new();
|
||||
//public ObservableValue<VPet_Simulator.Core.Main.WorkingState> WorkingState { get; } = new();
|
||||
|
@ -2,11 +2,25 @@
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 可观察的范围
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public class ObservableRange<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 最小值
|
||||
/// </summary>
|
||||
public ObservableValue<T> Min { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 最大值
|
||||
/// </summary>
|
||||
public ObservableValue<T> Max { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 信息
|
||||
/// </summary>
|
||||
public ObservableValue<string> Info { get; } = new();
|
||||
|
||||
public ObservableRange()
|
||||
@ -15,23 +29,32 @@ public class ObservableRange<T>
|
||||
Max.ValueChanged += ValueChanged;
|
||||
}
|
||||
|
||||
private void ValueChanged(T oldValue, T newValue)
|
||||
{
|
||||
Info.Value = $"({Min.Value}, {Max.Value})";
|
||||
}
|
||||
|
||||
public ObservableRange(T min, T max)
|
||||
: this()
|
||||
{
|
||||
SetValue(min, max);
|
||||
}
|
||||
|
||||
private void ValueChanged(T oldValue, T newValue)
|
||||
{
|
||||
Info.Value = $"({Min.Value}, {Max.Value})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置值
|
||||
/// </summary>
|
||||
/// <param name="min">最小值</param>
|
||||
/// <param name="max">最大值</param>
|
||||
public void SetValue(T min, T max)
|
||||
{
|
||||
Min.Value = min;
|
||||
Max.Value = max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ObservableRange<T> Copy()
|
||||
{
|
||||
return new(Min.Value, Max.Value);
|
||||
|
@ -9,9 +9,19 @@ using System.Windows.Media.Imaging;
|
||||
|
||||
namespace VPet.ModMaker.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 工具
|
||||
/// </summary>
|
||||
public static class Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// 解码像素宽度
|
||||
/// </summary>
|
||||
public const int DecodePixelWidth = 250;
|
||||
|
||||
/// <summary>
|
||||
/// 节码像素高度
|
||||
/// </summary>
|
||||
public const int DecodePixelHeight = 250;
|
||||
public static char[] Separator { get; } = new char[] { '_' };
|
||||
|
||||
@ -31,6 +41,11 @@ public static class Utils
|
||||
// return bitmapImage;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 载入图片至内存流
|
||||
/// </summary>
|
||||
/// <param name="imagePath"></param>
|
||||
/// <returns></returns>
|
||||
public static BitmapImage LoadImageToMemoryStream(string imagePath)
|
||||
{
|
||||
BitmapImage bitmapImage = new();
|
||||
|
@ -110,7 +110,7 @@
|
||||
<Compile Include="Models\ModModel\ImageModel.cs" />
|
||||
<Compile Include="Models\ModModel\LowTextModel.cs" />
|
||||
<Compile Include="Models\ModLoader.cs" />
|
||||
<Compile Include="Models\ModMakerHistory.cs" />
|
||||
<Compile Include="Models\ModMakeHistory.cs" />
|
||||
<Compile Include="Models\ModMakerInfo.cs" />
|
||||
<Compile Include="Models\ModModel\MoveModel.cs" />
|
||||
<Compile Include="Models\ObservableRange.cs" />
|
||||
|
@ -3,6 +3,7 @@ using LinePutScript.Localization.WPF;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -16,27 +17,91 @@ namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
|
||||
public class AnimeEditWindowVM
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前宠物
|
||||
/// </summary>
|
||||
public PetModel CurrentPet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 旧动画
|
||||
/// </summary>
|
||||
public AnimeTypeModel OldAnime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 动画
|
||||
/// </summary>
|
||||
public ObservableValue<AnimeTypeModel> Anime { get; } = new(new());
|
||||
|
||||
/// <summary>
|
||||
/// 当前图像模型
|
||||
/// </summary>
|
||||
public ObservableValue<ImageModel> CurrentImageModel { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前动画模型
|
||||
/// </summary>
|
||||
public ObservableValue<AnimeModel> CurrentAnimeModel { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前模式
|
||||
/// </summary>
|
||||
public GameSave.ModeType CurrentMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 循环
|
||||
/// </summary>
|
||||
public ObservableValue<bool> Loop { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 含有多个状态 参见 <see cref="AnimeTypeModel.HasMultiTypeAnimes"/>
|
||||
/// </summary>
|
||||
public ObservableValue<bool> HasMultiType { get; } = new(false);
|
||||
|
||||
/// <summary>
|
||||
/// 含有动画名称 参见 <see cref="AnimeTypeModel.HasNameAnimes"/>
|
||||
/// </summary>
|
||||
public ObservableValue<bool> HasAnimeName { get; } = new(false);
|
||||
|
||||
#region Command
|
||||
/// <summary>
|
||||
/// 播放命令
|
||||
/// </summary>
|
||||
public ObservableCommand PlayCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 停止命令
|
||||
/// </summary>
|
||||
public ObservableCommand StopCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 添加图片命令
|
||||
/// </summary>
|
||||
public ObservableCommand<AnimeModel> AddImageCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 清除图片命令
|
||||
/// </summary>
|
||||
public ObservableCommand<AnimeModel> ClearImageCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 删除动画命令
|
||||
/// </summary>
|
||||
public ObservableCommand<AnimeModel> RemoveAnimeCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 删除图片命令
|
||||
/// </summary>
|
||||
public ObservableCommand<AnimeModel> RemoveImageCommand { get; } = new();
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 正在播放
|
||||
/// </summary>
|
||||
private bool _playing = false;
|
||||
|
||||
/// <summary>
|
||||
/// 动画任务
|
||||
/// </summary>
|
||||
private Task _playerTask;
|
||||
|
||||
public AnimeEditWindowVM()
|
||||
@ -55,6 +120,7 @@ public class AnimeEditWindowVM
|
||||
Anime.ValueChanged += Anime_ValueChanged;
|
||||
}
|
||||
|
||||
#region LoadAnime
|
||||
private void Anime_ValueChanged(AnimeTypeModel oldValue, AnimeTypeModel newValue)
|
||||
{
|
||||
CheckGraphType(newValue);
|
||||
@ -68,29 +134,11 @@ public class AnimeEditWindowVM
|
||||
if (AnimeTypeModel.HasNameAnimes.Contains(model.GraphType.Value))
|
||||
HasAnimeName.Value = true;
|
||||
}
|
||||
|
||||
private void CurrentAnimeModel_ValueChanged(AnimeModel oldValue, AnimeModel newValue)
|
||||
{
|
||||
StopCommand_ExecuteEvent();
|
||||
if (oldValue is not null)
|
||||
oldValue.Images.CollectionChanged -= Images_CollectionChanged;
|
||||
if (newValue is not null)
|
||||
newValue.Images.CollectionChanged += Images_CollectionChanged;
|
||||
}
|
||||
|
||||
private void Images_CollectionChanged(
|
||||
object sender,
|
||||
System.Collections.Specialized.NotifyCollectionChangedEventArgs e
|
||||
)
|
||||
{
|
||||
StopCommand_ExecuteEvent();
|
||||
}
|
||||
|
||||
private void RemoveImageCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
CurrentImageModel.Value.Close();
|
||||
value.Images.Remove(CurrentImageModel.Value);
|
||||
}
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// 删除动画
|
||||
/// </summary>
|
||||
/// <param name="value">动画模型</param>
|
||||
|
||||
private void RemoveAnimeCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
@ -110,6 +158,10 @@ public class AnimeEditWindowVM
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空图片
|
||||
/// </summary>
|
||||
/// <param name="value">动画模型</param>
|
||||
private void ClearImageCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
if (
|
||||
@ -121,20 +173,25 @@ public class AnimeEditWindowVM
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加图片
|
||||
/// </summary>
|
||||
/// <param name="value">动画模型</param>
|
||||
private void AddImageCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
OpenFileDialog openFileDialog =
|
||||
new()
|
||||
{
|
||||
Title = "选择图片".Translate(),
|
||||
Filter = $"图片|*.jpg;*.jpeg;*.png;*.bmp".Translate()
|
||||
};
|
||||
new() { Title = "选择图片".Translate(), Filter = $"图片|*.png".Translate() };
|
||||
if (openFileDialog.ShowDialog() is true)
|
||||
{
|
||||
value.Images.Add(new(Utils.LoadImageToMemoryStream(openFileDialog.FileName)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加图片
|
||||
/// </summary>
|
||||
/// <param name="model">动画模型</param>
|
||||
/// <param name="paths">路径</param>
|
||||
public void AddImages(AnimeModel model, IEnumerable<string> paths)
|
||||
{
|
||||
try
|
||||
@ -160,6 +217,34 @@ public class AnimeEditWindowVM
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除图片
|
||||
/// </summary>
|
||||
/// <param name="value">动画模型</param>
|
||||
private void RemoveImageCommand_ExecuteEvent(AnimeModel value)
|
||||
{
|
||||
CurrentImageModel.Value.Close();
|
||||
value.Images.Remove(CurrentImageModel.Value);
|
||||
}
|
||||
|
||||
#region Player
|
||||
private void CurrentAnimeModel_ValueChanged(AnimeModel oldValue, AnimeModel newValue)
|
||||
{
|
||||
StopCommand_ExecuteEvent();
|
||||
if (oldValue is not null)
|
||||
oldValue.Images.CollectionChanged -= Images_CollectionChanged;
|
||||
if (newValue is not null)
|
||||
newValue.Images.CollectionChanged += Images_CollectionChanged;
|
||||
}
|
||||
|
||||
private void Images_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
StopCommand_ExecuteEvent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止播放
|
||||
/// </summary>
|
||||
private void StopCommand_ExecuteEvent()
|
||||
{
|
||||
if (_playing is false)
|
||||
@ -167,6 +252,9 @@ public class AnimeEditWindowVM
|
||||
Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始播放
|
||||
/// </summary>
|
||||
private void PlayCommand_ExecuteEvent()
|
||||
{
|
||||
if (_playing)
|
||||
@ -183,6 +271,9 @@ public class AnimeEditWindowVM
|
||||
_playerTask.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放
|
||||
/// </summary>
|
||||
private void Play()
|
||||
{
|
||||
do
|
||||
@ -198,9 +289,13 @@ public class AnimeEditWindowVM
|
||||
Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置
|
||||
/// </summary>
|
||||
private void Reset()
|
||||
{
|
||||
_playing = false;
|
||||
_playerTask = new(Play);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -16,16 +16,45 @@ namespace VPet.ModMaker.ViewModels.ModEdit.AnimeEdit;
|
||||
public class AnimePageVM
|
||||
{
|
||||
#region Value
|
||||
/// <summary>
|
||||
/// 显示的动画
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableCollection<AnimeTypeModel>> ShowAnimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 动画
|
||||
/// </summary>
|
||||
public ObservableCollection<AnimeTypeModel> Animes => CurrentPet.Value.Animes;
|
||||
|
||||
/// <summary>
|
||||
/// 宠物列表
|
||||
/// </summary>
|
||||
public ObservableCollection<PetModel> Pets => ModInfoModel.Current.Pets;
|
||||
|
||||
/// <summary>
|
||||
/// 当前宠物
|
||||
/// </summary>
|
||||
public ObservableValue<PetModel> CurrentPet { get; } = new(new());
|
||||
|
||||
/// <summary>
|
||||
/// 搜索
|
||||
/// </summary>
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
#endregion
|
||||
#region Command
|
||||
/// <summary>
|
||||
/// 添加命令
|
||||
/// </summary>
|
||||
public ObservableCommand AddCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 编辑命令
|
||||
/// </summary>
|
||||
public ObservableCommand<AnimeTypeModel> EditCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 删除命令
|
||||
/// </summary>
|
||||
public ObservableCommand<AnimeTypeModel> RemoveCommand { get; } = new();
|
||||
#endregion
|
||||
public AnimePageVM()
|
||||
@ -58,8 +87,9 @@ public class AnimePageVM
|
||||
}
|
||||
}
|
||||
|
||||
public void Close() { }
|
||||
|
||||
/// <summary>
|
||||
/// 添加动画
|
||||
/// </summary>
|
||||
private void Add()
|
||||
{
|
||||
var selectGraphTypeWindow = new SelectGraphTypeWindow();
|
||||
@ -79,6 +109,10 @@ public class AnimePageVM
|
||||
Animes.Add(vm.Anime.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑动画
|
||||
/// </summary>
|
||||
/// <param name="model">动画类型模型</param>
|
||||
public void Edit(AnimeTypeModel model)
|
||||
{
|
||||
var window = new AnimeEditWindow();
|
||||
@ -100,18 +134,22 @@ public class AnimePageVM
|
||||
}
|
||||
}
|
||||
|
||||
private void Remove(AnimeTypeModel food)
|
||||
/// <summary>
|
||||
/// 删除动画
|
||||
/// </summary>
|
||||
/// <param name="model">动画类型模型</param>
|
||||
private void Remove(AnimeTypeModel model)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
return;
|
||||
if (ShowAnimes.Value.Count == Animes.Count)
|
||||
{
|
||||
Animes.Remove(food);
|
||||
Animes.Remove(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowAnimes.Value.Remove(food);
|
||||
Animes.Remove(food);
|
||||
ShowAnimes.Value.Remove(model);
|
||||
Animes.Remove(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,14 @@ public class ClickTextEditWindowVM
|
||||
public I18nHelper I18nData => I18nHelper.Current;
|
||||
|
||||
#region Value
|
||||
|
||||
/// <summary>
|
||||
/// 旧点击文本
|
||||
/// </summary>
|
||||
public ClickTextModel OldClickText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 点击文本
|
||||
/// </summary>
|
||||
public ObservableValue<ClickTextModel> ClickText { get; } = new(new());
|
||||
#endregion
|
||||
public ClickTextEditWindowVM() { }
|
||||
|
@ -15,13 +15,35 @@ namespace VPet.ModMaker.ViewModels.ModEdit.ClickTextEdit;
|
||||
public class ClickTextPageVM
|
||||
{
|
||||
#region Value
|
||||
/// <summary>
|
||||
/// 显示的点击文本
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableCollection<ClickTextModel>> ShowClickTexts { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 点击文本
|
||||
/// </summary>
|
||||
public ObservableCollection<ClickTextModel> ClickTexts => ModInfoModel.Current.ClickTexts;
|
||||
|
||||
/// <summary>
|
||||
/// 搜索
|
||||
/// </summary>
|
||||
public ObservableValue<string> Search { get; } = new();
|
||||
#endregion
|
||||
#region Command
|
||||
/// <summary>
|
||||
/// 添加命令
|
||||
/// </summary>
|
||||
public ObservableCommand AddCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 编辑命令
|
||||
/// </summary>
|
||||
public ObservableCommand<ClickTextModel> EditCommand { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 删除命令
|
||||
/// </summary>
|
||||
public ObservableCommand<ClickTextModel> RemoveCommand { get; } = new();
|
||||
#endregion
|
||||
|
||||
@ -50,6 +72,9 @@ public class ClickTextPageVM
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加点击文本
|
||||
/// </summary>
|
||||
private void Add()
|
||||
{
|
||||
var window = new ClickTextEditWindow();
|
||||
@ -60,6 +85,10 @@ public class ClickTextPageVM
|
||||
ClickTexts.Add(vm.ClickText.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑点击文本
|
||||
/// </summary>
|
||||
/// <param name="model">模型</param>
|
||||
public void Edit(ClickTextModel model)
|
||||
{
|
||||
var window = new ClickTextEditWindow();
|
||||
@ -80,6 +109,10 @@ public class ClickTextPageVM
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除点击文本
|
||||
/// </summary>
|
||||
/// <param name="model">模型</param>
|
||||
private void Remove(ClickTextModel model)
|
||||
{
|
||||
if (MessageBox.Show("确定删除吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.No)
|
||||
|
@ -33,12 +33,12 @@ public class ModMakerWindowVM
|
||||
/// <summary>
|
||||
/// 显示的历史
|
||||
/// </summary>
|
||||
public ObservableValue<ObservableCollection<ModMakerHistory>> ShowHistories { get; } = new();
|
||||
public ObservableValue<ObservableCollection<ModMakeHistory>> ShowHistories { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 历史
|
||||
/// </summary>
|
||||
public ObservableCollection<ModMakerHistory> Histories { get; } = new();
|
||||
public ObservableCollection<ModMakeHistory> Histories { get; } = new();
|
||||
#endregion
|
||||
#region Command
|
||||
/// <summary>
|
||||
@ -59,7 +59,7 @@ public class ModMakerWindowVM
|
||||
/// <summary>
|
||||
/// 删除历史命令
|
||||
/// </summary>
|
||||
public ObservableCommand<ModMakerHistory> RemoveHistoryCommand { get; } = new();
|
||||
public ObservableCommand<ModMakeHistory> RemoveHistoryCommand { get; } = new();
|
||||
#endregion
|
||||
|
||||
public ModMakerWindowVM(ModMakerWindow window)
|
||||
@ -83,7 +83,7 @@ public class ModMakerWindowVM
|
||||
}
|
||||
|
||||
#region History
|
||||
private void RemoveHistory(ModMakerHistory value)
|
||||
private void RemoveHistory(ModMakeHistory value)
|
||||
{
|
||||
Histories.Remove(value);
|
||||
SaveHistories();
|
||||
@ -99,7 +99,7 @@ public class ModMakerWindowVM
|
||||
var lps = new LPS(File.ReadAllText(ModMakerInfo.HistoryFile));
|
||||
foreach (var line in lps)
|
||||
{
|
||||
var history = LPSConvert.DeserializeObject<ModMakerHistory>(line);
|
||||
var history = LPSConvert.DeserializeObject<ModMakeHistory>(line);
|
||||
if (Histories.All(h => h.InfoFile != history.InfoFile))
|
||||
Histories.Add(history);
|
||||
}
|
||||
@ -136,7 +136,7 @@ public class ModMakerWindowVM
|
||||
{
|
||||
if (
|
||||
Histories.FirstOrDefault(h => h.SourcePath == modInfo.SourcePath.Value)
|
||||
is ModMakerHistory history
|
||||
is ModMakeHistory history
|
||||
)
|
||||
{
|
||||
history.Id = modInfo.Id.Value;
|
||||
@ -240,23 +240,22 @@ public class ModMakerWindowVM
|
||||
/// <param name="path">位置</param>
|
||||
public void LoadMod(string path)
|
||||
{
|
||||
ModLoader? loader = null;
|
||||
try
|
||||
{
|
||||
var mod = new ModLoader(new DirectoryInfo(path));
|
||||
if (mod.SuccessLoad is false)
|
||||
{
|
||||
MessageBox.Show("模组载入失败".Translate());
|
||||
return;
|
||||
}
|
||||
var pendingHandler = PendingBox.Show("载入中".Translate());
|
||||
var modInfo = new ModInfoModel(mod);
|
||||
EditMod(modInfo);
|
||||
pendingHandler.Close();
|
||||
loader = new ModLoader(new DirectoryInfo(path));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("模组载入失败:\n{0}".Translate(ex));
|
||||
}
|
||||
if (loader is not null)
|
||||
{
|
||||
var pendingHandler = PendingBox.Show("载入中".Translate());
|
||||
var modInfo = new ModInfoModel(loader);
|
||||
EditMod(modInfo);
|
||||
pendingHandler.Close();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public partial class ModMakerWindow : Window
|
||||
{
|
||||
if (sender is not ListBoxItem item)
|
||||
return;
|
||||
if (item.DataContext is not ModMakerHistory history)
|
||||
if (item.DataContext is not ModMakeHistory history)
|
||||
return;
|
||||
if (Directory.Exists(history.SourcePath) is false)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user