00_Main.gd
· 5.2 KiB · GDScript3
Brut
Playground
# warning-ignore-all:return_value_discarded
extends HBoxContainer
class_name ChitinousCanrival
const event_player_scene = preload("res://scenes/ui/EventPlayer.tscn")
@onready var MinigameHandler := %MinigameHandler as MinigameHandler
@onready var TravelButtons := %TravelButtons as TravelButtons
@onready var EventPlayerContainer := %EventPlayerContainer as EventPlayerContainer
@onready var InventoryMenu := %InventoryMenu as InventoryMenu
@onready var SettingsMenu := %SettingsMenu as SettingsMenu
@onready var SaveMenu := %SaveMenu as SaveMenu
@onready var ChoicePanel := %ChoicePanel as Choice
@onready var StatusPanel := %StatusPanel as StatusPanel
@onready var Blackout := %BlackoutPanel as BlackoutPanel
var _current_sequence: String = ""
func _ready() -> void:
randomize()
MusicState.change_bg(MusicState.BACKGROUND_THEME)
ExploreState.set_start_time()
ExploreState._set_location(SimpleState.state.explore.location)
TravelButtons.set_button_disabled(SimpleState.state.explore.location)
SaveState.save_loaded.connect(_on_save_loaded)
EventPlayerContainer.minigame_started.connect(_on_minigame_started)
MinigameHandler.minigame_finished.connect(_on_minigame_finished)
StatusPanel.inventory_button_toggled.connect(_on_inventory_button_toggled)
StatusPanel.settings_button_toggled.connect(_on_settings_button_toggled)
StatusPanel.save_button_toggled.connect(_on_save_button_toggled)
InventoryMenu.visibility_changed.connect(_on_menu_visibility_changed)
SaveMenu.visibility_changed.connect(_on_menu_visibility_changed)
SaveMenu.closed.connect(StatusPanel.saving_closed)
SettingsMenu.visibility_changed.connect(_on_menu_visibility_changed)
SettingsMenu.closed.connect(StatusPanel.settings_closed)
TravelButtons.waited.connect(_on_wait_button_pressed)
ChoicePanel.options_shown.connect(_on_options_shown)
ChoicePanel.options_cleared.connect(_on_options_cleared)
ExploreState.trap_triggered.connect(_on_trap_triggered)
ExploreState.event_triggered.connect(_on_event_triggered)
ExploreState.event_trigger_forced.connect(_on_event_trigger_forced)
ExploreState.revisited.connect(_on_revisited)
ExploreState.wandered.connect(_on_wandered)
ExploreState.item_selected.connect(_on_item_selected)
ExploreState.masturbated.connect(_on_masturbated)
if not MemoryState.has_seen("00-intro/00-premise"):
InventoryState.add_trap("intro")
EventPlayerContainer.run("00-intro/00-premise")
if not SimpleState.state.sequence.current_sequence != "None":
EventPlayerContainer.restore_from_state()
await Blackout.fade_in()
func _on_revisited(event: String) -> void:
EventPlayerContainer.run(event)
func _on_wandered(where: String) -> void:
EventPlayerContainer.run("01-location/%s/wander" % where)
func _on_item_selected(what: String) -> void:
StatusPanel.inventory_closed()
EventPlayerContainer.run("items/%s" % what)
func _on_save_loaded(title) -> void:
if not title:
await Blackout.fade_out()
EventPlayerContainer.hard_stop()
ChoicePanel.clear_options()
if SimpleState.state.sequence.current_sequence != "NONE":
EventPlayerContainer.restore_from_state()
else:
EventPlayerContainer.hide()
await Blackout.fade_in()
func _on_minigame_started(minigame: String, initial_state: Dictionary) -> void:
MinigameHandler.play_minigame(minigame, initial_state)
func _on_minigame_finished(result) -> void:
EventPlayerContainer.minigame_finished(result)
func _on_inventory_button_toggled(pressed: bool) -> void:
InventoryMenu.visible = pressed
if pressed:
SettingsMenu.visible = false
StatusPanel.settings_closed()
SaveMenu.visible = false
StatusPanel.saving_closed()
func _on_settings_button_toggled(pressed: bool) -> void:
SettingsMenu.visible = pressed
if pressed:
InventoryMenu.visible = false
StatusPanel.inventory_closed()
SaveMenu.visible = false
StatusPanel.saving_closed()
func _on_save_button_toggled(pressed: bool) -> void:
SaveMenu.visible = pressed
if pressed:
InventoryMenu.visible = false
StatusPanel.inventory_closed()
SettingsMenu.visible = false
StatusPanel.settings_closed()
func _on_menu_visibility_changed() -> void:
EventPlayerContainer.set_input_disabled(any_menu_open())
ChoicePanel.visible = !any_menu_open() and ChoicePanel.active
func _on_wait_button_pressed() -> void:
await Blackout.fade_out()
ExploreState.wait()
await Blackout.fade_in()
func _on_options_shown() -> void:
ChoicePanel.visible = !any_menu_open() and ChoicePanel.active
func _on_options_cleared() -> void:
ChoicePanel.hide()
await get_tree().process_frame
func _on_trap_triggered(_trap_name: String, event: String) -> void:
EventPlayerContainer.run(event)
func _on_event_triggered(event, entry: String = "intro") -> void:
EventPlayerContainer.run(event, entry)
func _on_event_trigger_forced(event, entry: String) -> void:
if event == "NONE":
EventPlayerContainer._on_scene_ended()
ChoicePanel.clear_options()
else:
EventPlayerContainer._on_sequence_changed(event, entry)
func _on_masturbated() -> void:
EventPlayerContainer.run("masturbations/init")
func any_menu_open() -> bool:
return InventoryMenu.visible \
or SettingsMenu.visible \
or SaveMenu.visible
| 1 | # warning-ignore-all:return_value_discarded |
| 2 | extends HBoxContainer |
| 3 | class_name ChitinousCanrival |
| 4 | |
| 5 | const event_player_scene = preload("res://scenes/ui/EventPlayer.tscn") |
| 6 | |
| 7 | @onready var MinigameHandler := %MinigameHandler as MinigameHandler |
| 8 | @onready var TravelButtons := %TravelButtons as TravelButtons |
| 9 | @onready var EventPlayerContainer := %EventPlayerContainer as EventPlayerContainer |
| 10 | @onready var InventoryMenu := %InventoryMenu as InventoryMenu |
| 11 | @onready var SettingsMenu := %SettingsMenu as SettingsMenu |
| 12 | @onready var SaveMenu := %SaveMenu as SaveMenu |
| 13 | @onready var ChoicePanel := %ChoicePanel as Choice |
| 14 | @onready var StatusPanel := %StatusPanel as StatusPanel |
| 15 | @onready var Blackout := %BlackoutPanel as BlackoutPanel |
| 16 | |
| 17 | var _current_sequence: String = "" |
| 18 | |
| 19 | func _ready() -> void: |
| 20 | randomize() |
| 21 | |
| 22 | MusicState.change_bg(MusicState.BACKGROUND_THEME) |
| 23 | |
| 24 | ExploreState.set_start_time() |
| 25 | ExploreState._set_location(SimpleState.state.explore.location) |
| 26 | TravelButtons.set_button_disabled(SimpleState.state.explore.location) |
| 27 | |
| 28 | SaveState.save_loaded.connect(_on_save_loaded) |
| 29 | EventPlayerContainer.minigame_started.connect(_on_minigame_started) |
| 30 | MinigameHandler.minigame_finished.connect(_on_minigame_finished) |
| 31 | |
| 32 | StatusPanel.inventory_button_toggled.connect(_on_inventory_button_toggled) |
| 33 | StatusPanel.settings_button_toggled.connect(_on_settings_button_toggled) |
| 34 | StatusPanel.save_button_toggled.connect(_on_save_button_toggled) |
| 35 | |
| 36 | InventoryMenu.visibility_changed.connect(_on_menu_visibility_changed) |
| 37 | |
| 38 | SaveMenu.visibility_changed.connect(_on_menu_visibility_changed) |
| 39 | SaveMenu.closed.connect(StatusPanel.saving_closed) |
| 40 | |
| 41 | SettingsMenu.visibility_changed.connect(_on_menu_visibility_changed) |
| 42 | SettingsMenu.closed.connect(StatusPanel.settings_closed) |
| 43 | |
| 44 | TravelButtons.waited.connect(_on_wait_button_pressed) |
| 45 | |
| 46 | ChoicePanel.options_shown.connect(_on_options_shown) |
| 47 | ChoicePanel.options_cleared.connect(_on_options_cleared) |
| 48 | |
| 49 | ExploreState.trap_triggered.connect(_on_trap_triggered) |
| 50 | ExploreState.event_triggered.connect(_on_event_triggered) |
| 51 | ExploreState.event_trigger_forced.connect(_on_event_trigger_forced) |
| 52 | ExploreState.revisited.connect(_on_revisited) |
| 53 | ExploreState.wandered.connect(_on_wandered) |
| 54 | ExploreState.item_selected.connect(_on_item_selected) |
| 55 | ExploreState.masturbated.connect(_on_masturbated) |
| 56 | |
| 57 | if not MemoryState.has_seen("00-intro/00-premise"): |
| 58 | InventoryState.add_trap("intro") |
| 59 | EventPlayerContainer.run("00-intro/00-premise") |
| 60 | |
| 61 | if not SimpleState.state.sequence.current_sequence != "None": |
| 62 | EventPlayerContainer.restore_from_state() |
| 63 | |
| 64 | await Blackout.fade_in() |
| 65 | |
| 66 | |
| 67 | func _on_revisited(event: String) -> void: |
| 68 | EventPlayerContainer.run(event) |
| 69 | |
| 70 | |
| 71 | func _on_wandered(where: String) -> void: |
| 72 | EventPlayerContainer.run("01-location/%s/wander" % where) |
| 73 | |
| 74 | |
| 75 | func _on_item_selected(what: String) -> void: |
| 76 | StatusPanel.inventory_closed() |
| 77 | EventPlayerContainer.run("items/%s" % what) |
| 78 | |
| 79 | func _on_save_loaded(title) -> void: |
| 80 | if not title: |
| 81 | await Blackout.fade_out() |
| 82 | |
| 83 | EventPlayerContainer.hard_stop() |
| 84 | ChoicePanel.clear_options() |
| 85 | |
| 86 | if SimpleState.state.sequence.current_sequence != "NONE": |
| 87 | EventPlayerContainer.restore_from_state() |
| 88 | else: |
| 89 | EventPlayerContainer.hide() |
| 90 | |
| 91 | await Blackout.fade_in() |
| 92 | |
| 93 | |
| 94 | func _on_minigame_started(minigame: String, initial_state: Dictionary) -> void: |
| 95 | MinigameHandler.play_minigame(minigame, initial_state) |
| 96 | |
| 97 | |
| 98 | func _on_minigame_finished(result) -> void: |
| 99 | EventPlayerContainer.minigame_finished(result) |
| 100 | |
| 101 | |
| 102 | func _on_inventory_button_toggled(pressed: bool) -> void: |
| 103 | |
| 104 | InventoryMenu.visible = pressed |
| 105 | |
| 106 | if pressed: |
| 107 | SettingsMenu.visible = false |
| 108 | StatusPanel.settings_closed() |
| 109 | |
| 110 | SaveMenu.visible = false |
| 111 | StatusPanel.saving_closed() |
| 112 | |
| 113 | |
| 114 | func _on_settings_button_toggled(pressed: bool) -> void: |
| 115 | SettingsMenu.visible = pressed |
| 116 | |
| 117 | if pressed: |
| 118 | InventoryMenu.visible = false |
| 119 | StatusPanel.inventory_closed() |
| 120 | |
| 121 | SaveMenu.visible = false |
| 122 | StatusPanel.saving_closed() |
| 123 | |
| 124 | |
| 125 | func _on_save_button_toggled(pressed: bool) -> void: |
| 126 | SaveMenu.visible = pressed |
| 127 | |
| 128 | if pressed: |
| 129 | InventoryMenu.visible = false |
| 130 | StatusPanel.inventory_closed() |
| 131 | |
| 132 | SettingsMenu.visible = false |
| 133 | StatusPanel.settings_closed() |
| 134 | |
| 135 | |
| 136 | func _on_menu_visibility_changed() -> void: |
| 137 | EventPlayerContainer.set_input_disabled(any_menu_open()) |
| 138 | ChoicePanel.visible = !any_menu_open() and ChoicePanel.active |
| 139 | |
| 140 | |
| 141 | func _on_wait_button_pressed() -> void: |
| 142 | await Blackout.fade_out() |
| 143 | ExploreState.wait() |
| 144 | await Blackout.fade_in() |
| 145 | |
| 146 | |
| 147 | func _on_options_shown() -> void: |
| 148 | ChoicePanel.visible = !any_menu_open() and ChoicePanel.active |
| 149 | |
| 150 | |
| 151 | func _on_options_cleared() -> void: |
| 152 | ChoicePanel.hide() |
| 153 | await get_tree().process_frame |
| 154 | |
| 155 | |
| 156 | func _on_trap_triggered(_trap_name: String, event: String) -> void: |
| 157 | EventPlayerContainer.run(event) |
| 158 | |
| 159 | |
| 160 | func _on_event_triggered(event, entry: String = "intro") -> void: |
| 161 | EventPlayerContainer.run(event, entry) |
| 162 | |
| 163 | |
| 164 | func _on_event_trigger_forced(event, entry: String) -> void: |
| 165 | if event == "NONE": |
| 166 | EventPlayerContainer._on_scene_ended() |
| 167 | ChoicePanel.clear_options() |
| 168 | else: |
| 169 | EventPlayerContainer._on_sequence_changed(event, entry) |
| 170 | |
| 171 | |
| 172 | func _on_masturbated() -> void: |
| 173 | EventPlayerContainer.run("masturbations/init") |
| 174 | |
| 175 | |
| 176 | func any_menu_open() -> bool: |
| 177 | return InventoryMenu.visible \ |
| 178 | or SettingsMenu.visible \ |
| 179 | or SaveMenu.visible |
| 180 |
01_EventPlayerContainer.gd
· 4.7 KiB · GDScript3
Brut
Playground
extends Control
class_name EventPlayerContainer
signal scene_change_finished()
signal sequence_changed(sequence) # warning-ignore:unused_signal
signal options_shown(options)
signal scene_change_started()
signal minigame_started(minigame, initial_state)
const EventPlayerScene = preload("res://scenes/ui/EventPlayer.tscn")
var allow_fade_skip := false
var _event_player_scene : EventPlayer = null
var _changing_scenes := false
func _ready() -> void:
set_input_disabled(true)
SimpleState.state_changed.connect(_on_state_changed) # warning-ignore:return_value_discarded
func _on_state_changed(_name: String, _state: Dictionary) -> void:
pass
func _input(event) -> void:
var mouse_down = event is InputEventMouseButton and event.is_pressed() and event.button_index == MOUSE_BUTTON_LEFT
var ui_accept = event.is_action_pressed("ui_accept") and not event.is_echo()
if (mouse_down or ui_accept) and allow_fade_skip:
$FadePanel.skip()
func connect_events(scene) -> void:
# Handled Events
scene.fade_in_started.connect(_on_fade_in_started)
scene.fade_out_started.connect(_on_fade_out_started)
scene.scene_ended.connect(_on_scene_ended)
scene.sequence_changed.connect(_on_sequence_changed)
# Bubbled Events
scene.minigame_started.connect(_on_minigame_started)
func add_to_tree(scene : EventPlayer) -> void:
add_child(scene)
move_child(scene, 0)
func run_scene(scene : EventPlayer, sequence : String, entry : String) -> void:
MemoryState.seen_passage(sequence)
scene.run(sequence, entry)
func restore_scene(scene : EventPlayer, sequence : String, entry : String) -> void:
scene.restore(sequence, entry)
func run(sequence: String, entry: String = "intro") -> void:
_event_player_scene = EventPlayerScene.instantiate()
SimpleState.update("sequence", { current_sequence = sequence, current_line_id = entry })
show()
connect_events(_event_player_scene)
add_to_tree(_event_player_scene)
run_scene(_event_player_scene, sequence, entry)
func restore_from_state() -> void:
var sequence = SimpleState.state.sequence.current_sequence
var entry = SimpleState.state.sequence.current_line_id
_event_player_scene = EventPlayerScene.instantiate()
show()
connect_events(_event_player_scene)
add_to_tree(_event_player_scene)
restore_scene(_event_player_scene, sequence, entry)
func minigame_finished(result) -> void:
if is_instance_valid(_event_player_scene):
_event_player_scene.emit_signal("minigame_finished", result)
func _on_fade_out_started() -> void:
allow_fade_skip = true
if not $FadePanel.fade_shown:
await $FadePanel.fade_out()
if is_instance_valid(_event_player_scene):
_event_player_scene.emit_signal("fade_finished")
else:
_on_fade_out_started()
func _on_fade_in_started() -> void:
if $FadePanel.fade_shown:
await $FadePanel.fade_in()
allow_fade_skip = false
if is_instance_valid(_event_player_scene):
_event_player_scene.emit_signal("fade_finished")
func _on_scene_ended() -> void:
if not _changing_scenes:
stop()
# Bubble Up Events
func _on_minigame_started(minigame: String, initial_state: Dictionary) -> void:
emit_signal("minigame_started", minigame, initial_state)
func _on_sequence_changed(scene: String, line: String = "intro") -> void:
emit_signal("scene_change_started")
_changing_scenes = true
if not $FadePanel.fade_shown:
await $FadePanel.fade_out()
if is_instance_valid(_event_player_scene):
if _event_player_scene.get_parent():
_event_player_scene.get_parent().remove_child(_event_player_scene)
_event_player_scene.queue_free()
run(scene, line)
if $FadePanel.fade_shown:
await $FadePanel.fade_in()
_changing_scenes = false
_event_player_scene.emit_signal("change_scene_finished")
emit_signal("scene_change_finished")
func _options_shown(options: Array) -> void:
emit_signal("options_shown", options)
func stop() -> void:
SimpleState.update("sequence", { current_sequence = "NONE"
, current_line_id = ""
, background = []
, dialogue_pos = "left"
, blackout_visible = false
, dialogue_visible = false
, characters = {}
})
await $FadePanel.fade_out()
if is_instance_valid(_event_player_scene):
if _event_player_scene and _event_player_scene.get_parent():
_event_player_scene.get_parent().remove_child(_event_player_scene)
_event_player_scene.queue_free()
await $FadePanel.fade_in()
hide()
func hard_stop() -> void:
if is_instance_valid(_event_player_scene):
if _event_player_scene and _event_player_scene.get_parent():
_event_player_scene.get_parent().remove_child(_event_player_scene)
_event_player_scene.queue_free()
func set_input_disabled(value: bool) -> void:
if is_instance_valid(_event_player_scene):
_event_player_scene.set_input_disabled(value)
| 1 | extends Control |
| 2 | class_name EventPlayerContainer |
| 3 | |
| 4 | signal scene_change_finished() |
| 5 | signal sequence_changed(sequence) # warning-ignore:unused_signal |
| 6 | signal options_shown(options) |
| 7 | signal scene_change_started() |
| 8 | signal minigame_started(minigame, initial_state) |
| 9 | |
| 10 | const EventPlayerScene = preload("res://scenes/ui/EventPlayer.tscn") |
| 11 | |
| 12 | var allow_fade_skip := false |
| 13 | |
| 14 | var _event_player_scene : EventPlayer = null |
| 15 | var _changing_scenes := false |
| 16 | |
| 17 | func _ready() -> void: |
| 18 | set_input_disabled(true) |
| 19 | SimpleState.state_changed.connect(_on_state_changed) # warning-ignore:return_value_discarded |
| 20 | |
| 21 | |
| 22 | func _on_state_changed(_name: String, _state: Dictionary) -> void: |
| 23 | pass |
| 24 | |
| 25 | |
| 26 | func _input(event) -> void: |
| 27 | var mouse_down = event is InputEventMouseButton and event.is_pressed() and event.button_index == MOUSE_BUTTON_LEFT |
| 28 | var ui_accept = event.is_action_pressed("ui_accept") and not event.is_echo() |
| 29 | if (mouse_down or ui_accept) and allow_fade_skip: |
| 30 | $FadePanel.skip() |
| 31 | |
| 32 | |
| 33 | func connect_events(scene) -> void: |
| 34 | # Handled Events |
| 35 | scene.fade_in_started.connect(_on_fade_in_started) |
| 36 | scene.fade_out_started.connect(_on_fade_out_started) |
| 37 | scene.scene_ended.connect(_on_scene_ended) |
| 38 | scene.sequence_changed.connect(_on_sequence_changed) |
| 39 | |
| 40 | # Bubbled Events |
| 41 | scene.minigame_started.connect(_on_minigame_started) |
| 42 | |
| 43 | |
| 44 | func add_to_tree(scene : EventPlayer) -> void: |
| 45 | add_child(scene) |
| 46 | move_child(scene, 0) |
| 47 | |
| 48 | |
| 49 | func run_scene(scene : EventPlayer, sequence : String, entry : String) -> void: |
| 50 | MemoryState.seen_passage(sequence) |
| 51 | scene.run(sequence, entry) |
| 52 | |
| 53 | |
| 54 | func restore_scene(scene : EventPlayer, sequence : String, entry : String) -> void: |
| 55 | scene.restore(sequence, entry) |
| 56 | |
| 57 | |
| 58 | func run(sequence: String, entry: String = "intro") -> void: |
| 59 | _event_player_scene = EventPlayerScene.instantiate() |
| 60 | SimpleState.update("sequence", { current_sequence = sequence, current_line_id = entry }) |
| 61 | |
| 62 | show() |
| 63 | connect_events(_event_player_scene) |
| 64 | add_to_tree(_event_player_scene) |
| 65 | run_scene(_event_player_scene, sequence, entry) |
| 66 | |
| 67 | |
| 68 | func restore_from_state() -> void: |
| 69 | var sequence = SimpleState.state.sequence.current_sequence |
| 70 | var entry = SimpleState.state.sequence.current_line_id |
| 71 | _event_player_scene = EventPlayerScene.instantiate() |
| 72 | |
| 73 | show() |
| 74 | connect_events(_event_player_scene) |
| 75 | add_to_tree(_event_player_scene) |
| 76 | restore_scene(_event_player_scene, sequence, entry) |
| 77 | |
| 78 | |
| 79 | func minigame_finished(result) -> void: |
| 80 | if is_instance_valid(_event_player_scene): |
| 81 | _event_player_scene.emit_signal("minigame_finished", result) |
| 82 | |
| 83 | |
| 84 | func _on_fade_out_started() -> void: |
| 85 | allow_fade_skip = true |
| 86 | if not $FadePanel.fade_shown: |
| 87 | await $FadePanel.fade_out() |
| 88 | |
| 89 | if is_instance_valid(_event_player_scene): |
| 90 | _event_player_scene.emit_signal("fade_finished") |
| 91 | else: |
| 92 | _on_fade_out_started() |
| 93 | |
| 94 | |
| 95 | func _on_fade_in_started() -> void: |
| 96 | if $FadePanel.fade_shown: |
| 97 | await $FadePanel.fade_in() |
| 98 | |
| 99 | |
| 100 | allow_fade_skip = false |
| 101 | if is_instance_valid(_event_player_scene): |
| 102 | _event_player_scene.emit_signal("fade_finished") |
| 103 | |
| 104 | |
| 105 | func _on_scene_ended() -> void: |
| 106 | if not _changing_scenes: |
| 107 | stop() |
| 108 | |
| 109 | |
| 110 | # Bubble Up Events |
| 111 | func _on_minigame_started(minigame: String, initial_state: Dictionary) -> void: |
| 112 | emit_signal("minigame_started", minigame, initial_state) |
| 113 | |
| 114 | |
| 115 | func _on_sequence_changed(scene: String, line: String = "intro") -> void: |
| 116 | emit_signal("scene_change_started") |
| 117 | _changing_scenes = true |
| 118 | |
| 119 | if not $FadePanel.fade_shown: |
| 120 | await $FadePanel.fade_out() |
| 121 | |
| 122 | if is_instance_valid(_event_player_scene): |
| 123 | if _event_player_scene.get_parent(): |
| 124 | _event_player_scene.get_parent().remove_child(_event_player_scene) |
| 125 | _event_player_scene.queue_free() |
| 126 | |
| 127 | run(scene, line) |
| 128 | |
| 129 | if $FadePanel.fade_shown: |
| 130 | await $FadePanel.fade_in() |
| 131 | |
| 132 | _changing_scenes = false |
| 133 | _event_player_scene.emit_signal("change_scene_finished") |
| 134 | emit_signal("scene_change_finished") |
| 135 | |
| 136 | |
| 137 | func _options_shown(options: Array) -> void: |
| 138 | emit_signal("options_shown", options) |
| 139 | |
| 140 | |
| 141 | func stop() -> void: |
| 142 | SimpleState.update("sequence", { current_sequence = "NONE" |
| 143 | , current_line_id = "" |
| 144 | , background = [] |
| 145 | , dialogue_pos = "left" |
| 146 | , blackout_visible = false |
| 147 | , dialogue_visible = false |
| 148 | , characters = {} |
| 149 | }) |
| 150 | await $FadePanel.fade_out() |
| 151 | |
| 152 | if is_instance_valid(_event_player_scene): |
| 153 | if _event_player_scene and _event_player_scene.get_parent(): |
| 154 | _event_player_scene.get_parent().remove_child(_event_player_scene) |
| 155 | _event_player_scene.queue_free() |
| 156 | |
| 157 | await $FadePanel.fade_in() |
| 158 | hide() |
| 159 | |
| 160 | func hard_stop() -> void: |
| 161 | if is_instance_valid(_event_player_scene): |
| 162 | if _event_player_scene and _event_player_scene.get_parent(): |
| 163 | _event_player_scene.get_parent().remove_child(_event_player_scene) |
| 164 | _event_player_scene.queue_free() |
| 165 | |
| 166 | |
| 167 | func set_input_disabled(value: bool) -> void: |
| 168 | if is_instance_valid(_event_player_scene): |
| 169 | _event_player_scene.set_input_disabled(value) |
| 170 |
02_EventPlayer.gd
· 5.0 KiB · GDScript3
Brut
Playground
extends Control
class_name EventPlayer
# Signal
signal fade_in_started()
signal fade_out_started()
signal scene_ended()
# Proxied Signals
signal minigame_started(minigame : String, initial_state : Dictionary)
signal sequence_changed(sequence : String)
# Signals to Yield on
signal fade_finished() # warning-ignore:unused_signal
signal minigame_finished() # warning-ignore:unused_signal
signal change_scene_finished() # warning-ignore:unused_signal
enum NextFade { FADE_OUT, FADE_IN }
var fade_active = false
var next_fade : NextFade = NextFade.FADE_OUT
@onready var playback : Playback = $Playback
@onready var dialogue_presenter = $DialoguePresenter
@onready var background_presenter = $BackgroundPresenter
@onready var character_handler = $CharacterHandler
@onready var blackout_panel = $BlackoutPanel
@onready var dialogue_box = $DialogueBox
@onready var prize_screen = $PrizeScreen
@onready var choice_panel = get_tree().current_scene.get_node("%MainLayout/%ChoicePanel")
func _ready() -> void:
playback.line_changed.connect(_on_line_changed)
playback.dialogue_shown.connect(_on_dialogue_shown)
playback.options_shown.connect(_on_options_shown)
playback.dialogue_cleared.connect(_on_dialogue_cleared)
playback.scene_finished.connect(_on_scene_finished)
choice_panel.option_picked.connect(_on_option_picked)
playback.extra_game_states = [ self
, dialogue_presenter
, background_presenter
, character_handler
, dialogue_box
, prize_screen
]
# Callbacks
func _on_line_changed(line_id: String) -> void:
SimpleState.update("sequence",
{ current_line_id = line_id })
func _on_dialogue_shown(dialogue_line : DialogueLine) -> void:
if get_parent()._changing_scenes:
await self.change_scene_finished
await dialogue_presenter.show_dialogue(dialogue_line)
playback.dialogue_finished.emit()
func _on_options_shown(options: Array[String]) -> void:
if get_parent()._changing_scenes:
await self.change_scene_finished
choice_panel.show_options(options)
func _on_dialogue_cleared() -> void:
dialogue_presenter.clear_dialogue()
func _on_scene_finished() -> void:
emit_signal("scene_ended")
func _on_options_cleared() -> void:
choice_panel.clear_options()
func _on_option_picked(__, line_id) -> void:
playback.emit_signal("options_picked", line_id)
# Public Methods
func run(sequence: String, entry: String) -> void:
playback.run(Events.items[sequence], entry)
func restore(sequence: String, entry: String) -> void:
var dialogue_pos = SimpleState.state.sequence.dialogue_pos
var background = SimpleState.state.sequence.background
var blackout_visible = SimpleState.state.sequence.blackout_visible
var characters = SimpleState.state.sequence.characters
next_fade = SimpleState.state.sequence.next_fade
dialogue_box.call(dialogue_pos)
background_presenter.background(background)
for character in characters:
character_handler.enter(character, characters[character])
choice_panel.clear_options()
blackout(blackout_visible)
playback.run(Events.items[sequence], entry, true)
func goto(sequence: String) -> void:
sequence_changed.emit(sequence)
await change_scene_finished
func visit_random_minigame() -> void:
var seen = MemoryState.get_seen_minigames()
var unseen = ArrayUtil.difference(CarnivalGames.items.keys(), seen)
var key = ArrayUtil.either(unseen)
var sequence_name = to_squence_name(key)
sequence_changed.emit("minigames/%s/init" % sequence_name)
func to_squence_name(key) -> String:
return key \
.capitalize() \
.replace(" ", "-") \
.to_lower()
func exit() -> void:
await fade_out()
func blackout(visibility: bool) -> void:
SimpleState.update("sequence", { blackout_visible = visibility })
blackout_panel.visible = visibility
func swap_background(layers: Array) -> void:
await fade_out()
await get_tree().process_frame
background_presenter.background(layers)
await fade_in()
func unimplemented() -> void:
assert(false, "Unimplemented Scene")
func play_minigame(minigame: String, initial_state: Dictionary = {}) -> void:
minigame_started.emit(minigame, initial_state)
var result = await self.minigame_finished
SimpleState.update_deep("temp", { values = result })
func fade() -> void:
if fade_active: return
fade_active = true
match next_fade:
NextFade.FADE_OUT:
next_fade = NextFade.FADE_IN
await fade_out()
NextFade.FADE_IN:
next_fade = NextFade.FADE_OUT
await fade_in()
SimpleState.update("sequence", { next_fade = next_fade })
fade_active = false
func fade_out() -> void:
fade_out_started.emit()
await self.fade_finished
func fade_in() -> void:
fade_in_started.emit()
await self.fade_finished
func set_input_disabled(value: bool) -> void:
$Background.input_disabled = value
$Background/SubViewport.gui_disable_input = value
func goto_birth_scene() -> void:
var scene = TempState["parasite"].birthing_scene
ExploreState.emit_signal("event_triggered", scene)
func interaction(background: String) -> void:
set_input_disabled(false)
await background_presenter.start_interaction(background)
set_input_disabled(true)
| 1 | extends Control |
| 2 | class_name EventPlayer |
| 3 | |
| 4 | # Signal |
| 5 | signal fade_in_started() |
| 6 | signal fade_out_started() |
| 7 | signal scene_ended() |
| 8 | |
| 9 | # Proxied Signals |
| 10 | signal minigame_started(minigame : String, initial_state : Dictionary) |
| 11 | signal sequence_changed(sequence : String) |
| 12 | |
| 13 | # Signals to Yield on |
| 14 | signal fade_finished() # warning-ignore:unused_signal |
| 15 | signal minigame_finished() # warning-ignore:unused_signal |
| 16 | signal change_scene_finished() # warning-ignore:unused_signal |
| 17 | |
| 18 | enum NextFade { FADE_OUT, FADE_IN } |
| 19 | var fade_active = false |
| 20 | var next_fade : NextFade = NextFade.FADE_OUT |
| 21 | |
| 22 | @onready var playback : Playback = $Playback |
| 23 | @onready var dialogue_presenter = $DialoguePresenter |
| 24 | @onready var background_presenter = $BackgroundPresenter |
| 25 | @onready var character_handler = $CharacterHandler |
| 26 | @onready var blackout_panel = $BlackoutPanel |
| 27 | @onready var dialogue_box = $DialogueBox |
| 28 | @onready var prize_screen = $PrizeScreen |
| 29 | @onready var choice_panel = get_tree().current_scene.get_node("%MainLayout/%ChoicePanel") |
| 30 | |
| 31 | func _ready() -> void: |
| 32 | playback.line_changed.connect(_on_line_changed) |
| 33 | playback.dialogue_shown.connect(_on_dialogue_shown) |
| 34 | playback.options_shown.connect(_on_options_shown) |
| 35 | playback.dialogue_cleared.connect(_on_dialogue_cleared) |
| 36 | playback.scene_finished.connect(_on_scene_finished) |
| 37 | choice_panel.option_picked.connect(_on_option_picked) |
| 38 | |
| 39 | playback.extra_game_states = [ self |
| 40 | , dialogue_presenter |
| 41 | , background_presenter |
| 42 | , character_handler |
| 43 | , dialogue_box |
| 44 | , prize_screen |
| 45 | ] |
| 46 | |
| 47 | |
| 48 | # Callbacks |
| 49 | func _on_line_changed(line_id: String) -> void: |
| 50 | SimpleState.update("sequence", |
| 51 | { current_line_id = line_id }) |
| 52 | |
| 53 | |
| 54 | func _on_dialogue_shown(dialogue_line : DialogueLine) -> void: |
| 55 | if get_parent()._changing_scenes: |
| 56 | await self.change_scene_finished |
| 57 | |
| 58 | await dialogue_presenter.show_dialogue(dialogue_line) |
| 59 | playback.dialogue_finished.emit() |
| 60 | |
| 61 | func _on_options_shown(options: Array[String]) -> void: |
| 62 | if get_parent()._changing_scenes: |
| 63 | await self.change_scene_finished |
| 64 | |
| 65 | choice_panel.show_options(options) |
| 66 | |
| 67 | |
| 68 | func _on_dialogue_cleared() -> void: |
| 69 | dialogue_presenter.clear_dialogue() |
| 70 | |
| 71 | |
| 72 | func _on_scene_finished() -> void: |
| 73 | emit_signal("scene_ended") |
| 74 | |
| 75 | |
| 76 | func _on_options_cleared() -> void: |
| 77 | choice_panel.clear_options() |
| 78 | |
| 79 | |
| 80 | func _on_option_picked(__, line_id) -> void: |
| 81 | playback.emit_signal("options_picked", line_id) |
| 82 | |
| 83 | |
| 84 | # Public Methods |
| 85 | func run(sequence: String, entry: String) -> void: |
| 86 | playback.run(Events.items[sequence], entry) |
| 87 | |
| 88 | |
| 89 | func restore(sequence: String, entry: String) -> void: |
| 90 | var dialogue_pos = SimpleState.state.sequence.dialogue_pos |
| 91 | var background = SimpleState.state.sequence.background |
| 92 | var blackout_visible = SimpleState.state.sequence.blackout_visible |
| 93 | var characters = SimpleState.state.sequence.characters |
| 94 | |
| 95 | next_fade = SimpleState.state.sequence.next_fade |
| 96 | |
| 97 | dialogue_box.call(dialogue_pos) |
| 98 | background_presenter.background(background) |
| 99 | |
| 100 | for character in characters: |
| 101 | character_handler.enter(character, characters[character]) |
| 102 | |
| 103 | choice_panel.clear_options() |
| 104 | blackout(blackout_visible) |
| 105 | playback.run(Events.items[sequence], entry, true) |
| 106 | |
| 107 | |
| 108 | func goto(sequence: String) -> void: |
| 109 | sequence_changed.emit(sequence) |
| 110 | await change_scene_finished |
| 111 | |
| 112 | |
| 113 | func visit_random_minigame() -> void: |
| 114 | var seen = MemoryState.get_seen_minigames() |
| 115 | var unseen = ArrayUtil.difference(CarnivalGames.items.keys(), seen) |
| 116 | var key = ArrayUtil.either(unseen) |
| 117 | var sequence_name = to_squence_name(key) |
| 118 | |
| 119 | sequence_changed.emit("minigames/%s/init" % sequence_name) |
| 120 | |
| 121 | |
| 122 | func to_squence_name(key) -> String: |
| 123 | return key \ |
| 124 | .capitalize() \ |
| 125 | .replace(" ", "-") \ |
| 126 | .to_lower() |
| 127 | |
| 128 | |
| 129 | func exit() -> void: |
| 130 | await fade_out() |
| 131 | |
| 132 | |
| 133 | func blackout(visibility: bool) -> void: |
| 134 | SimpleState.update("sequence", { blackout_visible = visibility }) |
| 135 | blackout_panel.visible = visibility |
| 136 | |
| 137 | |
| 138 | func swap_background(layers: Array) -> void: |
| 139 | await fade_out() |
| 140 | await get_tree().process_frame |
| 141 | background_presenter.background(layers) |
| 142 | await fade_in() |
| 143 | |
| 144 | |
| 145 | func unimplemented() -> void: |
| 146 | assert(false, "Unimplemented Scene") |
| 147 | |
| 148 | |
| 149 | func play_minigame(minigame: String, initial_state: Dictionary = {}) -> void: |
| 150 | minigame_started.emit(minigame, initial_state) |
| 151 | var result = await self.minigame_finished |
| 152 | SimpleState.update_deep("temp", { values = result }) |
| 153 | |
| 154 | |
| 155 | |
| 156 | func fade() -> void: |
| 157 | if fade_active: return |
| 158 | |
| 159 | fade_active = true |
| 160 | |
| 161 | match next_fade: |
| 162 | NextFade.FADE_OUT: |
| 163 | next_fade = NextFade.FADE_IN |
| 164 | await fade_out() |
| 165 | |
| 166 | NextFade.FADE_IN: |
| 167 | next_fade = NextFade.FADE_OUT |
| 168 | await fade_in() |
| 169 | |
| 170 | SimpleState.update("sequence", { next_fade = next_fade }) |
| 171 | fade_active = false |
| 172 | |
| 173 | |
| 174 | |
| 175 | func fade_out() -> void: |
| 176 | fade_out_started.emit() |
| 177 | await self.fade_finished |
| 178 | |
| 179 | |
| 180 | func fade_in() -> void: |
| 181 | fade_in_started.emit() |
| 182 | await self.fade_finished |
| 183 | |
| 184 | |
| 185 | func set_input_disabled(value: bool) -> void: |
| 186 | $Background.input_disabled = value |
| 187 | $Background/SubViewport.gui_disable_input = value |
| 188 | |
| 189 | |
| 190 | func goto_birth_scene() -> void: |
| 191 | var scene = TempState["parasite"].birthing_scene |
| 192 | ExploreState.emit_signal("event_triggered", scene) |
| 193 | |
| 194 | |
| 195 | func interaction(background: String) -> void: |
| 196 | set_input_disabled(false) |
| 197 | await background_presenter.start_interaction(background) |
| 198 | set_input_disabled(true) |
| 199 |
03_CharacterHandler.gd
· 3.1 KiB · GDScript3
Brut
Playground
extends Node
@export var character_layer_path : NodePath
@export var msg_listener_name = "character_handler"
@onready var character_layer: CanvasLayer = get_node(character_layer_path)
var _characters = {}
var _last_character := ""
func enter(who: String, modifiers: Dictionary = {}) -> void:
if modifiers.has("facing") : match modifiers.facing:
"left" : modifiers.facing = Character.FACING_LEFT
"right" : modifiers.facing = Character.FACING_RIGHT
else:
modifiers.facing = Character.FACING_RIGHT
if modifiers.has("standing") : match modifiers.standing:
"left" : modifiers.standing = Character.STANDING_LEFT
"center": modifiers.standing = Character.STANDING_CENTER
"right" : modifiers.standing = Character.STANDING_RIGHT
else:
modifiers.standing = Character.STANDING_LEFT
if not modifiers.has("current_emote"): modifiers.current_emote = "default"
if not who in _characters:
_characters[who] = Characters.items[who].instantiate()
character_layer.add_child(_characters[who])
for modifier in modifiers:
_characters[who][modifier] = modifiers[modifier]
_last_character = who
SimpleState.update_deep("sequence",
{ characters = { who: modifiers } }
)
func face(face: String, character: String = _last_character) -> void:
assert(face in ["left", "right"]
, "Invalid position %s. Must be 'left' or 'right" % face)
SimpleState.update_deep("sequence",
{ characters = { character: { facing = face } } }
)
if character != _last_character: _last_character = character
var facing: int = Character.STANDING_LEFT
match face:
"left" : facing = Character.FACING_LEFT
"right" : facing = Character.FACING_RIGHT
update(character, "facing", facing)
func stand(stand: String, character: String = _last_character) -> void:
assert(stand in ["left", "center", "right"]
, "Invalid position %s. Must be 'left' or 'center' or 'right" % stand)
SimpleState.update_deep("sequence",
{ characters = { character: { standing = stand } } }
)
if character != _last_character: _last_character = character
var standing: int = Character.STANDING_LEFT
match stand:
"left" : standing = Character.STANDING_LEFT
"center": standing = Character.STANDING_CENTER
"right" : standing = Character.STANDING_RIGHT
update(character, "standing", standing)
func emote(emote: String, character: String = _last_character) -> void:
SimpleState.update_deep("sequence",
{ characters = { character: { current_emote = emote } } }
)
if character != _last_character: _last_character = character
update(character, "current_emote", emote)
func update(who: String, what: String, with) -> void:
_characters[who][what] = with
_last_character = who
func leave(who: String) -> void:
var characters: Dictionary = SimpleState.state.sequence.characters.duplicate()
characters.erase(who) # warning-ignore:return_value_discarded
SimpleState.update("sequence",
{ characters = characters }
)
if who in _characters:
character_layer.remove_child(_characters[who])
_characters[who].queue_free()
_characters.erase(who)
func everyone_leave() -> void:
for who in _characters:
character_layer.remove_child(_characters[who])
| 1 | extends Node |
| 2 | |
| 3 | @export var character_layer_path : NodePath |
| 4 | @export var msg_listener_name = "character_handler" |
| 5 | |
| 6 | @onready var character_layer: CanvasLayer = get_node(character_layer_path) |
| 7 | |
| 8 | var _characters = {} |
| 9 | var _last_character := "" |
| 10 | |
| 11 | func enter(who: String, modifiers: Dictionary = {}) -> void: |
| 12 | if modifiers.has("facing") : match modifiers.facing: |
| 13 | "left" : modifiers.facing = Character.FACING_LEFT |
| 14 | "right" : modifiers.facing = Character.FACING_RIGHT |
| 15 | else: |
| 16 | modifiers.facing = Character.FACING_RIGHT |
| 17 | |
| 18 | if modifiers.has("standing") : match modifiers.standing: |
| 19 | "left" : modifiers.standing = Character.STANDING_LEFT |
| 20 | "center": modifiers.standing = Character.STANDING_CENTER |
| 21 | "right" : modifiers.standing = Character.STANDING_RIGHT |
| 22 | else: |
| 23 | modifiers.standing = Character.STANDING_LEFT |
| 24 | |
| 25 | if not modifiers.has("current_emote"): modifiers.current_emote = "default" |
| 26 | |
| 27 | if not who in _characters: |
| 28 | _characters[who] = Characters.items[who].instantiate() |
| 29 | character_layer.add_child(_characters[who]) |
| 30 | |
| 31 | |
| 32 | for modifier in modifiers: |
| 33 | _characters[who][modifier] = modifiers[modifier] |
| 34 | |
| 35 | _last_character = who |
| 36 | |
| 37 | SimpleState.update_deep("sequence", |
| 38 | { characters = { who: modifiers } } |
| 39 | ) |
| 40 | |
| 41 | |
| 42 | func face(face: String, character: String = _last_character) -> void: |
| 43 | assert(face in ["left", "right"] |
| 44 | , "Invalid position %s. Must be 'left' or 'right" % face) |
| 45 | SimpleState.update_deep("sequence", |
| 46 | { characters = { character: { facing = face } } } |
| 47 | ) |
| 48 | if character != _last_character: _last_character = character |
| 49 | |
| 50 | var facing: int = Character.STANDING_LEFT |
| 51 | match face: |
| 52 | "left" : facing = Character.FACING_LEFT |
| 53 | "right" : facing = Character.FACING_RIGHT |
| 54 | |
| 55 | update(character, "facing", facing) |
| 56 | |
| 57 | |
| 58 | func stand(stand: String, character: String = _last_character) -> void: |
| 59 | assert(stand in ["left", "center", "right"] |
| 60 | , "Invalid position %s. Must be 'left' or 'center' or 'right" % stand) |
| 61 | |
| 62 | SimpleState.update_deep("sequence", |
| 63 | { characters = { character: { standing = stand } } } |
| 64 | ) |
| 65 | if character != _last_character: _last_character = character |
| 66 | |
| 67 | var standing: int = Character.STANDING_LEFT |
| 68 | match stand: |
| 69 | "left" : standing = Character.STANDING_LEFT |
| 70 | "center": standing = Character.STANDING_CENTER |
| 71 | "right" : standing = Character.STANDING_RIGHT |
| 72 | |
| 73 | update(character, "standing", standing) |
| 74 | |
| 75 | |
| 76 | func emote(emote: String, character: String = _last_character) -> void: |
| 77 | SimpleState.update_deep("sequence", |
| 78 | { characters = { character: { current_emote = emote } } } |
| 79 | ) |
| 80 | if character != _last_character: _last_character = character |
| 81 | |
| 82 | update(character, "current_emote", emote) |
| 83 | |
| 84 | |
| 85 | func update(who: String, what: String, with) -> void: |
| 86 | _characters[who][what] = with |
| 87 | _last_character = who |
| 88 | |
| 89 | func leave(who: String) -> void: |
| 90 | var characters: Dictionary = SimpleState.state.sequence.characters.duplicate() |
| 91 | characters.erase(who) # warning-ignore:return_value_discarded |
| 92 | SimpleState.update("sequence", |
| 93 | { characters = characters } |
| 94 | ) |
| 95 | |
| 96 | if who in _characters: |
| 97 | character_layer.remove_child(_characters[who]) |
| 98 | _characters[who].queue_free() |
| 99 | _characters.erase(who) |
| 100 | |
| 101 | |
| 102 | func everyone_leave() -> void: |
| 103 | for who in _characters: |
| 104 | character_layer.remove_child(_characters[who]) |
| 105 |
03_OptionPresenter.gd
· 1.5 KiB · GDScript3
Brut
Playground
extends Node
class_name Choice
const ButtonBase = preload("res://scenes/ui/misc/ButtonBase.tscn")
signal options_shown()
signal options_cleared()
signal option_picked(index, line_id)
@export var option_path : NodePath
@export var msg_listener_name = "option_presenter"
var active := false
@onready var options: VBoxContainer = get_node(option_path)
func show_options(option_list: Array) -> void:
assert(len(option_list) % 2 == 0, "Options must be multiples of 2")
var count = min(6, len(option_list))
var buttons = []
for i in range(0, count, 2):
buttons.append(_add_option(option_list[i], option_list[i + 1]))
(buttons[0] as Button).grab_focus()
for i in range(1, len(buttons)):
var top: Button = buttons[i - 1]
var bottom: Button = buttons[i]
bottom.focus_neighbor_top = top.get_path()
top.focus_neighbor_bottom = bottom.get_path()
active = true
emit_signal("options_shown")
func clear_options() -> void:
for child in options.get_children():
options.remove_child(child)
child.queue_free()
active = false
emit_signal("options_cleared")
func _add_option(text: String, line_id: String) -> Button:
var button = ButtonBase.instantiate()
button.focus_mode = Control.FOCUS_ALL
button.text = text
button.connect("pressed", Callable(self, "_on_button_pressed").bind(options.get_child_count(), line_id))
options.add_child(button)
return button
func _on_button_pressed(index: int, line: String) -> void:
clear_options()
emit_signal("option_picked", index, line)
| 1 | extends Node |
| 2 | class_name Choice |
| 3 | const ButtonBase = preload("res://scenes/ui/misc/ButtonBase.tscn") |
| 4 | |
| 5 | signal options_shown() |
| 6 | signal options_cleared() |
| 7 | signal option_picked(index, line_id) |
| 8 | |
| 9 | @export var option_path : NodePath |
| 10 | @export var msg_listener_name = "option_presenter" |
| 11 | |
| 12 | var active := false |
| 13 | |
| 14 | @onready var options: VBoxContainer = get_node(option_path) |
| 15 | |
| 16 | |
| 17 | func show_options(option_list: Array) -> void: |
| 18 | assert(len(option_list) % 2 == 0, "Options must be multiples of 2") |
| 19 | |
| 20 | var count = min(6, len(option_list)) |
| 21 | var buttons = [] |
| 22 | for i in range(0, count, 2): |
| 23 | buttons.append(_add_option(option_list[i], option_list[i + 1])) |
| 24 | |
| 25 | (buttons[0] as Button).grab_focus() |
| 26 | for i in range(1, len(buttons)): |
| 27 | var top: Button = buttons[i - 1] |
| 28 | var bottom: Button = buttons[i] |
| 29 | bottom.focus_neighbor_top = top.get_path() |
| 30 | top.focus_neighbor_bottom = bottom.get_path() |
| 31 | |
| 32 | active = true |
| 33 | emit_signal("options_shown") |
| 34 | |
| 35 | |
| 36 | func clear_options() -> void: |
| 37 | for child in options.get_children(): |
| 38 | options.remove_child(child) |
| 39 | child.queue_free() |
| 40 | |
| 41 | active = false |
| 42 | emit_signal("options_cleared") |
| 43 | |
| 44 | |
| 45 | func _add_option(text: String, line_id: String) -> Button: |
| 46 | var button = ButtonBase.instantiate() |
| 47 | button.focus_mode = Control.FOCUS_ALL |
| 48 | button.text = text |
| 49 | button.connect("pressed", Callable(self, "_on_button_pressed").bind(options.get_child_count(), line_id)) |
| 50 | options.add_child(button) |
| 51 | return button |
| 52 | |
| 53 | func _on_button_pressed(index: int, line: String) -> void: |
| 54 | clear_options() |
| 55 | emit_signal("option_picked", index, line) |
| 56 |
03_Playback.gd
· 1.3 KiB · GDScript3
Brut
Playground
extends Node
class_name Playback
signal line_changed(line : String)
signal dialogue_shown(dialogue : DialogueLine)
signal options_shown(options : Array[String])
signal dialogue_cleared
signal scene_finished
signal options_picked(line_id : String)
signal dialogue_finished # warning-ignore:unused_signal
var dialogue_line : DialogueLine
var extra_game_states : Array
func run(script : DialogueResource, entry: String = "intro", _restore : bool = false) -> void:
dialogue_line = await DialogueManager.get_next_dialogue_line(script, entry, extra_game_states)
line_changed.emit(entry)
while dialogue_line:
var next_id = dialogue_line.next_id
if not dialogue_line.text.is_empty():
dialogue_shown.emit(dialogue_line)
await self.dialogue_finished
if len(dialogue_line.responses) > 0:
var options : Array[String] = []
for response in dialogue_line.responses:
options.append(response.text)
options.append(response.next_id)
options_shown.emit(options)
next_id = await self.options_picked
else:
var default : Array[String] = [">> Next", ""]
options_shown.emit(default)
await self.options_picked
dialogue_cleared.emit()
line_changed.emit(next_id)
dialogue_line = await DialogueManager.get_next_dialogue_line(script, next_id, extra_game_states)
scene_finished.emit()
| 1 | extends Node |
| 2 | class_name Playback |
| 3 | |
| 4 | signal line_changed(line : String) |
| 5 | signal dialogue_shown(dialogue : DialogueLine) |
| 6 | signal options_shown(options : Array[String]) |
| 7 | signal dialogue_cleared |
| 8 | signal scene_finished |
| 9 | |
| 10 | signal options_picked(line_id : String) |
| 11 | signal dialogue_finished # warning-ignore:unused_signal |
| 12 | |
| 13 | var dialogue_line : DialogueLine |
| 14 | var extra_game_states : Array |
| 15 | |
| 16 | func run(script : DialogueResource, entry: String = "intro", _restore : bool = false) -> void: |
| 17 | dialogue_line = await DialogueManager.get_next_dialogue_line(script, entry, extra_game_states) |
| 18 | |
| 19 | line_changed.emit(entry) |
| 20 | while dialogue_line: |
| 21 | var next_id = dialogue_line.next_id |
| 22 | |
| 23 | if not dialogue_line.text.is_empty(): |
| 24 | dialogue_shown.emit(dialogue_line) |
| 25 | await self.dialogue_finished |
| 26 | |
| 27 | if len(dialogue_line.responses) > 0: |
| 28 | var options : Array[String] = [] |
| 29 | |
| 30 | for response in dialogue_line.responses: |
| 31 | options.append(response.text) |
| 32 | options.append(response.next_id) |
| 33 | |
| 34 | options_shown.emit(options) |
| 35 | next_id = await self.options_picked |
| 36 | |
| 37 | else: |
| 38 | var default : Array[String] = [">> Next", ""] |
| 39 | options_shown.emit(default) |
| 40 | await self.options_picked |
| 41 | |
| 42 | dialogue_cleared.emit() |
| 43 | line_changed.emit(next_id) |
| 44 | dialogue_line = await DialogueManager.get_next_dialogue_line(script, next_id, extra_game_states) |
| 45 | |
| 46 | scene_finished.emit() |
| 47 |
04_SimpleState.gd
· 1.7 KiB · GDScript3
Brut
Playground
extends Node
class_name _SimpleState
signal state_changed(name, state)
var state := { }
func register(state_name: String, inital_state: Dictionary = {}) -> void:
state[state_name] = inital_state
func replace(state_name: String, new_state: Dictionary) -> void:
state[state_name] = new_state.duplicate(true)
emit_signal("state_changed", state_name, state)
func update(state_name: String, new_state: Dictionary) -> void:
state[state_name] = _SimpleState.merge(get_state(state_name), new_state)
emit_signal("state_changed", state_name, state)
func update_deep(state_name: String, new_state: Dictionary) -> void:
state[state_name] = _SimpleState.merge_deep(get_state(state_name), new_state)
emit_signal("state_changed", state_name, state)
func update_mut(state_name: String, new_state: Dictionary) -> void:
_SimpleState.copy_to(state[state_name], new_state)
emit_signal("state_changed")
func _on_update_state(data: Dictionary) -> void:
update(data.state_name, data.state)
func get_state(state_name: String) -> Dictionary:
return state[state_name].duplicate()
static func copy_to(a: Dictionary, b: Dictionary) -> void:
for key in b:
a[key] = b[key]
static func copy_to_deep(a: Dictionary, b: Dictionary) -> void:
for k in b:
if process_recursively(a, b, k):
copy_to_deep(a[k], b[k])
else:
a[k] = b[k]
static func process_recursively(a, b, k) -> bool:
return a.has(k) and a[k] is Dictionary and b[k] is Dictionary
static func merge(a: Dictionary, b: Dictionary) -> Dictionary:
var c := a.duplicate(true)
copy_to(c, b)
return c
static func merge_deep(a: Dictionary, b: Dictionary) -> Dictionary:
var c := a.duplicate(true)
copy_to_deep(c, b)
return c
| 1 | extends Node |
| 2 | class_name _SimpleState |
| 3 | |
| 4 | signal state_changed(name, state) |
| 5 | |
| 6 | var state := { } |
| 7 | |
| 8 | |
| 9 | func register(state_name: String, inital_state: Dictionary = {}) -> void: |
| 10 | state[state_name] = inital_state |
| 11 | |
| 12 | |
| 13 | func replace(state_name: String, new_state: Dictionary) -> void: |
| 14 | state[state_name] = new_state.duplicate(true) |
| 15 | emit_signal("state_changed", state_name, state) |
| 16 | |
| 17 | |
| 18 | func update(state_name: String, new_state: Dictionary) -> void: |
| 19 | state[state_name] = _SimpleState.merge(get_state(state_name), new_state) |
| 20 | emit_signal("state_changed", state_name, state) |
| 21 | |
| 22 | |
| 23 | func update_deep(state_name: String, new_state: Dictionary) -> void: |
| 24 | state[state_name] = _SimpleState.merge_deep(get_state(state_name), new_state) |
| 25 | emit_signal("state_changed", state_name, state) |
| 26 | |
| 27 | |
| 28 | func update_mut(state_name: String, new_state: Dictionary) -> void: |
| 29 | _SimpleState.copy_to(state[state_name], new_state) |
| 30 | emit_signal("state_changed") |
| 31 | |
| 32 | |
| 33 | func _on_update_state(data: Dictionary) -> void: |
| 34 | update(data.state_name, data.state) |
| 35 | |
| 36 | |
| 37 | func get_state(state_name: String) -> Dictionary: |
| 38 | return state[state_name].duplicate() |
| 39 | |
| 40 | |
| 41 | static func copy_to(a: Dictionary, b: Dictionary) -> void: |
| 42 | for key in b: |
| 43 | a[key] = b[key] |
| 44 | |
| 45 | |
| 46 | |
| 47 | static func copy_to_deep(a: Dictionary, b: Dictionary) -> void: |
| 48 | for k in b: |
| 49 | if process_recursively(a, b, k): |
| 50 | copy_to_deep(a[k], b[k]) |
| 51 | else: |
| 52 | a[k] = b[k] |
| 53 | |
| 54 | |
| 55 | static func process_recursively(a, b, k) -> bool: |
| 56 | return a.has(k) and a[k] is Dictionary and b[k] is Dictionary |
| 57 | |
| 58 | static func merge(a: Dictionary, b: Dictionary) -> Dictionary: |
| 59 | var c := a.duplicate(true) |
| 60 | copy_to(c, b) |
| 61 | return c |
| 62 | |
| 63 | |
| 64 | static func merge_deep(a: Dictionary, b: Dictionary) -> Dictionary: |
| 65 | var c := a.duplicate(true) |
| 66 | copy_to_deep(c, b) |
| 67 | return c |
| 68 |