feat: added colors and protagonist to preview
This commit is contained in:
parent
b62d8793b9
commit
1e1bb8936f
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
.import
|
||||
.DS_Store
|
||||
export
|
||||
|
|
|
@ -41,7 +41,7 @@ There are few things that need to be ironed out to be 100% feature compatible wi
|
|||
- [ ] Support for [format functions](https://yarnspinner.dev/docs/syntax/#format-functions).
|
||||
- [ ] ~Support~ Fix for conditional options.
|
||||
- [ ] In-editor dialogue editor with preview.
|
||||
- [ ] Lines connecting different nodes if they refer to eachother.
|
||||
- [x] Lines connecting different nodes if they refer to eachother.
|
||||
- [x] Error hints when doing something wrong.
|
||||
- [x] Basic saving, opening and saving-as.
|
||||
- [ ] Remove all `printerr` in favor of (soft) `assert`s.
|
||||
|
|
|
@ -50,12 +50,13 @@ class Command:
|
|||
|
||||
class WolNode:
|
||||
var name = ''
|
||||
var program
|
||||
var instructions = []
|
||||
var labels = {}
|
||||
var tags = []
|
||||
var source_id = ''
|
||||
|
||||
func _init(other = null):
|
||||
func _init(_program, other = null):
|
||||
if other != null and other.get_script() == self.get_script():
|
||||
name = other.name
|
||||
instructions += other.instructions
|
||||
|
@ -64,6 +65,8 @@ class WolNode:
|
|||
tags += other.tags
|
||||
source_id = other.source_id
|
||||
|
||||
program = _program
|
||||
|
||||
func equals(other):
|
||||
if other.get_script() != get_script():
|
||||
return false
|
||||
|
@ -80,6 +83,15 @@ class WolNode:
|
|||
func _to_string():
|
||||
return "WolNode[%s:%s]" % [name, source_id]
|
||||
|
||||
func get_lines():
|
||||
var lines = []
|
||||
|
||||
for instruction in instructions:
|
||||
if instruction.operation == Constants.ByteCode.RunLine:
|
||||
lines.append(program.strings[instruction.operands.front().value])
|
||||
|
||||
return lines
|
||||
|
||||
# TODO: Make this make sense
|
||||
class Operand:
|
||||
enum ValueType {
|
||||
|
|
|
@ -163,7 +163,7 @@ func compile():
|
|||
func compile_node(program, parsed_node):
|
||||
self.assert(not program.nodes.has(parsed_node.name), 'Duplicate node in program: %s' % parsed_node.name)
|
||||
|
||||
var node_compiled = Program.WolNode.new()
|
||||
var node_compiled = Program.WolNode.new(program)
|
||||
|
||||
node_compiled.name = parsed_node.name
|
||||
node_compiled.tags = parsed_node.tags
|
||||
|
|
|
@ -4,12 +4,14 @@ extends Panel
|
|||
var current_graph_node
|
||||
|
||||
onready var preview = get_node('../Preview')
|
||||
onready var wol_editor = find_parent('WolEditor')
|
||||
|
||||
func _ready():
|
||||
hide()
|
||||
connect('visibility_changed', self, '_on_visibility_changed')
|
||||
$Tools/Left/Play.connect('pressed', self, '_on_play')
|
||||
$Tools/Right/Close.connect('pressed', self, 'close')
|
||||
$Tools/Right/Delete.connect('pressed', self, '_on_delete_pressed')
|
||||
|
||||
func close():
|
||||
hide()
|
||||
|
@ -55,6 +57,9 @@ func toggle_text_edit(text_edit):
|
|||
func _on_play():
|
||||
preview.open_node(current_graph_node)
|
||||
|
||||
func _on_delete_pressed():
|
||||
wol_editor.confirm_delete_node(current_graph_node)
|
||||
|
||||
func _on_title_changed():
|
||||
current_graph_node.node.title = $HBoxContainer/TextEdit.text
|
||||
current_graph_node.compile()
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
tool
|
||||
extends Panel
|
||||
|
||||
var current_graph_node
|
||||
|
@ -7,14 +8,15 @@ onready var button_template = $Options/List/ButtonTemplate
|
|||
|
||||
onready var wol_editor = find_parent('WolEditor')
|
||||
|
||||
# TODO: Make sure all focus is lost when clicking this pane
|
||||
# TODO: Add restart button
|
||||
# TODO: Add next button
|
||||
|
||||
func _ready():
|
||||
hide()
|
||||
$Wol.connect('line', self, '_on_line')
|
||||
$Wol.connect('options', self, '_on_options')
|
||||
|
||||
connect('gui_input', self, '_on_gui_input')
|
||||
|
||||
$Tools/Left/Next.connect('pressed', self, 'next')
|
||||
$Tools/Left/Restart.connect('pressed', self, 'restart')
|
||||
$Tools/Right/Close.connect('pressed', self, 'close')
|
||||
|
||||
func open_node(graph_node):
|
||||
|
@ -22,6 +24,23 @@ func open_node(graph_node):
|
|||
|
||||
$Wol.stop()
|
||||
|
||||
yield(get_tree(), 'idle_frame')
|
||||
|
||||
clear_chat()
|
||||
|
||||
$Tools/Left/Protagonist.text = guess_protagonist()
|
||||
|
||||
$Wol.variable_storage = {}
|
||||
$Wol.set_program(wol_editor.get_program())
|
||||
|
||||
yield(get_tree(), 'idle_frame')
|
||||
|
||||
$Wol.start(current_graph_node.node.title)
|
||||
|
||||
show()
|
||||
grab_focus()
|
||||
|
||||
func clear_chat():
|
||||
for child in $Content/List.get_children():
|
||||
if child != line_template and not 'Padding' in child.name:
|
||||
$Content/List.remove_child(child)
|
||||
|
@ -31,11 +50,24 @@ func open_node(graph_node):
|
|||
if child != button_template:
|
||||
$Options/List.remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
$Wol.variable_storage = {}
|
||||
$Wol.set_program(wol_editor.get_program())
|
||||
$Wol.start(current_graph_node.node.title)
|
||||
show()
|
||||
|
||||
|
||||
func guess_protagonist():
|
||||
var protagonist = 'You'
|
||||
var wol_node = wol_editor.get_program().nodes[current_graph_node.node.title]
|
||||
|
||||
for line in wol_node.get_lines():
|
||||
if get_protagonist(line):
|
||||
protagonist = get_protagonist(line)
|
||||
if protagonist == 'You':
|
||||
break
|
||||
|
||||
return protagonist
|
||||
|
||||
func get_protagonist(line):
|
||||
if ':' in line.text and line.text.find(':') < 30:
|
||||
return line.text.split(':')[0]
|
||||
return
|
||||
|
||||
func close():
|
||||
hide()
|
||||
|
@ -45,14 +77,33 @@ func close():
|
|||
func next():
|
||||
$Wol.resume()
|
||||
|
||||
func restart():
|
||||
$Wol.stop()
|
||||
|
||||
yield(get_tree(), 'idle_frame')
|
||||
|
||||
clear_chat()
|
||||
|
||||
yield(get_tree(), 'idle_frame')
|
||||
|
||||
$Wol.start(current_graph_node.node.title)
|
||||
|
||||
func _on_line(line):
|
||||
var line_node = line_template.duplicate()
|
||||
$Content/List.add_child(line_node)
|
||||
$Content/List/PaddingBottom.raise()
|
||||
# TODO: Add hash() based color from speaker
|
||||
|
||||
# TODO: Add hash() based color from speaker
|
||||
line_node.get_node('RichTextLabel').bbcode_text = line.text
|
||||
|
||||
var padding_node = 'PaddingRight' if get_protagonist(line) == $Tools/Left/Protagonist.text else 'PaddingLeft'
|
||||
line_node.get_node(padding_node).size_flags_horizontal = SIZE_EXPAND_FILL
|
||||
var panel = line_node.get_node('RichTextLabel/Panel').get('custom_styles/panel').duplicate()
|
||||
panel.bg_color = Color(hash(get_protagonist(line)))
|
||||
line_node.get_node('RichTextLabel/Panel').set('custom_styles/panel', panel)
|
||||
|
||||
line_node.show()
|
||||
|
||||
yield(get_tree(), 'idle_frame')
|
||||
$Content.scroll_vertical = $Content/List.rect_size.y
|
||||
|
||||
|
@ -73,10 +124,14 @@ func _on_option_pressed(option):
|
|||
$Options/List.remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
func _on_gui_input(event):
|
||||
if visible:
|
||||
if event is InputEventMouseButton and event.doubleclick:
|
||||
next()
|
||||
|
||||
if event is InputEventMouseButton and event.pressed:
|
||||
grab_focus()
|
||||
|
||||
func _input(event):
|
||||
if visible \
|
||||
and ( \
|
||||
(event is InputEventMouseButton and event.doubleclick) \
|
||||
or (event is InputEventKey and not event.pressed and event.scancode in [KEY_SPACE, KEY_ENTER]) \
|
||||
):
|
||||
if visible and has_focus() and event is InputEventKey and not event.pressed and event.scancode in [KEY_SPACE, KEY_ENTER]:
|
||||
next()
|
||||
|
|
|
@ -10,6 +10,17 @@ var selected_node
|
|||
|
||||
onready var original_delete_node_dialog = $DeleteNodeDialog.dialog_text
|
||||
|
||||
# TODO: Conditionally load in theme based on Editor or standalone
|
||||
# TODO: Make deleting undo-able
|
||||
# TODO: Implement alternative "single" line style of connecting
|
||||
# TODO: Test out web version
|
||||
# TODO: Make web loading / saving work
|
||||
# TODO: Make theme for standalone editor
|
||||
# TODO: Make a "Godot editor" version of the editor theme
|
||||
# FIXME: Make lines render appropriately after connecting
|
||||
# FIXME: Make all parts of the code "tool"s and safekeep its execution while in editor
|
||||
# FIXME: Fix changing of titles
|
||||
|
||||
func _ready():
|
||||
for menu_button in [$Menu/File]:
|
||||
menu_button.get_popup().connect('index_pressed', self, '_on_menu_pressed', [menu_button.get_popup()])
|
||||
|
@ -20,13 +31,10 @@ func _ready():
|
|||
|
||||
$DeleteNodeDialog.connect('confirmed', self, 'delete_node')
|
||||
|
||||
# TODO: Conditionally load in theme based on Editor or standalone
|
||||
|
||||
path = 'res://dialogue.wol'
|
||||
build_nodes()
|
||||
|
||||
func create_node(position = Vector2.ZERO):
|
||||
print('creating node!')
|
||||
var graph_node = GraphNodeTemplate.duplicate()
|
||||
$GraphEdit.add_child(graph_node)
|
||||
|
||||
|
@ -43,9 +51,16 @@ func create_node(position = Vector2.ZERO):
|
|||
graph_node.show()
|
||||
|
||||
func delete_node(node = selected_node):
|
||||
if $HBoxContainer/Editor.visible:
|
||||
$HBoxContainer/Editor.close()
|
||||
$GraphEdit.remove_child(node)
|
||||
node.queue_free()
|
||||
|
||||
func confirm_delete_node(node = selected_node):
|
||||
selected_node = node
|
||||
$DeleteNodeDialog.dialog_text = original_delete_node_dialog % selected_node.name
|
||||
$DeleteNodeDialog.popup()
|
||||
|
||||
func build_nodes():
|
||||
for node in Compiler.new(path).get_nodes():
|
||||
var graph_node = GraphNodeTemplate.duplicate()
|
||||
|
@ -178,6 +193,5 @@ func _input(event):
|
|||
and not event.pressed and event.scancode == KEY_DELETE \
|
||||
and selected_node \
|
||||
and not $HBoxContainer/Editor.visible:
|
||||
$DeleteNodeDialog.dialog_text = original_delete_node_dialog % selected_node.name
|
||||
$DeleteNodeDialog.popup()
|
||||
|
||||
confirm_delete_node()
|
||||
|
||||
|
|
BIN
addons/Wol/editor/WolEditor.tscn
(Stored with Git LFS)
BIN
addons/Wol/editor/WolEditor.tscn
(Stored with Git LFS)
Binary file not shown.
Reference in a new issue