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

View File

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

View File

@ -223,14 +223,6 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
Directory.CreateDirectory(petPath); Directory.CreateDirectory(petPath);
foreach (var pet in Pets) 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) foreach (var cultureName in I18nHelper.Current.CultureNames)
{ {
_saveI18nDatas[cultureName].TryAdd( _saveI18nDatas[cultureName].TryAdd(
@ -246,6 +238,77 @@ public class ModInfoModel : I18nModel<I18nModInfoModel>
pet.I18nDatas[cultureName].Description.Value 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"> <Compile Include="Views\ModEdit\AnimeEdit\AnimePage.xaml.cs">
<DependentUpon>AnimePage.xaml</DependentUpon> <DependentUpon>AnimePage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\ModEdit\AnimeEdit\SelectGraphTypeWindow.xaml.cs">
<DependentUpon>SelectGraphTypeWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModEdit\ClickTextEdit\ClickTextPage.xaml.cs"> <Compile Include="Views\ModEdit\ClickTextEdit\ClickTextPage.xaml.cs">
<DependentUpon>ClickTextPage.xaml</DependentUpon> <DependentUpon>ClickTextPage.xaml</DependentUpon>
</Compile> </Compile>
@ -245,6 +248,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\ModEdit\AnimeEdit\SelectGraphTypeWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ModEdit\ClickTextEdit\ClickTextPage.xaml"> <Page Include="Views\ModEdit\ClickTextEdit\ClickTextPage.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

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

View File

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

View File

@ -195,4 +195,12 @@ public partial class AnimeEditWindow : Window
else if (ViewModel.CurrentMode is GameSave.ModeType.Ill) else if (ViewModel.CurrentMode is GameSave.ModeType.Ill)
ViewModel.Anime.Value.IllAnimes.Add(new()); 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();
}
}