└── addons
└── eazy_dialog
├── main.gd.uid
├── plugin.gd.uid
├── main_view.gd.uid
├── components
├── item.gd.uid
├── Compiler.cs.uid
├── Resolver.cs.uid
├── muti_node.gd.uid
├── EazyDialogRuntime.cs.uid
├── editor
│ ├── dialog_edit.gd.uid
│ ├── dialog_edit.gd
│ └── dialog_edit.tscn
├── compiler.tscn
├── item.gd
├── muti_node.gd
├── dialog_context.tscn
├── end_node.tscn
├── start_node.tscn
├── item_dialog.tscn
├── dialog_node.tscn
├── muti_node.tscn
├── EazyDialogRuntime.cs
├── Resolver.cs
└── Compiler.cs
├── eazy_dialog_runtime.gd.uid
├── plugin.cfg
├── node_style.tres
├── icon
├── file.svg
├── add_character.svg
├── add.svg
├── save.svg
├── delete.svg
├── dialog_text.svg
└── dialog.svg
├── plugin.gd
├── eazy_dialog_runtime.gd
├── main.gd
├── main_view.gd
├── eazy_dialog.tscn16798228990.tmp
└── main.tscn
/addons/eazy_dialog/main.gd.uid:
--------------------------------------------------------------------------------
1 | uid://ctgr1vtlph2kk
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/plugin.gd.uid:
--------------------------------------------------------------------------------
1 | uid://2w0rnn1rd4rf
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/main_view.gd.uid:
--------------------------------------------------------------------------------
1 | uid://bgaq00g2th64d
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/item.gd.uid:
--------------------------------------------------------------------------------
1 | uid://bj6jmv62yd5kf
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/Compiler.cs.uid:
--------------------------------------------------------------------------------
1 | uid://dmssf6jsnbt3y
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/Resolver.cs.uid:
--------------------------------------------------------------------------------
1 | uid://b7ksxlca2qwp6
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/muti_node.gd.uid:
--------------------------------------------------------------------------------
1 | uid://cs5vg5fxtrcjb
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/eazy_dialog_runtime.gd.uid:
--------------------------------------------------------------------------------
1 | uid://cwdxb0mrcwsqf
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/EazyDialogRuntime.cs.uid:
--------------------------------------------------------------------------------
1 | uid://b38gib0imotd6
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/editor/dialog_edit.gd.uid:
--------------------------------------------------------------------------------
1 | uid://b5slpjeiuqkgl
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/compiler.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene format=3 uid="uid://dl2h84k6j5rrm"]
2 |
3 | [node name="Compiler" type="Node"]
4 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/plugin.cfg:
--------------------------------------------------------------------------------
1 | [plugin]
2 |
3 | name="Eazy Dialog"
4 | description="Eazy Dialog"
5 | author="Ivan"
6 | version="0.2.5"
7 | script="plugin.gd"
8 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/item.gd:
--------------------------------------------------------------------------------
1 |
2 | @tool
3 | extends HBoxContainer
4 |
5 |
6 |
7 | func _on_button_pressed() -> void:
8 | get_parent().remove_child(self)
9 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/node_style.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Theme" load_steps=2 format=3 uid="uid://dialggjrx4vmt"]
2 |
3 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hvsfu"]
4 | content_margin_left = 8.0
5 | bg_color = Color(0.0509804, 0.431373, 0.992157, 1)
6 | corner_radius_top_left = 8
7 | corner_radius_top_right = 8
8 |
9 | [resource]
10 | GraphNode/styles/titlebar = SubResource("StyleBoxFlat_hvsfu")
11 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/muti_node.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends GraphNode
3 | const ITEM_DIALOG = preload("res://addons/eazy_dialog/components/item_dialog.tscn")
4 | @onready var item_container: VBoxContainer = $VBoxContainer/ItemContainer
5 | var index = 0
6 | func _on_add_item_button_pressed() -> void:
7 | var item = ITEM_DIALOG.instantiate()
8 | item.name = "item_"+str(index)
9 | item_container.add_child(item)
10 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/editor/dialog_edit.gd:
--------------------------------------------------------------------------------
1 | @tool
2 |
3 | extends GraphEdit
4 |
5 | func _on_connection_request(from_node: StringName, from_port: int, to_node: StringName, to_port: int) -> void:
6 | connect_node(from_node,from_port,to_node,to_port)
7 |
8 |
9 | func _on_delete_nodes_request(nodes: Array[StringName]) -> void:
10 | for node_name in nodes:
11 | var node = get_node_or_null(node_name.simplify_path())
12 | if node:
13 | remove_child(node)
14 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/icon/file.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/dialog_context.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene format=3 uid="uid://dndw6nbqmg1ms"]
2 |
3 | [node name="PanelContainer" type="PanelContainer"]
4 | offset_top = 203.0
5 | offset_right = 276.0
6 | offset_bottom = 391.0
7 | size_flags_horizontal = 3
8 | size_flags_vertical = 3
9 |
10 | [node name="VBoxContainer" type="VBoxContainer" parent="."]
11 | layout_mode = 2
12 |
13 | [node name="Label" type="Label" parent="VBoxContainer"]
14 | layout_mode = 2
15 | text = "Content"
16 |
17 | [node name="TextEdit" type="TextEdit" parent="VBoxContainer"]
18 | layout_mode = 2
19 | size_flags_vertical = 3
20 | placeholder_text = "O Captain! My Captain!
21 |
22 | "
23 | wrap_mode = 1
24 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/end_node.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://b4p5xpw070bdj"]
2 |
3 | [ext_resource type="Theme" uid="uid://dialggjrx4vmt" path="res://addons/eazy_dialog/node_style.tres" id="1_lncs0"]
4 |
5 | [node name="END" type="GraphNode"]
6 | theme = ExtResource("1_lncs0")
7 | resizable = true
8 | title = "END"
9 | slot/0/left_enabled = true
10 | slot/0/left_type = 0
11 | slot/0/left_color = Color(0.556863, 0.937255, 0.592157, 1)
12 | slot/0/left_icon = null
13 | slot/0/right_enabled = false
14 | slot/0/right_type = 0
15 | slot/0/right_color = Color(1, 1, 1, 1)
16 | slot/0/right_icon = null
17 | slot/0/draw_stylebox = true
18 |
19 | [node name="Label" type="Label" parent="."]
20 | layout_mode = 2
21 | text = "END"
22 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/editor/dialog_edit.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://dgsi83vnjytcd"]
2 |
3 | [ext_resource type="Script" uid="uid://b5slpjeiuqkgl" path="res://addons/eazy_dialog/components/editor/dialog_edit.gd" id="1_qqjym"]
4 |
5 | [node name="DialogEdit" type="GraphEdit"]
6 | size_flags_horizontal = 3
7 | size_flags_vertical = 3
8 | size_flags_stretch_ratio = 5.0
9 | theme_override_colors/selection_stroke = Color(0.556863, 0.937255, 0.592157, 1)
10 | grid_pattern = 1
11 | right_disconnects = true
12 | show_zoom_label = true
13 | script = ExtResource("1_qqjym")
14 |
15 | [connection signal="connection_request" from="." to="." method="_on_connection_request"]
16 | [connection signal="delete_nodes_request" from="." to="." method="_on_delete_nodes_request"]
17 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/start_node.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://b8fu3clan4c14"]
2 |
3 | [ext_resource type="Theme" uid="uid://dialggjrx4vmt" path="res://addons/eazy_dialog/node_style.tres" id="1_phmxm"]
4 |
5 | [node name="START" type="GraphNode"]
6 | offset_right = 234.0
7 | offset_bottom = 86.0
8 | theme = ExtResource("1_phmxm")
9 | resizable = true
10 | title = "START"
11 | slot/0/left_enabled = false
12 | slot/0/left_type = 0
13 | slot/0/left_color = Color(1, 1, 1, 1)
14 | slot/0/left_icon = null
15 | slot/0/right_enabled = true
16 | slot/0/right_type = 0
17 | slot/0/right_color = Color(0.556863, 0.937255, 0.592157, 1)
18 | slot/0/right_icon = null
19 | slot/0/draw_stylebox = true
20 |
21 | [node name="HBoxContainer" type="HBoxContainer" parent="."]
22 | layout_mode = 2
23 | size_flags_vertical = 3
24 |
25 | [node name="Label" type="Label" parent="HBoxContainer"]
26 | layout_mode = 2
27 | size_flags_horizontal = 6
28 | text = "Dialog Name"
29 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/item_dialog.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=3 uid="uid://c6mgh5y4vkyp8"]
2 |
3 | [ext_resource type="Script" uid="uid://bj6jmv62yd5kf" path="res://addons/eazy_dialog/components/item.gd" id="1_co6sr"]
4 | [ext_resource type="Texture2D" uid="uid://oreb7ri1w86p" path="res://addons/eazy_dialog/icon/delete.svg" id="1_yrnnd"]
5 |
6 | [node name="ItemDialog" type="HBoxContainer"]
7 | custom_minimum_size = Vector2(100, 30)
8 | offset_right = 298.0
9 | offset_bottom = 41.0
10 | size_flags_horizontal = 3
11 | size_flags_vertical = 3
12 | script = ExtResource("1_co6sr")
13 |
14 | [node name="TextEdit" type="TextEdit" parent="."]
15 | layout_mode = 2
16 | size_flags_horizontal = 3
17 | wrap_mode = 1
18 |
19 | [node name="Button" type="Button" parent="."]
20 | layout_mode = 2
21 | size_flags_horizontal = 4
22 | size_flags_vertical = 4
23 | icon = ExtResource("1_yrnnd")
24 | flat = true
25 |
26 | [connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
27 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/icon/add_character.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/icon/add.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/icon/save.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/plugin.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends EditorPlugin
3 |
4 |
5 | const MainPanel =preload("res://addons/eazy_dialog/main.tscn")
6 | var main_panel_instance
7 | var inspector_plugin
8 |
9 |
10 |
11 |
12 | func _enter_tree():
13 | main_panel_instance = MainPanel.instantiate()
14 | # Add the main panel to the editor's main viewport.
15 | EditorInterface.get_editor_main_screen().add_child(main_panel_instance)
16 | # Hide the main panel. Very much required.
17 | _make_visible(false)
18 | var dir = DirAccess.open("res://")
19 | if not dir.dir_exists("res://eazy_dialog_data"):
20 | dir.make_dir("res://eazy_dialog_data")
21 | save_text_to_cfg()
22 |
23 |
24 |
25 |
26 | func _exit_tree():
27 | if main_panel_instance:
28 | main_panel_instance.queue_free()
29 |
30 |
31 |
32 |
33 | func _has_main_screen():
34 | return true
35 |
36 |
37 | func _make_visible(visible):
38 | if main_panel_instance:
39 | main_panel_instance.visible = visible
40 |
41 |
42 | func _get_plugin_name():
43 | return "Eazy Dialog"
44 |
45 |
46 | func _get_plugin_icon():
47 | # Must return some kind of Texture for the icon.
48 | return EditorInterface.get_editor_theme().get_icon("Node", "EditorIcons")
49 |
50 |
51 | # 保存文本到 .cfg 文件
52 | func save_text_to_cfg():
53 | # 创建新的 ConfigFile 对象。
54 | var config = ConfigFile.new()
55 | if config.load("res://eazy_dialog_data/data.cfg") != OK:
56 | config.set_value("EazyDialog", "Character", "")
57 | config.save("res://eazy_dialog_data/data.cfg")
58 | _refresh_filesystem()
59 |
60 | func _refresh_filesystem():
61 | var a = EditorInterface.get_resource_filesystem()
62 | a.scan()
63 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/eazy_dialog_runtime.gd:
--------------------------------------------------------------------------------
1 | class_name EazyDialogRuntime extends Node
2 |
3 | const runtime_cs = preload("res://addons/eazy_dialog/components/EazyDialogRuntime.cs")
4 | var runtime
5 | var _name:Label
6 | var _content:Label
7 | var _item_list: ItemList
8 | var _dialog_file:String
9 |
10 | signal dialog_start()
11 | signal dialog_play(character:String,content:String)
12 | signal dialog_selection_show(answers:Array)
13 | signal dialog_end()
14 |
15 |
16 | func _init(dialog_file:String,nameLabel:Label,contentLabel:Label,item_list: ItemList) -> void:
17 | _name = nameLabel
18 | _content = contentLabel
19 | _item_list = item_list
20 | _dialog_file = dialog_file
21 |
22 | runtime = runtime_cs.new()
23 | runtime.DialogueSignal.connect(_dialogue_signal)
24 | runtime.DialogueSelectionSignal.connect(_dialogue_selection_signal)
25 | runtime.DialogueEndSignal.connect(_dialogue_end_signal)
26 | if(!item_list.item_selected.has_connections()):
27 | item_list.item_selected.connect(_on_item_list_item_selected)
28 | runtime.PlayNext(_dialog_file,-1)
29 | call_deferred("emit_signal", "dialog_start")
30 |
31 |
32 | func play()->void:
33 | runtime.PlayNext(_dialog_file,-1)
34 |
35 | func _dialogue_signal(character:String,content:String)->void:
36 | _name.text = character
37 | _content.text = content
38 | dialog_play.emit(character,content)
39 |
40 | func _dialogue_selection_signal(answers:Array)->void:
41 | _item_list.clear()
42 | _item_list.visible = true
43 | for answer in answers:
44 | _item_list.add_item(answer)
45 | dialog_selection_show.emit(answers)
46 |
47 |
48 | func _dialogue_end_signal()->void:
49 | _item_list.clear()
50 | dialog_end.emit()
51 | self.queue_free()
52 |
53 | func _on_item_list_item_selected(index:int)->void:
54 |
55 | runtime.PlayNext(_dialog_file,index)
56 |
57 | _item_list.visible = false
58 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/icon/delete.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/dialog_node.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=3 uid="uid://rn53cgkwpy6"]
2 |
3 | [ext_resource type="PackedScene" uid="uid://dndw6nbqmg1ms" path="res://addons/eazy_dialog/components/dialog_context.tscn" id="2_7gcu4"]
4 | [ext_resource type="Texture2D" uid="uid://brfe7v7ea0h8k" path="res://addons/eazy_dialog/icon/add.svg" id="3_2e87v"]
5 |
6 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5qmam"]
7 | content_margin_left = 8.0
8 | bg_color = Color(0.0980392, 0.529412, 0.329412, 1)
9 | corner_radius_top_left = 8
10 | corner_radius_top_right = 8
11 |
12 | [node name="DialogNode" type="GraphNode"]
13 | offset_right = 294.0
14 | offset_bottom = 233.0
15 | size_flags_horizontal = 3
16 | size_flags_vertical = 3
17 | theme_override_styles/titlebar = SubResource("StyleBoxFlat_5qmam")
18 | resizable = true
19 | title = "Dialog"
20 | slot/0/left_enabled = true
21 | slot/0/left_type = 0
22 | slot/0/left_color = Color(0.556863, 0.937255, 0.592157, 1)
23 | slot/0/left_icon = null
24 | slot/0/right_enabled = true
25 | slot/0/right_type = 0
26 | slot/0/right_color = Color(0.556863, 0.937255, 0.592157, 1)
27 | slot/0/right_icon = null
28 | slot/0/draw_stylebox = true
29 |
30 | [node name="HFlowContainer" type="VBoxContainer" parent="."]
31 | layout_mode = 2
32 | size_flags_vertical = 3
33 |
34 | [node name="HBoxContainer" type="HBoxContainer" parent="HFlowContainer"]
35 | layout_mode = 2
36 |
37 | [node name="Label" type="Label" parent="HFlowContainer/HBoxContainer"]
38 | layout_mode = 2
39 | text = "Character"
40 |
41 | [node name="OptionButton" type="OptionButton" parent="HFlowContainer/HBoxContainer"]
42 | layout_mode = 2
43 | size_flags_horizontal = 3
44 |
45 | [node name="VBoxContainer" type="VBoxContainer" parent="HFlowContainer"]
46 | layout_mode = 2
47 | size_flags_vertical = 3
48 |
49 | [node name="DialogContext" parent="HFlowContainer/VBoxContainer" instance=ExtResource("2_7gcu4")]
50 | clip_contents = true
51 | layout_mode = 2
52 |
53 | [node name="Button" type="Button" parent="HFlowContainer/VBoxContainer"]
54 | visible = false
55 | layout_mode = 2
56 | size_flags_horizontal = 4
57 | icon = ExtResource("3_2e87v")
58 | flat = true
59 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/muti_node.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=3 uid="uid://be0tywtto5t4f"]
2 |
3 | [ext_resource type="Script" uid="uid://cs5vg5fxtrcjb" path="res://addons/eazy_dialog/components/muti_node.gd" id="1_1chja"]
4 | [ext_resource type="Texture2D" uid="uid://brfe7v7ea0h8k" path="res://addons/eazy_dialog/icon/add.svg" id="2_m56ld"]
5 |
6 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1chja"]
7 | content_margin_left = 8.0
8 | bg_color = Color(0.454902, 0.188235, 0.976471, 1)
9 | corner_radius_top_left = 8
10 | corner_radius_top_right = 8
11 |
12 | [node name="MutiNode" type="GraphNode"]
13 | offset_right = 228.0
14 | offset_bottom = 108.0
15 | size_flags_horizontal = 3
16 | size_flags_vertical = 3
17 | theme_override_styles/titlebar = SubResource("StyleBoxFlat_1chja")
18 | resizable = true
19 | title = "Selection"
20 | slot/0/left_enabled = true
21 | slot/0/left_type = 0
22 | slot/0/left_color = Color(1, 1, 1, 1)
23 | slot/0/left_icon = null
24 | slot/0/right_enabled = true
25 | slot/0/right_type = 0
26 | slot/0/right_color = Color(1, 1, 1, 1)
27 | slot/0/right_icon = null
28 | slot/0/draw_stylebox = true
29 | script = ExtResource("1_1chja")
30 |
31 | [node name="VBoxContainer" type="VBoxContainer" parent="."]
32 | layout_mode = 2
33 | size_flags_vertical = 3
34 |
35 | [node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
36 | layout_mode = 2
37 |
38 | [node name="Label" type="Label" parent="VBoxContainer/HBoxContainer"]
39 | layout_mode = 2
40 | text = "Character"
41 |
42 | [node name="OptionButton" type="OptionButton" parent="VBoxContainer/HBoxContainer"]
43 | layout_mode = 2
44 | size_flags_horizontal = 3
45 |
46 | [node name="Label" type="Label" parent="VBoxContainer"]
47 | layout_mode = 2
48 | text = "Selection"
49 |
50 | [node name="ItemContainer" type="VBoxContainer" parent="VBoxContainer"]
51 | unique_name_in_owner = true
52 | layout_mode = 2
53 | size_flags_horizontal = 3
54 | size_flags_vertical = 3
55 |
56 | [node name="AddItemButton" type="Button" parent="VBoxContainer"]
57 | layout_mode = 2
58 | size_flags_horizontal = 4
59 | icon = ExtResource("2_m56ld")
60 | flat = true
61 |
62 | [connection signal="pressed" from="VBoxContainer/AddItemButton" to="." method="_on_add_item_button_pressed"]
63 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/EazyDialogRuntime.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using System.IO;
4 | using System.Collections.Generic;
5 | using EazyDialog.Resolver;
6 |
7 | namespace EazyDialog{
8 |
9 | public class Dialogue
10 | {
11 | public string Character { get; set; }
12 | public string Content { get; set; }
13 | public List Selections { get; set; } = new List();
14 | public List Left { get; set; } = new List();
15 | public List Right { get; set; } = new List();
16 | }
17 |
18 | namespace Runtime{
19 |
20 |
21 | public partial class EazyDialogRuntime : Node
22 | {
23 |
24 | [Signal]
25 | public delegate void DialogueSignalEventHandler(string character,string content);
26 | [Signal]
27 | public delegate void DialogueSelectionSignalEventHandler(Godot.Collections.Array answers);
28 |
29 | [Signal]
30 | public delegate void DialogueEndSignalEventHandler();
31 |
32 | private static Random _random = new Random();
33 | private string dialogName;
34 | private Dictionary dialogs = null;
35 |
36 | private EazyDialogResolver resolver = new EazyDialogResolver();
37 |
38 | public void PlayNext(string dialogFile,int index ){
39 | if(dialogs == null){
40 | dialogs = resolver.ParseFile(dialogFile);
41 | var startRight = dialogs["START"].Right;
42 | dialogName = startRight[0];
43 | }
44 |
45 | if(dialogName =="END"){
46 | dialogs = null;
47 | dialogName = null;
48 | EmitSignal(SignalName.DialogueEndSignal);
49 | return;
50 |
51 | }
52 |
53 | if(index != -1){
54 | GD.Print(index);
55 | dialogName = dialogs[dialogName].Right[index];
56 | }
57 |
58 | if(dialogs[dialogName].Right.Count>0){
59 |
60 |
61 | if(dialogs[dialogName].Right[0].StartsWith("Mutiple")){
62 |
63 | Godot.Collections.Array mAnswers = new Godot.Collections.Array();
64 |
65 | if(dialogs[dialogs[dialogName].Right[0]].Selections.Count >0){
66 | foreach (string selection in dialogs[dialogs[dialogName].Right[0]].Selections){
67 | mAnswers.Add(selection);
68 | }
69 | EmitSignal(SignalName.DialogueSelectionSignal, mAnswers);}
70 |
71 | }}
72 |
73 |
74 | if(dialogName.StartsWith("Dialog")){
75 | string characterName = dialogs[dialogName].Character;
76 | string nextContent = dialogs[dialogName].Content;
77 | dialogName = dialogs[dialogName].Right[0];
78 | EmitSignal(SignalName.DialogueSignal, characterName,nextContent);
79 |
80 | }
81 |
82 |
83 |
84 |
85 |
86 | }
87 |
88 |
89 |
90 | }
91 |
92 |
93 | }
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | }
102 |
103 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/Resolver.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using EazyDialog;
4 | using System.IO;
5 | using System.Collections.Generic;
6 |
7 | namespace EazyDialog.Resolver{
8 | public partial class EazyDialogResolver : Node
9 | {
10 | public Dictionary ParseFile(string dialogFile){
11 | string mainCharacter = GetNthLastDirectory(dialogFile, 2);
12 | string secondaryCharacter = GetNthLastDirectory(dialogFile, 1);
13 | string context = LoadFile(dialogFile);
14 | var dialogues = new Dictionary();
15 | var lines = context.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
16 |
17 | Dialogue currentDialogue = null;
18 | string currentKey = null;
19 | string currentSection = null;
20 | foreach (var line in lines)
21 | {
22 | string trimmed = line.Trim();
23 |
24 | if (trimmed.StartsWith("[") && trimmed.EndsWith("]"))
25 | {
26 | currentKey = trimmed.Trim('[', ']');
27 | currentDialogue = new Dialogue { };
28 | dialogues[currentKey] = currentDialogue;
29 | }
30 | else if (trimmed.Equals("Character"))
31 | {
32 | currentSection = "Character";
33 | }
34 | else if (trimmed.Equals("Context"))
35 | {
36 | currentSection = "Context";
37 | }
38 | else if (trimmed.Equals("LEFT"))
39 | {
40 | currentSection = "LEFT";
41 | }
42 | else if (trimmed.Equals("RIGHT"))
43 | {
44 | currentSection = "RIGHT";
45 | }
46 | else if (trimmed.Equals("Selections"))
47 | {
48 | currentSection = "Selections";
49 | }
50 | else if (trimmed.StartsWith("- "))
51 | {
52 | string content = trimmed.Substring(2).Trim();
53 | if (currentDialogue != null && currentSection != null)
54 | {
55 | if(currentSection == "Character"){
56 | currentDialogue.Character = content;
57 |
58 | }
59 | else if (currentSection == "Context")
60 | {
61 | currentDialogue.Content += (string.IsNullOrEmpty(currentDialogue.Content) ? "" : "\n") + content;
62 | }
63 | else if (currentSection == "LEFT")
64 | {
65 | currentDialogue.Left.Add(content);
66 | }
67 | else if (currentSection == "RIGHT")
68 | {
69 | currentDialogue.Right.Add(content);
70 | }
71 | else if (currentSection == "Selections")
72 | {
73 | currentDialogue.Selections.Add(content);
74 | }
75 | }
76 | }
77 | else{
78 | if (currentSection == "Context")
79 | {
80 | currentDialogue.Content += (string.IsNullOrEmpty(currentDialogue.Content) ? "" : "\n") + trimmed;
81 | }
82 | }
83 | }
84 |
85 | return dialogues;
86 |
87 | }
88 |
89 | public List GetCharacters(string dialogFile){
90 | List characters = new();
91 | DirectoryInfo dirInfo = new DirectoryInfo(dialogFile);
92 | string primary = dirInfo.Parent?.Name ?? "无";
93 | string secondary = dirInfo.Parent.Parent.Name;
94 | characters.Add(primary);
95 | characters.Add(secondary);
96 |
97 | return characters;
98 | }
99 |
100 | private string GetNthLastDirectory(string filePath, int n)
101 | {
102 | string directoryPath = Path.GetDirectoryName(filePath); // 获取文件所在的目录
103 | if (directoryPath == null) return "无效路径";
104 |
105 | string[] folders = directoryPath.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
106 | if (folders.Length < n) return "文件夹数量不足";
107 |
108 | return folders[folders.Length - n]; // 取倒数第 n 个文件夹
109 | }
110 |
111 |
112 | private string LoadFile(string filePath)
113 | {
114 | using var file = Godot.FileAccess.Open(filePath, Godot.FileAccess.ModeFlags.Read);
115 | string content = file.GetAsText();
116 | return content;
117 | }
118 |
119 |
120 |
121 |
122 | }
123 | }
--------------------------------------------------------------------------------
/addons/eazy_dialog/icon/dialog_text.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/main.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Node
3 | @onready var new_button: Button = %newButton
4 | @onready var text_edit: TextEdit = $NewCharacterDialog/TextEdit
5 | @onready var new_character_dialog: ConfirmationDialog = $NewCharacterDialog
6 | @onready var content: HSplitContainer = $MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content
7 | @onready var main_character_button: OptionButton = $NewSessionDialog/VBoxContainer/HBoxContainer/MainCharacterButton
8 | @onready var secondary_character_button: OptionButton = $NewSessionDialog/VBoxContainer/HBoxContainer2/SecondaryCharacterButton
9 | @onready var new_session_dialog: ConfirmationDialog = $NewSessionDialog
10 | @onready var dialog_name_edit: LineEdit = $NewSessionDialog/VBoxContainer/HBoxContainer3/DialogNameEdit
11 | @onready var file_dialog: FileDialog = $FileDialog
12 |
13 | const DIALOG_EDIT = preload("res://addons/eazy_dialog/components/editor/dialog_edit.tscn")
14 | var start_node = preload("res://addons/eazy_dialog/components/start_node.tscn")
15 | var dialog_node = preload("res://addons/eazy_dialog/components/dialog_node.tscn")
16 | var muti_node = preload("res://addons/eazy_dialog/components/muti_node.tscn")
17 | var end_node = preload("res://addons/eazy_dialog/components/end_node.tscn")
18 | const MUTI_NODE = preload("res://addons/eazy_dialog/components/muti_node.tscn")
19 | var index_Dialog = 0
20 | var index_Mutiple = 0
21 | var csharp_compiler = preload("res://addons/eazy_dialog/components/Compiler.cs")
22 | var main_character = ""
23 | var secondary_character = ""
24 | var dialog_name = ""
25 | var dialog_edit: GraphEdit
26 |
27 | func _ready() -> void:
28 | dialog_edit = DIALOG_EDIT.instantiate()
29 |
30 | func _on_new_character_button_pressed() -> void:
31 | new_character_dialog.popup_centered()
32 |
33 |
34 | func _on_new_button_pressed() -> void:
35 | var content = ""
36 | var config = ConfigFile.new()
37 | if config.load("res://eazy_dialog_data/data.cfg") == OK:
38 | content = config.get_value("EazyDialog", "Character","")
39 | print("Character:"+content)
40 | var parts = content.split("|")
41 | main_character_button.clear()
42 | secondary_character_button.clear()
43 |
44 | for part in parts:
45 | main_character_button.add_item(part)
46 | secondary_character_button.add_item(part)
47 | new_session_dialog.popup_centered()
48 |
49 |
50 |
51 | func _on_add_start_node_pressed() -> void:
52 | var node = start_node.instantiate()
53 | node.position_offset = dialog_edit.get_global_mouse_position()
54 | dialog_edit.add_child(node)
55 |
56 |
57 | func _on_add_dialog_node_pressed() -> void:
58 | var node:GraphNode = dialog_node.instantiate()
59 | node.position_offset = dialog_edit.get_screen_position()
60 | node.name = "Dialog_"+str(index_Dialog)
61 | node.title = "Dialog_"+str(index_Dialog)
62 | var optionButton:OptionButton = node.get_node("HFlowContainer/HBoxContainer/OptionButton")
63 | print("测试"+main_character+secondary_character)
64 | optionButton.add_item(main_character)
65 | optionButton.add_item(secondary_character)
66 | dialog_edit.add_child(node)
67 | index_Dialog+=1
68 |
69 | func _on_add_muti_node_pressed() -> void:
70 | var node:GraphNode = muti_node.instantiate()
71 | node.position_offset = dialog_edit.get_screen_position()
72 | node.name = "Mutiple_"+str(index_Mutiple)
73 | node.title = "Mutiple_"+str(index_Mutiple)
74 | var optionButton:OptionButton = node.get_node("VBoxContainer/HBoxContainer/OptionButton")
75 | optionButton.add_item(main_character)
76 | optionButton.add_item(secondary_character)
77 | dialog_edit.add_child(node)
78 | index_Mutiple+=1
79 |
80 |
81 | func _on_add_end_node_pressed() -> void:
82 | var node:GraphNode = end_node.instantiate()
83 | node.position_offset = dialog_edit.get_screen_position()
84 | dialog_edit.add_child(node)
85 |
86 |
87 | func _on_save_button_pressed() -> void:
88 | var csharp_compiler_node = csharp_compiler.new()
89 | var dir = DirAccess.open("res://")
90 | _create_folder("res://eazy_dialog_data/"+main_character+"/"+secondary_character)
91 | csharp_compiler_node.ExportGraph(dialog_edit,"res://eazy_dialog_data/"+main_character+"/"+secondary_character+"/"+dialog_name+".txt")
92 | _refresh_filesystem()
93 |
94 |
95 |
96 |
97 | func _on_new_character_dialog_confirmed() -> void:
98 | if (text_edit.text!=null):
99 | save_text_to_cfg(text_edit.text)
100 |
101 |
102 |
103 | # 保存文本到 .cfg 文件
104 | func save_text_to_cfg(character_name):
105 | # 创建新的 ConfigFile 对象。
106 | var config = ConfigFile.new()
107 |
108 | var file_path = "res://eazy_dialog_data/data.cfg"
109 | var content = ""
110 | if config.load(file_path) == OK:
111 | content = config.get_value("EazyDialog", "Character","")
112 | if(content == ""):
113 | content += character_name
114 | else :
115 | content = content + "|"+character_name
116 |
117 | config.set_value("EazyDialog", "Character",content)
118 | #DirAccess.remove_absolute(file_path)
119 | config.save(file_path)
120 | _refresh_filesystem()
121 |
122 |
123 | func _create_folder(path: String) -> void:
124 | var dir := DirAccess.open("res://")
125 | var current_path := "res://"
126 | for folder in path.replace("res://", "").split("/"):
127 | current_path += folder + "/"
128 | if not dir.dir_exists(current_path):
129 | dir.make_dir(current_path)
130 | print("Created folder: " + current_path)
131 |
132 | func _refresh_filesystem():
133 | var fs = EditorInterface.get_resource_filesystem()
134 | fs.scan_sources()
135 |
136 |
137 | func _on_main_character_button_item_selected(index: int) -> void:
138 | main_character = main_character_button.get_item_text(index)
139 | print(main_character)
140 |
141 | func _on_secondary_character_button_item_selected(index: int) -> void:
142 | secondary_character = secondary_character_button.get_item_text(index)
143 | print(secondary_character)
144 |
145 |
146 | func _on_new_session_dialog_confirmed() -> void:
147 | dialog_name = dialog_name_edit.text
148 | var node:GraphNode = start_node.instantiate()
149 | var label:Label = node.get_node("HBoxContainer/Label")
150 | if (content.has_node("DialogEdit")):
151 | content.remove_child(dialog_edit)
152 | content.add_child(dialog_edit)
153 | content.move_child(dialog_edit,0)
154 |
155 | node.position_offset = dialog_edit.get_screen_position()
156 | label.text = dialog_name
157 | dialog_edit.add_child(node)
158 | main_character = main_character_button.get_item_text(main_character_button.get_selected_id())
159 | secondary_character = secondary_character_button.get_item_text(secondary_character_button.get_selected_id())
160 | index_Dialog = 0
161 | index_Mutiple = 0
162 | if(!content.visible):
163 | content.visible = true
164 |
165 |
166 | func _on_open_button_pressed() -> void:
167 | file_dialog.popup_centered()
168 |
169 |
170 | func _on_file_dialog_confirmed() -> void:
171 | var csharp_compiler_node = csharp_compiler.new()
172 | #csharp_compiler_node.FileToGraph("res://eazy_dialog_data/Cat/Chicken/A.txt",dialog_edit)
173 | if (content.has_node("DialogEdit")):
174 | content.remove_child(dialog_edit)
175 | content.add_child(dialog_edit)
176 | content.move_child(dialog_edit,0)
177 |
178 | csharp_compiler_node.FileToGraph(file_dialog.current_path,dialog_edit)
179 |
180 |
181 | func _on_dialog_edit_delete_nodes_request(nodes: Array[StringName]) -> void:
182 | pass # Replace with function body.
183 |
184 |
185 | func _on_dialog_edit_disconnection_request(from_node: StringName, from_port: int, to_node: StringName, to_port: int) -> void:
186 | pass # Replace with function body.
187 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/main_view.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Node
3 | @onready var new_button: Button = %newButton
4 | @onready var text_edit: TextEdit = $NewCharacterDialog/TextEdit
5 | @onready var new_character_dialog: ConfirmationDialog = $NewCharacterDialog
6 | @onready var content: HSplitContainer = $MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content
7 | @onready var main_character_button: OptionButton = $NewSessionDialog/VBoxContainer/HBoxContainer/MainCharacterButton
8 | @onready var secondary_character_button: OptionButton = $NewSessionDialog/VBoxContainer/HBoxContainer2/SecondaryCharacterButton
9 | @onready var new_session_dialog: ConfirmationDialog = $NewSessionDialog
10 | @onready var dialog_name_edit: LineEdit = $NewSessionDialog/VBoxContainer/HBoxContainer3/DialogNameEdit
11 | @onready var file_dialog: FileDialog = $FileDialog
12 |
13 | const DIALOG_EDIT = preload("res://addons/eazy_dialog/components/editor/dialog_edit.tscn")
14 | var start_node = preload("res://addons/eazy_dialog/components/start_node.tscn")
15 | var dialog_node = preload("res://addons/eazy_dialog/components/dialog_node.tscn")
16 | var muti_node = preload("res://addons/eazy_dialog/components/muti_node.tscn")
17 | var end_node = preload("res://addons/eazy_dialog/components/end_node.tscn")
18 | const MUTI_NODE = preload("res://addons/eazy_dialog/components/muti_node.tscn")
19 | var index_Dialog = 0
20 | var index_Mutiple = 0
21 | var csharp_compiler = preload("res://addons/eazy_dialog/components/Compiler.cs")
22 | var main_character = ""
23 | var secondary_character = ""
24 | var dialog_name = ""
25 | var dialog_edit: GraphEdit
26 |
27 | func _ready() -> void:
28 | dialog_edit = DIALOG_EDIT.instantiate()
29 |
30 | func _on_new_character_button_pressed() -> void:
31 | new_character_dialog.popup_centered()
32 |
33 |
34 | func _on_new_button_pressed() -> void:
35 | var content = ""
36 | var config = ConfigFile.new()
37 | if config.load("res://eazy_dialog_data/data.cfg") == OK:
38 | content = config.get_value("EazyDialog", "Character","")
39 | print("Character:"+content)
40 | var parts = content.split("|")
41 | main_character_button.clear()
42 | secondary_character_button.clear()
43 |
44 | for part in parts:
45 | main_character_button.add_item(part)
46 | secondary_character_button.add_item(part)
47 | new_session_dialog.popup_centered()
48 |
49 |
50 |
51 | func _on_add_start_node_pressed() -> void:
52 | var node = start_node.instantiate()
53 | node.position_offset = dialog_edit.get_global_mouse_position()
54 | dialog_edit.add_child(node)
55 |
56 |
57 | func _on_add_dialog_node_pressed() -> void:
58 | var node:GraphNode = dialog_node.instantiate()
59 | node.position_offset = dialog_edit.get_screen_position()
60 | node.name = "Dialog_"+str(index_Dialog)
61 | node.title = "Dialog_"+str(index_Dialog)
62 | var optionButton:OptionButton = node.get_node("HFlowContainer/HBoxContainer/OptionButton")
63 | print("测试"+main_character+secondary_character)
64 | optionButton.add_item(main_character)
65 | optionButton.add_item(secondary_character)
66 | dialog_edit.add_child(node)
67 | index_Dialog+=1
68 |
69 | func _on_add_muti_node_pressed() -> void:
70 | var node:GraphNode = muti_node.instantiate()
71 | node.position_offset = dialog_edit.get_screen_position()
72 | node.name = "Mutiple_"+str(index_Mutiple)
73 | node.title = "Mutiple_"+str(index_Mutiple)
74 | var optionButton:OptionButton = node.get_node("VBoxContainer/HBoxContainer/OptionButton")
75 | optionButton.add_item(main_character)
76 | optionButton.add_item(secondary_character)
77 | dialog_edit.add_child(node)
78 | index_Mutiple+=1
79 |
80 |
81 | func _on_add_end_node_pressed() -> void:
82 | var node:GraphNode = end_node.instantiate()
83 | node.position_offset = dialog_edit.get_screen_position()
84 | dialog_edit.add_child(node)
85 |
86 |
87 | func _on_save_button_pressed() -> void:
88 | var csharp_compiler_node = csharp_compiler.new()
89 | var dir = DirAccess.open("res://")
90 | _create_folder("res://eazy_dialog_data/"+main_character+"/"+secondary_character)
91 | csharp_compiler_node.ExportGraph(dialog_edit,"res://eazy_dialog_data/"+main_character+"/"+secondary_character+"/"+dialog_name+".txt")
92 | _refresh_filesystem()
93 |
94 |
95 |
96 |
97 | func _on_new_character_dialog_confirmed() -> void:
98 | if (text_edit.text!=null):
99 | save_text_to_cfg(text_edit.text)
100 |
101 |
102 |
103 | # 保存文本到 .cfg 文件
104 | func save_text_to_cfg(character_name):
105 | # 创建新的 ConfigFile 对象。
106 | var config = ConfigFile.new()
107 |
108 | var file_path = "res://eazy_dialog_data/data.cfg"
109 | var content = ""
110 | if config.load(file_path) == OK:
111 | content = config.get_value("EazyDialog", "Character","")
112 | if(content == ""):
113 | content += character_name
114 | else :
115 | content = content + "|"+character_name
116 |
117 | config.set_value("EazyDialog", "Character",content)
118 | #DirAccess.remove_absolute(file_path)
119 | config.save(file_path)
120 | _refresh_filesystem()
121 |
122 |
123 | func _create_folder(path: String) -> void:
124 | var dir := DirAccess.open("res://")
125 | var current_path := "res://"
126 | for folder in path.replace("res://", "").split("/"):
127 | current_path += folder + "/"
128 | if not dir.dir_exists(current_path):
129 | dir.make_dir(current_path)
130 | print("Created folder: " + current_path)
131 |
132 | func _refresh_filesystem():
133 | var fs = EditorInterface.get_resource_filesystem()
134 | fs.scan_sources()
135 |
136 |
137 | func _on_main_character_button_item_selected(index: int) -> void:
138 | main_character = main_character_button.get_item_text(index)
139 | print(main_character)
140 |
141 | func _on_secondary_character_button_item_selected(index: int) -> void:
142 | secondary_character = secondary_character_button.get_item_text(index)
143 | print(secondary_character)
144 |
145 |
146 | func _on_new_session_dialog_confirmed() -> void:
147 | dialog_name = dialog_name_edit.text
148 | var node:GraphNode = start_node.instantiate()
149 | var label:Label = node.get_node("HBoxContainer/Label")
150 | if (content.has_node("DialogEdit")):
151 | content.remove_child(dialog_edit)
152 | content.add_child(dialog_edit)
153 | content.move_child(dialog_edit,0)
154 |
155 | node.position_offset = dialog_edit.get_screen_position()
156 | label.text = dialog_name
157 | dialog_edit.add_child(node)
158 | main_character = main_character_button.get_item_text(main_character_button.get_selected_id())
159 | secondary_character = secondary_character_button.get_item_text(secondary_character_button.get_selected_id())
160 | index_Dialog = 0
161 | index_Mutiple = 0
162 | main_character = ""
163 | secondary_character = ""
164 | dialog_name = ""
165 | if(!content.visible):
166 | content.visible = true
167 |
168 |
169 | func _on_open_button_pressed() -> void:
170 | file_dialog.popup_centered()
171 |
172 |
173 | func _on_file_dialog_confirmed() -> void:
174 | var csharp_compiler_node = csharp_compiler.new()
175 | #csharp_compiler_node.FileToGraph("res://eazy_dialog_data/Cat/Chicken/A.txt",dialog_edit)
176 | if (content.has_node("DialogEdit")):
177 | content.remove_child(dialog_edit)
178 | content.add_child(dialog_edit)
179 | content.move_child(dialog_edit,0)
180 |
181 | csharp_compiler_node.FileToGraph(file_dialog.current_path,dialog_edit)
182 |
183 |
184 | func _on_dialog_edit_delete_nodes_request(nodes: Array[StringName]) -> void:
185 | pass # Replace with function body.
186 |
187 |
188 | func _on_dialog_edit_disconnection_request(from_node: StringName, from_port: int, to_node: StringName, to_port: int) -> void:
189 | pass # Replace with function body.
190 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/eazy_dialog.tscn16798228990.tmp:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=6 format=3 uid="uid://dqcvihf76dpx1"]
2 |
3 | [ext_resource type="Script" uid="uid://bgaq00g2th64d" path="res://addons/eazy_dialog/main.gd" id="1_8mdd1"]
4 | [ext_resource type="Texture2D" uid="uid://brfe7v7ea0h8k" path="res://addons/eazy_dialog/icon/add.svg" id="1_ls5wj"]
5 | [ext_resource type="Texture2D" uid="uid://bpl30vnsef15x" path="res://addons/eazy_dialog/icon/add_character.svg" id="3_cub2t"]
6 | [ext_resource type="Script" uid="uid://b0xyf2wj8bo7j" path="res://addons/eazy_dialog/dialog_edit.gd" id="4_gv8kj"]
7 | [ext_resource type="Texture2D" uid="uid://dgrroyjmi6eeo" path="res://addons/eazy_dialog/icon/save.svg" id="4_kgaqg"]
8 |
9 | [node name="Eazy Dialog" type="Control"]
10 | layout_mode = 3
11 | anchors_preset = 15
12 | anchor_right = 1.0
13 | anchor_bottom = 1.0
14 | grow_horizontal = 2
15 | grow_vertical = 2
16 | size_flags_horizontal = 3
17 | size_flags_vertical = 3
18 | script = ExtResource("1_8mdd1")
19 |
20 | [node name="NewCharacterDialog" type="ConfirmationDialog" parent="."]
21 | title = "添加角色"
22 | position = Vector2i(476, 274)
23 |
24 | [node name="TextEdit" type="TextEdit" parent="NewCharacterDialog"]
25 | offset_left = 8.0
26 | offset_top = 8.0
27 | offset_right = 192.0
28 | offset_bottom = 51.0
29 |
30 | [node name="MarginContainer" type="MarginContainer" parent="."]
31 | layout_mode = 1
32 | anchors_preset = 15
33 | anchor_right = 1.0
34 | anchor_bottom = 1.0
35 | offset_right = 0.0300293
36 | grow_horizontal = 2
37 | grow_vertical = 2
38 |
39 | [node name="Panel" type="Panel" parent="MarginContainer"]
40 | layout_mode = 2
41 | size_flags_horizontal = 3
42 |
43 | [node name="HSplitContainer" type="HSplitContainer" parent="MarginContainer"]
44 | layout_mode = 2
45 | dragger_visibility = 1
46 |
47 | [node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HSplitContainer"]
48 | custom_minimum_size = Vector2(150, 0)
49 | layout_mode = 2
50 | size_flags_horizontal = 3
51 |
52 | [node name="ToolBar" type="HBoxContainer" parent="MarginContainer/HSplitContainer/VBoxContainer"]
53 | layout_mode = 2
54 |
55 | [node name="newButton" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/ToolBar"]
56 | unique_name_in_owner = true
57 | layout_mode = 2
58 | tooltip_text = "添加对话
59 | "
60 | text = "创建对话"
61 | icon = ExtResource("1_ls5wj")
62 | flat = true
63 |
64 | [node name="newCharacterButton" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/ToolBar"]
65 | unique_name_in_owner = true
66 | layout_mode = 2
67 | tooltip_text = "添加角色
68 | "
69 | text = "创建角色
70 | "
71 | icon = ExtResource("3_cub2t")
72 | flat = true
73 |
74 | [node name="SaveButton" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/ToolBar"]
75 | layout_mode = 2
76 | text = "保存"
77 | icon = ExtResource("4_kgaqg")
78 | flat = true
79 |
80 | [node name="HSeparator" type="HSeparator" parent="MarginContainer/HSplitContainer/VBoxContainer"]
81 | layout_mode = 2
82 |
83 | [node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/HSplitContainer/VBoxContainer"]
84 | visible = false
85 | layout_mode = 2
86 | size_flags_vertical = 3
87 |
88 | [node name="DialogEdit" type="GraphEdit" parent="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer"]
89 | unique_name_in_owner = true
90 | clip_contents = false
91 | layout_mode = 2
92 | size_flags_horizontal = 3
93 | size_flags_vertical = 3
94 | size_flags_stretch_ratio = 5.0
95 | theme_override_colors/selection_stroke = Color(0.556863, 0.937255, 0.592157, 1)
96 | show_zoom_label = true
97 | script = ExtResource("4_gv8kj")
98 |
99 | [node name="VSeparator" type="VSeparator" parent="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer"]
100 | layout_mode = 2
101 |
102 | [node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer"]
103 | layout_mode = 2
104 | size_flags_horizontal = 3
105 |
106 | [node name="Label" type="Label" parent="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
107 | layout_mode = 2
108 | text = "添加结点"
109 |
110 | [node name="AddStartNode" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
111 | layout_mode = 2
112 | text = "开始结点"
113 |
114 | [node name="AddDialogNode" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
115 | layout_mode = 2
116 | text = "对话结点"
117 |
118 | [node name="AddEndNode" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
119 | layout_mode = 2
120 | text = "结束结点"
121 |
122 | [node name="NewSessionDialog" type="ConfirmationDialog" parent="."]
123 | title = "创建对话"
124 | initial_position = 1
125 | size = Vector2i(200, 139)
126 |
127 | [node name="VBoxContainer" type="VBoxContainer" parent="NewSessionDialog"]
128 | offset_left = 8.0
129 | offset_top = 8.0
130 | offset_right = 192.0
131 | offset_bottom = 90.0
132 |
133 | [node name="HBoxContainer" type="HBoxContainer" parent="NewSessionDialog/VBoxContainer"]
134 | layout_mode = 2
135 |
136 | [node name="Label" type="Label" parent="NewSessionDialog/VBoxContainer/HBoxContainer"]
137 | layout_mode = 2
138 | text = "角色1"
139 |
140 | [node name="MainCharacterButton" type="OptionButton" parent="NewSessionDialog/VBoxContainer/HBoxContainer"]
141 | layout_mode = 2
142 | size_flags_horizontal = 3
143 |
144 | [node name="HBoxContainer2" type="HBoxContainer" parent="NewSessionDialog/VBoxContainer"]
145 | layout_mode = 2
146 |
147 | [node name="Label" type="Label" parent="NewSessionDialog/VBoxContainer/HBoxContainer2"]
148 | layout_mode = 2
149 | text = "角色2"
150 |
151 | [node name="SecondaryCharacterButton" type="OptionButton" parent="NewSessionDialog/VBoxContainer/HBoxContainer2"]
152 | layout_mode = 2
153 | size_flags_horizontal = 3
154 |
155 | [node name="HBoxContainer3" type="HBoxContainer" parent="NewSessionDialog/VBoxContainer"]
156 | layout_mode = 2
157 |
158 | [node name="Label" type="Label" parent="NewSessionDialog/VBoxContainer/HBoxContainer3"]
159 | layout_mode = 2
160 | text = "对话名称"
161 |
162 | [node name="DialogNameEdit" type="LineEdit" parent="NewSessionDialog/VBoxContainer/HBoxContainer3"]
163 | layout_mode = 2
164 | size_flags_horizontal = 3
165 |
166 | [connection signal="confirmed" from="NewCharacterDialog" to="." method="_on_new_character_dialog_confirmed"]
167 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/ToolBar/newButton" to="." method="_on_new_button_pressed"]
168 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/ToolBar/newCharacterButton" to="." method="_on_new_character_button_pressed"]
169 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/ToolBar/SaveButton" to="." method="_on_save_button_pressed"]
170 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/AddStartNode" to="." method="_on_add_start_node_pressed"]
171 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/AddDialogNode" to="." method="_on_add_dialog_node_pressed"]
172 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/AddEndNode" to="." method="_on_add_end_node_pressed"]
173 | [connection signal="confirmed" from="NewSessionDialog" to="." method="_on_new_session_dialog_confirmed"]
174 | [connection signal="item_selected" from="NewSessionDialog/VBoxContainer/HBoxContainer/MainCharacterButton" to="." method="_on_main_character_button_item_selected"]
175 | [connection signal="item_selected" from="NewSessionDialog/VBoxContainer/HBoxContainer2/SecondaryCharacterButton" to="." method="_on_secondary_character_button_item_selected"]
176 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/icon/dialog.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=11 format=3 uid="uid://dqcvihf76dpx1"]
2 |
3 | [ext_resource type="Script" uid="uid://bgaq00g2th64d" path="res://addons/eazy_dialog/main_view.gd" id="1_4wxcw"]
4 | [ext_resource type="Texture2D" uid="uid://brfe7v7ea0h8k" path="res://addons/eazy_dialog/icon/add.svg" id="2_bkuf4"]
5 | [ext_resource type="Texture2D" uid="uid://bpl30vnsef15x" path="res://addons/eazy_dialog/icon/add_character.svg" id="3_652i0"]
6 | [ext_resource type="Texture2D" uid="uid://dgrroyjmi6eeo" path="res://addons/eazy_dialog/icon/save.svg" id="4_mm8bl"]
7 | [ext_resource type="Texture2D" uid="uid://bma1mbgscsf2d" path="res://addons/eazy_dialog/icon/file.svg" id="5_bg2r5"]
8 |
9 | [sub_resource type="CompressedTexture2D" id="CompressedTexture2D_fd25j"]
10 |
11 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fd25j"]
12 | bg_color = Color(0.0509804, 0.431373, 0.992157, 1)
13 |
14 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_twdvk"]
15 | bg_color = Color(0.0980392, 0.529412, 0.329412, 1)
16 |
17 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ad5ia"]
18 | bg_color = Color(0.454902, 0.188235, 0.976471, 1)
19 |
20 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_lyc3t"]
21 | bg_color = Color(0.0509804, 0.431373, 0.992157, 1)
22 |
23 | [node name="Eazy Dialog" type="Control"]
24 | layout_mode = 3
25 | anchors_preset = 15
26 | anchor_right = 1.0
27 | anchor_bottom = 1.0
28 | grow_horizontal = 2
29 | grow_vertical = 2
30 | size_flags_horizontal = 3
31 | size_flags_vertical = 3
32 | script = ExtResource("1_4wxcw")
33 |
34 | [node name="NewCharacterDialog" type="ConfirmationDialog" parent="."]
35 | title = "添加角色"
36 | position = Vector2i(476, 274)
37 |
38 | [node name="TextEdit" type="TextEdit" parent="NewCharacterDialog"]
39 | offset_left = 8.0
40 | offset_top = 8.0
41 | offset_right = 192.0
42 | offset_bottom = 51.0
43 |
44 | [node name="MarginContainer" type="MarginContainer" parent="."]
45 | layout_mode = 1
46 | anchors_preset = 15
47 | anchor_right = 1.0
48 | anchor_bottom = 1.0
49 | offset_right = 0.0300293
50 | grow_horizontal = 2
51 | grow_vertical = 2
52 |
53 | [node name="Panel" type="Panel" parent="MarginContainer"]
54 | layout_mode = 2
55 | size_flags_horizontal = 3
56 |
57 | [node name="HSplitContainer" type="HSplitContainer" parent="MarginContainer"]
58 | layout_mode = 2
59 | dragger_visibility = 1
60 |
61 | [node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HSplitContainer"]
62 | custom_minimum_size = Vector2(150, 0)
63 | layout_mode = 2
64 | size_flags_horizontal = 3
65 |
66 | [node name="ToolBar" type="HBoxContainer" parent="MarginContainer/HSplitContainer/VBoxContainer"]
67 | layout_mode = 2
68 |
69 | [node name="newButton" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/ToolBar"]
70 | unique_name_in_owner = true
71 | layout_mode = 2
72 | tooltip_text = "添加对话
73 | "
74 | text = "创建对话"
75 | icon = ExtResource("2_bkuf4")
76 | flat = true
77 |
78 | [node name="newCharacterButton" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/ToolBar"]
79 | unique_name_in_owner = true
80 | layout_mode = 2
81 | tooltip_text = "添加角色
82 | "
83 | text = "创建角色
84 | "
85 | icon = ExtResource("3_652i0")
86 | flat = true
87 |
88 | [node name="VSeparator" type="VSeparator" parent="MarginContainer/HSplitContainer/VBoxContainer/ToolBar"]
89 | layout_mode = 2
90 |
91 | [node name="SaveButton" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/ToolBar"]
92 | layout_mode = 2
93 | text = "保存"
94 | icon = ExtResource("4_mm8bl")
95 | flat = true
96 |
97 | [node name="OpenButton" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/ToolBar"]
98 | layout_mode = 2
99 | text = "打开"
100 | icon = ExtResource("5_bg2r5")
101 | flat = true
102 |
103 | [node name="HSeparator" type="HSeparator" parent="MarginContainer/HSplitContainer/VBoxContainer"]
104 | layout_mode = 2
105 |
106 | [node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HSplitContainer/VBoxContainer"]
107 | layout_mode = 2
108 | size_flags_vertical = 3
109 |
110 | [node name="TextureRect" type="TextureRect" parent="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer"]
111 | visible = false
112 | layout_mode = 2
113 | texture = SubResource("CompressedTexture2D_fd25j")
114 |
115 | [node name="Content" type="HSplitContainer" parent="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer"]
116 | visible = false
117 | layout_mode = 2
118 | size_flags_vertical = 3
119 |
120 | [node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content"]
121 | layout_mode = 2
122 | size_flags_horizontal = 3
123 |
124 | [node name="Label" type="Label" parent="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content/VBoxContainer"]
125 | layout_mode = 2
126 | text = "添加结点"
127 |
128 | [node name="AddStartNode" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content/VBoxContainer"]
129 | layout_mode = 2
130 | theme_override_styles/normal = SubResource("StyleBoxFlat_fd25j")
131 | text = "开始结点"
132 |
133 | [node name="AddDialogNode" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content/VBoxContainer"]
134 | layout_mode = 2
135 | theme_override_styles/normal = SubResource("StyleBoxFlat_twdvk")
136 | text = "对话结点"
137 |
138 | [node name="AddMutiNode" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content/VBoxContainer"]
139 | layout_mode = 2
140 | theme_override_styles/normal = SubResource("StyleBoxFlat_ad5ia")
141 | text = "选项节点"
142 |
143 | [node name="AddEndNode" type="Button" parent="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content/VBoxContainer"]
144 | layout_mode = 2
145 | theme_override_styles/normal = SubResource("StyleBoxFlat_lyc3t")
146 | text = "结束结点"
147 |
148 | [node name="NewSessionDialog" type="ConfirmationDialog" parent="."]
149 | title = "创建对话"
150 | initial_position = 1
151 | size = Vector2i(200, 139)
152 |
153 | [node name="VBoxContainer" type="VBoxContainer" parent="NewSessionDialog"]
154 | offset_left = 8.0
155 | offset_top = 8.0
156 | offset_right = 192.0
157 | offset_bottom = 90.0
158 |
159 | [node name="HBoxContainer" type="HBoxContainer" parent="NewSessionDialog/VBoxContainer"]
160 | layout_mode = 2
161 |
162 | [node name="Label" type="Label" parent="NewSessionDialog/VBoxContainer/HBoxContainer"]
163 | layout_mode = 2
164 | text = "角色1"
165 |
166 | [node name="MainCharacterButton" type="OptionButton" parent="NewSessionDialog/VBoxContainer/HBoxContainer"]
167 | layout_mode = 2
168 | size_flags_horizontal = 3
169 |
170 | [node name="HBoxContainer2" type="HBoxContainer" parent="NewSessionDialog/VBoxContainer"]
171 | layout_mode = 2
172 |
173 | [node name="Label" type="Label" parent="NewSessionDialog/VBoxContainer/HBoxContainer2"]
174 | layout_mode = 2
175 | text = "角色2"
176 |
177 | [node name="SecondaryCharacterButton" type="OptionButton" parent="NewSessionDialog/VBoxContainer/HBoxContainer2"]
178 | layout_mode = 2
179 | size_flags_horizontal = 3
180 |
181 | [node name="HBoxContainer3" type="HBoxContainer" parent="NewSessionDialog/VBoxContainer"]
182 | layout_mode = 2
183 |
184 | [node name="Label" type="Label" parent="NewSessionDialog/VBoxContainer/HBoxContainer3"]
185 | layout_mode = 2
186 | text = "对话名称"
187 |
188 | [node name="DialogNameEdit" type="LineEdit" parent="NewSessionDialog/VBoxContainer/HBoxContainer3"]
189 | layout_mode = 2
190 | size_flags_horizontal = 3
191 |
192 | [node name="FileDialog" type="FileDialog" parent="."]
193 | title = "Open a File"
194 | initial_position = 1
195 | ok_button_text = "Open"
196 | file_mode = 0
197 | filters = PackedStringArray("*.txt")
198 |
199 | [connection signal="confirmed" from="NewCharacterDialog" to="." method="_on_new_character_dialog_confirmed"]
200 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/ToolBar/newButton" to="." method="_on_new_button_pressed"]
201 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/ToolBar/newCharacterButton" to="." method="_on_new_character_button_pressed"]
202 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/ToolBar/SaveButton" to="." method="_on_save_button_pressed"]
203 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/ToolBar/OpenButton" to="." method="_on_open_button_pressed"]
204 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content/VBoxContainer/AddStartNode" to="." method="_on_add_start_node_pressed"]
205 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content/VBoxContainer/AddDialogNode" to="." method="_on_add_dialog_node_pressed"]
206 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content/VBoxContainer/AddMutiNode" to="." method="_on_add_muti_node_pressed"]
207 | [connection signal="pressed" from="MarginContainer/HSplitContainer/VBoxContainer/MarginContainer/Content/VBoxContainer/AddEndNode" to="." method="_on_add_end_node_pressed"]
208 | [connection signal="confirmed" from="NewSessionDialog" to="." method="_on_new_session_dialog_confirmed"]
209 | [connection signal="item_selected" from="NewSessionDialog/VBoxContainer/HBoxContainer/MainCharacterButton" to="." method="_on_main_character_button_item_selected"]
210 | [connection signal="item_selected" from="NewSessionDialog/VBoxContainer/HBoxContainer2/SecondaryCharacterButton" to="." method="_on_secondary_character_button_item_selected"]
211 | [connection signal="confirmed" from="FileDialog" to="." method="_on_file_dialog_confirmed"]
212 |
--------------------------------------------------------------------------------
/addons/eazy_dialog/components/Compiler.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using System.IO;
4 | using System.Collections.Generic;
5 | using EazyDialog.Resolver;
6 | using EazyDialog;
7 | using System.Linq;
8 | [Tool]
9 | public partial class Compiler : EditorPlugin
10 | {
11 | string nodeName = "START";
12 | Vector2 position = new Vector2(0,0);
13 | Dictionary visited = new();
14 | EazyDialogResolver resolver = new EazyDialogResolver();
15 | Dictionary dialogs;
16 | List characterNames;
17 | PackedScene startNode = GD.Load("res://addons/eazy_dialog/components/start_node.tscn");
18 | PackedScene endNode = GD.Load("res://addons/eazy_dialog/components/end_node.tscn");
19 | PackedScene dialogNode = GD.Load("res://addons/eazy_dialog/components/dialog_node.tscn");
20 | PackedScene mutipleNode = GD.Load("res://addons/eazy_dialog/components/muti_node.tscn");
21 |
22 | PackedScene itemNode = GD.Load("res://addons/eazy_dialog/components/item_dialog.tscn");
23 |
24 | public void ExportGraph(GraphEdit graphEdit,string savePath)
25 | {
26 |
27 |
28 | if (graphEdit == null)
29 | {
30 | GD.PrintErr("GraphEdit 未找到!");
31 | return;
32 | }
33 |
34 | Dictionary> leftConnections = new();
35 | Dictionary> rightConnections = new();
36 | Dictionary> selections = new();
37 |
38 | Dictionary context = new();
39 | Dictionary character = new();
40 |
41 | List dialogs = new();
42 |
43 |
44 | // 获取所有 GraphNode 并分类
45 | foreach (var child in graphEdit.GetChildren())
46 | {
47 | if (child is GraphNode graphNode)
48 | {
49 | string nodeTitle = graphNode.Title;
50 | dialogs.Add(nodeTitle);
51 | leftConnections[nodeTitle] = new List();
52 | rightConnections[nodeTitle] = new List();
53 | selections[nodeTitle] = new List();
54 | context[nodeTitle] = "";
55 | if (nodeTitle.Contains("Dialog"))
56 | {
57 | string dialogContent = child.GetNode("HFlowContainer/VBoxContainer/DialogContext/VBoxContainer/TextEdit").Text;
58 | string characterName = child.GetNode("HFlowContainer/HBoxContainer/OptionButton").Text;
59 | context[nodeTitle]=dialogContent;
60 | character[nodeTitle] = characterName;
61 |
62 | }
63 | else if(nodeTitle.Contains("Mutiple")){
64 | VBoxContainer itemContainer = child.GetNode("VBoxContainer/ItemContainer");
65 | string characterName = child.GetNode("VBoxContainer/HBoxContainer/OptionButton").Text;
66 | for(int i=0;i("TextEdit").Text);
68 | }
69 | character[nodeTitle] = characterName;
70 | }
71 | else{
72 | context[nodeTitle] = "...";
73 | character[nodeTitle] = "...";
74 |
75 | }
76 | }
77 | }
78 |
79 | // 获取连接信息
80 | foreach (var connection in graphEdit.GetConnectionList())
81 | {
82 | string fromNode = connection["from_node"].AsString();
83 | string toNode = connection["to_node"].AsString();
84 | int fromPort = connection["from_port"].AsInt32();
85 | rightConnections[fromNode].Add(toNode);
86 | leftConnections[toNode].Add(fromNode);
87 |
88 | }
89 |
90 |
91 | string content = "";
92 |
93 | foreach (var dialog in dialogs)
94 | {
95 | content += $"[{dialog}]\n";
96 | content += $" Character\n";
97 | content += $" - {character[dialog]}\n";
98 | content += $" Context\n";
99 | content += $" - {context[dialog]}\n";
100 |
101 | if(selections[dialog].Count>0){
102 | content += $" Selections\n";
103 | foreach (var selection in selections[dialog])
104 | {
105 | content += $" - {selection}\n";
106 | }
107 | }
108 |
109 | // LEFT
110 | if (leftConnections[dialog].Count > 0)
111 | {
112 | content += $" LEFT\n";
113 | foreach (var left in leftConnections[dialog])
114 | {
115 | content += $" - {left}\n";
116 | }
117 | }
118 |
119 | // RIGHT
120 | if (rightConnections[dialog].Count > 0)
121 | {
122 | content += $" RIGHT\n";
123 | foreach (var right in rightConnections[dialog])
124 | {
125 | content += $" - {right}\n";
126 | }
127 | }
128 | content += "\n";
129 | }
130 | WriteFile(savePath,content);
131 |
132 |
133 |
134 | GD.Print("Graph 数据已成功导出:\n ", content);
135 | }
136 |
137 |
138 | private void WriteFile(String path,string content)
139 | {
140 |
141 | using var file = Godot.FileAccess.Open(path, Godot.FileAccess.ModeFlags.Write);
142 | file.StoreString(content);
143 | }
144 |
145 | public void ConnectNode(GraphEdit graphEdit){
146 |
147 | foreach(var _node in dialogs[nodeName].Right){
148 | graphEdit.ConnectNode(nodeName,0,_node,0);
149 | }
150 |
151 | foreach(var _node in dialogs[nodeName].Right){
152 | nodeName = _node;
153 | ConnectNode(graphEdit);
154 | }
155 |
156 |
157 |
158 | }
159 |
160 | public void AddNode(string filePath,GraphEdit graphEdit){
161 |
162 | if(dialogs ==null)
163 | dialogs = resolver.ParseFile(filePath);
164 | characterNames = resolver.GetCharacters(filePath);
165 |
166 | if(visited.ContainsKey(nodeName))
167 | return;
168 | else
169 | visited.Add(nodeName,true);
170 |
171 |
172 | if (nodeName.StartsWith("START")){
173 | GraphNode node = (GraphNode)startNode.Instantiate();
174 | node.Name = nodeName;
175 | node.Title = nodeName;
176 | Label dialogName= (Label)node.GetNode("HBoxContainer/Label");
177 | dialogName.Text = Path.GetFileNameWithoutExtension(filePath);
178 | node.PositionOffset = position;
179 | position.X +=300;
180 | graphEdit.AddChild(node);
181 |
182 | }else if(nodeName.StartsWith("Dialog")){
183 | GraphNode node = (GraphNode)dialogNode.Instantiate();
184 | node.Name = nodeName;
185 | node.Title = nodeName;
186 | TextEdit contentEditor = node.GetNode("HFlowContainer/VBoxContainer/DialogContext/VBoxContainer/TextEdit");
187 | OptionButton characterNameEditor = node.GetNode("HFlowContainer/HBoxContainer/OptionButton");
188 | contentEditor.Text = dialogs[nodeName].Content;
189 | foreach (var (item, index) in characterNames.Select((value, i) => (value, i))){
190 | characterNameEditor.AddItem(item);
191 |
192 | }
193 | characterNameEditor.Select(characterNames.IndexOf(dialogs[nodeName].Character));
194 |
195 | if(dialogs[nodeName].Left.Count != 0){
196 | GraphNode fatherNode =(GraphNode) graphEdit.GetNode( dialogs[nodeName].Left[0]);
197 | node.PositionOffset = new Vector2(fatherNode.PositionOffset.X+500,fatherNode.PositionOffset.Y+(dialogs[fatherNode.Name].Right.IndexOf(nodeName))*300);
198 |
199 |
200 | }
201 |
202 | graphEdit.AddChild(node);
203 |
204 | }else if(nodeName.StartsWith("Mutiple")){
205 | GraphNode node = (GraphNode)mutipleNode.Instantiate();
206 | node.Name = nodeName;
207 | node.Title = nodeName;
208 | OptionButton characterNameEditor = node.GetNode("VBoxContainer/HBoxContainer/OptionButton");
209 | foreach (var (item, index) in characterNames.Select((value, i) => (value, i))){
210 | characterNameEditor.AddItem(item);
211 | }
212 | characterNameEditor.Select(characterNames.IndexOf(dialogs[nodeName].Character));
213 |
214 | foreach(var content in dialogs[nodeName].Selections){
215 | HBoxContainer container = (HBoxContainer) itemNode.Instantiate();
216 | container.Name = nodeName;
217 | TextEdit textEdit = (TextEdit) container.GetNode("TextEdit");
218 | textEdit.Text = content;
219 | node.GetNode("VBoxContainer/ItemContainer").AddChild(container);
220 |
221 |
222 |
223 | }
224 |
225 |
226 |
227 |
228 |
229 |
230 | if(dialogs[nodeName].Left.Count != 0){
231 | GraphNode fatherNode =(GraphNode) graphEdit.GetNode( dialogs[nodeName].Left[0]);
232 | node.PositionOffset = new Vector2(fatherNode.PositionOffset.X+500,fatherNode.PositionOffset.Y+(dialogs[fatherNode.Name].Right.IndexOf(nodeName))*300);
233 |
234 |
235 | }
236 |
237 | graphEdit.AddChild(node);
238 |
239 | }
240 |
241 |
242 |
243 | else if(nodeName.StartsWith("END")){
244 | GraphNode node = (GraphNode)endNode.Instantiate();
245 | node.Name = nodeName;
246 | node.Title = nodeName;
247 | node.PositionOffset = position;
248 | if(dialogs[nodeName].Left.Count != 0){
249 | GraphNode fatherNode =(GraphNode) graphEdit.GetNode( dialogs[nodeName].Left[0]);
250 | node.PositionOffset = new Vector2(fatherNode.PositionOffset.X+500,fatherNode.PositionOffset.Y);
251 |
252 | }
253 |
254 |
255 | graphEdit.AddChild(node);
256 |
257 | }
258 |
259 | foreach(var _node in dialogs[nodeName].Right){
260 |
261 |
262 | nodeName = _node;
263 | FileToGraph(filePath,graphEdit);
264 |
265 | }
266 |
267 |
268 |
269 |
270 |
271 |
272 | }
273 |
274 | public void FileToGraph(string filePath,GraphEdit graphEdit){
275 | AddNode(filePath,graphEdit);
276 | nodeName = "START";
277 | ConnectNode(graphEdit);
278 |
279 |
280 |
281 |
282 | }
283 | }
284 |
--------------------------------------------------------------------------------