更新小说编辑器

This commit is contained in:
milimoe 2025-02-15 17:15:30 +08:00
parent 7ff4b56444
commit 5532108296
Signed by: milimoe
GPG Key ID: 05D280912DA6C69E
5 changed files with 180 additions and 49 deletions

View File

@ -0,0 +1,17 @@
<Window x:Class="Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor.InputDialog"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor"
mc:Ignorable="d"
Title="InputDialog" Height="150" Width="300" WindowStartupLocation="CenterScreen">
<StackPanel Margin="10">
<TextBlock x:Name="lblQuestion" Text="请输入内容:" Margin="0,0,0,5"/>
<TextBox x:Name="txtInput" Margin="0,0,0,10"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="确定" IsDefault="True" Click="Button_Click" Width="70" Margin="0,0,5,0"/>
<Button Content="取消" IsCancel="True" Width="70"/>
</StackPanel>
</StackPanel>
</Window>

View File

@ -0,0 +1,24 @@
using System.Windows;
namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
{
public partial class InputDialog : Window
{
public string ResponseText { get; set; } = "";
public InputDialog(string question, string title = "InputDialog")
{
InitializeComponent();
lblQuestion.Text = question;
Title = title;
txtInput.Loaded += (sender, e) => txtInput.Focus();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ResponseText = txtInput.Text;
DialogResult = true;
Close();
}
}
}

View File

@ -1,11 +1,30 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Model;
namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
{
internal class NovelTest
public class NovelConstant
{
internal static void CreateNovels()
public static Dictionary<Character, int> Likability { get; } = [];
public static Dictionary<string, Func<bool>> Conditions { get; } = [];
public static Character MainCharacter { get; set; } = Factory.GetCharacter();
public static Character { get; set; } = Factory.GetCharacter();
public static void InitConstatnt()
{
MainCharacter.Name = "主角";
MainCharacter.NickName = "主角";
.Name = "马猴烧酒";
.NickName = "魔法少女";
Likability.Add(, 100);
Conditions.Add("马猴烧酒的好感度低于50", () => 50());
Conditions.Add("主角攻击力大于20", () => 20(MainCharacter));
Conditions.Add("马猴烧酒攻击力大于20", () => 20());
}
public static void CreateNovels()
{
NovelNode node1 = new()
{
@ -16,7 +35,7 @@ namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
NovelNode node2 = new()
{
Key = "node2",
Name = NovelEditor.MainCharacter.NickName,
Name = MainCharacter.NickName,
Content = "什么人!"
};
node1.NextNodes.Add(node2);
@ -32,26 +51,26 @@ namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
Name = "我不认识你。",
AndPredicates = new()
{
{ "主角攻击力大于20", NovelEditor.Conditions["主角攻击力大于20"] }
{ "主角攻击力大于20", Conditions["主角攻击力大于20"] }
}
};
NovelNode node3 = new()
{
Key = "node3",
Name = NovelEditor..NickName,
Name = .NickName,
Content = "你好,我叫【马猴烧酒】!",
Options = [option1, option2]
};
NovelNode node4 = new()
{
Key = "node4",
Name = NovelEditor..NickName,
Name = .NickName,
Content = "你的名字是?"
};
NovelNode node5 = new()
{
Key = "node5",
Name = NovelEditor..NickName,
Name = .NickName,
Content = "滚,谁要认识你?"
};
node2.NextNodes.Add(node3);
@ -76,19 +95,19 @@ namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
Options = [option3],
AndPredicates = new()
{
{ "主角攻击力大于20", NovelEditor.Conditions["主角攻击力大于20"] }
{ "主角攻击力大于20", Conditions["主角攻击力大于20"] }
},
OrPredicates = new()
{
{ "马猴烧酒的好感度低于50", NovelEditor.Conditions["马猴烧酒的好感度低于50"] },
{ "马猴烧酒攻击力大于20", NovelEditor.Conditions["马猴烧酒攻击力大于20"] }
{ "马猴烧酒的好感度低于50", Conditions["马猴烧酒的好感度低于50"] },
{ "马猴烧酒攻击力大于20", Conditions["马猴烧酒攻击力大于20"] }
}
};
node4.NextNodes.Add(node6);
node5.NextNodes.Add(node6);
node5.NextNodes.Add(node7);
NovelConfig config = new("novel1", "chapter1")
NovelConfig config = new("NovelEditor", "example")
{
{ node1.Key, node1 },
{ node2.Key, node2 },
@ -100,5 +119,15 @@ namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
};
config.SaveConfig();
}
public static bool 20(Character character)
{
return character.ATK > 20;
}
public static bool 50(Character character)
{
return Likability[character] > 50;
}
}
}

View File

@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor"
mc:Ignorable="d"
Title="NovelEditor" Height="450" Width="800"
Title="NovelEditor" Height="450" Width="800" WindowStartupLocation="CenterScreen"
>
<Grid>
<Grid.ColumnDefinitions>
@ -15,8 +15,24 @@
<!-- 左侧:节点列表和操作按钮 -->
<StackPanel Grid.Column="0" Margin="10">
<Button Content="添加节点" Click="AddNodeButton_Click" Margin="0,0,0,10"/>
<Button Content="编辑节点" Click="EditNodeButton_Click" Margin="0,0,0,10"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Content="添加节点" Click="AddNodeButton_Click" Margin="5,5,5,5" Grid.Column="0" Grid.Row="0"/>
<Button Content="编辑节点" Click="EditNodeButton_Click" Margin="5,5,5,5" Grid.Column="1" Grid.Row="0"/>
<Button Content="加载" Click="LoadButton_Click" Margin="5,5,5,5" Grid.Column="0" Grid.Row="1"/>
<Button Content="保存" Click="SaveButton_Click" Margin="5,5,5,5" Grid.Column="1" Grid.Row="1"/>
<TextBlock x:Name="OpenedFileName" HorizontalAlignment="Center" Margin="5,5,5,5" Grid.Column="0" Grid.Row="2"/>
<Button Content="另存为" Click="SaveAsButton_Click" Margin="5,5,5,5" Grid.Column="1" Grid.Row="2"/>
</Grid>
<ListBox x:Name="NodeListBox" SelectionChanged="NodeListBox_SelectionChanged" d:ItemsSource="{d:SampleData ItemCount=5}">
<ListBox.ItemTemplate>
<DataTemplate>

View File

@ -1,7 +1,6 @@
using System.Windows;
using System.Windows.Controls;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Model;
using Button = System.Windows.Controls.Button;
using MessageBox = System.Windows.MessageBox;
@ -13,33 +12,22 @@ namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
/// </summary>
public partial class NovelEditor : Window
{
public static Dictionary<Character, int> Likability { get; } = [];
public static Dictionary<string, Func<bool>> Conditions { get; } = [];
public static Character MainCharacter { get; set; } = Factory.GetCharacter();
public static Character { get; set; } = Factory.GetCharacter();
private readonly NovelConfig _config;
private NovelConfig _config;
public NovelEditor()
{
InitializeComponent();
MainCharacter.Name = "主角";
MainCharacter.NickName = "主角";
.Name = "马猴烧酒";
.NickName = "魔法少女";
Likability.Add(, 100);
Conditions.Add("马猴烧酒的好感度低于50", () => 50());
Conditions.Add("主角攻击力大于20", () => 20(MainCharacter));
Conditions.Add("马猴烧酒攻击力大于20", () => 20());
// 初始化必要常量
NovelConstant.InitConstatnt();
// 如果需要,初始化小说
//NovelTest.CreateNovels();
//NovelConstant.CreateNovels();
// 小说配置
_config = new NovelConfig("novel1", "chapter1");
LoadNovelData();
_config = new NovelConfig("NovelEditor", "example");
_config.LoadConfig(NovelConstant.Conditions);
OpenedFileName.Text = _config.FileName;
// 绑定节点列表
NodeListBox.ItemsSource = _config.Values;
@ -49,12 +37,6 @@ namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
}
}
private void LoadNovelData()
{
// 加载已有的小说数据
_config.LoadConfig(Conditions);
}
private void NodeListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (NodeListBox.SelectedItem is NovelNode selectedNode)
@ -185,6 +167,7 @@ namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
_config.Add(newNode.Key, newNode);
NodeListBox.Items.Refresh();
if (!Title.StartsWith('*')) Title = "* " + Title;
}
private void EditNodeButton_Click(object sender, RoutedEventArgs e)
@ -193,6 +176,78 @@ namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
{
selectedNode.Content = "此示例节点已被编辑";
NodeContentText.Text = "文本:" + selectedNode.Content;
if (!Title.StartsWith('*')) Title = "* " + Title;
}
}
private void LoadButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new()
{
Filter = "小说配置文件 (*.json)|*.json|所有文件 (*.*)|*.*",
Title = "选择小说配置文件"
};
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string filePath = openFileDialog.FileName;
try
{
_config = NovelConfig.LoadFrom(filePath, "NovelEditor", false, NovelConstant.Conditions);
OpenedFileName.Text = _config.FileName;
NodeListBox.ItemsSource = _config.Values;
NodeListBox.Items.Refresh();
Title = Title.Replace("*", "").Trim();
if (NovelConfig.ExistsFile("NovelEditor", _config.FileName))
{
MessageBox.Show("这是一个在配置文件中已存在相同文件名的文件,建议保存时使用另存为功能。", "提示");
}
}
catch (Exception ex)
{
MessageBox.Show($"打开文件失败:{ex.Message}");
}
}
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
_config.SaveConfig();
NodeListBox.Items.Refresh();
Title = Title.Replace("*", "").Trim();
}
private void SaveAsButton_Click(object sender, RoutedEventArgs e)
{
InputDialog inputDialog = new("请输入新的小说章节名称:", "另存为");
if (inputDialog.ShowDialog() == true)
{
string name = inputDialog.ResponseText;
if (name.Trim() != "")
{
if (NovelConfig.ExistsFile("NovelEditor", name))
{
if (MessageBox.Show("文件已经存在,是否覆盖?", "提示", MessageBoxButton.YesNo) == MessageBoxResult.No)
{
return;
}
}
NovelConfig config2 = new("NovelEditor", name);
foreach (string key in _config.Keys)
{
config2[key] = _config[key];
}
_config = config2;
_config.SaveConfig();
OpenedFileName.Text = _config.FileName;
NodeListBox.ItemsSource = _config.Values;
NodeListBox.Items.Refresh();
Title = Title.Replace("*", "").Trim();
MessageBox.Show($"已经添加新的文件:{name}.json", "提示");
}
else
{
MessageBox.Show("文件名不能为空,另存为失败。");
}
}
}
@ -204,15 +259,5 @@ namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
NodeListBox.ScrollIntoView(target);
}
}
public static bool 20(Character character)
{
return character.ATK > 20;
}
public static bool 50(Character character)
{
return Likability[character] > 50;
}
}
}