Skip to content

Instantly share code, notes, and snippets.

@Capital-EX
Created August 27, 2024 04:21
Show Gist options
  • Save Capital-EX/9d2eaa46fe3465aca4149b5b24f2f2cf to your computer and use it in GitHub Desktop.
Save Capital-EX/9d2eaa46fe3465aca4149b5b24f2f2cf to your computer and use it in GitHub Desktop.
# warning-ignore-all:void_assignment
# warning-ignore-all:return_value_discarded
extends Control
class_name Sequence
# todo - impelement prize screen
signal dialogue_shown()
signal option_pressed(id)
enum Commands {
FADE_OUT, FADE_IN,
CHAR_ENTER, CHAR_MOVE, CHAR_FLIP, CHAR_EXIT, CHAR_EMOTE,
HIDE_DIALOGUE,
APPEND_HISTORY,
WHEN_SEEN, SET_SEEN,
WHEN_FLAG, SET_FLAG,
WHEN, PICK, RUN, GOTO,
AWAIT_RUN, AWAIT_RESULT, AWAIT_SIGNAL,
AWAIT_INTERACTION, AWAIT_MINIGAME,
GIVE_PRIZE, GIVE_ITEM, TAKE_ITEM,
SET_BACKDROP, ADD_BACKDROP, REMOVE_BACKDROP, CLEAR_BACKDROP,
SAY,
# RESPOND is for when the player says something
# NEXT is for when the player needs to click next
# WAIT is for when the player only needs to wait for the dialogue to end
RESPOND, NEXT, WAIT,
CHANGE_STAT, SET_STAT, WHEN_STAT,
CHANGE_MUSIC,
SHOW_BLACKOUT, HIDE_BLACKOUT,
TRANSITION, END
}
enum {
POS_LEFT,
POS_CENTER,
POS_RIGHT,
POS_TOP,
POS_BOTTOM,
}
enum {
FADE_INVISIBLE,
FADE_VISIBLE,
}
const ButtonBase = preload("res://scenes/ui/misc/ButtonBase.tscn")
const ButtonPrize = null
const QMo8_24px = preload("res://fonts/QMo8_24px.tres")
const NoImage = preload("res://imgs/events/NoImage.png")
var entry_passage = "intro"
var entry_line = 0
var entry_previous_state = {}
var opcode = []
var ip = 0
var running = false
var character_lookup = {}
var backdrop_lookup: Dictionary = {}
var skip_fade: bool = false
var fade_state: int = FADE_INVISIBLE
onready var Blackout: ColorRect = $Blackout
onready var BackgroundLayer: CanvasLayer = $SceneContainer/SceneViewport/BackgroundLayer
onready var CharacterLayer: CanvasLayer = $SceneContainer/SceneViewport/CharacterLayer
onready var DialogueContainer: Container = $DialogueContainer
onready var DialogueLabel: Label = $DialogueContainer/MarginContainer/DialogueBox/DialogueMargin/DialogueLabel
onready var OptionsContainer: Container = $MarginContainer/OptionsContainer
onready var ItemScreen: Control = $ItemScreen
onready var FadePlayer: AnimationPlayer = $BlackoutPanel/FadePlayer
onready var DialogueShower: Tween = $DialogueContainer/DailogShower
onready var SceneViewport: Viewport = $SceneContainer/SceneViewport
func set_entry(passage: String, line: int, previous_state: Dictionary) -> void:
prints(passage, line, previous_state)
entry_passage = passage
entry_line = line
entry_previous_state = previous_state
func _ready() -> void:
setup()
execute(entry_passage, entry_line)
func _input(event: InputEvent):
if event is InputEventMouseButton and event.is_pressed() and not event.is_echo():
if DialogueShower.is_active():
DialogueShower.seek(DialogueShower.get_runtime())
if FadePlayer.is_playing():
if FadePlayer.current_animation == "fade_out":
FadePlayer.playback_speed = 1000.0
skip_fade = true
elif FadePlayer.current_animation == "fade_in":
FadePlayer.playback_speed = 1000.0
skip_fade = false
func _exit_tree() -> void:
for character in character_lookup:
character_lookup[character].free()
for backdrop in backdrop_lookup:
backdrop_lookup[backdrop].free()
func _on_option_pressed(id: int) -> void:
$Click.play()
_clear_options()
emit_signal("option_pressed", id)
func setup() -> void:
push_warning("Setup function not overridden.")
func intro() -> void:
push_warning("Missing intro passage.")
func save() -> Dictionary:
var data = {}
for backdrop in backdrop_lookup:
if backdrop_lookup[backdrop].has_method('save') and backdrop_lookup[backdrop].is_ready:
data[backdrop] = backdrop_lookup[backdrop].save()
return data
func execute(entry: String, line: int = 0) -> void:
opcode = []
ip = line
self.call(entry)
State.remember_current_passage(entry)
if ip != 0:
# this must be from an ActionType.RESTORE_STATE
# there exist no op code that results in an IP != 0
# when execute is called.
var current_dialogue = State.fetch_current_dialogue()
var blackout_active = State.fetch_blackout_visible()
var active_backdrop_list = State.fetch_backdrop_list()
var active_character_list = State.fetch_character_list()
if not current_dialogue.empty():
if 'text' in current_dialogue and not current_dialogue.text.empty():
_say(current_dialogue.text, current_dialogue.position, current_dialogue.rate)
DialogueShower.seek(DialogueShower.get_runtime())
if current_dialogue.hidden:
_hide_dialogue()
if blackout_active:
_show_blackout()
for backdrop in active_backdrop_list:
_add_backdrop(backdrop)
for backdrop in entry_previous_state:
prints(backdrop, entry_previous_state[backdrop])
backdrop_lookup[backdrop].set_restore_data(entry_previous_state[backdrop])
for character in active_character_list:
var data = active_character_list[character]
_enter(character, data.standing, data.facing, data.emote)
if opcode[ip].command != Commands.FADE_IN:
$BlackoutPanel.material.set_shader_param('offset', 0)
if not running:
interpret()
func clear() -> void:
for character in character_lookup:
character_lookup[character].free()
for backdrop in backdrop_lookup:
backdrop_lookup[backdrop].free()
func interpret() -> void:
running = true
while ip < len(opcode):
var co: GDScriptFunctionState
var op: Dictionary = opcode[ip]
State.remember_current_line(ip)
ip += 1
co = eval(op)
if co:
yield(co, "completed")
if not opcode[-1].command != Commands.END:
push_warning("Sequence: end() was not called but there are no more instructions to run...")
end()
running = false
func eval(op) -> GDScriptFunctionState:
var co = null
match op.command:
Commands.FADE_IN:
co = _fade_in()
Commands.FADE_OUT:
co = _fade_out()
Commands.CHAR_ENTER:
co = _enter(op.character, op.standing, op.facing, op.emote)
Commands.CHAR_MOVE:
co = _move(op.character, op.standing)
Commands.CHAR_FLIP:
co = _face(op.character, op.facing)
Commands.CHAR_EXIT:
co = _exit(op.character)
Commands.CHAR_EMOTE:
co = _emote(op.character, op.emote)
Commands.HIDE_DIALOGUE:
co = _hide_dialogue()
Commands.APPEND_HISTORY:
co = _append_history(op.history)
Commands.WHEN_SEEN:
co = _when_seen(op.conds)
Commands.SET_SEEN:
co = _set_seen(op.passage)
Commands.WHEN_FLAG:
co = _when_flag(op.conds)
Commands.SET_FLAG:
co = _set_flag(op.flag)
Commands.WHEN:
co = _when(op.conds)
Commands.PICK:
if FADE_VISIBLE: push_warning("Sequencer: fade_out has not been called")
co = _pick(op.options)
Commands.RUN:
co = _run(op.object, op.method, op.args)
Commands.GOTO:
co = _goto(op.passage)
Commands.AWAIT_RUN:
co = _await_run(op. object, op.method, op.args)
Commands.AWAIT_RESULT:
co = _await_result(op.object, op.sig, op.callback, op.handler)
Commands.AWAIT_SIGNAL:
co = _await_signal(op.object, op.sig)
Commands.AWAIT_INTERACTION:
co = _await_interaction(op.id, op.callback, op.sig, op.handler)
Commands.AWAIT_MINIGAME:
co = _await_minigame(op.minigame, op.callback, op.handler)
Commands.GIVE_PRIZE:
co = _give_prize(op.options)
Commands.GIVE_ITEM:
co = _give_item(op.name)
Commands.TAKE_ITEM:
co = _take_item(op.id)
Commands.SET_BACKDROP:
co = _set_backdrop(op.id)
Commands.ADD_BACKDROP:
co = _add_backdrop(op.id)
Commands.REMOVE_BACKDROP:
co = _remove_backdrop(op.id)
Commands.CLEAR_BACKDROP:
co = _clear_backdrop()
Commands.SAY:
if FADE_VISIBLE: push_warning("Sequencer: fade_out has not been called")
co = _say(op.message, op.pos, op.rate)
Commands.RESPOND:
if FADE_VISIBLE: push_warning("Sequencer: fade_out has not been called")
co = _respond(op.message)
Commands.NEXT:
if FADE_VISIBLE: push_warning("Sequencer: fade_out has not been called")
co = _next()
Commands.WAIT:
co = _wait(op.delay)
Commands.CHANGE_STAT:
co = _change_stat(op.stat, op.delta)
Commands.SET_STAT:
co = _set_stat(op.stat, op.value)
Commands.WHEN_STAT:
co = _when_stat(op.conds)
Commands.CHANGE_MUSIC:
co = _change_music(op.track)
Commands.SHOW_BLACKOUT:
co = _show_blackout()
Commands.HIDE_BLACKOUT:
co = _hide_blackout()
Commands.TRANSITION:
co = _transition(op.to)
Commands.END:
co = _end()
return co
func character(character: String) -> void:
character_lookup[character] = Characters.get_character(character)
# ! This will need to be changed to the background loading system
func backdrop_image(id: String, texture: Texture) -> void:
var texture_rect: Sprite = Sprite.new()
texture_rect.centered = false
texture_rect.texture = texture
backdrop_lookup[id] = texture_rect
# ! This will need to be changed to the background loading system
func backdrop_scene(id: String, scene: PackedScene) -> void:
backdrop_lookup[id] = scene.instance()
func get_backdrop(backdrop_name) -> CanvasItem:
return backdrop_lookup.get(backdrop_name)
func fade_out() -> void:
opcode.push_back({
command = Commands.FADE_OUT,
})
func fade_in() -> void:
opcode.push_back({
command = Commands.FADE_IN,
})
func enter(character: String,
standing: int = Character.STANDING_LEFT,
facing: int = Character.FACING_RIGHT,
emote: String = "default") -> void:
opcode.push_back({
command = Commands.CHAR_ENTER,
character = character,
standing = standing,
facing = facing,
emote = emote
})
func move(character: String, standing: int) -> void:
opcode.push_back({
command = Commands.CHAR_MOVE,
character = character,
standing = standing
})
func face(character: String, facing: int) -> void:
opcode.push_back({
command = Commands.CHAR_FLIP,
character = character,
facing = facing,
})
func exit(character: String) -> void:
opcode.push_back({
command = Commands.CHAR_EXIT,
character = character
})
func emote(character: String, emote: String) -> void:
opcode.push_back({
command = Commands.CHAR_EMOTE,
character = character,
emote = emote
})
func hide_dialogue() -> void:
opcode.push_back({
command = Commands.HIDE_DIALOGUE
})
func append_history(history: String) -> void:
opcode.push_back({
command = Commands.APPEND_HISTORY,
history = history
})
func when_seen(conds: Array) -> void:
opcode.push_back({
command = Commands.WHEN_SEEN,
conds = conds
})
func set_seen(passage: String) -> void:
opcode.push_back({
command = Commands.SET_SEEN,
passage = passage
})
func when_flag(conds: Array) -> void:
opcode.push_back({
command = Commands.WHEN_FLAG,
conds = conds
})
func set_flag(flag: String) -> void:
opcode.push_back({
command = Commands.SET_FLAG,
flag = flag
})
func when(conds: Array) -> void:
opcode.push_back({
command = Commands.WHEN_SEEN,
conds = conds
})
func pick(options: Array) -> void:
opcode.push_back({
command = Commands.PICK,
options = options
})
func run(object: Object, method: String, args: Array = []) -> void:
opcode.push_back({
command = Commands.RUN,
object = object,
method = method,
args = args
})
func run_away(object: Object, method: String, args: Array = []) -> void:
opcode.push_back({
command = Commands.WAIT_FOR,
object = object,
method = method,
args = args
})
func goto(passage: String) -> void:
opcode.push_back({
command = Commands.GOTO,
passage = passage
})
# The await_run method is used to wait for a method to complete. This function assumes
# that method returns void. In oreder to wait for a result use await_result.
func await_run(object: Object, method: String, args: Array = []) -> void:
opcode.push_back({
command = Commands.AWAIT_RUN,
object = object,
method = method,
args = args
})
# ! If await_result, await_signal, await_interaction, or await_minigame need to change the story's opcode
# ! then they need to be the last instruction in a passage or call `execute('<passage name>')`. Otherwise,
# ! the instructions they push into the opcode will be executed *after* the remander of the current passage.
# ! However, this could be used to append additional dialogue to the end of the current passage. But, that
# ! may lead to confusion when debugging passages.
# !
# ! Use with cation.
# The await_result method is used to wait for a signal to be emmitted. Additionally, this method allows the
# handler object to receive thee result of the signal. This method should be used to listen for
# the result of any method you want to run.
func await_result(object: Object, sig: String, callback: String, handler: Object = self) -> void:
opcode.push_back({
command = Commands.AWAIT_RESULT,
object = object,
sig = sig,
callback = callback,
handler = handler
})
# The await_signal method will pause the script execution until a specific signal has been emitted.
# This should never be used alone as the story will hang is the signal is never emitted.
func await_signal(object: Object, sig: String) -> void:
opcode.push_back({
command = Commands.AWAIT_SIGNAL,
object = object,
sig = sig
})
# The await_interaction method is used to begin a gameplay sequence in the middle of a story sequence.
# This is short hand for:
# ```gd
# set_backdrop(id)
# run(get_backdrop(id), 'start_interaction')
# await_result(get_backdrop(id), 'interaction_completed', callback, handler)
# ```
# This method *requires* the backdrop specified by the id have the method 'start_interaction'
# and the signal 'interaction_completed' in order to succeed. Additionally, thie method will hang
# the story if 'interaction_completed' is never emitted.
func await_interaction(id: String, callback: String, sig: String = 'interaction_completed', handler: Object = self) -> void:
opcode.push_back({
command = Commands.AWAIT_INTERACTION,
id = id,
callback = callback,
sig = sig,
handler = handler
})
# The await_minigame method starts the specified minigame and then waits for the player to complete it.
# It then passes control to the specified handler.
func await_minigame(minigame: String, callback: String, handler: Object = self) -> void:
opcode.push_back({
command = Commands.AWAIT_MINIGAME,
minigame = minigame,
callback = callback,
handler = handler,
})
func give_prize(options = []) -> void:
opcode.push_back({
command = Commands.GIVE_PRIZE,
options = options
})
func give_item(name: String) -> void:
opcode.push_back({
command = Commands.GIVE_ITEM,
name = name
})
func take_item(id: int) -> void:
opcode.push_back({
command = Commands.TAKE_ITEM,
id = id
})
func set_backdrop(id: String) -> void:
opcode.push_back({
command = Commands.SET_BACKDROP,
id = id
})
func add_backdrop(id: String) -> void:
opcode.push_back({
command = Commands.ADD_BACKDROP,
id = id
})
func remove_backdrop(id: String) -> void:
opcode.push_back({
command= Commands.REMOVE_BACKDROP,
id = id
})
func clear_backdrop() -> void:
opcode.push_back({
command = Commands.CLEAR_BACKDROP
})
func say_left(message: String, rate = 1.0 / 60.0) -> void:
opcode.push_back({
command = Commands.SAY,
pos = POS_LEFT,
message = message,
rate = rate
})
func say_center(message: String, rate = 1.0 / 60.0) -> void:
opcode.push_back({
command = Commands.SAY,
pos = POS_CENTER,
message = message,
rate = rate
})
func say_right(message: String, rate = 1.0 / 60.0) -> void:
opcode.push_back({
command = Commands.SAY,
pos = POS_RIGHT,
message = message,
rate = rate
})
func say_top(message: String, rate = 1.0 / 60.0) -> void:
opcode.push_back({
command = Commands.SAY,
pos = POS_TOP,
message = message,
rate = rate
})
func say_bottom(message: String, rate = 1.0 / 60.0) -> void:
opcode.push_back({
command = Commands.SAY,
pos = POS_BOTTOM,
message = message,
rate = rate
})
func respond(message: String) -> void:
opcode.push_back({
command = Commands.RESPOND,
message = message
})
func next() -> void:
opcode.push_back({
command = Commands.NEXT,
})
func wait(delay: float) -> void:
opcode.push_back({
command = Commands.WAIT,
delay = delay
})
func change_stat(stat: String, delta: int) -> void:
opcode.push_back({
command = Commands.CHANGE_STAT,
stat = stat,
delta = delta
})
func set_stat(stat: String, value: int) -> void:
opcode.push_back({
command = Commands.SET_STAT,
stat = stat,
value = value
})
func when_stat(conds: Array) -> void:
opcode.push_back({
command = Commands.WHEN_STAT,
conds = conds
})
func change_music(track: String) -> void:
opcode.push_back({
command = Commands.CHANGE_MUSIC,
track = track
})
func show_blackout() -> void:
opcode.push_back({
command = Commands.SHOW_BLACKOUT
})
func hide_blackout() -> void:
opcode.push_back({
command = Commands.HIDE_BLACKOUT
})
func transition(to: String) -> void:
opcode.push_back({
command = Commands.TRANSITION,
to = to
})
func end(to: String = Events.NONE) -> void:
opcode.push_back({
command = Commands.END,
to = to
})
# * Private Methods:
func _show_dialogue() -> void:
DialogueContainer.show()
State.remember_dialogue_hidden(false)
func _clear_dialogue() -> void:
DialogueLabel.text = ""
State.forget_current_dialogue()
func _add_option(message: String = "") -> Button:
var button = ButtonBase.instance()
button.text = message
button.size_flags_horizontal = 0
button.add_font_override("font", QMo8_24px)
button.connect("pressed", self, "_on_option_pressed", [OptionsContainer.get_child_count()])
OptionsContainer.add_child(button)
return button
func _clear_options() -> void:
for child in OptionsContainer.get_children():
child.queue_free()
func _fade_out() -> void:
fade_state = FADE_VISIBLE
FadePlayer.play("fade_out")
yield(FadePlayer, "animation_finished")
FadePlayer.playback_speed = 1.0
func _fade_in() -> void:
FadePlayer.play("fade_in")
fade_state = FADE_INVISIBLE
if skip_fade:
FadePlayer.playback_speed = 1000.0
yield(FadePlayer, "animation_finished")
FadePlayer.playback_speed = 1.0
skip_fade = false
func _enter(character: String, standing: int, facing: int, emote: String) -> void:
CharacterLayer.add_child(character_lookup[character])
character_lookup[character].standing = standing
character_lookup[character].facing = facing
character_lookup[character].current_emote = emote
State.remember_character(character, standing, facing, emote)
func _move(character: String, standing: int) -> void:
character_lookup[character].standing = standing
var c = character_lookup[character]
State.remember_character(c, c.standing, c.facing, c.current_emote)
func _face(character: String, facing: int) -> void:
character_lookup[character].facing = facing
var c = character_lookup[character]
State.remember_character(c, c.standing, c.facing, c.current_emote)
func _emote(character: String, emote: String) -> void:
character_lookup[character].current_emote = emote
var c = character_lookup[character]
State.remember_character(c.name, c.standing, c.facing, c.current_emote)
func _exit(character: String) -> void:
CharacterLayer.remove_child(character_lookup[character])
State.forget_character(character)
func _hide_dialogue() -> void:
DialogueContainer.hide()
State.remember_dialogue_hidden(true)
func _append_history(history: String) -> void:
State.append_history(history)
func _when_seen(conds: Array) -> void:
for i in range(0, len(conds), 2):
if State.has_seen(conds[i]):
print(conds[i])
execute(conds[i + 1])
return
execute(conds[-1])
func _set_seen(passage: String) -> void:
State.set_seen(passage)
# TODO - Implement flag system for when a sub-sequence has been seen
func _when_flag(_conds: Array) -> void:
pass
func _set_flag(_flag: String) -> void:
pass
# ! This may be useless with how the interpreter works.
func _when(conds: Array) -> void:
for i in range(0, len(conds), 2):
if conds[i]:
execute(conds[i + 1])
return
execute(conds[-1])
func _pick(options: Array) -> void:
for i in range(0, len(options), 2):
_add_option(options[i])
var id = yield(self, "option_pressed")
_hide_dialogue()
execute(options[id * 2 + 1])
func _run(object: Object, method: String, args: Array = []) -> void:
object.callv(method, args)
func _await_run(object: Object, method: String, args: Array = []) -> void:
var co = object.callv(method, args)
if co is GDScriptFunctionState:
yield(co, "completed")
else:
push_warning("The method %s is not a coroutine. Continuing execution of story." % method)
func _await_result(object: Object, sig: String, callback: String, handler: Object = self) -> void:
object.connect(sig, handler, callback, [], Object.CONNECT_ONESHOT)
yield(object, sig)
func _await_signal(object: Object, sig: String) -> void:
yield(object, sig)
func _await_interaction(id: String, callback: String, sig: String = 'interaction_completed', handler: Object = self) -> void:
var backdrop = backdrop_lookup[id]
State.disable_saving()
# Require to work around quirk where GUI nodes inside a view port will eat the input before
# the outer nodes have a chance to process it
SceneViewport.gui_disable_input = false
_set_backdrop(id)
_run(backdrop, 'start_interaction')
yield(_await_result(backdrop, sig, callback, handler), "completed")
State.enable_saving()
SceneViewport.gui_disable_input = true
func _await_minigame(minigame: String, callback: String, handler: Object = self) -> void:
State.connect('minigame_ended', handler, callback, [], CONNECT_ONESHOT)
State.set_current_minigame(minigame)
func _give_prize(options: Array) -> void:
yield(_fade_out(), 'completed')
ItemScreen.show()
for option in options:
ItemScreen.add_item(option)
yield(_fade_in(), 'completed')
var prize = yield(ItemScreen, 'item_selected')
_give_item(prize)
yield(_fade_out(), "completed")
ItemScreen.hide()
func _give_item(name: String) -> void:
State.add_item(name)
func _take_item(id: int) -> void:
State.remove_item(id)
func _goto(passage: String) -> void:
execute(passage)
func _set_backdrop(backdrop: String) -> void:
_clear_backdrop()
_add_backdrop(backdrop)
func _add_backdrop(backdrop: String) -> void:
BackgroundLayer.add_child(backdrop_lookup[backdrop])
State.remember_backdrop(backdrop)
func _remove_backdrop(backdrop: String) -> void:
var parent = backdrop_lookup[backdrop].get_parent()
if parent:
parent.remove_child(backdrop_lookup[backdrop])
else:
push_warning('The backdrop "%s" is not currently used' % backdrop)
State.forget_backdrop(backdrop)
func _clear_backdrop() -> void:
for child in BackgroundLayer.get_children():
BackgroundLayer.remove_child(child)
State.forget_all_backdrops()
func _clear_characters() -> void:
for child in CharacterLayer.get_children():
CharacterLayer.remove_child(child)
State.forget_all_characters()
func _say(string: String, pos: int = -1, rate = 1.0 / 60.0) -> void:
string = string.dedent().strip_edges()
var count = len(string)
var duration = rate * len(string)
State.remember_current_dialogue(string, pos, rate)
_show_dialogue()
match pos:
POS_LEFT:
position_dialog_left()
POS_CENTER:
position_dialog_center()
POS_RIGHT:
position_dialog_right()
POS_TOP:
position_dialog_top()
POS_BOTTOM:
position_dialog_bottom()
DialogueLabel.text = string
DialogueLabel.visible_characters = 0
DialogueShower.interpolate_property(DialogueLabel, "visible_characters", 0, count, duration)
DialogueShower.start()
yield(DialogueShower, "tween_all_completed")
emit_signal("dialogue_shown")
func _respond(message: String) -> void:
_add_option(message)
yield(self, "option_pressed")
_hide_dialogue()
func _next() -> void:
_add_option(">> Next")
yield(self, "option_pressed")
_hide_dialogue()
func _wait(delay: float) -> void:
yield(get_tree().create_timer(delay), 'timeout')
func _change_stat(stat: String, delta: int) -> void:
State.change_stat(stat, delta)
func _set_stat(stat: String, value: int) -> void:
State.set_stat(stat, value)
func _when_stat(conds: Array) -> void:
for i in range(0, len(conds) - (len(conds) % 4), 4):
var stat: String = conds[i]
var cond: String = conds[i + 1]
var value: int = conds[i + 2]
var method: String = conds[i + 3]
var success: bool = false
match cond:
'<':
success = State.get_stat(stat) < value
'>':
success = State.get_stat(stat) > value
'<=':
success = State.get_stat(stat) <= value
'>=':
success = State.get_stat(stat) >= value
'=', '==':
success = State.get_stat(stat) == value
if success:
execute(method)
return
if len(conds) % 4 == 1:
execute(conds[-1])
elif len(conds) % 4 == 0:
push_warning("Condition array is missing default clause.")
else:
push_warning("Condition array contains incomplete entries.")
func _change_music(track: String) -> void:
State.change_music(track)
func _show_blackout() -> void:
Blackout.show()
State.remember_blackout_visible(true)
func _hide_blackout() -> void:
Blackout.hide()
State.remember_blackout_visible(false)
func _transition(to: String) -> void:
yield(_fade_out(), "completed")
_clear_backdrop()
_clear_characters()
_clear_dialogue()
_clear_options()
_hide_dialogue()
_hide_blackout()
State.set_current_event(to)
func _end() -> void:
yield(_fade_out(), "completed")
_clear_backdrop()
_clear_characters()
_clear_dialogue()
_clear_options()
_hide_dialogue()
_hide_blackout()
_change_music(Music.BACKGROUND_THEME)
yield(_fade_in(), "completed")
State.enable_saving()
State.set_current_event(Events.NONE)
func position_dialog_top() -> void:
DialogueContainer.size_flags_horizontal = Control.SIZE_FILL
DialogueContainer.size_flags_vertical = 0
DialogueLabel.rect_min_size = Vector2(650, 0)
func position_dialog_bottom() -> void:
DialogueContainer.size_flags_horizontal = Control.SIZE_FILL
DialogueContainer.size_flags_vertical = 0
DialogueLabel.rect_min_size = Vector2(650, 0)
func position_dialog_left() -> void:
DialogueContainer.size_flags_horizontal = 0
DialogueContainer.size_flags_vertical = Control.SIZE_FILL
DialogueLabel.rect_min_size = Vector2(250, 0)
func position_dialog_center() -> void:
DialogueContainer.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
DialogueContainer.size_flags_vertical = Control.SIZE_FILL
DialogueLabel.rect_min_size = Vector2(250, 0)
func position_dialog_right() -> void:
DialogueContainer.size_flags_horizontal = Control.SIZE_SHRINK_END
DialogueContainer.size_flags_vertical = Control.SIZE_FILL
DialogueLabel.rect_min_size = Vector2(250, 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment