完成 SaveAnime_Default

This commit is contained in:
Hakoyu 2023-09-19 23:25:17 +08:00
parent 63df5c128d
commit 5df65eb11e
10 changed files with 307 additions and 34 deletions

View File

@ -108,10 +108,7 @@ public class AnimeModel
.Split(_splits, StringSplitOptions.RemoveEmptyEntries);
Id.Value = info[0];
var duration = info.Last();
var imageModel = new ImageModel(
Utils.LoadImageToMemoryStream(file),
int.Parse(duration)
);
var imageModel = new ImageModel(Utils.LoadImageToStream(file), int.Parse(duration));
Images.Add(imageModel);
}
}
@ -125,4 +122,10 @@ public class AnimeModel
model.Images.Add(image);
return model;
}
public void Close()
{
foreach (var image in Images)
image.Close();
}
}

View File

@ -27,4 +27,9 @@ public class ImageModel
);
return model;
}
public void Close()
{
Image.Value?.CloseStream();
}
}

View File

@ -223,14 +223,6 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
Directory.CreateDirectory(petPath);
foreach (var pet in Pets)
{
var petFile = Path.Combine(petPath, $"{pet.Id.Value}.lps");
if (File.Exists(petFile) is false)
File.Create(petFile).Close();
var lps = new LPS();
GetPetInfo(lps, pet);
GetWorksInfo(lps, pet);
GetMoveInfo(lps, pet);
File.WriteAllText(petFile, lps.ToString());
foreach (var cultureName in I18nHelper.Current.CultureNames)
{
_saveI18nDatas[cultureName].TryAdd(
@ -246,6 +238,77 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
pet.I18nDatas[cultureName].Description.Value
);
}
var petFile = Path.Combine(petPath, $"{pet.Id.Value}.lps");
if (File.Exists(petFile) is false)
File.Create(petFile).Close();
var lps = new LPS();
GetPetInfo(lps, pet);
GetWorksInfo(lps, pet);
GetMoveInfo(lps, pet);
File.WriteAllText(petFile, lps.ToString());
var petAnimePath = Path.Combine(petPath, pet.Id.Value);
Directory.CreateDirectory(petAnimePath);
SaveAnime_Default(petAnimePath, pet);
}
}
void SaveAnime_Default(string path, PetModel pet)
{
if (
pet.Animes.FirstOrDefault(m => m.GraphType.Value == GraphInfo.GraphType.Default)
is not AnimeTypeModel animeType
)
return;
var animePath = Path.Combine(path, nameof(GraphInfo.GraphType.Default));
Directory.CreateDirectory(animePath);
if (animeType.HappyAnimes.Count > 0)
{
var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.Happy));
SaveImage(animeType.HappyAnimes, animeType, modePath);
}
if (animeType.NomalAnimes.Count > 0)
{
var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.Nomal));
SaveImage(animeType.NomalAnimes, animeType, modePath);
}
if (animeType.PoorConditionAnimes.Count > 0)
{
var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.PoorCondition));
SaveImage(animeType.PoorConditionAnimes, animeType, modePath);
}
if (animeType.IllAnimes.Count > 0)
{
var modePath = Path.Combine(animePath, nameof(GameSave.ModeType.Ill));
SaveImage(animeType.IllAnimes, animeType, modePath);
}
static void SaveImage(
ObservableCollection<AnimeModel> animes,
AnimeTypeModel animeType,
string modePath
)
{
Directory.CreateDirectory(modePath);
var count = 0;
foreach (var anime in animes)
{
var imagePath = Path.Combine(modePath, count.ToString());
Directory.CreateDirectory(imagePath);
var imageIndex = 0;
foreach (var image in anime.Images)
{
File.Copy(
image.Image.Value.GetSourceFile(),
Path.Combine(
imagePath,
$"{anime.Id.Value}_{imageIndex:000}_{image.Duration.Value}.png"
)
);
imageIndex++;
}
count++;
}
}
}

View File

@ -139,6 +139,9 @@
<Compile Include="Views\ModEdit\AnimeEdit\AnimePage.xaml.cs">
<DependentUpon>AnimePage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModEdit\AnimeEdit\SelectGraphTypeWindow.xaml.cs">
<DependentUpon>SelectGraphTypeWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModEdit\ClickTextEdit\ClickTextPage.xaml.cs">
<DependentUpon>ClickTextPage.xaml</DependentUpon>
</Compile>
@ -245,6 +248,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ModEdit\AnimeEdit\SelectGraphTypeWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ModEdit\ClickTextEdit\ClickTextPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -20,10 +20,12 @@ public class AnimeEditWindowVM
public AnimeTypeModel OldAnime { get; set; }
public ObservableValue<AnimeTypeModel> Anime { get; } = new(new());
public ObservableValue<ImageModel> CurrentImageModel { get; } = new();
public ObservableValue<AnimeModel> CurrentAnimeModel { get; } = new();
public GameSave.ModeType CurrentMode { get; set; }
public ObservableValue<bool> Loop { get; } = new();
#region Command
public ObservableCommand PlayCommand { get; } = new();
public ObservableCommand PauseCommand { get; } = new();
public ObservableCommand StopCommand { get; } = new();
public ObservableCommand<AnimeModel> AddImageCommand { get; } = new();
public ObservableCommand<AnimeModel> ClearImageCommand { get; } = new();
@ -31,22 +33,42 @@ public class AnimeEditWindowVM
public ObservableCommand<AnimeModel> RemoveImageCommand { get; } = new();
#endregion
public bool _pause = false;
public Task _playerTask;
private bool _playing = false;
private Task _playerTask;
public AnimeEditWindowVM()
{
//_playerTask = new(Play);
//PlayCommand.ExecuteEvent += PlayCommand_ExecuteEvent;
//PauseCommand.ExecuteEvent += PauseCommand_ExecuteEvent;
_playerTask = new(Play);
CurrentAnimeModel.ValueChanged += CurrentAnimeModel_ValueChanged;
;
PlayCommand.ExecuteEvent += PlayCommand_ExecuteEvent;
StopCommand.ExecuteEvent += StopCommand_ExecuteEvent;
AddImageCommand.ExecuteEvent += AddImageCommand_ExecuteEvent;
ClearImageCommand.ExecuteEvent += ClearImageCommand_ExecuteEvent;
RemoveAnimeCommand.ExecuteEvent += RemoveAnimeCommand_ExecuteEvent;
RemoveImageCommand.ExecuteEvent += RemoveImageCommand_ExecuteEvent;
}
private void CurrentAnimeModel_ValueChanged(AnimeModel oldValue, AnimeModel newValue)
{
StopCommand_ExecuteEvent();
oldValue.Images.CollectionChanged -= Images_CollectionChanged;
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);
}
@ -64,6 +86,7 @@ public class AnimeEditWindowVM
Anime.Value.PoorConditionAnimes.Remove(value);
else if (CurrentMode is GameSave.ModeType.Ill)
Anime.Value.IllAnimes.Remove(value);
value.Close();
}
}
@ -72,7 +95,10 @@ public class AnimeEditWindowVM
if (
MessageBox.Show("确定清空吗".Translate(), "", MessageBoxButton.YesNo) is MessageBoxResult.Yes
)
{
value.Close();
value.Images.Clear();
}
}
private void AddImageCommand_ExecuteEvent(AnimeModel value)
@ -89,25 +115,42 @@ public class AnimeEditWindowVM
}
}
private void PauseCommand_ExecuteEvent()
private void StopCommand_ExecuteEvent()
{
//_pause = true;
if (_playing is false)
return;
Reset();
}
private void PlayCommand_ExecuteEvent()
{
//_playerTask.Start();
if (_playing)
{
MessageBox.Show("正在播放".Translate());
return;
}
_playing = true;
_playerTask.Start();
}
private void Play()
{
//while (_pause is false)
//{
// foreach (var model in Anime.Value.ImageModels)
// {
// Anime.Value.CurrentImageModel.Value = model;
// Task.Delay(model.Duration.Value).Wait();
// }
//}
do
{
foreach (var model in CurrentAnimeModel.Value.Images)
{
CurrentImageModel.Value = model;
Task.Delay(model.Duration.Value).Wait();
if (_playing is false)
return;
}
} while (Loop.Value);
Reset();
}
private void Reset()
{
_playing = false;
_playerTask = new(Play);
}
}

View File

@ -62,9 +62,16 @@ public class AnimePageVM
private void Add()
{
var selectGraphTypeWindow = new SelectGraphTypeWindow();
selectGraphTypeWindow.CurrentPet.Value = CurrentPet.Value;
selectGraphTypeWindow.ShowDialog();
var graphType = selectGraphTypeWindow.GraphType.Value;
if (selectGraphTypeWindow.IsCancel)
return;
var window = new AnimeEditWindow();
var vm = window.ViewModel;
vm.CurrentPet = CurrentPet.Value;
vm.Anime.Value.GraphType.Value = graphType;
window.ShowDialog();
if (window.IsCancel)
return;

View File

@ -68,7 +68,8 @@
ItemsSource="{Binding Images, IsAsync=True}"
PreviewMouseMove="ListBox_PreviewMouseMove"
PreviewMouseWheel="ListBox_PreviewMouseWheel"
SelectedItem="{Binding DataContext.CurrentImageModel.Value, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}">
SelectedItem="{Binding DataContext.CurrentImageModel.Value, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
SelectionChanged="ListBox_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
@ -128,9 +129,15 @@
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Image Width="250" Height="250">
<Image
Width="250"
Height="250"
Source="{Binding CurrentImageModel.Value.Image.Value}">
<Image.ToolTip>
<Image Width="500" Height="500" />
<Image
Width="500"
Height="500"
Source="{Binding CurrentImageModel.Value.Image.Value}" />
</Image.ToolTip>
</Image>
<Grid Grid.Row="1">
@ -139,12 +146,15 @@
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Command="{Binding PauseCommand}" Content="{ll:Str 停止}" />
<Button Command="{Binding StopCommand}" Content="{ll:Str 停止}" />
<Button
Grid.Column="1"
Command="{Binding PlayCommand}"
Content="{ll:Str 播放}" />
<ToggleButton Grid.Column="2" Content="{ll:Str 循环}" />
<ToggleButton
Grid.Column="2"
Content="{ll:Str 循环}"
IsChecked="{Binding Loop.Value}" />
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>

View File

@ -195,4 +195,12 @@ public partial class AnimeEditWindow : Window
else if (ViewModel.CurrentMode is GameSave.ModeType.Ill)
ViewModel.Anime.Value.IllAnimes.Add(new());
}
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is not ListBox listBox)
return;
if (listBox.DataContext is AnimeModel model)
ViewModel.CurrentAnimeModel.Value = model;
}
}

View File

@ -0,0 +1,56 @@
<Window
x:Class="VPet.ModMaker.Views.ModEdit.AnimeEdit.SelectGraphTypeWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ll="clr-namespace:LinePutScript.Localization.WPF;assembly=LinePutScript.Localization.WPF"
xmlns:local="clr-namespace:VPet.ModMaker.Views.ModEdit.AnimeEdit"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pu="https://opensource.panuon.com/wpf-ui"
Title="SelectGraphTypeWindow"
Width="500"
Height="300"
mc:Ignorable="d">
<d:Window.DataContext>
<local:SelectGraphTypeWindow />
</d:Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="当前只支持 Default 动画" />
<Grid
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Content="{ll:Str 动画类型}" />
<ComboBox
Grid.Column="1"
ItemsSource="{Binding GraphTypes}"
SelectedItem="{Binding GraphType.Value}" />
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button
x:Name="Button_Cancel"
Margin="10"
Click="Button_Cancel_Click"
Content="{ll:Str 取消}" />
<Button
x:Name="Button_Yes"
Grid.Column="1"
Margin="10"
Click="Button_Yes_Click"
Content="{ll:Str 确定}" />
</Grid>
</Grid>
</Window>

View File

@ -0,0 +1,71 @@
using HKW.HKWViewModels.SimpleObservable;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using VPet.ModMaker.Models;
using VPet.ModMaker.Models.ModModel;
using VPet_Simulator.Core;
namespace VPet.ModMaker.Views.ModEdit.AnimeEdit;
/// <summary>
/// SelectGraphTypeWindow.xaml 的交互逻辑
/// </summary>
public partial class SelectGraphTypeWindow : Window
{
public SelectGraphTypeWindow()
{
InitializeComponent();
DataContext = this;
CurrentPet.ValueChanged += CurrentPet_ValueChanged;
Closed += (s, e) =>
{
try
{
DataContext = null;
}
catch { }
};
}
private void CurrentPet_ValueChanged(PetModel oldValue, PetModel newValue)
{
if (CurrentPet.Value.Animes.Count == 0)
{
GraphTypes.Value.Add(GraphInfo.GraphType.Default);
return;
}
GraphTypes.Value = new(
AnimeTypeModel.GraphTypes.Except(CurrentPet.Value.Animes.Select(m => m.GraphType.Value))
);
}
public ObservableValue<PetModel> CurrentPet { get; } = new();
public ObservableValue<GraphInfo.GraphType> GraphType { get; } = new();
public ObservableValue<ObservableCollection<GraphInfo.GraphType>> GraphTypes { get; } =
new(new());
public bool IsCancel { get; private set; } = true;
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void Button_Yes_Click(object sender, RoutedEventArgs e)
{
IsCancel = false;
Close();
}
}