extends Object class_name YarnRunner var yarnScript : YarnScript var say_func : FuncRef = null var choices_func : FuncRef = null var commands := {} signal resume_workaround func run_all(): var next_node = yarnScript.nodes["Start"] while next_node != null: print("-> Jump to " + next_node["title"]) var next_node_key = yield(run_body(next_node["body"]), "completed") if (yarnScript.nodes.has(next_node_key)): next_node = yarnScript.nodes[next_node_key] else: next_node = null func run_body(body): yield(Controller.get_tree(), "idle_frame") # workaround before await for element in body: if element["type"] == "jump": return element["node"] elif element["type"] == "command": yield(run_command(element["command"], element["args"]), "completed") elif element["type"] == "choice_blocks": var block = yield(decide_choice_block(element["blocks"]), "completed") print(block) return block["node"] # todo change later with "-> choices" elif element["type"] == "condition_blocks": var block = decide_condition_block(element["blocks"]) var next_node_key = yield(run_body(block["body"]), "completed") if next_node_key != "": return next_node_key else: if say_func == null or !say_func.is_valid(): printerr("no say_func provided") else: yield(say_func.call_func(element), "completed") return "" func add_command(command_key, function): commands[command_key] = function func run_command(command_key, args): if (commands.has(command_key)): var command : FuncRef = commands[command_key] yield(command.call_func(args), "completed") func decide_choice_block(blocks): if choices_func == null or !choices_func.is_valid(): printerr("no choices_func provided") else: return yield(choices_func.call_func(blocks), "completed") func decide_condition_block(blocks): for block in blocks: var expr := Expression.new() var err := expr.parse(block["condition"]) if err == OK and expr.execute(): return block return null