feat: added colors and protagonist to preview

This commit is contained in:
Bram Dingelstad 2021-12-08 20:29:52 +01:00
parent b62d8793b9
commit 1e1bb8936f
8 changed files with 113 additions and 26 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
.import
.DS_Store
export

View file

@ -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.

View file

@ -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 {

View file

@ -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

View file

@ -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()

View file

@ -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)
@ -32,10 +51,23 @@ func open_node(graph_node):
$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()

View file

@ -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)

Binary file not shown.