mirror of
https://github.com/milimoe/FunGame-Testing.git
synced 2025-04-21 03:39:34 +08:00
添加视觉小说编辑器
This commit is contained in:
parent
e24346bf57
commit
7ff4b56444
8
Desktop/App.xaml
Normal file
8
Desktop/App.xaml
Normal file
@ -0,0 +1,8 @@
|
||||
<Application x:Class="Milimoe.FunGame.Testing.Desktop.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
StartupUri="Solutions/NovelEditor/NovelEditor.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
12
Desktop/App.xaml.cs
Normal file
12
Desktop/App.xaml.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using Application = System.Windows.Application;
|
||||
|
||||
namespace Milimoe.FunGame.Testing.Desktop
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
public App()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<BaseOutputPath>..\bin\</BaseOutputPath>
|
||||
<RootNamespace>Milimoe.$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
|
||||
<UseWPF>True</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
@ -22,6 +23,10 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Include="App.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="FunGame.Core">
|
||||
<HintPath>..\..\FunGame.Core\bin\Debug\net9.0\FunGame.Core.dll</HintPath>
|
||||
|
@ -1,20 +1,20 @@
|
||||
using Milimoe.FunGame.Testing.Desktop.Solutions;
|
||||
//using Milimoe.FunGame.Testing.Desktop.Solutions;
|
||||
|
||||
namespace Desktop
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
//Application.Run(new ChessBoardExample.ChessBoardExample());
|
||||
Application.Run(new EntityEditor());
|
||||
}
|
||||
}
|
||||
}
|
||||
//namespace Desktop
|
||||
//{
|
||||
// internal static class Program
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// The main entry point for the application.
|
||||
// /// </summary>
|
||||
// [STAThread]
|
||||
// static void Main()
|
||||
// {
|
||||
// // To customize application configuration such as set high DPI settings or default font,
|
||||
// // see https://aka.ms/applicationconfiguration.
|
||||
// ApplicationConfiguration.Initialize();
|
||||
// //Application.Run(new ChessBoardExample.ChessBoardExample());
|
||||
// Application.Run(new EntityEditor());
|
||||
// }
|
||||
// }
|
||||
//}
|
89
Desktop/Solutions/NovelEditor/NovelEditor.xaml
Normal file
89
Desktop/Solutions/NovelEditor/NovelEditor.xaml
Normal file
@ -0,0 +1,89 @@
|
||||
<Window x:Class="Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor.NovelEditor"
|
||||
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="NovelEditor" Height="450" Width="800"
|
||||
>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="200"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 左侧:节点列表和操作按钮 -->
|
||||
<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"/>
|
||||
<ListBox x:Name="NodeListBox" SelectionChanged="NodeListBox_SelectionChanged" d:ItemsSource="{d:SampleData ItemCount=5}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Key}" />
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 右侧:节点详情 -->
|
||||
<ScrollViewer Grid.Column="1" Margin="10">
|
||||
<StackPanel Grid.Column="1" Margin="10">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Text="节点详情" FontSize="16" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
|
||||
<!-- 导航按钮 -->
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Content="上一个" Click="PreviousSentence_Click" Margin="5,0,0,0" Width="80"/>
|
||||
<Button Content="下一个" Click="NextSentence_Click" Margin="5,0,0,0" Width="80"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<TextBlock x:Name="NodeKeyText" Margin="0,8,0,0" LineHeight="20" />
|
||||
<TextBlock x:Name="NodeNameText" Margin="0,8,0,0" LineHeight="20" />
|
||||
<TextBlock x:Name="NodeContentText" Margin="0,8,0,0" TextWrapping="Wrap" LineHeight="20"/>
|
||||
|
||||
<!-- 显示条件 -->
|
||||
<TextBlock Text="显示条件" FontSize="14" FontWeight="Bold" Margin="0,10,0,0"/>
|
||||
<TextBlock x:Name="NodeConditionsText" Margin="0,5,0,0" TextWrapping="Wrap" LineHeight="20" />
|
||||
|
||||
<!-- 选项 -->
|
||||
<TextBlock Text="选项" FontSize="14" FontWeight="Bold" Margin="0,10,0,0"/>
|
||||
<ListBox x:Name="OptionsListBox" d:ItemsSource="{d:SampleData ItemCount=5}" HorizontalContentAlignment="Stretch">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid Width="auto">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- 使用 ItemsControl 为每个 TargetNode 创建一个按钮 -->
|
||||
<ItemsControl Grid.Column="1" ItemsSource="{Binding Targets}" HorizontalAlignment="Right">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<DockPanel LastChildFill="False" HorizontalAlignment="Right"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Button Content="{Binding Key}" Click="OptionButton_Click" Tag="{Binding}" Margin="5" Width="80" DockPanel.Dock="Right"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
|
||||
<TextBlock Text="{Binding Conditions}" Margin="10,0,0,0" TextWrapping="Wrap" Foreground="Gray"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Window>
|
218
Desktop/Solutions/NovelEditor/NovelEditor.xaml.cs
Normal file
218
Desktop/Solutions/NovelEditor/NovelEditor.xaml.cs
Normal file
@ -0,0 +1,218 @@
|
||||
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;
|
||||
|
||||
namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// NovelEditor.xaml 的交互逻辑
|
||||
/// </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;
|
||||
|
||||
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(马猴烧酒));
|
||||
|
||||
// 如果需要,初始化小说
|
||||
//NovelTest.CreateNovels();
|
||||
|
||||
// 小说配置
|
||||
_config = new NovelConfig("novel1", "chapter1");
|
||||
LoadNovelData();
|
||||
|
||||
// 绑定节点列表
|
||||
NodeListBox.ItemsSource = _config.Values;
|
||||
if (_config.Count > 0)
|
||||
{
|
||||
NodeListBox.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadNovelData()
|
||||
{
|
||||
// 加载已有的小说数据
|
||||
_config.LoadConfig(Conditions);
|
||||
}
|
||||
|
||||
private void NodeListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (NodeListBox.SelectedItem is NovelNode selectedNode)
|
||||
{
|
||||
// 显示节点详情
|
||||
NodeKeyText.Text = "编号:" + selectedNode.Key;
|
||||
NodeNameText.Text = "角色:" + selectedNode.Name;
|
||||
NodeContentText.Text = "文本:" + selectedNode.Content;
|
||||
|
||||
// 显示节点的显示条件
|
||||
NodeConditionsText.Text = FormatConditions(selectedNode);
|
||||
|
||||
// 显示选项
|
||||
OptionsListBox.ItemsSource = selectedNode.Options.Select(option => new
|
||||
{
|
||||
option.Name,
|
||||
option.Targets,
|
||||
Conditions = FormatOptionConditions(option)
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
private void PreviousSentence_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (NodeListBox.SelectedItem is NovelNode selectedNode)
|
||||
{
|
||||
if (selectedNode.Previous is null)
|
||||
{
|
||||
if (NodeListBox.SelectedIndex - 1 >= 0)
|
||||
{
|
||||
MessageBox.Show("此节点没有定义上一个节点!现在跳转列表的上一个节点。");
|
||||
NodeListBox.SelectedIndex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("此节点没有定义上一个节点,并且已经达到列表顶部!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeListBox.SelectedItem = selectedNode.Previous;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void NextSentence_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (NodeListBox.SelectedItem is NovelNode selectedNode)
|
||||
{
|
||||
NovelNode? next = selectedNode.Next;
|
||||
if (next is null)
|
||||
{
|
||||
if (NodeListBox.SelectedIndex + 1 < NodeListBox.Items.Count)
|
||||
{
|
||||
MessageBox.Show("此节点没有定义下一个节点!现在跳转列表的下一个节点。");
|
||||
NodeListBox.SelectedIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("此节点没有定义下一个节点,并且已经到达列表底部!现在跳转到列表的起始处。");
|
||||
NodeListBox.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeListBox.SelectedItem = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatConditions(NovelNode node)
|
||||
{
|
||||
List<string> conditions = [];
|
||||
|
||||
if (node.AndPredicates.Count != 0)
|
||||
{
|
||||
conditions.Add("需满足以下所有条件:");
|
||||
foreach (string condition in node.AndPredicates.Keys)
|
||||
{
|
||||
conditions.Add($"- {condition}");
|
||||
}
|
||||
}
|
||||
|
||||
if (node.OrPredicates.Count != 0)
|
||||
{
|
||||
conditions.Add("需满足以下任意一个条件:");
|
||||
foreach (string condition in node.OrPredicates.Keys)
|
||||
{
|
||||
conditions.Add($"- {condition}");
|
||||
}
|
||||
}
|
||||
|
||||
return conditions.Count != 0 ? string.Join(Environment.NewLine, conditions) : "无显示条件";
|
||||
}
|
||||
|
||||
private static string FormatOptionConditions(NovelOption option)
|
||||
{
|
||||
List<string> conditions = [];
|
||||
|
||||
if (option.AndPredicates.Count != 0)
|
||||
{
|
||||
conditions.Add("需满足以下所有条件:");
|
||||
foreach (string condition in option.AndPredicates.Keys)
|
||||
{
|
||||
conditions.Add($"- {condition}");
|
||||
}
|
||||
}
|
||||
|
||||
if (option.OrPredicates.Count != 0)
|
||||
{
|
||||
conditions.Add("需满足以下任意一个条件:");
|
||||
foreach (string condition in option.OrPredicates.Keys)
|
||||
{
|
||||
conditions.Add($"- {condition}");
|
||||
}
|
||||
}
|
||||
|
||||
return conditions.Count != 0 ? string.Join(Environment.NewLine, conditions) : "";
|
||||
}
|
||||
|
||||
private void AddNodeButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
NovelNode newNode = new()
|
||||
{
|
||||
Key = "示例节点编号",
|
||||
Name = "示例发言人",
|
||||
Content = "示例发言内容"
|
||||
};
|
||||
|
||||
_config.Add(newNode.Key, newNode);
|
||||
NodeListBox.Items.Refresh();
|
||||
}
|
||||
|
||||
private void EditNodeButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (NodeListBox.SelectedItem is NovelNode selectedNode)
|
||||
{
|
||||
selectedNode.Content = "此示例节点已被编辑";
|
||||
NodeContentText.Text = "文本:" + selectedNode.Content;
|
||||
}
|
||||
}
|
||||
|
||||
private void OptionButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button && button.Tag is NovelNode node && NodeListBox.Items.OfType<NovelNode>().FirstOrDefault(n => n.Key == node.Key) is NovelNode target)
|
||||
{
|
||||
NodeListBox.SelectedItem = target;
|
||||
NodeListBox.ScrollIntoView(target);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool 攻击力大于20(Character character)
|
||||
{
|
||||
return character.ATK > 20;
|
||||
}
|
||||
|
||||
public static bool 好感度低于50(Character character)
|
||||
{
|
||||
return Likability[character] > 50;
|
||||
}
|
||||
}
|
||||
}
|
104
Desktop/Solutions/NovelEditor/NovelTest.cs
Normal file
104
Desktop/Solutions/NovelEditor/NovelTest.cs
Normal file
@ -0,0 +1,104 @@
|
||||
using Milimoe.FunGame.Core.Api.Utility;
|
||||
using Milimoe.FunGame.Core.Model;
|
||||
|
||||
namespace Milimoe.FunGame.Testing.Desktop.Solutions.NovelEditor
|
||||
{
|
||||
internal class NovelTest
|
||||
{
|
||||
internal static void CreateNovels()
|
||||
{
|
||||
NovelNode node1 = new()
|
||||
{
|
||||
Key = "node1",
|
||||
Name = "声音",
|
||||
Content = "听说你在等我?我来了!"
|
||||
};
|
||||
NovelNode node2 = new()
|
||||
{
|
||||
Key = "node2",
|
||||
Name = NovelEditor.MainCharacter.NickName,
|
||||
Content = "什么人!"
|
||||
};
|
||||
node1.NextNodes.Add(node2);
|
||||
node2.Previous = node1;
|
||||
NovelOption option1 = new()
|
||||
{
|
||||
Key = "option1",
|
||||
Name = "你好。"
|
||||
};
|
||||
NovelOption option2 = new()
|
||||
{
|
||||
Key = "option2",
|
||||
Name = "我不认识你。",
|
||||
AndPredicates = new()
|
||||
{
|
||||
{ "主角攻击力大于20", NovelEditor.Conditions["主角攻击力大于20"] }
|
||||
}
|
||||
};
|
||||
NovelNode node3 = new()
|
||||
{
|
||||
Key = "node3",
|
||||
Name = NovelEditor.马猴烧酒.NickName,
|
||||
Content = "你好,我叫【马猴烧酒】!",
|
||||
Options = [option1, option2]
|
||||
};
|
||||
NovelNode node4 = new()
|
||||
{
|
||||
Key = "node4",
|
||||
Name = NovelEditor.马猴烧酒.NickName,
|
||||
Content = "你的名字是?"
|
||||
};
|
||||
NovelNode node5 = new()
|
||||
{
|
||||
Key = "node5",
|
||||
Name = NovelEditor.马猴烧酒.NickName,
|
||||
Content = "滚,谁要认识你?"
|
||||
};
|
||||
node2.NextNodes.Add(node3);
|
||||
option1.Targets.Add(node4);
|
||||
option2.Targets.Add(node5);
|
||||
NovelNode node6 = new()
|
||||
{
|
||||
Key = "node6",
|
||||
Content = "旁白:示例结束。"
|
||||
};
|
||||
NovelOption option3 = new()
|
||||
{
|
||||
Key = "option3",
|
||||
Name = "重新开始游戏",
|
||||
Targets = [node1]
|
||||
};
|
||||
NovelNode node7 = new()
|
||||
{
|
||||
Key = "node7",
|
||||
Priority = 2,
|
||||
Content = "旁白:示例结束,你被马猴烧酒吃掉了。",
|
||||
Options = [option3],
|
||||
AndPredicates = new()
|
||||
{
|
||||
{ "主角攻击力大于20", NovelEditor.Conditions["主角攻击力大于20"] }
|
||||
},
|
||||
OrPredicates = new()
|
||||
{
|
||||
{ "马猴烧酒的好感度低于50", NovelEditor.Conditions["马猴烧酒的好感度低于50"] },
|
||||
{ "马猴烧酒攻击力大于20", NovelEditor.Conditions["马猴烧酒攻击力大于20"] }
|
||||
}
|
||||
};
|
||||
node4.NextNodes.Add(node6);
|
||||
node5.NextNodes.Add(node6);
|
||||
node5.NextNodes.Add(node7);
|
||||
|
||||
NovelConfig config = new("novel1", "chapter1")
|
||||
{
|
||||
{ node1.Key, node1 },
|
||||
{ node2.Key, node2 },
|
||||
{ node3.Key, node3 },
|
||||
{ node4.Key, node4 },
|
||||
{ node5.Key, node5 },
|
||||
{ node6.Key, node6 },
|
||||
{ node7.Key, node7 }
|
||||
};
|
||||
config.SaveConfig();
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ using Oshima.FunGame.OshimaModules;
|
||||
using Oshima.FunGame.OshimaServers.Service;
|
||||
using Oshima.FunGame.WebAPI.Controllers;
|
||||
|
||||
//7
|
||||
_ = new Milimoe.FunGame.Testing.Solutions.Novels();
|
||||
|
||||
//_ = new Milimoe.FunGame.Testing.Tests.CheckDLL();
|
||||
|
||||
|
214
Library/Solutions/Novels.cs
Normal file
214
Library/Solutions/Novels.cs
Normal file
@ -0,0 +1,214 @@
|
||||
using System.Text;
|
||||
using Milimoe.FunGame.Core.Api.Utility;
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Milimoe.FunGame.Core.Model;
|
||||
using MilimoeFunGame.Testing.Characters;
|
||||
|
||||
namespace Milimoe.FunGame.Testing.Solutions
|
||||
{
|
||||
public class Novels
|
||||
{
|
||||
public static Dictionary<Character, int> Likability { get; } = [];
|
||||
public static Dictionary<string, Func<bool>> Conditions { get; } = [];
|
||||
|
||||
public static bool 攻击力大于20(Character character)
|
||||
{
|
||||
return character.ATK > 20;
|
||||
}
|
||||
|
||||
public static bool 好感度低于50(Character character)
|
||||
{
|
||||
return Likability[character] > 50;
|
||||
}
|
||||
|
||||
public Novels()
|
||||
{
|
||||
Character main = OshimaCharacters.Oshima;
|
||||
Character character = OshimaCharacters.马猴烧酒;
|
||||
Likability.Add(character, 100);
|
||||
|
||||
Conditions.Add("马猴烧酒的好感度低于50", () => 好感度低于50(character));
|
||||
Conditions.Add("主角攻击力大于20", () => 攻击力大于20(main));
|
||||
Conditions.Add("马猴烧酒攻击力大于20", () => 攻击力大于20(character));
|
||||
NovelNode node1 = new()
|
||||
{
|
||||
Key = "node1",
|
||||
Name = "声音",
|
||||
Content = "听说你在等我?我来了!"
|
||||
};
|
||||
NovelNode node2 = new()
|
||||
{
|
||||
Key = "node2",
|
||||
Name = main.NickName,
|
||||
Content = "什么人!"
|
||||
};
|
||||
node1.NextNodes.Add(node2);
|
||||
node2.Previous = node1;
|
||||
NovelOption option1 = new()
|
||||
{
|
||||
Key = "option1",
|
||||
Name = "你好。"
|
||||
};
|
||||
NovelOption option2 = new()
|
||||
{
|
||||
Key = "option2",
|
||||
Name = "我不认识你。",
|
||||
AndPredicates = new()
|
||||
{
|
||||
{ "主角攻击力大于20", Conditions["主角攻击力大于20"] }
|
||||
}
|
||||
};
|
||||
NovelNode node3 = new()
|
||||
{
|
||||
Key = "node3",
|
||||
Name = character.NickName,
|
||||
Content = "你好,我叫【马猴烧酒】!",
|
||||
Options = [option1, option2]
|
||||
};
|
||||
NovelNode node4 = new()
|
||||
{
|
||||
Key = "node4",
|
||||
Name = character.NickName,
|
||||
Content = "你的名字是?"
|
||||
};
|
||||
NovelNode node5 = new()
|
||||
{
|
||||
Key = "node5",
|
||||
Name = character.NickName,
|
||||
Content = "滚,谁要认识你?"
|
||||
};
|
||||
node2.NextNodes.Add(node3);
|
||||
option1.Targets.Add(node4);
|
||||
option2.Targets.Add(node5);
|
||||
NovelNode node6 = new()
|
||||
{
|
||||
Key = "node6",
|
||||
Content = "旁白:示例结束。"
|
||||
};
|
||||
NovelNode node7 = new()
|
||||
{
|
||||
Key = "node7",
|
||||
Priority = 2,
|
||||
Content = "旁白:示例结束,你被马猴烧酒吃掉了。",
|
||||
AndPredicates = new()
|
||||
{
|
||||
{ "主角攻击力大于20", Conditions["主角攻击力大于20"] }
|
||||
},
|
||||
OrPredicates = new()
|
||||
{
|
||||
{ "马猴烧酒的好感度低于50", Conditions["马猴烧酒的好感度低于50"] },
|
||||
{ "马猴烧酒攻击力大于20", Conditions["马猴烧酒攻击力大于20"] }
|
||||
}
|
||||
};
|
||||
node4.NextNodes.Add(node6);
|
||||
node5.NextNodes.Add(node6);
|
||||
node5.NextNodes.Add(node7);
|
||||
|
||||
NovelConfig config = new("novel1", "chapter1")
|
||||
{
|
||||
{ node1.Key, node1 },
|
||||
{ node2.Key, node2 },
|
||||
{ node3.Key, node3 },
|
||||
{ node4.Key, node4 },
|
||||
{ node5.Key, node5 },
|
||||
{ node6.Key, node6 },
|
||||
{ node7.Key, node7 }
|
||||
};
|
||||
config.SaveConfig();
|
||||
|
||||
NovelConfig config2 = new("novel1", "chapter1");
|
||||
config2.LoadConfig(Conditions);
|
||||
|
||||
foreach (NovelNode node in config2.Values)
|
||||
{
|
||||
StringBuilder builder = new();
|
||||
builder.AppendLine("== 节点:" + node.Key + " ==");
|
||||
|
||||
if (node.AndPredicates.Union(node.OrPredicates).Any())
|
||||
{
|
||||
builder.AppendLine("对话触发条件(需满足以下所有条件):");
|
||||
int count = 0;
|
||||
if (node.AndPredicates.Count > 0)
|
||||
{
|
||||
count++;
|
||||
builder.AppendLine(count + ". " + "满足以下所有子条件:");
|
||||
int subCount = 0;
|
||||
foreach (string ap in node.AndPredicates.Keys)
|
||||
{
|
||||
subCount++;
|
||||
builder.AppendLine("(" + subCount + ") " + ap);
|
||||
}
|
||||
}
|
||||
if (node.OrPredicates.Count > 0)
|
||||
{
|
||||
count++;
|
||||
builder.AppendLine(count + ". " + "满足以下任意一个子条件:");
|
||||
int subCount = 0;
|
||||
foreach (string op in node.OrPredicates.Keys)
|
||||
{
|
||||
subCount++;
|
||||
builder.AppendLine("(" + subCount + ") " + op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node.Name != "")
|
||||
{
|
||||
builder.Append(node.Name + "说:");
|
||||
}
|
||||
builder.AppendLine(node.Content);
|
||||
|
||||
if (node.Options.Count > 0)
|
||||
{
|
||||
builder.AppendLine("选项:");
|
||||
int count = 0;
|
||||
foreach (NovelOption option in node.Options)
|
||||
{
|
||||
count++;
|
||||
builder.AppendLine(count + ". " + option.Name + "【可跳转:" + string.Join(",", option.Targets.Select(t => t.Key)) + "】");
|
||||
if (option.AndPredicates.Union(option.OrPredicates).Any())
|
||||
{
|
||||
builder.AppendLine("选项显示条件(需满足以下所有条件):");
|
||||
int optionCount = 0;
|
||||
if (option.AndPredicates.Count > 0)
|
||||
{
|
||||
optionCount++;
|
||||
builder.AppendLine(optionCount + ". " + "满足以下所有子条件:");
|
||||
int subCount = 0;
|
||||
foreach (string ap in option.AndPredicates.Keys)
|
||||
{
|
||||
subCount++;
|
||||
builder.AppendLine("(" + subCount + ") " + ap);
|
||||
}
|
||||
}
|
||||
if (option.OrPredicates.Count > 0)
|
||||
{
|
||||
optionCount++;
|
||||
builder.AppendLine(optionCount + ". " + "满足以下任意一个子条件:");
|
||||
int subCount = 0;
|
||||
foreach (string op in option.OrPredicates.Keys)
|
||||
{
|
||||
subCount++;
|
||||
builder.AppendLine("(" + subCount + ") " + op);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node.NextNodes.Count > 0)
|
||||
{
|
||||
builder.AppendLine("下一句对话:");
|
||||
int count = 0;
|
||||
foreach (NovelNode next in node.NextNodes)
|
||||
{
|
||||
count++;
|
||||
builder.AppendLine(count + ". " + next.Key);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine(builder.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user