capitalex ha revisionato questo gist . Vai alla revisione
1 file changed, 0 insertions, 0 deletions
00_SimpleState.gd rinominato come 04_SimpleState.gd
File rinominato senza modifiche
capitalex ha revisionato questo gist . Vai alla revisione
1 file changed, 67 insertions
00_SimpleState.gd(file creato)
@@ -0,0 +1,67 @@ | |||
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 |
capitalex ha revisionato questo gist . Vai alla revisione
6 files changed, 0 insertions, 0 deletions
Main.gd rinominato come 00_Main.gd
File rinominato senza modifiche
EventPlayerContainer.gd rinominato come 01_EventPlayerContainer.gd
File rinominato senza modifiche
EventPlayer.gd rinominato come 02_EventPlayer.gd
File rinominato senza modifiche
CharacterHandler.gd rinominato come 03_CharacterHandler.gd
File rinominato senza modifiche
OptionPresenter.gd rinominato come 03_OptionPresenter.gd
File rinominato senza modifiche
Playback.gd rinominato come 03_Playback.gd
File rinominato senza modifiche
capitalex ha revisionato questo gist . Vai alla revisione
1 file changed, 0 insertions, 0 deletions
EventPlayerContainer rinominato come EventPlayerContainer.gd
File rinominato senza modifiche
capitalex ha revisionato questo gist . Vai alla revisione
Nessuna modifica
capitalex ha revisionato questo gist . Vai alla revisione
6 files changed, 572 insertions
CharacterHandler.gd(file creato)
@@ -0,0 +1,104 @@ | |||
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]) |
EventPlayer.gd(file creato)
@@ -0,0 +1,198 @@ | |||
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) |
EventPlayerContainer(file creato)
@@ -0,0 +1,169 @@ | |||
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) |
main.gd rinominato come Main.gd
File rinominato senza modifiche
OptionPresenter.gd(file creato)
@@ -0,0 +1,55 @@ | |||
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) |
Playback.gd(file creato)
@@ -0,0 +1,46 @@ | |||
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() |
capitalex ha revisionato questo gist . Vai alla revisione
1 file changed, 179 insertions
main.gd(file creato)
@@ -0,0 +1,179 @@ | |||
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 |