Compare commits

..

89 Commits

Author SHA1 Message Date
betalars b752779526 importing and syncing german voicelines 2026-01-26 17:38:00 +01:00
tiger tiger tiger c603b2247b fix: rebake lights, optimize perf 2026-01-24 17:11:05 +01:00
tiger tiger tiger 791ba9946d fix: trains left invisible 2026-01-24 17:06:58 +01:00
tiger tiger tiger 7bd81643cc fix: rebake lights, optimize perf 2026-01-24 17:03:00 +01:00
tiger tiger tiger 6e67e083f8 fix: crash 2026-01-24 14:16:46 +01:00
tiger tiger tiger 6f2c278bfa fix: subways couldn't stop at endstation and would travel into limbo 2026-01-24 14:12:31 +01:00
tiger tiger tiger 2ceb9216e0 feat: working on train labels 2026-01-24 13:59:14 +01:00
tiger tiger tiger 2e473e4b4e feat: working on subway labeling and coloring system 2026-01-24 13:18:36 +01:00
tiger tiger tiger 6e9bd9b790 fix: voluntary room starting pitch was still overridden 2026-01-24 11:07:47 +01:00
tiger tiger tiger e813129cbe fix: card uniqueness 2026-01-24 11:01:49 +01:00
tiger tiger tiger dc9a06e375 fix: player animation track path fix 2026-01-24 10:57:55 +01:00
tiger tiger tiger 1dca96614e fix: player animation tracks no longer cut them down by 1 head's size 2026-01-24 10:50:38 +01:00
tiger tiger tiger 9fae245381 tweak: improved log message 2026-01-24 10:19:00 +01:00
tiger tiger tiger fd5ac294b3 test: reduced some normal map resolutions 2026-01-24 10:17:28 +01:00
tiger tiger tiger c645a39eba fix: reduced voxel GI resolution in youth room to restore light range 2026-01-24 10:14:20 +01:00
tiger tiger tiger b555ffaf46 tweak: added a (missing story caption) default for missing story captions. 2026-01-24 10:08:51 +01:00
tiger tiger tiger 5b1a989f66 fix: wrong interpolation method... 2026-01-23 17:38:32 +01:00
tiger tiger tiger fc3ad3a555 feat: back button maybe standard bottom right? 2026-01-23 16:31:14 +01:00
tiger tiger tiger f8f50a0755 feat: board can now be left with the mouse :D 2026-01-23 16:25:28 +01:00
tiger tiger tiger a1766d5c3c fix: wrong memento action was hooked up 2026-01-23 16:08:11 +01:00
tiger tiger tiger d78cece129 fix: had corrupted a translation key by removing punctuation 2026-01-23 16:05:46 +01:00
tiger tiger tiger a07ec30716 feat: game instruction shown in youth room for as long as no memento has been hovered and the room is not solved 2026-01-23 16:05:09 +01:00
tiger tiger tiger 34872b6b12 fix: removed custom positioning of interactables in youth room 2026-01-23 15:41:39 +01:00
tiger tiger tiger f6df5131dd fix: icons now refresh when icons change. 2026-01-23 15:38:21 +01:00
tiger tiger tiger 83a8973e6b feat: first prompts implemented, various small fixed 2026-01-23 15:30:58 +01:00
tiger tiger tiger 46a79eae61 feat: first basic prompt 2026-01-23 15:23:53 +01:00
tiger tiger tiger 86af2e812a feat: prompter is now an autoload 2026-01-23 15:05:24 +01:00
tiger tiger tiger a49325eb37 feat: can now add things to prompter and it can perform things. 2026-01-23 14:47:10 +01:00
tiger tiger tiger 6b9a338a20 fix: tool scripts were causing havoc on inherited scene editing§ 2026-01-23 14:12:12 +01:00
tiger tiger tiger f9655a47e6 feat: basic prompt button, needs work 2026-01-23 13:39:47 +01:00
tiger tiger tiger 1d9a264324 feat: started working on prompter class. feat: curtain now hides itself entirely in debug boot. change: skip action is now called scene_skip 2026-01-23 11:30:42 +01:00
tiger tiger tiger 14453c12b9 fix: no double escape press / settings menu doesnt steal focus 2026-01-22 20:29:22 +01:00
tiger tiger tiger 0de7f96064 fix: can now leave canvas (still bug needs double ESC) 2026-01-22 19:51:39 +01:00
tiger tiger tiger c0f3bd40a9 fix: can now leave canvas (still bug needs double ESC) 2026-01-22 19:42:28 +01:00
tiger tiger tiger 92879b6bbf feat: added scroll keys and better scrolling 2026-01-22 19:31:52 +01:00
tiger tiger tiger 53fd4a7501 fix: scrolling of stories. 2026-01-22 19:09:46 +01:00
tiger tiger tiger 54569c7adc fix: game never set state PLAY 2026-01-22 18:46:28 +01:00
tiger tiger tiger b57aa76e23 fix: Pause Menu now halts the app state and restores it, and ensures savegame 2026-01-22 18:41:44 +01:00
tiger tiger tiger d58225f21b fix: Pause Menu works. 2026-01-22 18:36:36 +01:00
tiger tiger tiger 03f427b76a fix: cards now properly talk to the right handler. 2026-01-22 17:58:56 +01:00
tiger tiger tiger 9990a80845 refactor: some events turned into gui_input 2026-01-22 17:42:56 +01:00
tiger tiger tiger 69cec724f5 fix: reduce debug spam 2026-01-22 17:05:27 +01:00
tiger tiger tiger 6c9bbe871d fix: reduce debug spam, refactor unhandled input 2026-01-22 16:43:25 +01:00
tiger tiger tiger 982c426439 fix: adding ui_pause input action, and logging unhandled input (very spammy) 2026-01-22 16:21:12 +01:00
tiger tiger tiger 059b4b96cc refactor: named the get_ready and start_room functions _async so it's clearer how they work differently 2026-01-22 16:06:11 +01:00
tiger tiger tiger 9ea0d05d72 tweak: remove demo ending 2026-01-22 16:00:01 +01:00
tiger tiger tiger 1edc6106ff tweak: remove demo ending button 2026-01-22 15:59:44 +01:00
tiger tiger tiger 72f79386db tweak: light now in keyhole of door 2026-01-22 15:59:01 +01:00
betalars f7c8b84531 revert removing export from progress variable 2026-01-22 15:52:03 +01:00
tiger tiger tiger b745593eb7 Merge branch 'development' of https://community.rokojori.com/betalars/frame-of-mind into development 2026-01-22 15:13:38 +01:00
betalars 2452081c45 adding existing audio clips into scenes 2026-01-22 15:12:25 +01:00
betalars 3de31d61b2 add blend1 files back to gitignore 2026-01-22 15:12:25 +01:00
tiger tiger tiger 406d7e5002 fix: pause menu cleanup 2026-01-22 15:12:24 +01:00
tiger tiger tiger b79780835e fix: void card 2026-01-22 14:56:16 +01:00
tiger tiger tiger 350361395d fix: can now debug-play StoryPlayables 2026-01-22 14:25:36 +01:00
tiger tiger tiger 95e7160920 fix: added doorinteractive to volunteer room 2026-01-22 14:19:22 +01:00
tiger tiger tiger e23f496b70 fix: add %UI node to subway_sequence 2026-01-22 12:04:41 +01:00
tiger tiger tiger 48242e954f fix: ensuring %DoorInteractable gets unlocked. 2026-01-22 12:02:18 +01:00
tiger tiger tiger 294a5c2a7d refactor: interactables also spawn more controlled, and there's a delayed inversion of control to ensure cardboard is ready. 2026-01-22 11:57:59 +01:00
tiger tiger tiger 7653be9555 refactor: rooms now ensure ID, rooms now share initialization code 2026-01-22 11:02:58 +01:00
tiger tiger tiger 2b949d8e73 tweak: doors unlock the collider on the up flank 2026-01-22 01:47:15 +01:00
tiger tiger tiger efc2488dff fix: loading in both board rooms unified 2026-01-22 01:36:54 +01:00
tiger tiger tiger 071c0de5a7 fix: loading savegame 3 times after merge 2026-01-22 01:28:34 +01:00
tiger tiger tiger a9af1e5995 merge: linux changes 2026-01-22 01:18:35 +01:00
tiger tiger tiger cc73e1e4b6 fix: card loading 2026-01-22 01:15:53 +01:00
tiger tiger tiger cdcf6609d7 fix: improper order of operations / delegation for cardboard caused it to be not loaded 2026-01-21 23:46:46 +01:00
tiger tiger tiger 7c8428af01 chore: remove count logic that was cause for a bug before 2026-01-21 23:40:53 +01:00
tiger tiger tiger 75c2200bd8 fix: evaluations now count correctly 2026-01-21 23:36:11 +01:00
tiger tiger tiger b5a4bd2896 fix: Id type now stricter 2026-01-21 23:32:55 +01:00
tiger tiger tiger 99632f6043 fix: bootup problems resolved. 2026-01-21 23:23:00 +01:00
tiger tiger tiger 80eb4a727f chore: debugging cardboard, better movement, but now save state has problems§ 2026-01-21 22:35:35 +01:00
tiger tiger tiger 69e05f7562 chore: clean up old code 2026-01-21 21:40:30 +01:00
tiger tiger tiger b47801ae5c fix: card-board uses more single-responsibility, and now allows cards to slide nicely into the gaps 2026-01-21 21:38:31 +01:00
tiger tiger tiger 666df45e06 fix: trying to make cards a bit more robust 2026-01-21 20:43:13 +01:00
tiger tiger tiger 9749736e7d fix: rosenthal station actually therapizes 2026-01-21 18:22:53 +01:00
tiger tiger tiger 8561310d9e feat: train easings exposed 2026-01-21 18:16:11 +01:00
tiger tiger tiger f0ad263e57 fix: godot chopped up music streams, and I found a lot of pcm compressed stuff 2026-01-21 18:01:56 +01:00
tiger tiger tiger 23d2d3bb9e fix: music playing 2026-01-21 17:38:43 +01:00
tiger tiger tiger cd42b64d1c fix: couldn't load into adult room correctly if going through the entire game 2026-01-21 17:11:25 +01:00
tiger tiger tiger c19b395d98 chore: regenerate lighting in volunteer room, and fixup collider on interactables. 2026-01-21 16:36:13 +01:00
tiger tiger tiger f2a2c13e65 fix: small sorting bug, tested adult room 2026-01-21 16:25:16 +01:00
tiger tiger tiger 7abff22ccc feat: interactable have a faint glow 2026-01-21 16:04:17 +01:00
tiger tiger tiger 2fccf9d545 feat: interactable have a faint glow 2026-01-21 16:01:51 +01:00
tiger tiger tiger 3fe7d4a6f5 fix: interactables now handle input as delegated by player, scene_finished etc. are not emitted twice 2026-01-21 15:41:40 +01:00
tiger tiger tiger c115e7b2d6 fix: room identification and save games were getting tangled up 2026-01-21 15:09:59 +01:00
tiger tiger tiger 3295c44ce9 fix: glitchy appearance of storyplayables 2026-01-21 13:33:13 +01:00
tiger tiger tiger 7fc85783cc fix: moved some audio sources 2026-01-21 13:25:38 +01:00
tiger tiger tiger 9eee693670 fix: moved some audio sources 2026-01-21 13:23:54 +01:00
tiger tiger tiger a0f6261c1e fix: train timings, minor transition issue to adult room, train audio 2026-01-21 13:23:04 +01:00
152 changed files with 2034 additions and 3061 deletions

4
.gitignore vendored
View File

@ -8,6 +8,10 @@ export.cfg
export_credentials.cfg export_credentials.cfg
*.tmp *.tmp
# Mics Backup and temp files
*.blend1
*.md.backup
# Imported translations (automatically generated from CSV files) # Imported translations (automatically generated from CSV files)
*.translation *.translation

View File

@ -47,6 +47,7 @@ func _update_events():
# TODO: Find a cleaner way to cast these values # TODO: Find a cleaner way to cast these values
var tmp: Array = [] var tmp: Array = []
if Engine.is_editor_hint(): if Engine.is_editor_hint():
print("reading project settings")
tmp = ProjectSettings.get_setting("input/" + action)["events"] tmp = ProjectSettings.get_setting("input/" + action)["events"]
else: else:
tmp = InputMap.action_get_events(action) tmp = InputMap.action_get_events(action)

View File

@ -5,5 +5,5 @@ func _ready() -> void:
$MarkdownLabel.display_file("res://addons/markdownlabel/README.md") $MarkdownLabel.display_file("res://addons/markdownlabel/README.md")
$MarkdownLabel.task_checkbox_clicked.connect( $MarkdownLabel.task_checkbox_clicked.connect(
func(id: int, line: int, checked: bool, text: String) -> void: func(id: int, line: int, checked: bool, text: String) -> void:
print_debug("%s task #%d on line %d: %s" % ["Checked" if checked else "Unchecked", id, line, text]) print("%s task #%d on line %d: %s" % ["Checked" if checked else "Unchecked", id, line, text])
) )

View File

@ -640,7 +640,7 @@ func _reset_escaped_chars(_text: String,code:=false) -> String:
func _debug(string: String) -> void: func _debug(string: String) -> void:
if not _debug_mode: if not _debug_mode:
return return
print_debug(string) print(string)
func _denotes_fenced_code_block(line: String, character: String) -> bool: func _denotes_fenced_code_block(line: String, character: String) -> bool:
var stripped_line := line.strip_edges() var stripped_line := line.strip_edges()

Binary file not shown.

View File

@ -5,25 +5,56 @@ extends Node3D
@export var index : int = -1 @export var index : int = -1
@export var signage_group : String @export var signage_group : String
@export var pre_arrival_time : float = 17.0 @export_group("Motion")
@export var arrival_time : float = 15.0 @export_subgroup("Arrival")
@export var pre_leave_time : float = 20.0 @export var pre_arrival_time : float = 17.0 # hold train for this long (to sync with audio!)
@export var arrival_time : float = 15.0 # train takes this long to enter (shorter = faster)
@export var trans_arrival : Tween.TransitionType = Tween.TRANS_CIRC
@export var ease_arrival : Tween.EaseType = Tween.EASE_OUT
@export_subgroup("In Station")
@export var station_wait_time : float = 20.0
@export_subgroup("Departure")
@export var door_close_time : float = 1.0 @export var door_close_time : float = 1.0
@export var leave_time : float = 15.0 @export var leave_time : float = 15.0 # train takes this long to leave the platform
@export var post_leave_time : float = 5.0 @export var trans_departure : Tween.TransitionType = Tween.TRANS_QUAD
@export var ease_departure : Tween.EaseType = Tween.EASE_IN
@onready var origination : Node3D = $Origination @onready var origination : Node3D = $Origination
@onready var destination : Node3D = $Destination @onready var destination : Node3D = $Destination
@onready var subway : SubwayTrain = $Subway @onready var subway : SubwayTrain = $Subway
@onready var subway_audio_main : AudioStreamPlayer3D = %SubwayTrainAudio
@onready var subway_audio_2 : AudioStreamPlayer3D = %SubwayTrainAudioIntense
var player_on_board : bool:
get: return %EntryDetect.overlaps_body(State.player)
var tween : Tween = null var tween : Tween = null
signal departure(index : int)
## Player is about to arrive
signal train_approaching(track : Dolly)
## Player has fully arrived at station
signal train_arrived(track : Dolly)
## Player is departing in train
signal train_departing(track : Dolly)
## Player has fully left the station with train
signal train_left(track : Dolly)
func _ready() -> void: func _ready() -> void:
reset() reset()
func set_line(line: StringName):
subway.set_line(line)
## One arrival and departure ## One arrival and departure
func cycle() -> void: func cycle() -> void:
await arrive() await arrive()
@ -33,48 +64,60 @@ func reset() -> void:
if tween: tween.kill() if tween: tween.kill()
subway.global_position = origination.global_position subway.global_position = origination.global_position
func _seat_player_if_inside() -> bool: func _seat_player() -> void:
if %EntryDetect.overlaps_body(State.player): prints("Player departs inside Train", self.name)
prints("Player departs inside Train", self.name) State.player.reparent(subway)
State.player.reparent(subway)
return true
return false
func _unseat_player_if_inside() -> void: func _unseat_player() -> void:
if %EntryDetect.overlaps_body(State.player): prints("Player arrives on Train", self.name)
prints("Player arrives on Train", self.name) State.player.reparent(get_parent())
State.player.reparent(get_parent())
func arrive(endstation : bool = false) -> void: func arrive(endstation : bool = false) -> void:
%SubwayTrainAudio.play(0) subway_audio_main.play()
%SubwayTrainAudioIntense.play(0) subway_audio_2.play()
await get_tree().create_timer(pre_arrival_time).timeout await get_tree().create_timer(pre_arrival_time).timeout
if player_on_board:
train_approaching.emit(self)
if tween: tween.kill() if tween: tween.kill()
tween = create_tween().set_trans(Tween.TRANS_CIRC).set_ease(Tween.EASE_OUT) tween = create_tween().set_trans(trans_arrival).set_ease(ease_arrival)
tween.parallel().tween_property(subway, "global_position", self.global_position, arrival_time) tween.parallel().tween_property(subway, "global_position", self.global_position, arrival_time)
await tween.finished await tween.finished
subway.door_open = true subway.door_open = true
_unseat_player_if_inside()
if player_on_board:
_unseat_player()
train_arrived.emit(self)
if endstation: if endstation:
%SubwayTrainAudio.stop() subway_audio_main.stop()
%SubwayTrainAudioIntense.stop() subway_audio_2.stop()
func leave() -> void: func leave() -> void:
await get_tree().create_timer(pre_leave_time).timeout await get_tree().create_timer(station_wait_time).timeout
subway.door_open = false subway.door_open = false
await get_tree().create_timer(door_close_time).timeout await get_tree().create_timer(door_close_time).timeout
var seated := _seat_player_if_inside()
if player_on_board:
_seat_player()
train_departing.emit(self)
if tween: tween.kill() if tween: tween.kill()
tween = create_tween().set_trans(Tween.TRANS_QUART).set_ease(Tween.EASE_IN) tween = create_tween().set_trans(trans_departure).set_ease(ease_departure)
tween.parallel().tween_property(subway, "global_position", destination.global_position, leave_time) tween.parallel().tween_property(subway, "global_position", destination.global_position, leave_time)
# Player is on board and will be leaving
await tween.finished await tween.finished
await %SubwayTrainAudio.finished
# Player was on board and has left the station # Player was on board and has left the station
if seated: departure.emit(index) if player_on_board: train_left.emit(self)
reset() reset() # Warp back / rewind train position

View File

@ -1,66 +1,77 @@
class_name Fahrplan extends Node3D class_name Fahrplan extends Node3D
## easy graph: <station> : [Track1Train1 (next halt), Track1Train2], [Track2Train1(next halt), ...] ## easy graph: <station> : [Track1Train1 (next halt), Track1Train2], [Track2Train1(next halt), ...]
@onready var fahrplan : Dictionary[Node3D, Array] = { ## CAVEAT: These must be direct children of the fahrplan!
$station_hirschfeld: [[$station_university_mensa, $station_parity_square],[]], @onready var fahrplan : Dictionary[Station, Array] = {
$station_hirschfeld : [[$station_university_mensa, $station_parity_square],[]], $hirschfeld: [["u2", $uni_mensa, "u1", $parity_square],[]],
$station_university_mensa : [[$station_university_main],[]], $uni_mensa : [["u2", $uni_main],[]],
$station_university_main: [[$station_ministry],[$station_rosenthal, $station_university_mensa]], $uni_main: [["u2", $ministry],["u8", $rosenthal, "u2", $uni_mensa, "u1", $saint_exupery]],
$station_parity_square : [[$station_saint_exupery],[$station_rosenthal]], $parity_square : [["u4", $saint_exupery, "u1", $saint_exupery], []],
$station_saint_exupery : [[$station_saint_exupery],[$station_rosenthal]], $saint_exupery : [["u4", $rosenthal], ["u1", $uni_main]],
$station_ministry : [null,null], # Endstation $ministry : [null, null], # Endstation
$station_rosenthal : [null,null], # Endstation $rosenthal : [null, null], # Endstation
} }
## List of all registered station nodes, used to unparent them
@onready var stations : Array[Station] = fahrplan.keys()
@onready var tracks : Array[Dolly] = [%Track0Dolly, %Track1Dolly] @onready var tracks : Array[Dolly] = [%Track0Dolly, %Track1Dolly]
@export var random_wait : Vector2 = Vector2(1.0, 10.0) @export var empty_train_random_delay : Vector2 = Vector2(5.0, 20.0)
func _set_signage_texts(group: StringName, message: String) -> void: func _set_signage_texts(group: StringName, message: String) -> void:
get_tree().call_group(group, "set_text", "") get_tree().set_group(group, "text", "")
for i in range(len(message)): for i in range(len(message)):
get_tree().call_group(group, "set_text", message.substr(0, i+1)) get_tree().set_group(group, "text", message.substr(0, i+1))
await get_tree().create_timer(0.05).timeout await get_tree().create_timer(0.05).timeout
func _ready() -> void: func _ready() -> void:
var x : Node3D = $station_hirschfeld
print(x.name)
await get_tree().process_frame await get_tree().process_frame
tracks[0].departure.connect(player_departed) tracks[0].train_left.connect(_player_train_left)
tracks[1].departure.connect(player_departed) tracks[1].train_left.connect(_player_train_left)
enter_station($station_hirschfeld) _unparent_all_stations_except($hirschfeld)
enter_station(current)
var current_station : Node3D = null ## The current station
var current : Station
var stop := false var stop := false
var destinations : Array[Node3D] = [null, null] var destinations : Array[Station] = [null, null]
func train_traffic_loop(track: Dolly, cancel: Array) -> void: ## Begins the scheduled traffic (looping through the list of destinations) on a given track
func _begin_traffic_loop(track: Dolly, cancel: Array) -> void:
if not track.player_on_board and fahrplan[current][track.index] == null: # empty trains dont arrive at endstation
_set_signage_texts(track.signage_group, "Gleis gesperrt")
return
if fahrplan[current_station][track.index] == null: # empty array (just no routes) would be falsy if fahrplan[current][track.index] == null: # empty trains dont arrive at endstation
track.arrive(true) track.arrive(true)
_set_signage_texts(track.signage_group, "Endstation") _set_signage_texts(track.signage_group, "Endstation")
return return
var routes : Array = fahrplan[current_station][track.index] var routes : Array = fahrplan[current][track.index]
if routes.is_empty(): if routes.is_empty():
_set_signage_texts(track.signage_group, "Verkehr z. Zt.\nunregelmäßig") _set_signage_texts(track.signage_group, "Verkehr z. Zt.\nunregelmäßig")
return return
while true: while true:
if cancel.is_empty(): return # abort the loop if cancel.is_empty(): return # abort the loop
var next : Node = routes.pop_front() var line : StringName = routes.pop_front()
var next : Station = routes.pop_front()
routes.append(line) # It's a ring buffer
routes.append(next) # It's a ring buffer routes.append(next) # It's a ring buffer
destinations[track.index] = next destinations[track.index] = next
_set_signage_texts(track.signage_group, next.name) # TODO: load nice string track.set_line(line)
_set_signage_texts(track.signage_group, current.get_label(line, next)) # TODO: load nice string
await get_tree().create_timer(randf_range(random_wait.x, random_wait.y)).timeout # Vary our schedule a little by making empty trains wait a random amount of time
if not track.player_on_board:
await get_tree().create_timer(randf_range(empty_train_random_delay.x, empty_train_random_delay.y)).timeout
if cancel.is_empty(): return # abort the loop if cancel.is_empty(): return # abort the loop
await track.cycle() # arrive and depart await track.cycle() # arrive and depart
@ -68,16 +79,26 @@ func train_traffic_loop(track: Dolly, cancel: Array) -> void:
var cancellation_token : Array var cancellation_token : Array
func enter_station(station: Node): func enter_station(station: Station):
prints("------------", "ENTER STATION", station, station.name, "------------") prints("------------", "ENTER STATION", station, station.name, "------------")
if current_station: current_station.visible = false remove_child(current)
current_station = station current = station
current_station.visible = true add_child(station)
cancellation_token = ["go"] # Allocate a new stopping token cancellation_token = ["go"] # Allocate a new stopping token
train_traffic_loop(tracks[0], cancellation_token) _begin_traffic_loop(tracks[0], cancellation_token)
train_traffic_loop(tracks[1], cancellation_token) _begin_traffic_loop(tracks[1], cancellation_token)
func player_departed(track_index : int) -> void: func _player_train_left(track: Dolly) -> void:
cancellation_token.clear() cancellation_token.clear()
enter_station(destinations[track_index]) enter_station(destinations[track.index])
func _unparent_all_stations_except(except : Node3D):
for station in stations:
assert(station.get_parent() == self, "A station that isn't a child of Fahrplan is in the Fahrplan: %s" % station.name)
station.visible = true # Make visible by default, parenting handles visibility and collision
if station == except:
current = station
continue
remove_child(station)

View File

@ -1,18 +1,8 @@
class_name Station extends Resource extends Node3D
class_name Station
enum id { @export var i18n_key : StringName
HIRSCHFELD, @export var train_labels : Dictionary[StringName,String] = {}
PARITY,
EXUPERY,
ROSENTHAL,
UNI_1,
UNI_2,
MINISTRY
}
@export var station_name: StringName = "" func get_label(line: StringName, next_stop: Station) -> String:
@export var memory: Scenes.id = Scenes.id.YOUTH_DRAVEN return train_labels.get(line+next_stop.name, line+next_stop.name)
@export_file("*.tscn") var station_path: String = ""
@export var arriving_lines: Dictionary[TrainLine.id, float]
@export var departing_lines: Dictionary[TrainLine.id, float]
@export var announcement: AudioStream

View File

@ -1 +1 @@
uid://cyeh7sa20bmcf uid://pmhadgsfinjc

View File

@ -1,26 +1,23 @@
extends RoomTemplate extends Room
class_name SubwaySequence class_name SubwaySequence
@export var all_stations: Dictionary[Station.id, Station]
@export var all_lines: Dictionary[TrainLine.id, TrainLine]
func _ready() -> void: func _ready() -> void:
super._ready()
id = State.rooms.TRANSITION id = State.rooms.TRANSITION
super._ready()
func get_ready_async() -> void:
await super.get_ready_async()
func start_room_async():
await super.start_room_async()
func start_room():
super.start_room()
Scenes.player_enable.emit(true) Scenes.player_enable.emit(true)
await Main.curtain.open() await Main.curtain.open()
var next_room : String = await proceed # emitted by burnout_station.gd and therapy_station.gd
await Main.curtain.black()
Main._load_room(next_room)
func pull_save_state(save: SaveGame) -> void: func pull_save_state(save: SaveGame) -> void:
#FIXME
save.sequences_enabled = Scenes.enabled_sequences save.sequences_enabled = Scenes.enabled_sequences
save.current_room = State.rooms.ADULTHOOD
save_game = save save_game = save
# Call parent to restore player position # Call parent to restore player position

View File

@ -1,6 +1,8 @@
extends Node3D extends Node3D
class_name SubwayTrain class_name SubwayTrain
@export var materials : Dictionary[StringName, Material] = {}
@export var door_open: bool: @export var door_open: bool:
set(open): set(open):
if door_open == open: return if door_open == open: return
@ -10,8 +12,11 @@ class_name SubwayTrain
else: else:
%TrainModel/AnimationPlayer.play("door_close") %TrainModel/AnimationPlayer.play("door_close")
func _ready() -> void: %FrontWallClosed.disabled = door_open
%TrainModel/AnimationPlayer.animation_finished.connect(_on_animation_finished)
func _on_animation_finished(_discard) -> void:
%FrontWallClosed.disabled = door_open func set_line(line : StringName):
$TrainModel/traun_hull.material_overlay = materials[line]
$TrainModel/LineLabelBack.text = line.to_upper()
$TrainModel/LineLabelFront.text = line.to_upper()

View File

@ -1,14 +0,0 @@
class_name TrainLine extends Resource
enum id {
NONE,
RING,
U2,
U3,
U8
}
@export var train_id: id = id.NONE
@export var destination: StringName = ""
@export var via: StringName = ""
@export var stops: Dictionary[Station, float]

View File

@ -1 +0,0 @@
uid://dfkq0djtygmma

View File

@ -8,6 +8,7 @@
[resource] [resource]
resource_name = "train_windows" resource_name = "train_windows"
transparency = 4 transparency = 4
cull_mode = 2
albedo_texture = ExtResource("1_qqnyp") albedo_texture = ExtResource("1_qqnyp")
metallic = 1.0 metallic = 1.0
metallic_texture = ExtResource("2_orwl3") metallic_texture = ExtResource("2_orwl3")

View File

@ -9,6 +9,7 @@
resource_name = "train_windows_transparent" resource_name = "train_windows_transparent"
transparency = 1 transparency = 1
blend_mode = 4 blend_mode = 4
cull_mode = 2
albedo_texture = ExtResource("1_p8q8d") albedo_texture = ExtResource("1_p8q8d")
metallic = 1.0 metallic = 1.0
metallic_texture = ExtResource("2_eds1u") metallic_texture = ExtResource("2_eds1u")

View File

@ -1,5 +1,5 @@
shader_type spatial; shader_type spatial;
render_mode cull_back, blend_add, unshaded; render_mode cull_disabled, blend_add, unshaded;
varying vec3 world_pos; varying vec3 world_pos;
uniform float state = 0.0; uniform float state = 0.0;

View File

@ -1,4 +1,4 @@
[gd_resource type="ShaderMaterial" format=3 uid="uid://dchm78gv31r6a"] [gd_resource type="ShaderMaterial" load_steps=4 format=3 uid="uid://dchm78gv31r6a"]
[ext_resource type="Shader" uid="uid://dpowid5cwvgu0" path="res://base-environments/transition/shaders/timetravel.gdshader" id="1_0da7x"] [ext_resource type="Shader" uid="uid://dpowid5cwvgu0" path="res://base-environments/transition/shaders/timetravel.gdshader" id="1_0da7x"]
[ext_resource type="Texture2D" uid="uid://dst0u5b51mx4h" path="res://base-environments/transition/shaders/water_color.exr" id="2_4vy32"] [ext_resource type="Texture2D" uid="uid://dst0u5b51mx4h" path="res://base-environments/transition/shaders/water_color.exr" id="2_4vy32"]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,8 @@
extends Node3D extends Station
func _ready() -> void: func _ready() -> void:
State.room.save_game.burnout = true %PlayerDetect.body_entered.connect(func(body):
%PlayerDetect.body_entered.connect(func(body): if visible and body is PlayerController: State.room.proceed.emit(Main.adulthood_room_path)) if visible and body is PlayerController:
State.room.save_game.subway_burnout = true
await Main.curtain.black()
State.room.proceed.emit(Main.adulthood_room_path))

View File

@ -1,4 +1,8 @@
extends Node3D extends Station
func _ready() -> void: func _ready() -> void:
%PlayerDetect.body_entered.connect(func(body): if visible and body is PlayerController: State.room.proceed.emit(Main.adulthood_room_path)) %PlayerDetect.body_entered.connect(func(body):
if visible and body is PlayerController:
State.room.save_game.subway_burnout = false
await Main.curtain.black()
State.room.proceed.emit(Main.adulthood_room_path))

View File

@ -1,19 +1,19 @@
[gd_scene format=3 uid="uid://uhayiqixlv0e"] [gd_scene load_steps=3 format=3 uid="uid://uhayiqixlv0e"]
[ext_resource type="PackedScene" uid="uid://7b8qxqyk4di2" path="res://base-environments/transition/import/volunteer_station.glb" id="1_gxnf0"] [ext_resource type="PackedScene" uid="uid://7b8qxqyk4di2" path="res://base-environments/transition/import/volunteer_station.glb" id="1_gxnf0"]
[ext_resource type="PackedScene" uid="uid://tuv111h6jsnu" path="res://base-environments/transition/import/textures/meta_station_imported.tscn" id="2_28xtj"] [ext_resource type="PackedScene" uid="uid://tuv111h6jsnu" path="res://base-environments/transition/import/textures/meta_station_imported.tscn" id="2_28xtj"]
[node name="volunteer_station" unique_id=1086700491 instance=ExtResource("1_gxnf0")] [node name="volunteer_station" instance=ExtResource("1_gxnf0")]
[node name="meta_station" parent="." index="46" unique_id=928456797 instance=ExtResource("2_28xtj")] [node name="meta_station" parent="." index="46" instance=ExtResource("2_28xtj")]
[node name="Lighting" type="Node3D" parent="." index="47" unique_id=614453572] [node name="Lighting" type="Node3D" parent="." index="47"]
visible = false visible = false
[node name="Left" type="Node3D" parent="Lighting" index="0" unique_id=841316440] [node name="Left" type="Node3D" parent="Lighting" index="0"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.1015987, 0, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.1015987, 0, 0)
[node name="OmniLight3D" type="SpotLight3D" parent="Lighting/Left" index="0" unique_id=858880331] [node name="OmniLight3D" type="SpotLight3D" parent="Lighting/Left" index="0"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -10.1989) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -10.1989)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -24,7 +24,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D13" type="SpotLight3D" parent="Lighting/Left" index="1" unique_id=1973416313] [node name="OmniLight3D13" type="SpotLight3D" parent="Lighting/Left" index="1"]
transform = Transform3D(1, 0, 0, 0, -0.50000024, 0.8660253, 0, -0.8660253, -0.50000024, -0.42258057, 2.0402927, -5.2949142) transform = Transform3D(1, 0, 0, 0, -0.50000024, 0.8660253, 0, -0.8660253, -0.50000024, -0.42258057, 2.0402927, -5.2949142)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -35,7 +35,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D2" type="SpotLight3D" parent="Lighting/Left" index="2" unique_id=1775276584] [node name="OmniLight3D2" type="SpotLight3D" parent="Lighting/Left" index="2"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -15.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -15.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -46,7 +46,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D3" type="SpotLight3D" parent="Lighting/Left" index="3" unique_id=56001064] [node name="OmniLight3D3" type="SpotLight3D" parent="Lighting/Left" index="3"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -20.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -20.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -57,7 +57,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D4" type="SpotLight3D" parent="Lighting/Left" index="4" unique_id=1665416716] [node name="OmniLight3D4" type="SpotLight3D" parent="Lighting/Left" index="4"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -25.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -25.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -68,7 +68,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D5" type="SpotLight3D" parent="Lighting/Left" index="5" unique_id=168448101] [node name="OmniLight3D5" type="SpotLight3D" parent="Lighting/Left" index="5"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -30.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -30.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -79,7 +79,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D6" type="SpotLight3D" parent="Lighting/Left" index="6" unique_id=144351960] [node name="OmniLight3D6" type="SpotLight3D" parent="Lighting/Left" index="6"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -35.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -35.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -90,7 +90,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D7" type="SpotLight3D" parent="Lighting/Left" index="7" unique_id=2109500620] [node name="OmniLight3D7" type="SpotLight3D" parent="Lighting/Left" index="7"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -40.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -40.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -101,7 +101,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D8" type="SpotLight3D" parent="Lighting/Left" index="8" unique_id=1075807285] [node name="OmniLight3D8" type="SpotLight3D" parent="Lighting/Left" index="8"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -45.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -45.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -112,7 +112,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D9" type="SpotLight3D" parent="Lighting/Left" index="9" unique_id=469725055] [node name="OmniLight3D9" type="SpotLight3D" parent="Lighting/Left" index="9"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -50.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -50.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -123,7 +123,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D10" type="SpotLight3D" parent="Lighting/Left" index="10" unique_id=1960377915] [node name="OmniLight3D10" type="SpotLight3D" parent="Lighting/Left" index="10"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -55.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -55.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -134,7 +134,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D11" type="SpotLight3D" parent="Lighting/Left" index="11" unique_id=1816850027] [node name="OmniLight3D11" type="SpotLight3D" parent="Lighting/Left" index="11"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -60.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -60.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -145,7 +145,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D12" type="SpotLight3D" parent="Lighting/Left" index="12" unique_id=308692117] [node name="OmniLight3D12" type="SpotLight3D" parent="Lighting/Left" index="12"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -65.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -65.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -156,10 +156,10 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="Right" type="Node3D" parent="Lighting" index="1" unique_id=630868085] [node name="Right" type="Node3D" parent="Lighting" index="1"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8136845, 0, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.8136845, 0, 0)
[node name="OmniLight3D" type="SpotLight3D" parent="Lighting/Right" index="0" unique_id=2056485181] [node name="OmniLight3D" type="SpotLight3D" parent="Lighting/Right" index="0"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -10.1989) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -10.1989)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -170,7 +170,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D13" type="SpotLight3D" parent="Lighting/Right" index="1" unique_id=809548263] [node name="OmniLight3D13" type="SpotLight3D" parent="Lighting/Right" index="1"]
transform = Transform3D(1, 0, 0, 0, -0.50000024, 0.8660253, 0, -0.8660253, -0.50000024, -0.42258057, 2.0402927, -5.2949142) transform = Transform3D(1, 0, 0, 0, -0.50000024, 0.8660253, 0, -0.8660253, -0.50000024, -0.42258057, 2.0402927, -5.2949142)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -181,7 +181,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D2" type="SpotLight3D" parent="Lighting/Right" index="2" unique_id=816752087] [node name="OmniLight3D2" type="SpotLight3D" parent="Lighting/Right" index="2"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -15.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -15.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -192,7 +192,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D3" type="SpotLight3D" parent="Lighting/Right" index="3" unique_id=927174265] [node name="OmniLight3D3" type="SpotLight3D" parent="Lighting/Right" index="3"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -20.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -20.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -203,7 +203,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D4" type="SpotLight3D" parent="Lighting/Right" index="4" unique_id=1690728036] [node name="OmniLight3D4" type="SpotLight3D" parent="Lighting/Right" index="4"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -25.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -25.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -214,7 +214,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D5" type="SpotLight3D" parent="Lighting/Right" index="5" unique_id=2096526257] [node name="OmniLight3D5" type="SpotLight3D" parent="Lighting/Right" index="5"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -30.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -30.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -225,7 +225,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D6" type="SpotLight3D" parent="Lighting/Right" index="6" unique_id=1776863402] [node name="OmniLight3D6" type="SpotLight3D" parent="Lighting/Right" index="6"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -35.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -35.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -236,7 +236,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D7" type="SpotLight3D" parent="Lighting/Right" index="7" unique_id=620392762] [node name="OmniLight3D7" type="SpotLight3D" parent="Lighting/Right" index="7"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -40.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -40.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -247,7 +247,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D8" type="SpotLight3D" parent="Lighting/Right" index="8" unique_id=1681381128] [node name="OmniLight3D8" type="SpotLight3D" parent="Lighting/Right" index="8"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -45.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -45.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -258,7 +258,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D9" type="SpotLight3D" parent="Lighting/Right" index="9" unique_id=430454083] [node name="OmniLight3D9" type="SpotLight3D" parent="Lighting/Right" index="9"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -50.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -50.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -269,7 +269,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D10" type="SpotLight3D" parent="Lighting/Right" index="10" unique_id=774180702] [node name="OmniLight3D10" type="SpotLight3D" parent="Lighting/Right" index="10"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -55.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -55.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -280,7 +280,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D11" type="SpotLight3D" parent="Lighting/Right" index="11" unique_id=955522321] [node name="OmniLight3D11" type="SpotLight3D" parent="Lighting/Right" index="11"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -60.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -60.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6
@ -291,7 +291,7 @@ spot_range = 6.5
spot_angle = 80.0 spot_angle = 80.0
spot_angle_attenuation = 0.517633 spot_angle_attenuation = 0.517633
[node name="OmniLight3D12" type="SpotLight3D" parent="Lighting/Right" index="12" unique_id=513566485] [node name="OmniLight3D12" type="SpotLight3D" parent="Lighting/Right" index="12"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -65.2744) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.42258057, 2.022126, -65.2744)
light_color = Color(0.978917, 0.789534, 0.685226, 1) light_color = Color(0.978917, 0.789534, 0.685226, 1)
light_size = 0.6 light_size = 0.6

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,15 @@
[gd_scene load_steps=25 format=3 uid="uid://df3ur5wll8vx7"] [gd_scene load_steps=31 format=3 uid="uid://df3ur5wll8vx7"]
[ext_resource type="PackedScene" uid="uid://4j1tlhfm3p40" path="res://base-environments/transition/subway_train.tscn" id="1_2h2xx"] [ext_resource type="PackedScene" uid="uid://4j1tlhfm3p40" path="res://base-environments/transition/subway_train.tscn" id="1_2h2xx"]
[ext_resource type="Script" uid="uid://dgfje4druu3sw" path="res://base-environments/transition/code/dolly.gd" id="1_5jpg8"] [ext_resource type="Script" uid="uid://dgfje4druu3sw" path="res://base-environments/transition/code/dolly.gd" id="1_5jpg8"]
[ext_resource type="Script" uid="uid://cyohujvfoiof7" path="res://base-environments/transition/code/subway_train.gd" id="2_aacjs"] [ext_resource type="Script" uid="uid://cyohujvfoiof7" path="res://base-environments/transition/code/subway_train.gd" id="2_aacjs"]
[ext_resource type="AudioStream" uid="uid://cwfr6sgcwg7sl" path="res://base-environments/transition/audio/450918__kyles__metro-subway-montreal-verdun-station-arrive-and-leave-semidistant-from-bridge-over-tracks-overpass.ogg" id="3_4h0n7"] [ext_resource type="AudioStream" uid="uid://cwfr6sgcwg7sl" path="res://base-environments/transition/audio/450918__kyles__metro-subway-montreal-verdun-station-arrive-and-leave-semidistant-from-bridge-over-tracks-overpass.ogg" id="3_4h0n7"]
[ext_resource type="Material" uid="uid://cl7e6lpjalm0c" path="res://base-environments/transition/shaders/u1.material" id="3_j8pin"]
[ext_resource type="Material" uid="uid://c0baqy42xdxtg" path="res://base-environments/transition/shaders/u2.material" id="4_3w708"]
[ext_resource type="Material" uid="uid://bw4y5b5lnw3cn" path="res://base-environments/transition/shaders/u4.material" id="5_3x5rc"]
[ext_resource type="Material" uid="uid://cor0uho8hnfqc" path="res://base-environments/transition/shaders/u7.material" id="6_ckebf"]
[ext_resource type="Material" uid="uid://d0kk76pja0orj" path="res://base-environments/transition/shaders/u8.material" id="7_dyyau"]
[ext_resource type="FontFile" uid="uid://b231f0liphck" path="res://import/fonts/AtkinsonHyperlegible-Regular.ttf" id="10_3w708"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_aacjs"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_aacjs"]
shading_mode = 0 shading_mode = 0
@ -108,14 +114,6 @@ size = Vector3(31.194, 0.8, 3.8)
[node name="TrainDolly" type="Node3D"] [node name="TrainDolly" type="Node3D"]
script = ExtResource("1_5jpg8") script = ExtResource("1_5jpg8")
index = null
signage_group = null
pre_arrival_time = null
arrival_time = null
pre_leave_time = null
door_close_time = null
leave_time = null
post_leave_time = null
metadata/_custom_type_script = "uid://dgfje4druu3sw" metadata/_custom_type_script = "uid://dgfje4druu3sw"
[node name="Destination" type="Node3D" parent="."] [node name="Destination" type="Node3D" parent="."]
@ -130,6 +128,13 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -150)
[node name="Subway" type="Node3D" parent="."] [node name="Subway" type="Node3D" parent="."]
script = ExtResource("2_aacjs") script = ExtResource("2_aacjs")
materials = Dictionary[StringName, Material]({
&"u1": ExtResource("3_j8pin"),
&"u2": ExtResource("4_3w708"),
&"u4": ExtResource("5_3x5rc"),
&"u7": ExtResource("6_ckebf"),
&"u8": ExtResource("7_dyyau")
})
metadata/_custom_type_script = "uid://cyohujvfoiof7" metadata/_custom_type_script = "uid://cyohujvfoiof7"
[node name="WarpEffecScreen" type="MeshInstance3D" parent="Subway"] [node name="WarpEffecScreen" type="MeshInstance3D" parent="Subway"]
@ -160,26 +165,40 @@ spot_angle = 15.0
[node name="SubwayTrainAudio" type="AudioStreamPlayer3D" parent="Subway"] [node name="SubwayTrainAudio" type="AudioStreamPlayer3D" parent="Subway"]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -0.4578781, 0, -6.1605225) transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 0, -0.742, -11.098)
stream = ExtResource("3_4h0n7") stream = ExtResource("3_4h0n7")
unit_size = 100.0 unit_size = 100.0
max_polyphony = 2
panning_strength = 0.7 panning_strength = 0.7
bus = &"sfx" bus = &"sfx"
playback_type = 1 playback_type = 1
[node name="SubwayTrainAudioIntense" type="AudioStreamPlayer3D" parent="Subway"] [node name="SubwayTrainAudioIntense" type="AudioStreamPlayer3D" parent="Subway"]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 0.6660023, 0, 0) transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 0, -0.802, 10.908)
stream = ExtResource("3_4h0n7") stream = ExtResource("3_4h0n7")
attenuation_model = 1 attenuation_model = 1
unit_size = 15.0 unit_size = 15.0
max_polyphony = 2
panning_strength = 0.9
bus = &"sfx" bus = &"sfx"
playback_type = 1 playback_type = 1
[node name="TrainModel" parent="Subway" instance=ExtResource("1_2h2xx")] [node name="TrainModel" parent="Subway" instance=ExtResource("1_2h2xx")]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -3.4114173e-08, 0, -0.7804413) transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -3.4114173e-08, 0, -0.7804413)
script = null
[node name="LineLabelFront" type="Label3D" parent="Subway/TrainModel"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -15.413577, 2.7434583, -6.737489e-07)
text = "U0"
font = ExtResource("10_3w708")
font_size = 64
[node name="LineLabelBack" type="Label3D" parent="Subway/TrainModel"]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 15.410003, 2.7434583, 6.9981036e-07)
text = "U0"
font = ExtResource("10_3w708")
font_size = 64
[node name="Collider" type="AnimatableBody3D" parent="Subway"] [node name="Collider" type="AnimatableBody3D" parent="Subway"]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -1,20 +1,12 @@
[gd_scene load_steps=15 format=4 uid="uid://4j1tlhfm3p40"] [gd_scene load_steps=14 format=4 uid="uid://4j1tlhfm3p40"]
[ext_resource type="PackedScene" uid="uid://dmh8tmuvftqus" path="res://base-environments/transition/import/subway_train.glb" id="1_8e51f"] [ext_resource type="PackedScene" uid="uid://dmh8tmuvftqus" path="res://base-environments/transition/import/subway_train.glb" id="1_8e51f"]
[ext_resource type="Material" uid="uid://dchm78gv31r6a" path="res://base-environments/transition/shaders/timetravel.tres" id="2_g5p57"] [ext_resource type="Material" uid="uid://dchm78gv31r6a" path="res://base-environments/transition/shaders/timetravel.tres" id="2_g5p57"]
[ext_resource type="Script" uid="uid://cyohujvfoiof7" path="res://base-environments/transition/code/subway_train.gd" id="2_skiem"] [ext_resource type="Material" uid="uid://ddw7mob1qmlbj" path="res://base-environments/transition/shaders/u0.material" id="3_81crm"]
[ext_resource type="Material" uid="uid://rh1lc61j6qd8" path="res://base-environments/transition/import/textures/roof_greeble.tres" id="3_q0ort"] [ext_resource type="Material" uid="uid://rh1lc61j6qd8" path="res://base-environments/transition/import/textures/roof_greeble.tres" id="3_q0ort"]
[ext_resource type="Texture2D" uid="uid://bewykr0twbplg" path="res://base-environments/transition/import/textures/LateralTren_baseColor_upscayl_2x_realesrgan-x4plus-anime.png" id="5_6pwip"] [ext_resource type="Texture2D" uid="uid://bewykr0twbplg" path="res://base-environments/transition/import/textures/LateralTren_baseColor_upscayl_2x_realesrgan-x4plus-anime.png" id="5_6pwip"]
[ext_resource type="VoxelGIData" uid="uid://coibvxeouqllc" path="res://base-environments/transition/vfx/voxelGI_subway_train.tres" id="5_q0ort"] [ext_resource type="VoxelGIData" uid="uid://coibvxeouqllc" path="res://base-environments/transition/vfx/voxelGI_subway_train.tres" id="5_q0ort"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8e51f"]
cull_mode = 2
albedo_color = Color(0.22188288, 0.6046251, 0.8484487, 1)
metallic = 0.5
roughness = 0.5
clearcoat_enabled = true
clearcoat_roughness = 0.2
[sub_resource type="ArrayMesh" id="ArrayMesh_f2ux3"] [sub_resource type="ArrayMesh" id="ArrayMesh_f2ux3"]
_surfaces = [{ _surfaces = [{
"aabb": AABB(-5.128359, -0.2631049, -1.4985942, 10.841061, 0.57964456, 3.1154532), "aabb": AABB(-5.128359, -0.2631049, -1.4985942, 10.841061, 0.57964456, 3.1154532),
@ -52,6 +44,7 @@ shadow_mesh = SubResource("ArrayMesh_f2ux3")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_q0ort"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_q0ort"]
transparency = 1 transparency = 1
blend_mode = 1 blend_mode = 1
cull_mode = 2
albedo_texture = ExtResource("5_6pwip") albedo_texture = ExtResource("5_6pwip")
roughness = 0.1 roughness = 0.1
@ -144,13 +137,12 @@ _data = {
} }
[node name="subway_train" instance=ExtResource("1_8e51f")] [node name="subway_train" instance=ExtResource("1_8e51f")]
script = ExtResource("2_skiem")
[node name="traun_hull" parent="." index="0"] [node name="traun_hull" parent="." index="0"]
transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0, 0, 0) transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0, 0, 0)
layers = 4 layers = 4
gi_mode = 2 gi_mode = 2
surface_material_override/0 = SubResource("StandardMaterial3D_8e51f") surface_material_override/0 = ExtResource("3_81crm")
[node name="ApoyaCristalesLateralesPared3_LP_004_LateralesInteriores_0_001" parent="traun_hull" index="0"] [node name="ApoyaCristalesLateralesPared3_LP_004_LateralesInteriores_0_001" parent="traun_hull" index="0"]
layers = 4 layers = 4
@ -338,5 +330,6 @@ libraries = {
[node name="VoxelGI" type="VoxelGI" parent="." index="2"] [node name="VoxelGI" type="VoxelGI" parent="." index="2"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.35, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.35, 0)
layers = 4 layers = 4
subdiv = 0
size = Vector3(35, 4.6, 4) size = Vector3(35, 4.6, 4)
data = ExtResource("5_q0ort") data = ExtResource("5_q0ort")

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -41,5 +41,5 @@ process/premult_alpha=false
process/normal_map_invert_y=false process/normal_map_invert_y=false
process/hdr_as_srgb=false process/hdr_as_srgb=false
process/hdr_clamp_exposure=false process/hdr_clamp_exposure=false
process/size_limit=2048 process/size_limit=1024
detect_3d/compress_to=0 detect_3d/compress_to=0

View File

@ -41,5 +41,5 @@ process/premult_alpha=false
process/normal_map_invert_y=false process/normal_map_invert_y=false
process/hdr_as_srgb=false process/hdr_as_srgb=false
process/hdr_clamp_exposure=false process/hdr_clamp_exposure=false
process/size_limit=2048 process/size_limit=1024
detect_3d/compress_to=0 detect_3d/compress_to=0

Binary file not shown.

View File

@ -1,24 +0,0 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://dg4cq1texkil5"
path="res://.godot/imported/FoM_xavier_therapie_1.wav-5b326af67128f51afe9b270b12a8a195.sample"
[deps]
source_file="res://base-environments/volunteer_room/scenes/FoM_xavier_therapie_1.wav"
dest_files=["res://.godot/imported/FoM_xavier_therapie_1.wav-5b326af67128f51afe9b270b12a8a195.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -4,7 +4,7 @@
[ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="2_abtq0"] [ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="2_abtq0"]
[ext_resource type="Texture2D" uid="uid://bwicl5q0lw06q" path="res://import/interface-elements/bottom.png" id="3_pcx8t"] [ext_resource type="Texture2D" uid="uid://bwicl5q0lw06q" path="res://import/interface-elements/bottom.png" id="3_pcx8t"]
[ext_resource type="PackedScene" uid="uid://dvwuhobhka78d" path="res://ui/skip_control/skip_control.tscn" id="4_w4vem"] [ext_resource type="PackedScene" uid="uid://dvwuhobhka78d" path="res://ui/skip_control/skip_control.tscn" id="4_w4vem"]
[ext_resource type="AudioStream" uid="uid://dupcfwi54fpjx" path="res://base-environments/youth_room/audio/FoM_Lisa_Kindheit_Voice_Acting_deutsch_newt.wav" id="5_0dsyx"] [ext_resource type="AudioStream" uid="uid://cw1s2g8wg3120" path="res://base-environments/volunteer_room/sounds/FoM_xavier_unifood.wav" id="5_86ec2"]
[ext_resource type="AudioStream" uid="uid://d15ltkofdggly" path="res://base-environments/youth_room/audio/Voice-Training-Workshop.wav" id="6_fiu8d"] [ext_resource type="AudioStream" uid="uid://d15ltkofdggly" path="res://base-environments/youth_room/audio/Voice-Training-Workshop.wav" id="6_fiu8d"]
[ext_resource type="Script" uid="uid://c1oub0cs7cph6" path="res://dev-util/stereo-switch.gd" id="7_sh3ja"] [ext_resource type="Script" uid="uid://c1oub0cs7cph6" path="res://dev-util/stereo-switch.gd" id="7_sh3ja"]
@ -99,7 +99,7 @@ tracks/5/keys = {
[sub_resource type="Animation" id="Animation_ayw8a"] [sub_resource type="Animation" id="Animation_ayw8a"]
resource_name = "de" resource_name = "de"
length = 86.0 length = 66.0
tracks/0/type = "audio" tracks/0/type = "audio"
tracks/0/imported = false tracks/0/imported = false
tracks/0/enabled = true tracks/0/enabled = true
@ -108,11 +108,11 @@ tracks/0/interp = 1
tracks/0/loop_wrap = true tracks/0/loop_wrap = true
tracks/0/keys = { tracks/0/keys = {
"clips": [{ "clips": [{
"end_offset": 1.36178, "end_offset": 0.3525498,
"start_offset": 0.0, "start_offset": 1.6578125,
"stream": ExtResource("5_0dsyx") "stream": ExtResource("5_86ec2")
}], }],
"times": PackedFloat32Array(1.16667) "times": PackedFloat32Array(2.2000003)
} }
tracks/0/use_blend = true tracks/0/use_blend = true
tracks/1/type = "value" tracks/1/type = "value"
@ -122,10 +122,10 @@ tracks/1/path = NodePath("../../..:progress")
tracks/1/interp = 1 tracks/1/interp = 1
tracks/1/loop_wrap = true tracks/1/loop_wrap = true
tracks/1/keys = { tracks/1/keys = {
"times": PackedFloat32Array(0, 1.66667, 4.73332, 6.03333, 11.6, 12.4, 15.8333, 16.4333, 18.9334, 19.6333, 24.5333, 25.6, 29, 30.3667, 36.1333, 39.4, 40.8, 42.2333, 44.6333, 45.2667, 47.0333, 49.2333, 53.4333, 54.6333, 57.1333, 57.8333, 61.1333, 63.2667, 66.5667, 67.5, 72.4597, 74.5, 77.2667, 78.4667, 85.2), "times": PackedFloat32Array(0, 1.66667, 4.73332, 6.03333, 11.6, 12.766666, 15.8333, 16.4333, 18.266666, 19.6333, 27.1, 29.8, 35.466633, 37.3, 39.933334, 41.233334, 43.800034, 45.233334, 52.833275, 53.466667, 58.166664, 59.6, 64.2),
"transitions": PackedFloat32Array(1, 0.482968, 1, 0.482968, 1, 0.482968, 1, 0.482968, 1, 1.23114, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.287175, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968), "transitions": PackedFloat32Array(1, 0.482968, 1, 0.482968, 1, 0.482968, 1, 0.482968, 1, 1.23114, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.287175, 0.482968, 0.482968, 0.482968),
"update": 0, "update": 0,
"values": [0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0, 5.0, 5.0, 6.0, 6.0, 7.0, 7.0, 8.0, 8.0, 9.0, 9.0, 10.0, 10.0, 11.0, 11.0, 12.0, 12.0, 13.0, 13.0, 14.0, 14.0, 15.0, 15.0, 16.0, 16.0, 17.0] "values": [0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0, 5.0, 5.0, 6.0, 6.0, 7.0, 7.0, 8.0, 8.0, 9.0, 9.0, 10.0, 10.0, 11.0]
} }
tracks/2/type = "method" tracks/2/type = "method"
tracks/2/imported = false tracks/2/imported = false
@ -134,8 +134,8 @@ tracks/2/path = NodePath("../../..")
tracks/2/interp = 1 tracks/2/interp = 1
tracks/2/loop_wrap = true tracks/2/loop_wrap = true
tracks/2/keys = { tracks/2/keys = {
"times": PackedFloat32Array(24.8, 47.87, 61.7667, 74.0333, 85.2667), "times": PackedFloat32Array(18.9, 40.766666, 65.2),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1), "transitions": PackedFloat32Array(1, 1, 1),
"values": [{ "values": [{
"args": [], "args": [],
"method": &"try_scroll" "method": &"try_scroll"
@ -144,12 +144,6 @@ tracks/2/keys = {
"method": &"try_scroll" "method": &"try_scroll"
}, { }, {
"args": [], "args": [],
"method": &"try_scroll"
}, {
"args": [],
"method": &"try_scroll"
}, {
"args": [],
"method": &"_on_text_finished" "method": &"_on_text_finished"
}] }]
} }
@ -469,6 +463,7 @@ script = ExtResource("1_86ec2")
scene_id = 8 scene_id = 8
story_array = PackedStringArray("God I am so \"happy\" mom took care of everything at home. The dishes, the laundry, the trash, the groceries, the food.", "But guess what: when you are at university, they don\'t provide a mom with your dorm.", "And suddenly, you don\'t just need to study for your first semester, you need to learn to survive on your own. Good luck building good habits with that.", "I got really thin.", "I didn\'t really manage to eat at home, I didn\'t have the money to eat takeout all the time and oh my god:", "how do students manage to survive in a cafeteria?", "I mean: How do they manage to socialise, attend all the lectures, find relationships and even look passable with all that going on?", "Is it just me? I don\'t know.", "Who I am glad about tho is Jules. She has an eating order history and someday had enough of seeing my body crumble and decieded to basically adopt me.", "I could never really relate with her former eating discorder thoughts she was probably trying to get out of my head.", "But I can\'t argue against her coping strategies helping my body get the food it needed.") story_array = PackedStringArray("God I am so \"happy\" mom took care of everything at home. The dishes, the laundry, the trash, the groceries, the food.", "But guess what: when you are at university, they don\'t provide a mom with your dorm.", "And suddenly, you don\'t just need to study for your first semester, you need to learn to survive on your own. Good luck building good habits with that.", "I got really thin.", "I didn\'t really manage to eat at home, I didn\'t have the money to eat takeout all the time and oh my god:", "how do students manage to survive in a cafeteria?", "I mean: How do they manage to socialise, attend all the lectures, find relationships and even look passable with all that going on?", "Is it just me? I don\'t know.", "Who I am glad about tho is Jules. She has an eating order history and someday had enough of seeing my body crumble and decieded to basically adopt me.", "I could never really relate with her former eating discorder thoughts she was probably trying to get out of my head.", "But I can\'t argue against her coping strategies helping my body get the food it needed.")
paragraph_lengths = PackedInt32Array(1, 2, 6, 8, 10) paragraph_lengths = PackedInt32Array(1, 2, 6, 8, 10)
progress = -1.0
[node name="PanelContainer" type="PanelContainer" parent="."] [node name="PanelContainer" type="PanelContainer" parent="."]
layout_mode = 2 layout_mode = 2

View File

@ -4,7 +4,7 @@
[ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="2_00crh"] [ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="2_00crh"]
[ext_resource type="Texture2D" uid="uid://bwicl5q0lw06q" path="res://import/interface-elements/bottom.png" id="3_3iy8l"] [ext_resource type="Texture2D" uid="uid://bwicl5q0lw06q" path="res://import/interface-elements/bottom.png" id="3_3iy8l"]
[ext_resource type="PackedScene" uid="uid://dvwuhobhka78d" path="res://ui/skip_control/skip_control.tscn" id="4_32a0r"] [ext_resource type="PackedScene" uid="uid://dvwuhobhka78d" path="res://ui/skip_control/skip_control.tscn" id="4_32a0r"]
[ext_resource type="AudioStream" uid="uid://dupcfwi54fpjx" path="res://base-environments/youth_room/audio/FoM_Lisa_Kindheit_Voice_Acting_deutsch_newt.wav" id="5_bfggg"] [ext_resource type="AudioStream" uid="uid://cnhkrhtk4cirx" path="res://base-environments/volunteer_room/sounds/FoM_xavier_therapie_1.wav" id="5_x5h0q"]
[ext_resource type="AudioStream" uid="uid://d15ltkofdggly" path="res://base-environments/youth_room/audio/Voice-Training-Workshop.wav" id="6_hdxjv"] [ext_resource type="AudioStream" uid="uid://d15ltkofdggly" path="res://base-environments/youth_room/audio/Voice-Training-Workshop.wav" id="6_hdxjv"]
[ext_resource type="Script" uid="uid://c1oub0cs7cph6" path="res://dev-util/stereo-switch.gd" id="7_xkdnh"] [ext_resource type="Script" uid="uid://c1oub0cs7cph6" path="res://dev-util/stereo-switch.gd" id="7_xkdnh"]
@ -99,7 +99,7 @@ tracks/5/keys = {
[sub_resource type="Animation" id="Animation_ayw8a"] [sub_resource type="Animation" id="Animation_ayw8a"]
resource_name = "de" resource_name = "de"
length = 86.0 length = 92.0
tracks/0/type = "audio" tracks/0/type = "audio"
tracks/0/imported = false tracks/0/imported = false
tracks/0/enabled = true tracks/0/enabled = true
@ -108,11 +108,11 @@ tracks/0/interp = 1
tracks/0/loop_wrap = true tracks/0/loop_wrap = true
tracks/0/keys = { tracks/0/keys = {
"clips": [{ "clips": [{
"end_offset": 1.36178, "end_offset": 0.0,
"start_offset": 0.0, "start_offset": 0.3923047,
"stream": ExtResource("5_bfggg") "stream": ExtResource("5_x5h0q")
}], }],
"times": PackedFloat32Array(1.16667) "times": PackedFloat32Array(1.9333333)
} }
tracks/0/use_blend = true tracks/0/use_blend = true
tracks/1/type = "value" tracks/1/type = "value"
@ -122,10 +122,10 @@ tracks/1/path = NodePath("../../..:progress")
tracks/1/interp = 1 tracks/1/interp = 1
tracks/1/loop_wrap = true tracks/1/loop_wrap = true
tracks/1/keys = { tracks/1/keys = {
"times": PackedFloat32Array(0, 1.66667, 4.73332, 6.03333, 11.6, 12.4, 15.8333, 16.4333, 18.9334, 19.6333, 24.5333, 25.6, 29, 30.3667, 36.1333, 39.4, 40.8, 42.2333, 44.6333, 45.2667, 47.0333, 49.2333, 53.4333, 54.6333, 57.1333, 57.8333, 61.1333, 63.2667, 66.5667, 67.5, 72.4597, 74.5, 77.2667, 78.4667, 85.2), "times": PackedFloat32Array(0, 1.66667, 4.73332, 7.0333333, 11.6, 13.033334, 17.433332, 19.166666, 26.733334, 27.933332, 29.733202, 30.799902, 34.1999, 35.5666, 39.866665, 41.3, 46.400066, 47.833366, 52.1666, 52.8, 55.1667, 56.5, 59.033333, 60.233334, 64.9, 66.86667, 67.26674, 69.40013, 73.6, 75.46662, 78.46667, 79.4, 87.9),
"transitions": PackedFloat32Array(1, 0.482968, 1, 0.482968, 1, 0.482968, 1, 0.482968, 1, 1.23114, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.287175, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968), "transitions": PackedFloat32Array(1, 0.482968, 1, 0.482968, 1, 0.482968, 1, 0.482968, 1, 1.23114, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.287175, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968, 0.482968),
"update": 0, "update": 0,
"values": [0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0, 5.0, 5.0, 6.0, 6.0, 7.0, 7.0, 8.0, 8.0, 9.0, 9.0, 10.0, 10.0, 11.0, 11.0, 12.0, 12.0, 13.0, 13.0, 14.0, 14.0, 15.0, 15.0, 16.0, 16.0, 17.0] "values": [0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0, 5.0, 5.0, 6.0, 6.0, 7.0, 7.0, 8.0, 8.0, 9.0, 9.0, 10.0, 10.0, 11.0, 11.0, 12.0, 12.0, 13.0, 13.0, 14.0, 14.0, 15.0, 15.0, 16.0]
} }
tracks/2/type = "method" tracks/2/type = "method"
tracks/2/imported = false tracks/2/imported = false
@ -134,7 +134,7 @@ tracks/2/path = NodePath("../../..")
tracks/2/interp = 1 tracks/2/interp = 1
tracks/2/loop_wrap = true tracks/2/loop_wrap = true
tracks/2/keys = { tracks/2/keys = {
"times": PackedFloat32Array(24.8, 47.87, 61.7667, 74.0333, 85.2667), "times": PackedFloat32Array(18.166666, 49.3, 59.666668, 74.76667, 91.63333),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1), "transitions": PackedFloat32Array(1, 1, 1, 1, 1),
"values": [{ "values": [{
"args": [], "args": [],
@ -469,6 +469,7 @@ script = ExtResource("1_ym0sv")
scene_id = 6 scene_id = 6
story_array = PackedStringArray("I sometimes wish I could go back in time to save myself from Lukas.", "Sometimes I even want to fight him one last time to make him feel how much he hurt me.", "I don\'t like these thoughts, because all they do is make my head spiral into an endless void of anger and doubt.", "So on a calm mind, I just hope he learned his lesson so his next love doesn\'t need to become a survivor.", "But do I regret being one?", "I mean it has made me go to therapy and that was a good thing.", "My therapist was pretty young and still in training.", "Talking to *him* about sex never really worked for me.", "So I still don\'t know what to do about my cravings. I\'d rather not have them but I can\'t deny they exist.", "At least he gave me the tools to figure it out on my own.", "Old thoughts are here to stay, he always said. But you can choose how to react.", "And while I choose to not react to my cravings for now, I can choose something different in the future.", "He also helped me manage the gauntlet that is an ADHD diagnosis. I suspect I wouldn\'t have the executive skills to get that on my own.", "So I guess I got my medication thanks to Lukas?", "And I can tell when to brace for my period because the weird urge to make my ex hit some very hard ground is quite specific.") story_array = PackedStringArray("I sometimes wish I could go back in time to save myself from Lukas.", "Sometimes I even want to fight him one last time to make him feel how much he hurt me.", "I don\'t like these thoughts, because all they do is make my head spiral into an endless void of anger and doubt.", "So on a calm mind, I just hope he learned his lesson so his next love doesn\'t need to become a survivor.", "But do I regret being one?", "I mean it has made me go to therapy and that was a good thing.", "My therapist was pretty young and still in training.", "Talking to *him* about sex never really worked for me.", "So I still don\'t know what to do about my cravings. I\'d rather not have them but I can\'t deny they exist.", "At least he gave me the tools to figure it out on my own.", "Old thoughts are here to stay, he always said. But you can choose how to react.", "And while I choose to not react to my cravings for now, I can choose something different in the future.", "He also helped me manage the gauntlet that is an ADHD diagnosis. I suspect I wouldn\'t have the executive skills to get that on my own.", "So I guess I got my medication thanks to Lukas?", "And I can tell when to brace for my period because the weird urge to make my ex hit some very hard ground is quite specific.")
paragraph_lengths = PackedInt32Array(2, 3, 4, 5, 8, 11, 12, 14) paragraph_lengths = PackedInt32Array(2, 3, 4, 5, 8, 11, 12, 14)
progress = -1.0
[node name="PanelContainer" type="PanelContainer" parent="."] [node name="PanelContainer" type="PanelContainer" parent="."]
layout_mode = 2 layout_mode = 2

View File

@ -1,54 +0,0 @@
extends RoomTemplate
@onready var card_picker: CardPicker = %Picker
@onready var player: PlayerController = %PlayerController
func _ready():
super._ready()
id = State.rooms.ADULTHOOD
func get_ready() -> void:
super.get_ready()
Scenes.scene_finished.connect(_on_scene_finished)
card_picker.cards_picked.connect(card_board.populate_board)
save_game = State.save_game
save_game.current_room = State.rooms.ADULTHOOD
Scenes.completed_sequences = save_game.mementos_complete
Scenes.started_sequences = save_game.mementos_complete
Scenes.enabled_sequences = save_game.sequences_enabled
#FIXME: fix the bloddy card board loading algorythm
#card_board.initialise_from_save(save_game)
card_board.board_completed.connect(func():
#TODO: hook in ending
save_room()
)
func start_room():
super.start_room()
%UI.show()
%PlayerController.process_mode = Node.PROCESS_MODE_INHERIT
# Give player control immediately, then open
Scenes.player_enable.emit(true)
await Main.curtain.open()
func _on_scene_finished(_id: int, _repeat:bool):
await get_tree().create_timer(3).timeout
save_room()
func save_room():
# Update board state before saving
card_board.save_to_resource(save_game)
save_game.mementos_complete = Scenes.completed_sequences
save_game.sequences_enabled = Scenes.enabled_sequences
super.save_room()
func prepare_transition():
pass
func unload():
pass

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://datmg48duktt1"
path="res://.godot/imported/FoM_xavier_DnD.wav-a689cfa18e7eb4ed0e110e9622a5b653.sample"
[deps]
source_file="res://base-environments/volunteer_room/sounds/FoM_xavier_DnD.wav"
dest_files=["res://.godot/imported/FoM_xavier_DnD.wav-a689cfa18e7eb4ed0e110e9622a5b653.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,34 @@
extends RoomWithBoard
class_name VolunteerRoom
func _ready() -> void:
super._ready() # UwU, superclass _ready is not called by Godot automatically...
prints("volunteer_room.gd", "_ready()", self)
func get_ready_async() -> void:
await super.get_ready_async()
%TherapyVoluntaryInteractable.visible = not save_game.subway_burnout
%TherapyUniInteractable.visible = save_game.subway_burnout
card_board.board_completed.connect(func():
save_game.childhood_board_complete = true
#%DoorInteractable.show()
)
func start_room_async():
await super.start_room_async()
# Give player control immediately, then open
%PlayerController.process_mode = Node.PROCESS_MODE_INHERIT
Scenes.player_enable.emit(true)
await Main.curtain.open()
func prepare_transition():
pass
func unload():
pass

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=49 format=3 uid="uid://flisupth27th"] [gd_scene load_steps=49 format=3 uid="uid://flisupth27th"]
[ext_resource type="PackedScene" uid="uid://dwbhei5kywqbd" path="res://volunteer_room_visuals.tscn" id="1_ln5pp"] [ext_resource type="PackedScene" uid="uid://dwbhei5kywqbd" path="res://volunteer_room_visuals.tscn" id="1_ln5pp"]
[ext_resource type="Script" uid="uid://wiw2j1gw230e" path="res://base-environments/volunteer_room/shared_flat.gd" id="1_wdfvq"] [ext_resource type="Script" uid="uid://wiw2j1gw230e" path="res://base-environments/volunteer_room/volunteer_room.gd" id="1_wdfvq"]
[ext_resource type="PackedScene" uid="uid://mkccbig41bqb" path="res://logic-scenes/player_controller/player_controller.tscn" id="2_upyac"] [ext_resource type="PackedScene" uid="uid://mkccbig41bqb" path="res://logic-scenes/player_controller/player_controller.tscn" id="2_upyac"]
[ext_resource type="Script" uid="uid://c281w7earok6w" path="res://base-environments/youth_room/crouch_volume.gd" id="3_fli74"] [ext_resource type="Script" uid="uid://c281w7earok6w" path="res://base-environments/youth_room/crouch_volume.gd" id="3_fli74"]
[ext_resource type="PackedScene" uid="uid://dreokijo757l1" path="res://logic-scenes/interactable/interactable.tscn" id="5_my8p4"] [ext_resource type="PackedScene" uid="uid://dreokijo757l1" path="res://logic-scenes/interactable/interactable.tscn" id="5_my8p4"]
@ -201,11 +201,14 @@ func _on_environment_settings_update():
[node name="SharedFlat" type="Node3D"] [node name="SharedFlat" type="Node3D"]
script = ExtResource("1_wdfvq") script = ExtResource("1_wdfvq")
id = 3
[node name="PlayerController" parent="." instance=ExtResource("2_upyac")] [node name="PlayerController" parent="." instance=ExtResource("2_upyac")]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 2.2023005, 0, 0.7319784) transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 2.2023005, 0, 0.7319784)
initial_pitch = 0.0
[node name="Camera3D" parent="PlayerController/Yaw/Pitch/Mount" index="0"]
transform = Transform3D(1, 0, 0, 0, 1.0000006, 0, 0, 0, 1.0000006, 0, 0.202, 0.157)
[node name="volunteer_room" parent="." instance=ExtResource("1_ln5pp")] [node name="volunteer_room" parent="." instance=ExtResource("1_ln5pp")]
@ -226,53 +229,58 @@ shape = SubResource("CapsuleShape3D_2fihi")
[node name="Collectables" type="Node3D" parent="."] [node name="Collectables" type="Node3D" parent="."]
[node name="KitchenInteractable" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="KitchenInteractable" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(-0.999999, 0, 8.742269e-08, 0, 1, 0, -8.742269e-08, 0, -0.999999, 3.46201, 1.8257881, -4.097006) transform = Transform3D(0.999999, 0, 0, 0, 1, 0, 0, 0, 0.999999, 0.8310573, 1.0068259, -2.7083611)
interaction = ExtResource("12_6rb4d") interaction = ExtResource("12_6rb4d")
[node name="BurnoutInteractable" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="BurnoutInteractable" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(1.3113409e-07, 0, 0.999999, 0, 1, 0, -0.999999, 0, 1.3113409e-07, -2.1812932, 0.8092947, 5.313688) transform = Transform3D(0.32358676, 0, -0.94619733, 0, 1, 0, 0.94619733, 0, 0.32358676, -2.1812932, 0.8092947, 5.313688)
interaction = ExtResource("11_kmoh8") interaction = ExtResource("11_kmoh8")
[node name="DiceInteractable" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="DiceInteractable" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(-0.70710593, 0, 0.70710605, 0, 1, 0, -0.70710605, 0, -0.70710593, -2.07945, 0.5828748, 3.3940656) transform = Transform3D(0.7071059, 0, -0.7071061, 0, 1, 0, 0.7071061, 0, 0.7071059, -2.07945, 0.5828748, 3.3940656)
interaction = ExtResource("16_e1uao") interaction = ExtResource("16_e1uao")
[node name="VoluntaryInteractable" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="VoluntaryInteractable" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(-4.3711392e-08, 0, -0.999999, 0, 1, 0, 0.999999, 0, -4.3711392e-08, 0.36332494, 1.2541859, 4.9624853) transform = Transform3D(-4.3711346e-08, 0, 0.999999, 0, 1, 0, -0.999999, 0, -4.3711346e-08, 0.36332494, 1.2541859, 4.9624853)
interaction = ExtResource("17_my8p4") interaction = ExtResource("17_my8p4")
billboard = false billboard = false
[node name="TherapyVoluntaryInteractable" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="TherapyVoluntaryInteractable" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(-0.999999, 0, 8.742269e-08, 0, 1, 0, -8.742269e-08, 0, -0.999999, 0.399901, 1.21835, 1.29166) unique_name_in_owner = true
transform = Transform3D(0.999999, 0, 0, 0, 1, 0, 0, 0, 0.999999, 0.399901, 1.21835, 1.29166)
interaction = ExtResource("15_ci4rn") interaction = ExtResource("15_ci4rn")
billboard = false billboard = false
[node name="TherapyUniInteractable" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="TherapyUniInteractable" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(-0.999999, 0, 8.742269e-08, 0, 1, 0, -8.742269e-08, 0, -0.999999, 0.399901, 1.21835, 1.29166) unique_name_in_owner = true
transform = Transform3D(0.999999, 0, 0, 0, 1, 0, 0, 0, 0.999999, 0.399901, 1.21835, 1.29166)
interaction = ExtResource("14_upyac") interaction = ExtResource("14_upyac")
billboard = false billboard = false
[node name="UniversityInteractable" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="UniversityInteractable" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(-4.371135e-08, 0, 0.9999991, 0, 1, 0, -0.9999991, 0, -4.371135e-08, -2.7745893, 1.593935, -3.0279322) transform = Transform3D(-4.371135e-08, 0, -0.9999991, 0, 1, 0, 0.9999991, 0, -4.371135e-08, -2.7745893, 1.4022808, -3.0279322)
interaction = ExtResource("13_5s6pb") interaction = ExtResource("13_5s6pb")
billboard = false billboard = false
[node name="OldThougtsInteractable" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="OldThougtsInteractable" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(1.3113399e-07, 0, 0.999999, 0, 1, 0, -0.999999, 0, 1.3113399e-07, -2.40979, 0.41340256, 0.403546) transform = Transform3D(-4.3711346e-08, 0, -0.999999, 0, 1, 0, 0.999999, 0, -4.3711346e-08, -2.40979, 0.41340256, 0.403546)
interaction = ExtResource("17_my8p4") interaction = ExtResource("17_my8p4")
[node name="AutismInteractable" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="AutismInteractable" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(0.49999908, 0, 0.86602396, 0, 1, 0, -0.86602396, 0, 0.49999908, -1.8407239, 1.0439266, -3.8908288) transform = Transform3D(-0.75470823, 0, -0.65605795, 0, 1, 0, 0.65605795, 0, -0.75470823, -1.8407239, 1.0439266, -3.8908288)
interaction = ExtResource("10_gcdra") interaction = ExtResource("10_gcdra")
[node name="Board" parent="Collectables" instance=ExtResource("5_my8p4")] [node name="Board" parent="Collectables" instance=ExtResource("5_my8p4")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -2.6904116, 1.240494, 4.441236) transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -2.7652016, 1.2894461, 4.522677)
interaction = ExtResource("19_ci4rn") interaction = ExtResource("19_ci4rn")
billboard = false billboard = false
[node name="DoorInteractable" type="Node3D" parent="Collectables"]
unique_name_in_owner = true
[node name="VoxelGI" type="VoxelGI" parent="."] [node name="VoxelGI" type="VoxelGI" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.08276367, 1.3269348, 0.05317688) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.08276367, 1.3269348, 0.09955597)
size = Vector3(6.132324, 2.9212036, 12.054474) size = Vector3(6.132324, 2.9212036, 12.147232)
data = ExtResource("8_fli74") data = ExtResource("8_fli74")
[node name="Collision" type="Node3D" parent="."] [node name="Collision" type="Node3D" parent="."]
@ -374,7 +382,7 @@ shape = SubResource("BoxShape3D_2ixm0")
[node name="Scenes" type="Node3D" parent="."] [node name="Scenes" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.4831846, 0, 2.44453) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.4831846, 0, 2.44453)
[node name="ScenePlayer" type="AnimationPlayer" parent="Scenes"] [node name="SceneAnimationPlayer" type="AnimationPlayer" parent="Scenes"]
unique_name_in_owner = true unique_name_in_owner = true
libraries = { libraries = {
&"": SubResource("AnimationLibrary_br20t") &"": SubResource("AnimationLibrary_br20t")
@ -406,3 +414,5 @@ script = SubResource("GDScript_ri8p0")
environment = SubResource("Environment_pdgua") environment = SubResource("Environment_pdgua")
camera_attributes = SubResource("CameraAttributesPractical_0bxa6") camera_attributes = SubResource("CameraAttributesPractical_0bxa6")
script = SubResource("GDScript_3k3rl") script = SubResource("GDScript_3k3rl")
[editable path="PlayerController"]

View File

@ -26,5 +26,5 @@ func scene_finished(_id: Scenes.id, _repeat: bool):
queue("RESET") queue("RESET")
func play(anin_name: StringName = "", a: float = -1, b: float = 1, c: bool = false) -> void: func play(anin_name: StringName = "", a: float = -1, b: float = 1, c: bool = false) -> void:
print_debug("anim player accessed!") print("anim player accessed!")
super.play(anin_name, a, b, c) super.play(anin_name, a, b, c)

View File

@ -21,4 +21,4 @@ edit/normalize=false
edit/loop_mode=2 edit/loop_mode=2
edit/loop_begin=0 edit/loop_begin=0
edit/loop_end=-1 edit/loop_end=-1
compress/mode=0 compress/mode=2

View File

@ -21,4 +21,4 @@ edit/normalize=false
edit/loop_mode=2 edit/loop_mode=2
edit/loop_begin=0 edit/loop_begin=0
edit/loop_end=-1 edit/loop_end=-1
compress/mode=0 compress/mode=2

View File

@ -21,4 +21,4 @@ edit/normalize=false
edit/loop_mode=2 edit/loop_mode=2
edit/loop_begin=0 edit/loop_begin=0
edit/loop_end=-1 edit/loop_end=-1
compress/mode=0 compress/mode=2

View File

@ -21,4 +21,4 @@ edit/normalize=false
edit/loop_mode=0 edit/loop_mode=0
edit/loop_begin=0 edit/loop_begin=0
edit/loop_end=-1 edit/loop_end=-1
compress/mode=0 compress/mode=2

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=96 format=4 uid="uid://b3b0gyvklqn50"] [gd_scene load_steps=90 format=4 uid="uid://b3b0gyvklqn50"]
[ext_resource type="Script" uid="uid://bsop46tqngddc" path="res://base-environments/youth_room/youth_room.gd" id="1_aitp0"] [ext_resource type="Script" uid="uid://bsop46tqngddc" path="res://base-environments/youth_room/youth_room.gd" id="1_aitp0"]
[ext_resource type="AudioStream" uid="uid://1h6k2d8q1kw3" path="res://base-environments/youth_room/import/sounds/rain_on_window.mp3" id="2_3haaq"] [ext_resource type="AudioStream" uid="uid://1h6k2d8q1kw3" path="res://base-environments/youth_room/import/sounds/rain_on_window.mp3" id="2_3haaq"]
@ -6,7 +6,6 @@
[ext_resource type="Script" uid="uid://c281w7earok6w" path="res://base-environments/youth_room/crouch_volume.gd" id="3_x3dlb"] [ext_resource type="Script" uid="uid://c281w7earok6w" path="res://base-environments/youth_room/crouch_volume.gd" id="3_x3dlb"]
[ext_resource type="Script" uid="uid://hji6r2e8mcqo" path="res://base-environments/youth_room/climb_volume.gd" id="4_dqyng"] [ext_resource type="Script" uid="uid://hji6r2e8mcqo" path="res://base-environments/youth_room/climb_volume.gd" id="4_dqyng"]
[ext_resource type="PackedScene" uid="uid://bnskiyx1sksww" path="res://logic-scenes/board/physics-board.tscn" id="4_gyjxx"] [ext_resource type="PackedScene" uid="uid://bnskiyx1sksww" path="res://logic-scenes/board/physics-board.tscn" id="4_gyjxx"]
[ext_resource type="PackedScene" uid="uid://citwb7f4dl3l1" path="res://thank-you.tscn" id="5_kts6y"]
[ext_resource type="AnimationLibrary" uid="uid://c80h2b0uyk27g" path="res://animations/youth_intro.res" id="8_bgk6f"] [ext_resource type="AnimationLibrary" uid="uid://c80h2b0uyk27g" path="res://animations/youth_intro.res" id="8_bgk6f"]
[ext_resource type="Texture2D" uid="uid://bwicl5q0lw06q" path="res://import/interface-elements/bottom.png" id="8_e5y1q"] [ext_resource type="Texture2D" uid="uid://bwicl5q0lw06q" path="res://import/interface-elements/bottom.png" id="8_e5y1q"]
[ext_resource type="AudioStream" uid="uid://cudna8k7fw06t" path="res://base-environments/youth_room/audio/Moving Loop.wav" id="8_egnow"] [ext_resource type="AudioStream" uid="uid://cudna8k7fw06t" path="res://base-environments/youth_room/audio/Moving Loop.wav" id="8_egnow"]
@ -116,27 +115,6 @@ size = Vector3(1.63347, 0.305693, 0.775269)
[sub_resource type="BoxShape3D" id="BoxShape3D_bq15k"] [sub_resource type="BoxShape3D" id="BoxShape3D_bq15k"]
size = Vector3(0.244565, 1, 0.245859) size = Vector3(0.244565, 1, 0.245859)
[sub_resource type="InputEventKey" id="InputEventKey_p2hyr"]
device = -1
keycode = 88
unicode = 120
[sub_resource type="InputEventJoypadButton" id="InputEventJoypadButton_e2vy5"]
button_index = 2
pressed = true
[sub_resource type="Shortcut" id="Shortcut_b3maf"]
events = [SubResource("InputEventKey_p2hyr"), SubResource("InputEventJoypadButton_e2vy5")]
[sub_resource type="GDScript" id="GDScript_uy50s"]
script/source = "extends Panel
func show():
mouse_filter = MOUSE_FILTER_STOP
visible = true
"
[sub_resource type="GDScript" id="GDScript_dqyng"] [sub_resource type="GDScript" id="GDScript_dqyng"]
script/source = "extends CenterContainer script/source = "extends CenterContainer
@ -177,10 +155,6 @@ _surfaces = [{
blend_shape_mode = 0 blend_shape_mode = 0
shadow_mesh = SubResource("ArrayMesh_lag5h") shadow_mesh = SubResource("ArrayMesh_lag5h")
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_dqyng"]
radius = 0.5600586
height = 1.2539063
[sub_resource type="GDScript" id="GDScript_35dmj"] [sub_resource type="GDScript" id="GDScript_35dmj"]
script/source = "extends SpotLight3D script/source = "extends SpotLight3D
@ -422,12 +396,19 @@ func hide():
[node name="youth room" type="Node3D" groups=["serializable"]] [node name="youth room" type="Node3D" groups=["serializable"]]
process_mode = 1 process_mode = 1
script = ExtResource("1_aitp0") script = ExtResource("1_aitp0")
id = 1
[node name="logic" type="Node3D" parent="."] [node name="logic" type="Node3D" parent="."]
[node name="PlayerController" parent="logic" groups=["camera_owner"] instance=ExtResource("3_foj4y")] [node name="PlayerController" parent="logic" groups=["camera_owner"] instance=ExtResource("3_foj4y")]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(0.686123, 0, 0.727485, 0, 1, 0, -0.727485, 0, 0.686123, 0.63, 0, 0.925) transform = Transform3D(0.686123, 0, 0.727485, 0, 1, 0, -0.727485, 0, 0.686123, 0.5654894, 0, 0.8411364)
[node name="Yaw" parent="logic/PlayerController" index="1"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.25, 0)
[node name="Pitch" parent="logic/PlayerController/Yaw" index="0"]
transform = Transform3D(1, 0, 0, 0, 0.64278716, -0.7660439, 0, 0.7660439, 0.64278716, 0, 0, 0)
[node name="Collision" type="Node3D" parent="logic"] [node name="Collision" type="Node3D" parent="logic"]
@ -603,31 +584,11 @@ grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2 mouse_filter = 2
[node name="ending_button" type="Button" parent="logic/UI"]
visible = false
top_level = true
layout_mode = 0
offset_left = 16.0
offset_top = 12.0
offset_right = 400.0
offset_bottom = 100.0
shortcut = SubResource("Shortcut_b3maf")
text = "You have completed
ordering your thoughts.
This is as far as the demo goes.
Press x or [ ] to wrap up."
[node name="Picker" parent="logic/UI" groups=["scene_actors"] instance=ExtResource("19_a4n1o")] [node name="Picker" parent="logic/UI" groups=["scene_actors"] instance=ExtResource("19_a4n1o")]
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false
layout_mode = 1 layout_mode = 1
[node name="ending" parent="logic/UI" instance=ExtResource("5_kts6y")]
visible = false
layout_mode = 1
mouse_filter = 2
script = SubResource("GDScript_uy50s")
[node name="Opening" type="CenterContainer" parent="logic/UI"] [node name="Opening" type="CenterContainer" parent="logic/UI"]
visible = false visible = false
layout_mode = 1 layout_mode = 1
@ -778,59 +739,44 @@ light_size = 20.0
omni_range = 16.8518 omni_range = 16.8518
[node name="MaskInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="MaskInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-0.8827416, 0, 0.4698562, 0, 1, 0, -0.4698562, 0, -0.8827416, -0.032227404, 0.58693635, 2.5655098) transform = Transform3D(0.8829465, 0, -0.4694709, 0, 1, 0, 0.4694709, 0, 0.8829465, -0.05572912, 0.60013723, 2.536849)
interaction = ExtResource("12_viwxf") interaction = ExtResource("12_viwxf")
[node name="MindBoardInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="MindBoardInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-4.371126e-08, 0, -0.9999984, 0, 1, 0, 0.9999984, 0, -4.371126e-08, -0.907206, 1.17661, 1.74337) transform = Transform3D(-4.3711317e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4.3711317e-08, -0.907206, 1.1721482, 1.6486336)
interaction = ExtResource("4_gyjxx") interaction = ExtResource("4_gyjxx")
billboard = false billboard = false
[node name="Frame" parent="logic/MindBoardInteractable" index="0"] [node name="Frame" parent="logic/MindBoardInteractable" index="2"]
transform = Transform3D(0.99999994, 0, 3.5527137e-15, 0, 1, 0, -3.5527137e-15, 0, 0.99999994, -0.08004689, -0.023632765, 0) transform = Transform3D(0.99999994, 0, 3.5527137e-15, 0, 1, 0, -3.5527137e-15, 0, 0.99999994, -0.08004689, -0.023632765, 0)
[node name="View" parent="logic/MindBoardInteractable" index="1"]
transform = Transform3D(-0.9999999, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -0.9999999, -0.08611119, 0.040526867, -0.06492537)
[node name="CeilingInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="CeilingInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(0.78626597, 0, 0.6178859, 0, 1, 0, -0.6178859, 0, 0.78626597, -0.13478619, 2.0720484, -0.42032808) transform = Transform3D(-0.7858558, 0, -0.6184074, 0, 1, 0, 0.6184074, 0, -0.7858558, -0.13478619, 2.0720484, -0.42032808)
interaction = ExtResource("19_d3c7p") interaction = ExtResource("19_d3c7p")
[node name="ComicInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="ComicInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(0.9797145, 0, 0.20039362, 0, 1, 0, -0.20039362, 0, 0.9797145, 2.8945682, 0.2537475, -0.88938636) transform = Transform3D(-0.86689585, 0, -0.49848735, 0, 1, 0, 0.49848735, 0, -0.86689585, 3.324154, 0.23257843, -0.91425914)
interaction = ExtResource("13_v3447") interaction = ExtResource("13_v3447")
[node name="View" parent="logic/ComicInteractable" index="1"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.36574292, 0.099999994, 0.032779038)
[node name="ClothesInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="ClothesInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(0.7935111, 0, -0.60855323, 0, 1, 0, 0.60855323, 0, 0.7935111, 1.6334484, 1.1331886, -0.8914416) transform = Transform3D(-0.79335207, 0, 0.6087605, 0, 1, 0, -0.6087605, 0, -0.79335207, 1.5984986, 1.1640409, -0.8420157)
interaction = ExtResource("12_x3dlb") interaction = ExtResource("12_x3dlb")
[node name="Sprite3D" parent="logic/ClothesInteractable/View" index="0"]
transform = Transform3D(1, 0, 2.9802322e-08, 0, 1, 0, -2.9802322e-08, 0, 1, -0.003991425, -0.04700005, 0.09138596)
[node name="collectable_particles" parent="logic/ClothesInteractable" index="3"] [node name="collectable_particles" parent="logic/ClothesInteractable" index="3"]
transform = Transform3D(0.99999976, 0, 0, 0, 1, 0, 0, 0, 0.99999976, 0.10009599, -0.040801764, -0.19775379) transform = Transform3D(0.99999976, 0, 0, 0, 1, 0, 0, 0, 0.99999976, 0.10009599, -0.040801764, -0.19775379)
[node name="DoorInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="DoorInteractable" parent="logic" instance=ExtResource("22_ks23q")]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(-0.9999984, 0, 8.7422585e-08, 0, 1, 0, -8.7422585e-08, 0, -0.9999984, 0.42437345, 0.9173807, -0.95442796) transform = Transform3D(-0.9999984, 0, 8.7422585e-08, 0, 1, 0, -8.7422585e-08, 0, -0.9999984, 0.50242007, 0.91625494, -0.9138791)
visible = false visible = false
interaction = ExtResource("11_5bsh1") interaction = ExtResource("11_5bsh1")
billboard = false billboard = false
[node name="View" parent="logic/DoorInteractable" index="1"] [node name="Frame" parent="logic/DoorInteractable" index="2"]
transform = Transform3D(-0.99999964, 0, -8.7422755e-08, 0, 1, 0, 8.7422755e-08, 0, -0.99999964, 0.30241805, 0.49012983, -5.9604645e-08) transform = Transform3D(-0.99999994, 0, 8.7422755e-08, 0, 1, 0, -8.7422755e-08, 0, -0.99999994, 0.03345099, 0.03331518, 0)
[node name="Area3D" parent="logic/DoorInteractable" index="2"]
transform = Transform3D(0.9999998, 0, 2.1316282e-14, 0, 1, 0, -2.1316282e-14, 0, 0.9999998, 0.5580833, 0.16355383, 0)
[node name="CollisionShape3D" parent="logic/DoorInteractable/Area3D" index="0"]
transform = Transform3D(-4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, 0, 1, -0.2322388, 0, 0)
shape = SubResource("CapsuleShape3D_dqyng")
[node name="RoomAnimationPlayer" type="AnimationPlayer" parent="."] [node name="RoomAnimationPlayer" type="AnimationPlayer" parent="."]
unique_name_in_owner = true
libraries = { libraries = {
&"": ExtResource("23_corra") &"": ExtResource("23_corra")
} }
@ -952,15 +898,16 @@ light_cull_mask = 4293918721
omni_range = 0.147682 omni_range = 0.147682
[node name="OmniLight3D2" type="OmniLight3D" parent="visuals/lights"] [node name="OmniLight3D2" type="OmniLight3D" parent="visuals/lights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.10614, 0.582081, 0.161548) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.837372, 0.7908516, -0.36576784)
light_color = Color(0.894118, 0.87451, 0.686275, 1) light_color = Color(0.894118, 0.87451, 0.686275, 1)
light_size = 0.2 light_size = 0.2
light_specular = 0.1 light_specular = 0.1
light_bake_mode = 1 light_bake_mode = 1
light_cull_mask = 4293918721 light_cull_mask = 4293918721
shadow_enabled = true shadow_enabled = true
omni_range = 2.0 shadow_caster_mask = 4293918721
omni_attenuation = 0.450626 omni_range = 1.733925
omni_attenuation = 0.3
[node name="OmniLight3D4" type="OmniLight3D" parent="visuals/lights"] [node name="OmniLight3D4" type="OmniLight3D" parent="visuals/lights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.47143, 1.6968, -0.548992) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.47143, 1.6968, -0.548992)
@ -1075,7 +1022,6 @@ light_array = Array[Vector3]([Vector3(-0.545, 0.915, 1.035), Vector3(-0.47, 0.85
[node name="VoxelGI" type="VoxelGI" parent="."] [node name="VoxelGI" type="VoxelGI" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.6709186, 1.184079, 0.941082) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.6709186, 1.184079, 0.941082)
subdiv = 2
size = Vector3(6.1783752, 2.4035423, 4.126381) size = Vector3(6.1783752, 2.4035423, 4.126381)
data = ExtResource("40_ea6x8") data = ExtResource("40_ea6x8")
@ -1087,10 +1033,8 @@ data = ExtResource("40_ea6x8")
[connection signal="body_exited" from="logic/Bed and Ladders/bed_duck" to="logic/Bed and Ladders/ladder" method="reset"] [connection signal="body_exited" from="logic/Bed and Ladders/bed_duck" to="logic/Bed and Ladders/ladder" method="reset"]
[connection signal="body_entered" from="logic/Bed and Ladders/bed_enter" to="logic/PlayerController" method="_on_bed_enter"] [connection signal="body_entered" from="logic/Bed and Ladders/bed_enter" to="logic/PlayerController" method="_on_bed_enter"]
[connection signal="body_exited" from="logic/Bed and Ladders/reset_failover" to="logic/PlayerController" method="_on_bed_exit"] [connection signal="body_exited" from="logic/Bed and Ladders/reset_failover" to="logic/PlayerController" method="_on_bed_exit"]
[connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending_button" method="hide"]
[connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending" method="show"]
[editable path="logic/PlayerController"]
[editable path="logic/MindBoardInteractable"] [editable path="logic/MindBoardInteractable"]
[editable path="logic/ComicInteractable"]
[editable path="logic/ClothesInteractable"] [editable path="logic/ClothesInteractable"]
[editable path="logic/DoorInteractable"] [editable path="logic/DoorInteractable"]

View File

@ -1,85 +0,0 @@
class_name InteractiveSprite extends Area3D
@export var interaction_ui: PackedScene = null
@onready var pass_to_actor: = $UiWrapper/UiSprite/SubViewport/CollectableUi
@onready var wrapper := $UiWrapper
@onready var ui: CollectableUi = $UiWrapper/UiSprite/SubViewport.get_child(0)
@onready var viewport:= $UiWrapper/UiSprite/SubViewport
@onready var distance_tween: Tween
var revealed: bool = false:
set(reveal):
revealed = reveal
if reveal:
wrapper.show()
if distance_tween != null:
if distance_tween.is_running(): distance_tween.stop()
distance_tween = get_tree().create_tween()
distance_tween.tween_property($UiWrapper/Frame, ^":visibility_range_end", 3.0, 1.0)
else:
wrapper.hide()
ui.vanish()
if distance_tween != null:
if distance_tween.is_running(): distance_tween.stop()
distance_tween = get_tree().create_tween()
distance_tween.tween_property($UiWrapper/Frame, ^":visibility_range_end", 0.6, 1.0)
await get_tree().create_timer(1).timeout
if not ui.visible:
wrapper.hide()
var has_mouse: bool = false
# Automatically triggered story playback - e.g. for Intro in Youth Room
func play_story() -> void:
await ui.collect_memento()
# Called when the node enters the scene tree for the first time.
func _ready():
if interaction_ui:
%CanvasLayer.add_child(interaction_ui.instantiate())
ui.canvas_layer = %CanvasLayer
# Find and wire the interaction UI (StoryPlayable or CardBoard)
for child in %CanvasLayer.get_children():
if child is CardBoard:
ui.interaction_ui = child
break
elif child is Control:
ui.interaction_ui = child
break
# Connect playback_finished to restore player control
ui.playback_finished.connect(_on_playback_finished)
func _on_mouse_entered():
if not Scenes.is_playing:
input_ray_pickable = false
has_mouse = true
func _on_mouse_exited():
input_ray_pickable = true
has_mouse = false
func try_reveal(for_player: PlayerController) -> bool:
print_debug("reveal ui!")
revealed = ui.try_reveal()
if revealed:
call_deferred("wait_for_ui_exit", for_player)
return revealed
func wait_for_ui_exit(for_player: PlayerController):
await for_player.ui_exited
collapse()
func collapse():
_on_mouse_exited()
revealed = false
func _on_playback_finished():
# Restore player control via central signal
Scenes.player_enable.emit(true)
func handle(event: InputEvent):
viewport.push_input(event)

View File

@ -1 +0,0 @@
uid://dr4wd80dobxjd

View File

@ -1,17 +1,19 @@
class_name YouthRoom class_name YouthRoom
extends RoomTemplate extends RoomWithBoard
## Used by the room system when this room becomes active func _ready() -> void:
# var is_active: bool = false # Reminder, do not uncomment, this field is inherited from RoomTemplate! super._ready() # UwU, superclass _ready is not called by Godot automatically...
prints("youth_room.gd", "_ready()", self)
@onready var card_picker: CardPicker = %Picker
@onready var ui: Control = %UI
func start_room(): func get_ready() -> void:
super.start_room() await super.get_ready_async()
prints("youth_room.gd", "get_ready()", self)
%UI.show() await Main.curtain.open()
func start_room_async():
await super.start_room_async()
await Main.curtain.open() await Main.curtain.open()
# To start breathing etc. # To start breathing etc.
@ -23,10 +25,12 @@ func start_room():
await _play_intro_scene() await _play_intro_scene()
else: else:
%LightAnimationPlayer.lights_on() %LightAnimationPlayer.lights_on()
%SceneAnimationPlayer.start_soundtrack()
if not State.save_game.childhood_board_complete:
P.instruction.call_deferred("Find all three Momentos to collect all thoughts.")
Scenes.player_enable.emit(true) Scenes.player_enable.emit(true)
@ -36,55 +40,14 @@ func _play_intro_scene() -> void:
await intro.interact() await intro.interact()
func get_ready():
super.get_ready()
prints("indeed")
Scenes.scene_finished.connect(_on_scene_finished)
card_board.board_completed.connect(func():
%DoorInteractable.show()
if not save_game.is_childhood_board_complete:
save_game.is_childhood_board_complete = true
save_room()
)
pull_save_state(State.save_game)
card_board.closed.connect(save_room)
card_picker.cards_picked.connect(card_board.populate_board)
ui.hide()
$sfx/distant_rain.play()
$"sfx/rain on window".play()
await get_tree().process_frame
func pull_save_state(save: SaveGame) -> void: func pull_save_state(save: SaveGame) -> void:
save_game = save super.pull_save_state(save)
save_game.current_room = id prints("youth_room.gd", "pull_save_state()", self)
# Load board state from save first, before overwriting it
card_board.initialise_from_save(save_game)
# TODO: These should be deprecated, SaveGame is our source of truth, and that contains what's complete etc.
Scenes.started_sequences = save_game.mementos_complete Scenes.started_sequences = save_game.mementos_complete
Scenes.completed_sequences = save_game.mementos_complete Scenes.completed_sequences = save_game.mementos_complete
# Call parent to restore player position
super.pull_save_state(save)
func _on_scene_finished(_id: int, _repeat:bool):
await get_tree().create_timer(3).timeout
save_room()
func save_room():
# Update board state before saving
card_board.save_to_resource(save_game)
save_game.mementos_complete = Scenes.completed_sequences
super.save_room()
## Override to handle scene-specific preparation (chest reveal animation) ## Override to handle scene-specific preparation (chest reveal animation)
func prepare_scene_start(scene_id: Scenes.id, is_repeating: bool) -> void: func prepare_scene_start(scene_id: Scenes.id, is_repeating: bool) -> void:
@ -97,3 +60,7 @@ func play_chest_reveal() -> void:
$visuals/AnimationPlayer.play("chest_reveal") $visuals/AnimationPlayer.play("chest_reveal")
$visuals/SecondaryAnimation.play("chest_reveal") $visuals/SecondaryAnimation.play("chest_reveal")
await $visuals/AnimationPlayer.animation_finished await $visuals/AnimationPlayer.animation_finished
func play_thunder() -> void:
%RoomAnimationPlayer.play("lightning_and_thunder")

View File

@ -8,11 +8,21 @@ func _ready() -> void:
Scenes.scene_finished.connect(_on_scene_finished) Scenes.scene_finished.connect(_on_scene_finished)
func start_soundtrack(): func start_soundtrack():
$Moving.play(70) _fade_in($Moving)
$Childhood.play(70) _fade_in($Childhood,)
$VoiceTraining.play(70) _fade_in($VoiceTraining)
var tween := create_tween()
tween.tween_property($Moving, "volume_db", 0, 3.0)
func _fade_in(audio_stream : AudioStreamPlayer) -> void:
if not audio_stream.playing:
audio_stream.volume_db = -80
audio_stream.play(70)
func _on_scene_starting(scene_id: Scenes.id, _repeat: bool) -> void: func _on_scene_starting(scene_id: Scenes.id, _repeat: bool) -> void:
print("YouthRoomScenePlayer._on_scene_starting(%s)" % Scenes.id.keys()[scene_id])
# Handle scene-specific music # Handle scene-specific music
# Note: Chest animation is now handled by YouthRoom.prepare_scene_start() # Note: Chest animation is now handled by YouthRoom.prepare_scene_start()
@ -25,18 +35,22 @@ func _on_scene_starting(scene_id: Scenes.id, _repeat: bool) -> void:
play("jui_jutsu_music") play("jui_jutsu_music")
Scenes.id.YOUTH_DRAVEN: Scenes.id.YOUTH_DRAVEN:
play("draeven") play("draeven")
_: pass
func _on_scene_finished(scene_id: Scenes.id, _repeat: bool) -> void: func _on_scene_finished(scene_id: Scenes.id, _repeat: bool) -> void:
print_debug("YouthRoomScenePlayer._on_scene_finished(%s)" % Scenes.id.keys()[scene_id]) print("YouthRoomScenePlayer._on_scene_finished(%s)" % Scenes.id.keys()[scene_id])
match scene_id: match scene_id:
Scenes.id.YOUTH_CHILDHOOD: Scenes.id.YOUTH_CHILDHOOD:
play_backwards("childhood_music") play_backwards("childhood_music")
Scenes.id.YOUTH_VOICE_TRAINING: Scenes.id.YOUTH_VOICE_TRAINING:
play_backwards("voice_music") play_backwards("voice_music")
Scenes.id.YOUTH_JUI_JUTSU:
play_backwards("jui_jutsu_music")
queue("RESET") queue("RESET")
func play(anim_name: StringName = "", a: float = -1, b: float = 1, c: bool = false) -> void: func play(anim_name: StringName = "", a: float = -1, b: float = 1, c: bool = false) -> void:
print_debug("YouthRoomScenePlayer.play(%s)" % anim_name) print("YouthRoomScenePlayer.play(%s)" % anim_name)
super.play(anim_name, a, b, c) super.play(anim_name, a, b, c)

View File

@ -6,7 +6,7 @@ class_name ThemedButton extends Button
@onready var lower_corner_decor := load("res://import/interface-elements/lower_corner.png") @onready var lower_corner_decor := load("res://import/interface-elements/lower_corner.png")
func _ready() -> void: func _ready() -> void:
print_debug(owner) print(owner)
rebuild() rebuild()
theme_changed.connect(rebuild) theme_changed.connect(rebuild)
resized.connect(rebuild) resized.connect(rebuild)

View File

@ -0,0 +1,22 @@
[gd_resource type="Resource" script_class="SaveGame" load_steps=2 format=3]
[ext_resource type="Script" path="res://dev-util/savegame.gd" id="1_sn6m6"]
[resource]
script = ExtResource("1_sn6m6")
unique_save_name = "frame_of_mind_2026-01-19_11-00-01-1526668039"
current_room = 1
board_positions = Dictionary[StringName, Vector2]({
&"c_confusion": Vector2(378, 687),
&"c_out_of_world": Vector2(452, 202),
&"p_outer_conflict": Vector2(-66, 83),
&"p_unique": Vector2(-66, 83)
})
board_attachments = Dictionary[StringName, StringName]({
&"p_outer_conflict": &"c_confusion",
&"p_unique": &"c_out_of_world"
})
childhood_board_complete = true
player_position = Vector3(0.63, -0.016315194, 0.925)
player_pitch = 0.87266463
last_saved = 1769029158

View File

@ -0,0 +1,23 @@
[gd_resource type="Resource" script_class="SaveGame" load_steps=2 format=3]
[ext_resource type="Script" path="res://dev-util/savegame.gd" id="1_8nsia"]
[resource]
script = ExtResource("1_8nsia")
unique_save_name = "frame_of_mind_2026-01-19_15-33-27-3130526064"
current_room = 1
mementos_complete = 3
board_positions = Dictionary[StringName, Vector2]({
&"c_confusion": Vector2(650, 582),
&"c_gifted": Vector2(1113, 592),
&"c_homework": Vector2(448, 707),
&"c_rejection": Vector2(197, 885),
&"p_good_grades": Vector2(133.33333, 440),
&"p_joy": Vector2(133.33333, 330),
&"p_laughed_at": Vector2(133.33333, 220),
&"p_outer_conflict": Vector2(133.33333, 110)
})
player_position = Vector3(0.61196893, -0.008183508, 1.9193625)
player_yaw = 0.61379147
player_pitch = -0.2038608
last_saved = 1768833300

View File

@ -0,0 +1,19 @@
[gd_resource type="Resource" script_class="SaveGame" load_steps=2 format=3 uid="uid://0tj8owvtod7q"]
[ext_resource type="Script" uid="uid://d06gpwuxmkxkt" path="res://dev-util/savegame.gd" id="1_mikml"]
[resource]
script = ExtResource("1_mikml")
unique_save_name = "frame_of_mind_2026-01-19_15-47-39-3506336039"
current_room = 1
mementos_complete = 1
board_positions = Dictionary[StringName, Vector2]({
&"c_out_of_world": Vector2(665, 759),
&"c_rejection": Vector2(281, 918),
&"p_finding_friends": Vector2(133.33333, 219.99997),
&"p_unique": Vector2(133.33333, 109.999985)
})
player_position = Vector3(0.6317782, -0.0027222226, 0.92837244)
player_yaw = 2.777015
player_pitch = -0.29538974
last_saved = 1768834191

View File

@ -0,0 +1,27 @@
[gd_resource type="Resource" script_class="SaveGame" load_steps=2 format=3 uid="uid://d2kixmoun8vv0"]
[ext_resource type="Script" uid="uid://d06gpwuxmkxkt" path="res://dev-util/savegame.gd" id="1_25kue"]
[resource]
script = ExtResource("1_25kue")
unique_save_name = "frame_of_mind_2026-01-19_16-30-10-1028460818"
current_room = 1
mementos_complete = 7
board_positions = Dictionary[StringName, Vector2]({
&"c_boy_stuff": Vector2(564, 318),
&"c_comic_heroes": Vector2(1397, 863),
&"c_confusion": Vector2(869, 234),
&"c_gifted": Vector2(187, 743),
&"c_rejection": Vector2(428, 717),
&"c_teachers": Vector2(253, 412),
&"p_becoming_teacher": Vector2(133.33331, 330),
&"p_effort": Vector2(133.33331, 660),
&"p_finding_friends": Vector2(133.33331, 219.99997),
&"p_inner_conflict": Vector2(133.33331, 109.999985),
&"p_pretending": Vector2(133.33331, 550),
&"p_upset_peers": Vector2(133.33331, 439.99994)
})
player_position = Vector3(3.203781, -0.0027222226, 0.5082533)
player_yaw = -0.53694016
player_pitch = -0.26962742
last_saved = 1768836806

View File

@ -0,0 +1,18 @@
[gd_resource type="Resource" script_class="SaveGame" load_steps=2 format=3 uid="uid://jbp7nfc2afb4"]
[ext_resource type="Script" uid="uid://d06gpwuxmkxkt" path="res://dev-util/savegame.gd" id="1_n0fgw"]
[resource]
script = ExtResource("1_n0fgw")
unique_save_name = "frame_of_mind_2026-01-21_15-06-29-376758416"
current_room = 1
board_positions = Dictionary[StringName, Vector2]({
&"c_confusion": Vector2(482, 974),
&"c_rejection": Vector2(241, 866),
&"p_laughed_at": Vector2(133.33333, 110),
&"p_outer_conflict": Vector2(133.33333, 220)
})
childhood_board_complete = true
player_position = Vector3(0.63, -0.016315194, 0.925)
player_pitch = 0.87266463
last_saved = 1769029090

View File

@ -34,7 +34,7 @@ func _process(delta: float) -> void:
_on_beat() _on_beat()
_last_beat_timing = sync_to.get_playback_position() _last_beat_timing = sync_to.get_playback_position()
else: else:
if not Engine.is_editor_hint(): print_debug(time_left) if not Engine.is_editor_hint(): print(time_left)
func start(time_sec: float = 0, starting_beat: int = 0, starting_bar: int = 0, sync_to_playback:AudioStreamPlayback = null) -> void: func start(time_sec: float = 0, starting_beat: int = 0, starting_bar: int = 0, sync_to_playback:AudioStreamPlayback = null) -> void:
if starting_bar == 0 and starting_beat > 0: starting_bar = starting_beat / beats_per_bar if starting_bar == 0 and starting_beat > 0: starting_bar = starting_beat / beats_per_bar

View File

@ -16,14 +16,13 @@ func create_bug_report():
OS: %s OS: %s
GPU: %s GPU: %s
Current Focus: %s
Current Scene: %s Current Scene: %s
Mementos: %s Mementos: %s
""" % [OS.get_name(), OS.get_video_adapter_driver_info(), Scenes.current_sequence, State.current_room, Scenes.completed_sequences] """ % [OS.get_name(), OS.get_video_adapter_driver_info(), State.room, Scenes.completed_sequences]
#debug_text = debug_text.replace(" ", "%20").replace("\n", "%0A").replace("\t", "") #debug_text = debug_text.replace(" ", "%20").replace("\n", "%0A").replace("\t", "")
DisplayServer.clipboard_set(debug_text) DisplayServer.clipboard_set(debug_text)
#print_debug("mailto:support@polynormal.games?subject=Frame%20of%20Mind%20Demo%20-%20Bug%20Report&body=" + debug_text) #print("mailto:support@polynormal.games?subject=Frame%20of%20Mind%20Demo%20-%20Bug%20Report&body=" + debug_text)

View File

@ -5,7 +5,7 @@ extends Area3D
@onready var viewport: SubViewport = $UiSprite/SubViewport @onready var viewport: SubViewport = $UiSprite/SubViewport
func _process(_delta): func _process(_delta : float) -> void:
if billboard: if billboard:
var camera := get_viewport().get_camera_3d() var camera := get_viewport().get_camera_3d()
@ -14,14 +14,13 @@ func _process(_delta):
look_at(global_position - (camera.global_position - global_position), up) look_at(global_position - (camera.global_position - global_position), up)
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
if event is InputEventAction: if event is InputEventAction:
print_debug(event.action) print(event.action)
#func _unhandled_input(event):
# viewport.push_input(event)
func _on_input_event(_camera: Camera3D, event: InputEvent, pos: Vector3, _normal: Vector3, _shape_idx: int): func _on_input_event(_camera: Camera3D, event: InputEvent, pos: Vector3, _normal: Vector3, _shape_idx: int) -> void:
if not Scenes.is_playing: if not Scenes.is_playing:
# Position of the event in Sprite3D local coordinates. # Position of the event in Sprite3D local coordinates.
var texture_3d_position := sprite.get_global_transform().affine_inverse() * pos var texture_3d_position := sprite.get_global_transform().affine_inverse() * pos
@ -37,8 +36,8 @@ func _on_input_event(_camera: Camera3D, event: InputEvent, pos: Vector3, _normal
e.set_global_position(texture_position) e.set_global_position(texture_position)
viewport.push_input(e) viewport.push_input(e)
func _on_button_pressed(): func _on_button_pressed() -> void:
print_debug("Button pressed") print("Button pressed")
func _on_line_edit_text_submitted(new_text): func _on_line_edit_text_submitted(new_text) -> void:
print_debug("Text submitted: ", new_text) print("Text submitted: ", new_text)

View File

@ -1,4 +1,4 @@
[gd_resource type="Resource" script_class="SaveGame" format=3 uid="uid://pndvrrytubnr"] [gd_resource type="Resource" script_class="SaveGame" load_steps=2 format=3 uid="uid://pndvrrytubnr"]
[ext_resource type="Script" uid="uid://d06gpwuxmkxkt" path="res://dev-util/savegame.gd" id="1_jr18u"] [ext_resource type="Script" uid="uid://d06gpwuxmkxkt" path="res://dev-util/savegame.gd" id="1_jr18u"]
@ -6,6 +6,6 @@
script = ExtResource("1_jr18u") script = ExtResource("1_jr18u")
unique_save_name = "DEBUG" unique_save_name = "DEBUG"
current_room = 3 current_room = 3
mementos_complete = 1669 mementos_complete = 1665
sequences_enabled = 255 sequences_enabled = 255
metadata/_custom_type_script = "uid://d06gpwuxmkxkt" metadata/_custom_type_script = "uid://d06gpwuxmkxkt"

View File

@ -1,6 +1,7 @@
class_name HardcodedCards extends Control class_name HardcodedCards extends Control
@onready var card_prefab : PackedScene = preload("res://logic-scenes/board/card.tscn") @onready var card_prefab : PackedScene = preload("res://logic-scenes/board/card.tscn")
@onready var void_prefab : PackedScene = preload("res://logic-scenes/board/void_card.tscn")
@onready var note_prefab : PackedScene = preload("res://logic-scenes/board/sticky-note.tscn") @onready var note_prefab : PackedScene = preload("res://logic-scenes/board/sticky-note.tscn")
var source_dicts: Array[Dictionary] = [ var source_dicts: Array[Dictionary] = [
@ -183,12 +184,21 @@ func get_cards_by_scene_id(id: int) -> Array[Card]:
var output:Array[Card] var output:Array[Card]
for card_name in source_dicts[id].keys(): for card_name in source_dicts[id].keys():
var card := card_prefab.instantiate() as Card var card : Card = _create_card(card_name)
card.init(card_name, all_ids[card_name]); card.init(card_name, all_ids[card_name]);
output.append(card) output.append(card)
return output return output
func _create_card(card_name: StringName) -> Card:
match card_name:
&"c_void": return void_prefab.instantiate() as Card
&"3.c_void": return void_prefab.instantiate() as Card
_: return card_prefab.instantiate() as Card
# used to put cards on the dev board # used to put cards on the dev board
func get_cards_by_name_array(names: Array[StringName]) -> Dictionary[String, Array]: func get_cards_by_name_array(names: Array[StringName]) -> Dictionary[String, Array]:
var output:Dictionary[String, Array] = { var output:Dictionary[String, Array] = {
@ -201,7 +211,7 @@ func get_cards_by_name_array(names: Array[StringName]) -> Dictionary[String, Arr
output["cards"].append(create_from_id(all_ids[card_name])) output["cards"].append(create_from_id(all_ids[card_name]))
else: else:
if not card_name in sticky_ids: if not card_name in sticky_ids:
push_error("No card or sticky with name '%s'!" % card_name) push_warning("get_cards_by_name_array: Skipping card or sticky with unknown name '%s'!" % card_name)
else: else:
output["sticky_notes"].append(create_from_id(all_ids[card_name])) output["sticky_notes"].append(create_from_id(all_ids[card_name]))
@ -210,7 +220,7 @@ func get_cards_by_name_array(names: Array[StringName]) -> Dictionary[String, Arr
func create_from_id(id:StringName) -> Area2D: func create_from_id(id:StringName) -> Area2D:
var parsed: PackedStringArray = id.rsplit(".") var parsed: PackedStringArray = id.rsplit(".")
if card_ids.values().has(id): if card_ids.values().has(id):
var card := card_prefab.instantiate() as Card var card := _create_card(id)
card.init(parsed[1], id); card.init(parsed[1], id);
return card return card
elif sticky_ids.values().has(id): elif sticky_ids.values().has(id):
@ -218,7 +228,7 @@ func create_from_id(id:StringName) -> Area2D:
note.init(parsed[2], id) note.init(parsed[2], id)
return note return note
else: else:
push_error("Attempted to create Card or Sticky from non-existent ID!") push_error("create_from_id: Attempted to create Card or Sticky from non-existent ID!")
return null return null
func create_dev_board(parent: Control, _rect: Rect2) -> void: func create_dev_board(parent: Control, _rect: Rect2) -> void:

View File

@ -2,7 +2,7 @@
[ext_resource type="Script" uid="uid://dysgoaaesqjbg" path="res://dev-util/hardcoded_cards.gd" id="1_5kg6w"] [ext_resource type="Script" uid="uid://dysgoaaesqjbg" path="res://dev-util/hardcoded_cards.gd" id="1_5kg6w"]
[node name="Node2D" type="PanelContainer"] [node name="HardcodedCards" type="PanelContainer"]
process_mode = 4 process_mode = 4
visible = false visible = false
anchors_preset = 15 anchors_preset = 15
@ -11,4 +11,6 @@ anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
focus_behavior_recursive = 1 focus_behavior_recursive = 1
mouse_filter = 2
mouse_behavior_recursive = 1
script = ExtResource("1_5kg6w") script = ExtResource("1_5kg6w")

View File

@ -2,11 +2,10 @@
extends Node extends Node
func get_memento_prompt(count: int) -> StringName: func get_memento_prompt(count: int) -> StringName:
return TranslationServer.translate(_memento_prompts.get(count, "")) return TranslationServer.translate(_memento_prompts.get(count, str(count)))
func get_story_caption(id: Scenes.id) -> StringName: func get_story_caption(id: Scenes.id) -> StringName:
return TranslationServer.translate(_story_captions.get(id, "")) return _story_captions.get(id, "(missing story caption)")
const _memento_prompts: Dictionary[int, StringName] = { const _memento_prompts: Dictionary[int, StringName] = {
1: "There are three Mementos left to find.", 1: "There are three Mementos left to find.",

View File

@ -57,7 +57,7 @@ func _ready() -> void:
stream = AudioStreamPolyphonic.new() stream = AudioStreamPolyphonic.new()
func play(from_position: float = 0.0): func play(from_position: float = 0.0):
print_debug("got called") print("got called")
super.play(from_position) super.play(from_position)
self._play(from_position) self._play(from_position)

87
src/dev-util/room.gd Normal file
View File

@ -0,0 +1,87 @@
extends Node3D
## A Room is a location that can be played through, and it emits a proceed signal that holds
## the scene path to the next room (or null for credits roll)
class_name Room
@onready var ui: Control = %UI
## Tells the main loop to proceed to the next scene
signal proceed(next_scene_path: String)
@export var id: State.rooms = State.rooms.NULL
@onready var player: PlayerController = %PlayerController
@onready var scene_player : AnimationPlayer = %SceneAnimationPlayer
## get-only property with the current authoritative savegame.
var save_game : SaveGame:
get: return State.save_game
func _ready() -> void:
assert(id != State.rooms.NULL, "Room " + str(self) + name + " has no proper ID set, it's still State.Rooms.NULL")
prints("room.gd", "_ready()", self)
State.room = self
if not save_game:
var debug_save_path := "res://dev-util/debug_save.tres"
push_warning("Room initialised without a SaveGame. Making a copy of ", debug_save_path)
State.save_game = ResourceLoader.load(debug_save_path).duplicate(true)
if not Main.normal_boot:
_debug_mode()
func get_ready_async():
prints("----------", "GET_READY", self.name, "--------------")
pull_save_state(save_game)
save_game.seen.append(name)
func start_room_async():
prints("----------", "START_ROOM", self.name, "--------------")
await get_tree().process_frame # so this registers as a coroutine in IDE
func play() -> String:
for i in range(20): await get_tree().process_frame #HACK - can probably be removed
await get_ready_async()
await start_room_async()
var next_room : StringName = await proceed
prints("----------", "PROCEEDING", next_room, "--------------")
return next_room
func pull_save_state(save: SaveGame) -> void:
# Override this function to load the state of the chapter from State.save_game
restore_player_from_save(save)
## Attempts to find player controller and restore position/rotation from save
func restore_player_from_save(save: SaveGame) -> void:
# only restore the player if we've already been in this room
if name in save.seen:
player.restore_from_save(save)
func save_room():
prints("room.gd", "save_room", self)
save_game.save_to_file(get_tree().root.get_texture())
func unload():
# Override this function to clean up things not owned by this room
pass
## Called before a scene starts to allow room-specific preparation (e.g., animations)
## Override in subclasses to add custom scene preparation logic
func prepare_scene_start(_scene_id: Scenes.id, _is_repeating: bool) -> void:
prints("PREPARE SCENE", _scene_id, _is_repeating)
await get_tree().process_frame # Dummy wait for LSP warning otherwise
## Override this (and call super._debug_mode()) if you want to initialize some data
## for running this Room standalone ("play current scene")
func _debug_mode() -> void:
push_warning("room.gd: DEBUG MODE - ", self)
await get_tree().create_timer(1).timeout
play()

View File

@ -1,80 +0,0 @@
class_name RoomTemplate extends Node3D
var initialised: bool = false
var id: State.rooms = State.rooms.NULL
@onready var scene_player : AnimationPlayer = %SceneAnimationPlayer
@onready var card_board : CardBoard # Optional Board, if present - set by the board in its own _ready()
var save_game:SaveGame = null
signal proceed(next_scene_path: String)
func _ready() -> void:
State.room = self
State.current_room = id
if not State.save_game:
push_warning("Room initialised without a SaveGame. Creating proxy save.")
State.save_game = ResourceLoader.load("res://dev-util/debug_save.tres")
save_game = State.save_game
save_game.current_room = id
save_game.player_position = %PlayerController.global_position
if not Main.normal_boot:
push_warning("------- DEBUG MODE --------")
play.call_deferred()
func disable()-> void:
push_warning("Room disabling is deprecated / unter reconstruction")
func get_ready():
prints("----------", "GET_READY", self.name, "--------------")
pass
func play() -> String:
await get_ready()
await start_room()
var next_room : StringName = await proceed
prints("----------", "PROCEEDING", next_room, "--------------")
return next_room
func start_room():
prints("----------", "START_ROOM", self.name, "--------------")
Main.curtain.open()
func pull_save_state(_save: SaveGame) -> void:
# Override this function to load the state of the chapter from State.save_game
restore_player_from_save(_save)
## Attempts to find player controller and restore position/rotation from save
func restore_player_from_save(save: SaveGame) -> void:
var player: PlayerController = null
# Try to find player controller in common locations
if has_node("%PlayerController"):
player = get_node("%PlayerController")
elif has_node("logic/PlayerController"):
player = get_node("logic/PlayerController")
if player and player is PlayerController:
player.restore_from_save(save)
else:
print_debug("RoomTemplate: Could not find PlayerController to restore position")
func save_room():
save_game.save_to_file(get_tree().root.get_texture())
func unload():
# Override this function to clean up things not owned by this room
pass
## Called before a scene starts to allow room-specific preparation (e.g., animations)
## Override in subclasses to add custom scene preparation logic
func prepare_scene_start(_scene_id: Scenes.id, _is_repeating: bool) -> void:
prints("PREPARE SCENE", _scene_id, _is_repeating)
await get_tree().process_frame # Dummy wait for LSP warning otherwise

View File

@ -0,0 +1,52 @@
extends Room
## A room with a CardBoard in it, has some special properties and initialization rules!
class_name RoomWithBoard
@onready var card_picker: CardPicker = %Picker
var card_board : CardBoard # Initialized by CardBoard itself.
func _ready() -> void:
super._ready() # UwU, superclass _ready is not called by Godot automatically...
prints("room_with_board.gd", "_ready()", self, owner)
func get_ready_async():
super.get_ready_async()
prints("room_with_board.gd", "get_ready()", self)
assert(card_board, str(self) + " has no CardBoard")
# Interactions can this way load their correct prompts
get_tree().call_group("interactables", "pull_save_state")
Scenes.scene_finished.connect(_on_scene_finished)
card_picker.cards_picked.connect(card_board.populate_board)
card_board.closed.connect(save_room)
card_board.board_completed.connect(func():
save_game.childhood_board_complete = true
%DoorInteractable.show()
)
# This MUST happen after the board_completed signal connection, or the door will remain locked
card_board.initialise_from_save(save_game)
func _on_scene_finished(_id: int, _repeat:bool):
await get_tree().create_timer(1).timeout # Formerly there was a 3 second wait here.
save_room.call_deferred()
func save_room():
prints("room_with_board.gd", "save_room", self)
card_board.save_to_resource(save_game)
#TODO these should be deprecated
save_game.mementos_complete = Scenes.completed_sequences
save_game.sequences_enabled = Scenes.enabled_sequences
super.save_room()

View File

@ -0,0 +1 @@
uid://demkhdo5aj71j

View File

@ -18,8 +18,8 @@ class_name SaveGame extends Resource
## Scenes / Items / IDs that were seen ## Scenes / Items / IDs that were seen
@export var seen : Array[StringName] = [] @export var seen : Array[StringName] = []
@export var is_childhood_board_complete: bool = false @export var childhood_board_complete: bool = false
@export var burnout : bool = false @export var subway_burnout : bool = false
@export var player_position : Vector3 = Vector3.ZERO @export var player_position : Vector3 = Vector3.ZERO
@export var player_yaw : float = 0.0 @export var player_yaw : float = 0.0
@ -76,7 +76,7 @@ static func create_new() -> SaveGame:
if not DirAccess.dir_exists_absolute(save.file_name.get_base_dir()): if not DirAccess.dir_exists_absolute(save.file_name.get_base_dir()):
DirAccess.make_dir_absolute(save.file_name.get_base_dir()) DirAccess.make_dir_absolute(save.file_name.get_base_dir())
print_debug("SaveGame: Created new save: %s" % save.file_name) print("SaveGame: Created new save: %s" % save.file_name)
return save return save
## Loads an existing save from disk ## Loads an existing save from disk
@ -126,7 +126,7 @@ func capture_player_state() -> void:
player_yaw = yaw.rotation.y player_yaw = yaw.rotation.y
player_pitch = pitch.rotation.x player_pitch = pitch.rotation.x
print_debug("SaveGame: Captured player state - pos: %s, yaw: %.2f, pitch: %.2f" % [player_position, player_yaw, player_pitch]) print("SaveGame: Captured player state - pos: %s, yaw: %.2f, pitch: %.2f" % [player_position, player_yaw, player_pitch])
## Saves to disk with thumbnail ## Saves to disk with thumbnail
func save_to_file(screen_shot: Texture2D) -> void: func save_to_file(screen_shot: Texture2D) -> void:
@ -134,11 +134,15 @@ func save_to_file(screen_shot: Texture2D) -> void:
push_warning("SaveGame: DEBUG save skipped (intentional).") push_warning("SaveGame: DEBUG save skipped (intentional).")
return return
if current_room == State.rooms.NULL: assert(State.room, "Trying to save while not in a room.")
push_warning("SaveGame: Not saving empty savegame.") assert(State.room.id != State.rooms.NULL, "Trying to save in a room that's not correctly initialized.")
return
print_debug("SaveGame: Saving to file: %s" % file_name) # Save game can track the room it is in by itself;
# and we should never save before having successfully entered a room.
current_room = State.room.id
prints("-----------", "SAVE POINT", State.room, "-----------")
print("SaveGame: Saving to file: %s" % file_name)
# Capture current state # Capture current state
capture_player_state() capture_player_state()
@ -152,7 +156,7 @@ func save_to_file(screen_shot: Texture2D) -> void:
if result != OK: if result != OK:
push_error("Failed to save resource to: %s (Error: %d)" % [file_name, result]) push_error("Failed to save resource to: %s (Error: %d)" % [file_name, result])
else: else:
print_debug("Successfully saved to: %s" % file_name) print("Successfully saved to: %s" % file_name)
## Processes and saves thumbnail as PNG ## Processes and saves thumbnail as PNG
func _save_thumbnail(screen_shot: Texture2D) -> void: func _save_thumbnail(screen_shot: Texture2D) -> void:
@ -174,8 +178,6 @@ func _save_thumbnail(screen_shot: Texture2D) -> void:
# === Legacy Validation (may want to be removed) === # === Legacy Validation (may want to be removed) ===
func _validate() -> bool: func _validate() -> bool:
if current_room < 0 or current_room >= State.rooms.keys().size():
return false
return _validate_board_state() return _validate_board_state()
func _validate_board_state() -> bool: func _validate_board_state() -> bool:
@ -184,7 +186,7 @@ func _validate_board_state() -> bool:
if not position is Vector2: if not position is Vector2:
push_error("Save %s: Corrupted board positions" % unique_save_name) push_error("Save %s: Corrupted board positions" % unique_save_name)
return false return false
# Validate attachments (sticky must exist, card must exist) # Validate attachments (sticky must exist, card must exist)
for sticky_name in board_attachments.keys(): for sticky_name in board_attachments.keys():
var card_name := board_attachments[sticky_name] var card_name := board_attachments[sticky_name]

View File

@ -17,4 +17,4 @@ func vanish():
get_parent_control().visible = false get_parent_control().visible = false
#func _input(event: InputEvent) -> void: #func _input(event: InputEvent) -> void:
# print(event) # print(event : InputEvent)

View File

@ -17,7 +17,7 @@ func _process(delta):
func _on_scene_actors_animation_finished(anim_name): func _on_scene_actors_animation_finished(anim_name):
print_debug(\"yay\") print(\"yay\")
" "
[sub_resource type="Shader" id="Shader_tcvor"] [sub_resource type="Shader" id="Shader_tcvor"]

View File

@ -19,10 +19,10 @@ func _on_pressed() -> void:
script/source = "extends MenuButton script/source = "extends MenuButton
func _ready() -> void: func _ready() -> void:
mouse_entered.connect(func(id): print_debug(\"mouse_entered\")) mouse_entered.connect(func(id): print(\"mouse_entered\"))
get_popup().id_pressed.connect(func(id): print_debug(\"id_pressed\")) get_popup().id_pressed.connect(func(id): print(\"id_pressed\"))
get_popup().index_pressed.connect(func(id): print_debug(\"id_pressed\")) get_popup().index_pressed.connect(func(id): print(\"id_pressed\"))
get_popup().id_focused.connect(func(id): print_debug(\"id_focused\")) get_popup().id_focused.connect(func(id): print(\"id_focused\"))
" "

File diff suppressed because one or more lines are too long

View File

@ -16,9 +16,6 @@ func _ready():
elif item is StickyNote: elif item is StickyNote:
spawn_sticky_note((item as StickyNote).duplicate()) spawn_sticky_note((item as StickyNote).duplicate())
func _process(delta: float):
pass
func spawn_card(card: Card): func spawn_card(card: Card):
$cards.add_child(card) $cards.add_child(card)

View File

@ -17,7 +17,7 @@ var board_was_completed: bool = false
var current_context : int = NAVIGATE var current_context : int = NAVIGATE
var selection_state : SelectionState var selection_state : SelectionState
@onready var instructions := $instructions_panel/HBoxContainer/cards_remaining #@onready var instructions := $instructions_panel/HBoxContainer/cards_remaining
@onready var dropzone : Control = %CardZone @onready var dropzone : Control = %CardZone
@onready var notezone : Control = %NoteZone @onready var notezone : Control = %NoteZone
@ -26,16 +26,46 @@ enum SelectionState {FREE,STICKIES,CARDS}
enum {NAVIGATE, ASSIGN, DRAG} enum {NAVIGATE, ASSIGN, DRAG}
func _ready() -> void:
prints("card-board.gd:", "_ready()", self, "room:", State.room, owner)
super._ready()
_delayed_ready.call_deferred()
# We need to wait for our room further up our parent hierarchy to actually make itself known
# for interactables to do things with it, e.g. CardBoard needs to register itself
func _delayed_ready() ->void:
var board_room := State.room as RoomWithBoard
assert(board_room, "CardBoard spawned in room that's not a RoomWithboard.")
board_room.card_board = self
## Updates prompt label based on the interaction type and collected state
func _show_prompt() -> void:
var overrides : Array[StringName] = [&"menu_back"]
P.right_bottom(P.pick(&"ui_cancel"), overrides)
P.instruction(I18n.get_memento_prompt(mementos_collected))
P.performed.connect(_perform)
func _hide_prompt():
P.performed.disconnect(_perform)
P.clear()
func play(): func play():
_show_prompt()
check_board_completion() check_board_completion()
await closed await closed
print("CardBoard.gd: closing")
_finalize_board_state() _finalize_board_state()
_hide_prompt()
var mementos_collected: int = 0: var mementos_collected: int = 0:
set(mementos): set(mementos):
mementos_collected = mementos mementos_collected = mementos
instructions.text = I18n.get_memento_prompt(mementos_collected)
var selection: Draggable = null: var selection: Draggable = null:
@ -67,38 +97,39 @@ func _navigate_prev():
selection = candidates[index-1] selection = candidates[index-1]
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
print_debug("CardBoard.gd: %s._ready()" % self.name)
super._ready()
# HACK: Lets us debug more easily
if get_parent() == get_tree().root:
_debug_mode()
return
print("Board Ready!", self, "room", State.room) ## frame rate independent FIR smoothing filter used for small or dynamic card adjustments
State.room.card_board = self
## frame rate independent FIR smoothing filter
func _smooth(current: Vector2, goal: Vector2, delta: float) -> Vector2: func _smooth(current: Vector2, goal: Vector2, delta: float) -> Vector2:
var k := pow(0.1, 60.0 * delta) var k := pow(0.9, 60.0 * delta)
return (1.0-k) * current + k * goal return (k) * current + (1.0-k) * goal
func _process(delta: float): func _process(delta: float):
var zone_position := Vector2(notezone.get_screen_position().x + sticky_width / 3.0, sticky_height) var zone_position := Vector2(notezone.get_screen_position().x + sticky_width / 3.0, sticky_height)
var dragging := notes.any(func (n : Draggable): return n.is_dragged)
if dragging:
# Y-sort the nodes, this lets us fill the gap more nicely.
notes.sort_custom(func (a:Draggable, b:Draggable): return a.global_position.y < b.global_position.y)
for note in notes: for note in notes:
# Skip all dragged and already attached notes # Skip all dragged and already attached notes
if note.is_attached: continue if note.is_attached: continue
if note.is_dragged: continue if note.is_dragged: continue
# Magnetically move all notes to where they ought to be on screen # Magnetically move all notes to where they ought to be on screen
note.position = _smooth(note.position, zone_position, delta) note.home = zone_position
zone_position.y += sticky_height zone_position.y += sticky_height
pass # Only if not already in transit / animated or user holding on to one
if not dragging and not note.tween:
note.animate_home()
else:
# do adjustment with FIR filter
note.position = _smooth(note.position, note.home, delta)
note.z_index = 0
func _check_completion() -> void: func _check_completion() -> void:
@ -120,18 +151,25 @@ func _finalize_board_state() -> void:
# Reset context to NAVIGATE # Reset context to NAVIGATE
current_context = NAVIGATE current_context = NAVIGATE
print_debug("CardBoard: Board state finalized") print("CardBoard: Board state finalized")
func _ensure_unique(items: Array[StringName]) -> Array[StringName]:
var result : Array[StringName] = []
for item in items:
if item not in result: result.append(item)
else: push_warning("card-board.gd: ", "discarding non-unique item ", item)
return result
## Spawn Cards and Post-Its ## Spawn Cards and Post-Its
# TODO: rename to "add to board" # TODO: rename to "add to board"
func populate_board(names: Array[StringName]): func populate_board(names: Array[StringName]):
mementos_collected += 1 mementos_collected += 1
for item in names: names = _ensure_unique(names)
assert(name not in all_names, "Tried to re-add card %s" % item)
var all_new:Dictionary = HardCards.get_cards_by_name_array(names) var all_new:Dictionary = HardCards.get_cards_by_name_array(names)
all_names.append_array(all_new.keys())
for new_card: Card in all_new["cards"]: for new_card: Card in all_new["cards"]:
add_card(new_card) add_card(new_card)
@ -195,7 +233,7 @@ func add_card(card: Card) -> void:
func add_note(note: StickyNote) -> void: func add_note(note: StickyNote) -> void:
add_child(note) add_child(note)
notes.append(note) notes.append(note)
note.is_dragable = true note.is_draggable = true
func appear(): func appear():
await Main.curtain.close() await Main.curtain.close()
@ -207,10 +245,6 @@ func vanish():
hide() hide()
await Main.curtain.open() await Main.curtain.open()
# Checks if a Node is currently inside the dropzone
func is_in_dropzone(to_check: Draggable) -> bool:
return dropzone.get_rect().has_point(to_check.global_position) #TODO: is global pos correct here?
# Called by notes when a mouse event needs handling # Called by notes when a mouse event needs handling
func handle_mouse_button(input: InputEventMouseButton, target: Draggable) -> void: func handle_mouse_button(input: InputEventMouseButton, target: Draggable) -> void:
@ -249,31 +283,12 @@ func _end_drag(draggable: Draggable) -> void:
# If dropped on a card, attach it # If dropped on a card, attach it
if destination and destination is Card: if destination and destination is Card:
var target_card := destination as Card var target_card := destination as Card
target_card.attach_or_exchange_note(sticky)
# If sticky was previously attached to a different card, detach it first
if sticky.is_attached and sticky.attached_to != target_card:
sticky.attached_to.remove_sticky_note()
# If target card already has a sticky, exchange them
if target_card.has_sticky_note_attached():
var exchanged_sticky := target_card.exchange_sticky_note_with(sticky)
# Reclaim the exchanged sticky to the board
if exchanged_sticky:
reclaim_sticky(exchanged_sticky)
else:
# Simple attach
sticky.reparent(target_card)
target_card.attach_sticky_note(sticky)
# If dropped on board (no destination), ensure it's a child of the board # If dropped on board (no destination), ensure it's a child of the board
elif not destination: elif not destination:
# If it was attached to a card, detach it first
if sticky.is_attached: if sticky.is_attached:
sticky.attached_to.remove_sticky_note() reclaim_sticky(sticky)
# Make sure sticky is parented to board
if sticky.get_parent() != self:
sticky.reparent(self)
# Check win condition after any sticky movement # Check win condition after any sticky movement
check_board_completion() check_board_completion()
@ -281,6 +296,7 @@ func _end_drag(draggable: Draggable) -> void:
func reclaim_sticky(note: StickyNote): func reclaim_sticky(note: StickyNote):
note.reparent(self) note.reparent(self)
note.tween = null
func check_board_completion(): func check_board_completion():
@ -301,16 +317,14 @@ var complete: bool = false
func give_lore_feedback(): func give_lore_feedback():
var fitting_card_count: int = 0 var fitting_card_count: int = 0
var total_card_count: int = 0 var total_card_count: int = len(cards)
for child in dropzone.get_children(): for child in cards:
if child is Card: if child.has_note_attached():
if child.has_sticky_note_attached(): fitting_card_count += int(child.card_id == child.get_attached_note().parent_id)
fitting_card_count += int(child.card_id == child.get_attached_sticky_note().parent_id)
total_card_count += 1
if float(fitting_card_count) / float(total_card_count) < 0.2: if float(fitting_card_count) / float(total_card_count) < 0.2:
instructions.text = "You can move on, but you may not have understood Lisa." P.instruction("You can move on, but you may not have understood Lisa.")
if not unfitting: if not unfitting:
if State.speech_language == 2: if State.speech_language == 2:
$AnimationPlayer.play("unfitting_de") $AnimationPlayer.play("unfitting_de")
@ -318,7 +332,7 @@ func give_lore_feedback():
$AnimationPlayer.play("unfitting") $AnimationPlayer.play("unfitting")
unfitting = true unfitting = true
elif fitting_card_count < total_card_count: elif fitting_card_count < total_card_count:
instructions.text = TranslationServer.translate("You may leave the room, but Lisa only agrees with %d of the %d connections.") % [fitting_card_count, total_card_count] P.instruction(TranslationServer.translate("You may leave the room, but Lisa only agrees with %d of the %d connections.") % [fitting_card_count, total_card_count])
if not incomplete: if not incomplete:
if State.speech_language == 2: if State.speech_language == 2:
$AnimationPlayer.play("incomplete_de") $AnimationPlayer.play("incomplete_de")
@ -326,7 +340,7 @@ func give_lore_feedback():
$AnimationPlayer.play("incomplete") $AnimationPlayer.play("incomplete")
incomplete = true incomplete = true
else: else:
instructions.text = "Lisa would like you to leave her room and move on." P.instruction("Lisa would like you to leave her room and move on.")
if not complete: if not complete:
if State.speech_language == 2: if State.speech_language == 2:
$AnimationPlayer.play("complete_de") $AnimationPlayer.play("complete_de")
@ -366,11 +380,12 @@ func _nearest_hovered(candidates: Array[Draggable]) -> Draggable:
func _by_spatial(a: Draggable, b: Draggable) -> bool: func _by_spatial(a: Draggable, b: Draggable) -> bool:
return a.position.x + a.position.y * 100 > b.position.x + b.position.y * 100 return a.position.x + a.position.y * 10000 > b.position.x + b.position.y * 10000
func _by_mouse(a: Draggable, b: Draggable) -> bool: func _by_mouse(a: Draggable, b: Draggable) -> bool:
var mouse_pos : Vector2 = get_viewport().get_mouse_position() var viewport := get_viewport() # when app closes, the sorting might still be going on
var mouse_pos : Vector2 = viewport.get_mouse_position() if viewport else Vector2.ZERO
return (a.position-mouse_pos).length() < (b.position-mouse_pos).length() return (a.position-mouse_pos).length() < (b.position-mouse_pos).length()
@ -394,12 +409,13 @@ func handle_drop(draggable: Draggable) -> int:
return Draggable.DropResult.ACCEPTED return Draggable.DropResult.ACCEPTED
# Takes the inputs for control inputs func _perform(action : StringName) -> void:
func _input(event) -> void: match action:
if event.is_action_pressed("ui_cancel"): &"ui_cancel": closed.emit()
closed.emit()
get_viewport().set_input_as_handled()
# Takes the inputs for control inputs
func _input(event : InputEvent) -> void:
if selection and not selection.is_dragged and event is InputEventMouseMotion and not event.is_action_pressed("mouse_left"): if selection and not selection.is_dragged and event is InputEventMouseMotion and not event.is_action_pressed("mouse_left"):
var candidate := _nearest_hovered(_sort_by_proximity_and_depth(notes)) var candidate := _nearest_hovered(_sort_by_proximity_and_depth(notes))
if not candidate: if not candidate:
@ -412,25 +428,25 @@ func save_to_resource(savegame: SaveGame) -> void:
savegame.board_positions.clear() savegame.board_positions.clear()
savegame.board_attachments.clear() savegame.board_attachments.clear()
print_debug("CardBoard: Saving board state...") print("CardBoard: Saving board state...")
# Save all cards and their positions # Save all cards and their positions
for card in cards: for card in cards:
savegame.board_positions[card.name] = card.position savegame.board_positions[card.name] = card.position
print_debug(" Card '%s' at %s" % [card.name, card.position]) print(" Card '%s' at %s" % [card.name, card.position])
# Save sticky note attachment if present # Save sticky note attachment if present
var note: StickyNote = card.get_attached_sticky_note() var note: StickyNote = card.get_attached_note()
if note: if note:
savegame.board_attachments[note.name] = card.name savegame.board_attachments[note.name] = card.name
print_debug(" Sticky '%s' attached to card '%s'" % [note.name, card.name]) print(" Sticky '%s' attached to card '%s'" % [note.name, card.name])
# Save loose sticky notes (not attached to cards) # Save loose sticky notes (not attached to cards)
for note in notes: for note in notes:
savegame.board_positions[note.name] = note.position savegame.board_positions[note.name] = note.position
print_debug(" Loose sticky '%s' at %s" % [note.name, note.position]) print(" Loose sticky '%s' at %s" % [note.name, note.position])
print_debug("CardBoard: Saved %d positions, %d attachments" % [ print("CardBoard: Saved %d positions, %d attachments" % [
savegame.board_positions.size(), savegame.board_positions.size(),
savegame.board_attachments.size() savegame.board_attachments.size()
]) ])
@ -440,11 +456,11 @@ func save_to_resource(savegame: SaveGame) -> void:
func initialise_from_save(savegame: SaveGame) -> void: func initialise_from_save(savegame: SaveGame) -> void:
# Early return if nothing to load # Early return if nothing to load
if savegame.board_positions.is_empty(): if savegame.board_positions.is_empty():
print_debug("CardBoard: No board state to load (save is empty or legacy format)") print("CardBoard: No board state to load (save is empty or legacy format)")
return return
print_debug("CardBoard: Loading board state from save...") print("CardBoard: Loading board state from save...")
print_debug(" Positions: %d, Attachments: %d" % [ print(" Positions: %d, Attachments: %d" % [
savegame.board_positions.size(), savegame.board_positions.size(),
savegame.board_attachments.size() savegame.board_attachments.size()
]) ])
@ -466,7 +482,7 @@ func initialise_from_save(savegame: SaveGame) -> void:
if card_name not in all_names: if card_name not in all_names:
all_names.append(card_name) all_names.append(card_name)
print_debug(" Collected %d unique card/sticky names to load" % all_names.size()) print(" Collected %d unique card/sticky names to load" % all_names.size())
# Create all cards and stickies # Create all cards and stickies
populate_board(all_names) populate_board(all_names)
@ -483,35 +499,34 @@ func initialise_from_save(savegame: SaveGame) -> void:
for card: Card in cards: for card: Card in cards:
if savegame.board_positions.has(card.name): if savegame.board_positions.has(card.name):
card.position = savegame.board_positions[card.name] card.position = savegame.board_positions[card.name]
print_debug(" Card '%s' at %s" % [card.name, card.position]) print(" Card '%s' at %s" % [card.name, card.position])
else: else:
card.position = _generate_random_position() card.position = _generate_random_position()
push_warning(" Card '%s' - no saved position, using random" % card.name) print(" Card '%s' - no saved position, using random" % card.name)
# Attach sticky notes to cards or position them loose # Attach sticky notes to cards or position them loose
for sticky: StickyNote in notes: for sticky: StickyNote in notes:
var card_name: StringName = savegame.board_attachments.get(sticky.name, &"") var card_name: StringName = savegame.board_attachments.get(sticky.name, &"--nil--")
if card_name and cards_by_name.has(card_name): if card_name and cards_by_name.has(card_name):
# Sticky is attached to a card # Sticky must be attached to a card
var card: Card = cards_by_name[card_name] var card: Card = cards_by_name[card_name]
sticky.reparent(card) card.attach_or_exchange_note(sticky, true)
card.attach_sticky_note(sticky) print(" Sticky '%s' attached to card '%s'" % [sticky.name, card_name])
print_debug(" Sticky '%s' attached to card '%s'" % [sticky.name, card_name])
else: else:
# Sticky is loose on the board # Sticky is loose on the board
if savegame.board_positions.has(sticky.name): if savegame.board_positions.has(sticky.name):
sticky.position = savegame.board_positions[sticky.name] sticky.position = savegame.board_positions[sticky.name]
print_debug(" Loose sticky '%s' at %s" % [sticky.name, sticky.position]) print(" Loose sticky '%s' at %s" % [sticky.name, sticky.position])
else: else:
# Fallback to center of board # Fallback to center of board
sticky.position = position + size / 2.0 sticky.position = position + size / 2.0
push_warning(" Sticky '%s' - no saved position, using center" % sticky.name) print(" Sticky '%s' - no saved position, using center" % sticky.name)
# Re-sort by positions for correct z-ordering # Re-sort by positions for correct z-ordering
_sort_by_positions() _sort_by_positions()
print_debug("CardBoard: Load complete!") print("CardBoard: Load complete!")
_check_completion() _check_completion()
@ -526,7 +541,7 @@ var _selection_candidates : Array[Draggable]:
SelectionState.CARDS: return cards as Array[Draggable] SelectionState.CARDS: return cards as Array[Draggable]
SelectionState.STICKIES: return notes as Array[Draggable] SelectionState.STICKIES: return notes as Array[Draggable]
SelectionState.FREE: SelectionState.FREE:
print_debug("switching from free selection to guided stickies selection") print("switching from free selection to guided stickies selection")
# Otherwise default to sticky selection # Otherwise default to sticky selection
selection_state = SelectionState.STICKIES selection_state = SelectionState.STICKIES
@ -536,6 +551,7 @@ var _selection_candidates : Array[Draggable]:
# === Util === # === Util ===
func _debug_mode() -> void: func _debug_mode() -> void:
super._debug_mode()
populate_board(["c_void", 'c_gifted', "p_wet", "p_joy"]) populate_board(["c_void", 'c_gifted', "p_wet", "p_joy"])
populate_board(["c_jui_jutsu", 'c_hit', "p_girly", "p_vent"]) populate_board(["c_jui_jutsu", 'c_hit', "p_girly", "p_vent"])
populate_board(["c_comic_heroes", 'c_teasing', "p_agent_q", "p_good_intended"]) populate_board(["c_comic_heroes", 'c_teasing', "p_agent_q", "p_good_intended"])

View File

@ -1,7 +1,7 @@
extends Draggable extends Draggable
class_name Card class_name Card
var card_id var card_id : StringName
enum burned { enum burned {
NOT, NOT,
@ -117,7 +117,7 @@ var burn_state: burned = burned.NOT:
burn_tween.tween_property(self, "burn_progress", 0.5, 2) burn_tween.tween_property(self, "burn_progress", 0.5, 2)
burn_state = burning burn_state = burning
burned.TORCHED: burned.TORCHED:
print_debug("Card %s has been burned." % HardCards.get_obscure_name(name)) print("Card %s has been burned." % HardCards.get_obscure_name(name))
has_burned.emit() has_burned.emit()
burn_state = burning burn_state = burning
@ -150,7 +150,7 @@ func _ready():
_on_text_updated.call_deferred() _on_text_updated.call_deferred()
func _on_text_updated(): func _on_text_updated():
if is_node_ready(): if is_node_ready() and name != "c_void" and name != "3.c_void":
var curr_frame := text.hash() % background_sprite.sprite_frames.get_frame_count(background_sprite.animation) var curr_frame := text.hash() % background_sprite.sprite_frames.get_frame_count(background_sprite.animation)
background_sprite.frame = curr_frame background_sprite.frame = curr_frame
@ -203,10 +203,10 @@ func _move_card():
if is_dragged: if is_dragged:
update_drag_position(get_viewport().get_mouse_position()) update_drag_position(get_viewport().get_mouse_position())
func has_sticky_note_attached() -> bool: func has_note_attached() -> bool:
return get_attached_sticky_note() != null return get_attached_note() != null
func get_attached_sticky_note() -> StickyNote: func get_attached_note() -> StickyNote:
for child in get_children(false): for child in get_children(false):
if child is StickyNote: if child is StickyNote:
return child return child
@ -224,41 +224,42 @@ func preview_sticky_note(sticky_note: StickyNote):
else: else:
push_warning("Card.preview_sticky_note: Invalid position calculated, skipping tween") push_warning("Card.preview_sticky_note: Invalid position calculated, skipping tween")
func attach_sticky_note(sticky_note: StickyNote) -> bool:
if has_sticky_note_attached():
return false
sticky_note.reparent(self) func attach_or_exchange_note(note: StickyNote, instant: bool = false) -> void:
sticky_note.position = sticky_note_position prints("Attaching", note, "to", self)
sticky_note.is_dragable = false
if name == "c_hit" and sticky_note.name == "c_effort" and Steamworks.has_initialized: # Out with the old...
var old := get_attached_note()
if old and note.is_attached: # swap with other card if possible
old.reparent(note.attached_to)
old.animate_home()
else:
remove_note_if_present() # just kick out our old note
# ... in with the new
note.reparent(self)
note.home = sticky_note_position
if not instant:
note.animate_home()
else:
note.position = sticky_note_position
if name == "c_hit" and note.name == "c_effort" and Steamworks.has_initialized:
Steam.setAchievement("FIGHT_FOR_GOOD") Steam.setAchievement("FIGHT_FOR_GOOD")
Steam.storeStats() Steam.storeStats()
return true
func remove_sticky_note() -> StickyNote: func remove_note_if_present() -> void:
var former_child: StickyNote = get_attached_sticky_note() var former_child: StickyNote = get_attached_note()
if not former_child: if not former_child: return
return null
former_child.reparent(get_parent()) former_child.reparent(get_parent())
return former_child former_child.tween = null # the positioning logic in card-board will pick that one up and calc a nice slot.
func exchange_sticky_note_with(new_note: StickyNote) -> StickyNote:
if new_note == get_attached_sticky_note():
return null
var old_note := remove_sticky_note()
attach_sticky_note(new_note)
return old_note
# === DROP TARGET PATTERN IMPLEMENTATION === # === DROP TARGET PATTERN IMPLEMENTATION ===
## Temporary storage for exchanged sticky during drop operation
var _last_exchanged_sticky: StickyNote = null
## Checks if this card can accept the given draggable ## Checks if this card can accept the given draggable
func can_accept_drop(draggable: Draggable) -> bool: func can_accept_drop(draggable: Draggable) -> bool:
return draggable is StickyNote return draggable is StickyNote
@ -269,32 +270,12 @@ func handle_drop(draggable: StickyNote) -> int:
if not can_accept_drop(draggable): if not can_accept_drop(draggable):
return Draggable.DropResult.REJECTED return Draggable.DropResult.REJECTED
if has_sticky_note_attached(): attach_or_exchange_note(draggable)
# Exchange: remove current, attach new, store old for retrieval draggable.z_index = 0
_last_exchanged_sticky = exchange_sticky_note_with(draggable) return Draggable.DropResult.ACCEPTED
# Reset z_index for newly attached sticky
draggable.z_index = 0
return Draggable.DropResult.EXCHANGED
else:
# Simple attach
if attach_sticky_note(draggable):
# Reset z_index for newly attached sticky
draggable.z_index = 0
return Draggable.DropResult.ACCEPTED
else:
# Attach failed (shouldn't happen, but handle it)
return Draggable.DropResult.REJECTED
## Retrieves the sticky that was exchanged during last drop
## Clears the reference after retrieval
func get_last_exchanged_sticky() -> StickyNote:
var result := _last_exchanged_sticky
_last_exchanged_sticky = null
return result
# === DRAG LIFECYCLE OVERRIDES === # === DRAG LIFECYCLE OVERRIDES ===
## Cards always drop back to board dropzone ## Cards always drop back to board dropzone
func find_drop_target() -> Node: func find_drop_target() -> Node:
return _get_board() return _get_button_handler()

View File

@ -12,7 +12,7 @@ collision_layer = 4
collision_mask = 0 collision_mask = 0
priority = 50 priority = 50
script = ExtResource("1_emip0") script = ExtResource("1_emip0")
text = "asdf" text = "card"
metadata/type = "card" metadata/type = "card"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]

View File

@ -11,7 +11,6 @@ extends Area2D
enum DropResult { enum DropResult {
ACCEPTED, # Drop successful, item is now owned by target ACCEPTED, # Drop successful, item is now owned by target
REJECTED, # Drop refused, item stays with previous owner REJECTED, # Drop refused, item stays with previous owner
EXCHANGED # Swap occurred, exchanged item needs handling
} }
var mouse_over: bool = false var mouse_over: bool = false
@ -21,6 +20,9 @@ var is_dragged: bool = false:
is_dragged = dragged is_dragged = dragged
z_index = int(dragged) z_index = int(dragged)
# local coordinates home position, where the draggable can try to animate_home to
var home : Vector2 = Vector2.ZERO
## Internal highlighted state - do not set directly, use set_highlight() ## Internal highlighted state - do not set directly, use set_highlight()
var _highlighted: bool = false var _highlighted: bool = false
@ -54,7 +56,7 @@ func _get_hover_handler() -> Node:
## Walks up the scene tree to find the CardBoard ## Walks up the scene tree to find the CardBoard
func _get_board() -> Node: func _get_button_handler() -> Node:
var node := get_parent() var node := get_parent()
while node: while node:
if node.has_method("handle_mouse_button"): if node.has_method("handle_mouse_button"):
@ -64,16 +66,24 @@ func _get_board() -> Node:
## === DRAG LIFECYCLE METHODS === ## === DRAG LIFECYCLE METHODS ===
## Override these in Card and StickyNote for specific behavior ## Override these in Card and StickyNote for specific behavior
var tween : Tween = null
func animate_home() -> void:
z_index = 100
if tween: tween.kill()
tween = create_tween().set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_QUART)
tween.tween_property(self, "position", home, 0.5)
func _on_mouse_entered() -> void: func _on_mouse_entered() -> void:
prints("Draggable[base]._on_mouse_entered", self, self.name) #prints("Draggable[base]._on_mouse_entered", self, self.name)
mouse_over = true mouse_over = true
var handler := _get_hover_handler() var handler := _get_hover_handler()
if handler: handler.handle_hover(self) if handler: handler.handle_hover(self)
func _on_mouse_exited() -> void: func _on_mouse_exited() -> void:
prints("Draggable[base]._on_mouse_exited", self, self.name) #prints("Draggable[base]._on_mouse_exited", self, self.name)
mouse_over = false mouse_over = false
var handler := _get_hover_handler() var handler := _get_hover_handler()
if handler: handler.handle_hover(self) if handler: handler.handle_hover(self)
@ -81,23 +91,18 @@ func _on_mouse_exited() -> void:
## Handles global input events (used to catch mouse release during drag) ## Handles global input events (used to catch mouse release during drag)
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
if event is InputEventMouseButton: if is_dragged and event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_released():
if event.button_index == MOUSE_BUTTON_LEFT and not event.pressed: is_dragged = false
if is_dragged: # Trigger the drop logic
is_dragged = false var handler := _get_button_handler()
# Trigger the drop logic if handler: handler.handle_mouse_button(event, self)
var board := _get_board()
if board and board.has_method("_end_drag"):
board._end_drag(self)
## Handles input events on this Area2D (used to start drag) ## Handles input events on this Area2D (used to start drag)
func _on_input_event(_viewport, event, _shape_idx): func _on_input_event(_viewport, event, _shape_idx):
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed: if highlighted and event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
if highlighted: var handler := _get_button_handler()
var board := _get_board() if handler: handler.handle_mouse_button(event, self)
if board and board.has_method("handle_mouse_button"):
board.handle_mouse_button(event, self)
## Starts a drag operation ## Starts a drag operation
@ -105,6 +110,7 @@ func start_drag(mouse_offset: Vector2) -> void:
_drag_start_position = global_position _drag_start_position = global_position
_mouse_drag_offset = mouse_offset _mouse_drag_offset = mouse_offset
_drag_source = get_parent() _drag_source = get_parent()
z_index = 60
is_dragged = true is_dragged = true
## Updates position during drag (call from _process or manual update) ## Updates position during drag (call from _process or manual update)
@ -119,8 +125,9 @@ func find_drop_target() -> Node:
# Base implementation: return parent (board) # Base implementation: return parent (board)
return get_parent() return get_parent()
## Called after drop to clean up drag state ## End drag operation and return the node we want to be accepted by (if any)
func end_drag() -> Node: func end_drag() -> Node:
z_index = 0
is_dragged = false is_dragged = false
_drag_source = null _drag_source = null
return null return null

View File

@ -168,7 +168,7 @@ unique_name_in_owner = true
self_modulate = Color(1, 1, 1, 0) self_modulate = Color(1, 1, 1, 0)
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
mouse_filter = 1 mouse_filter = 2
[node name="NoteZone" type="Control" parent="HBoxContainer"] [node name="NoteZone" type="Control" parent="HBoxContainer"]
unique_name_in_owner = true unique_name_in_owner = true
@ -176,31 +176,6 @@ custom_minimum_size = Vector2(400, 0)
layout_mode = 2 layout_mode = 2
mouse_filter = 1 mouse_filter = 1
[node name="instructions_panel" type="PanelContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 0
mouse_filter = 2
[node name="HBoxContainer" type="HBoxContainer" parent="instructions_panel"]
layout_mode = 2
mouse_filter = 2
[node name="VSeparator2" type="VSeparator" parent="instructions_panel/HBoxContainer"]
custom_minimum_size = Vector2(15, 0)
layout_mode = 2
[node name="cards_remaining" type="Label" parent="instructions_panel/HBoxContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Collect all four Mementos to fill the mind-board. "
horizontal_alignment = 1
vertical_alignment = 1
[node name="VSeparator" type="VSeparator" parent="instructions_panel/HBoxContainer"]
custom_minimum_size = Vector2(15, 0)
layout_mode = 2
[node name="Timer" type="Timer" parent="."] [node name="Timer" type="Timer" parent="."]
[node name="AnimationPlayer" type="AnimationPlayer" parent="."] [node name="AnimationPlayer" type="AnimationPlayer" parent="."]

View File

@ -2,7 +2,7 @@ extends Draggable
class_name StickyNote class_name StickyNote
var sticky_id var sticky_id
var parent_id var parent_id : StringName
var sibling: StickyNote var sibling: StickyNote
var shift_tween: Tween var shift_tween: Tween
@ -22,8 +22,6 @@ var attached_to: Card:
get: return get_parent() as Card if is_attached else null get: return get_parent() as Card if is_attached else null
signal transform_tween_finished
@onready var background_sprite: AnimatedSprite2D = %BackgroundSprite @onready var background_sprite: AnimatedSprite2D = %BackgroundSprite
@export var text: String = "" : @export var text: String = "" :
@ -58,19 +56,13 @@ func set_highlight(value: bool) -> void:
shift_tween.tween_property(content, "position", Vector2.ZERO, 0.5) shift_tween.tween_property(content, "position", Vector2.ZERO, 0.5)
@export var voice_line: AudioStream = null @export var voice_line: AudioStream = null
@export var is_dragable: bool = false @export var is_draggable: bool = false
var mouse_offset: Vector2 var mouse_offset: Vector2
@onready var diameter := 312.0 @onready var diameter := 312.0
@export_range(1.0, 10.0) var bounce_speed: float = 8 @export_range(1.0, 10.0) var bounce_speed: float = 8
## Computed property: Check if on the board (dropzone)
## Replaces on_board state tracking
var on_board: bool:
get:
var parent := get_parent()
return parent != null and parent.name == "dropzone"
func init(sticky_name: String = "sticky_note", card_id: StringName = "-1") -> void: func init(sticky_name: String = "sticky_note", card_id: StringName = "-1") -> void:
name = sticky_name name = sticky_name
@ -92,49 +84,14 @@ func _on_text_updated():
background_sprite.frame = text.hash() % background_sprite.sprite_frames.get_frame_count(background_sprite.animation) background_sprite.frame = text.hash() % background_sprite.sprite_frames.get_frame_count(background_sprite.animation)
func _process(delta: float) -> void: func _process(_delta: float) -> void:
_move_sticky_note(delta)
## frame rate independent FIR smoothing filter
func _smooth(current: Vector2, goal: Vector2, delta: float) -> Vector2:
var k := pow(0.1, 60.0 * delta)
return (1.0-k) * current + k * goal
func _move_sticky_note(delta: float) -> void:
if is_dragged: if is_dragged:
update_drag_position(get_viewport().get_mouse_position()) update_drag_position(get_viewport().get_mouse_position())
return
if is_attached:
var card := attached_to
position = _smooth(position, card.sticky_note_position, delta)
var transform_tween: Tween
func tween_transform_to(target: Transform2D, duration: float = 0.25) ->void:
# Validate position to prevent teleporting
if not is_finite(target.origin.x) or not is_finite(target.origin.y):
push_warning("StickyNote.tween_transform_to: Invalid position, skipping tween")
transform_tween_finished.emit()
return
if transform_tween and transform_tween.is_running():
transform_tween.stop()
transform_tween = create_tween()
transform_tween.tween_property(self, "transform", target, duration)
await transform_tween.finished
transform_tween_finished.emit()
# === DRAG LIFECYCLE OVERRIDES === # === DRAG LIFECYCLE OVERRIDES ===
## End drag operation and return the node we were dropped on
func end_drag() -> Node: func end_drag() -> Node:
super.end_drag() super.end_drag()
return _find_drop_target() return _find_drop_target()
@ -153,28 +110,7 @@ func _find_drop_target() -> Node:
return closest return closest
## Find the nearest panel that can accept this sticky
func _find_nearest_panel() -> StickyNotePanel:
if not current_handle or not current_handle.has_node("HBoxContainer/ScrollContainer/VBoxContainer"):
return null
var panel_container := current_handle.get_node("HBoxContainer/ScrollContainer/VBoxContainer")
var sticky_rect := Rect2(global_position - Vector2(diameter/2, 10), Vector2(diameter/2, 10))
# First pass: look for empty panels we're hovering over
for panel in panel_container.get_children():
if panel is StickyNotePanel:
if panel.is_empty() and panel.get_global_rect().intersects(sticky_rect):
return panel
# Second pass: if no empty panel found, find first empty panel
for panel in panel_container.get_children():
if panel is StickyNotePanel and panel.is_empty():
return panel
# No empty panels found - will need to create one (handled by board)
return null
## Sticky notes are exempt from confinement if stuck to a card
func confine_to_screen() -> void: func confine_to_screen() -> void:
if attached_to is not Card: super.confine_to_screen() if attached_to is not Card: super.confine_to_screen()

View File

@ -1,68 +0,0 @@
class_name StickyNotePanel
extends Panel
var minimum_size:Vector2 = Vector2(400, 100):
set(size):
minimum_size = size
custom_minimum_size = size
var attached_sticky_note: StickyNote
var ancor_position: Vector2
func _init(cstm_minimum_size: Vector2 = minimum_size, note_position: Vector2 = Vector2(105, 57)) -> void:
minimum_size = cstm_minimum_size
ancor_position = note_position
mouse_filter = MOUSE_FILTER_PASS
self_modulate = Color(1, 1, 1, 0)
@onready var board : CardBoard = get_parent().get_parent() as CardBoard
func _ready():
custom_minimum_size = Vector2(custom_minimum_size.x, 0)
func _process(delta: float) -> void:
var child := get_child(0) as StickyNote
if child and not child.is_dragged:
var k := pow(0.1, 60.0 * delta)
child.position = child.position * (1.0-k) + ancor_position * (k)
var is_attaching: bool = false
func attatch_sticky_note(attatchment: StickyNote, custom_handle: Node, animate:bool = true):
attached_sticky_note = attatchment
attatchment.current_handle = custom_handle
# Expand panel height
if animate:
var height_tween: Tween = create_tween()
height_tween.tween_property(self, "custom_minimum_size", minimum_size, 0.1)
else:
custom_minimum_size = minimum_size
# Position sticky
if animate:
await get_tree().process_frame
attatchment.z_index = 125 # On top during animation
# Reparent while keeping world position for smooth animation
attatchment.reparent(self, true)
# Tween to anchor position in panel's coordinate space
var tween := create_tween().set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_BACK)
tween.tween_property(attatchment, "position", ancor_position, 0.7)
tween.tween_property(attatchment, "rotation", 0.0, 0.7)
tween.parallel().tween_property(attatchment, "scale", Vector2.ONE, 0.7)
await tween.finished
attatchment.z_index = 0
else:
# Immediate placement (for initial board setup)
if attatchment.get_parent():
attatchment.reparent(self)
else:
add_child(attatchment)
attatchment.position = ancor_position
attatchment.rotation = 0.0
attatchment.scale = Vector2.ONE
func is_empty() -> bool:
return get_child_count() == 0

View File

@ -1 +0,0 @@
uid://c8gsxyymrldcd

View File

@ -1,15 +0,0 @@
[gd_scene load_steps=2 format=3 uid="uid://chwf61qpn2sqw"]
[ext_resource type="Script" uid="uid://c8gsxyymrldcd" path="res://logic-scenes/board/sticky_note_panel.gd" id="1_1dtc4"]
[node name="Panel" type="Panel"]
self_modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(400, 100)
offset_right = 400.0
offset_bottom = 120.0
mouse_filter = 1
script = ExtResource("1_1dtc4")
[node name="sticky-note_anchor" type="Node2D" parent="."]
z_index = 110
position = Vector2(105, 57)

View File

@ -1,39 +1,11 @@
[gd_scene load_steps=12 format=3 uid="uid://vqwep0whfb0o"] [gd_scene load_steps=11 format=3 uid="uid://vqwep0whfb0o"]
[ext_resource type="Script" uid="uid://2loic2eeec5b" path="res://logic-scenes/board/card.gd" id="1_6ceun"] [ext_resource type="Script" uid="uid://2loic2eeec5b" path="res://logic-scenes/board/card.gd" id="1_6ceun"]
[ext_resource type="Texture2D" uid="uid://sv0nhkkur1tt" path="res://logic-scenes/board/card-textures/cardsheet.png" id="2_buevv"] [ext_resource type="Texture2D" uid="uid://sv0nhkkur1tt" path="res://logic-scenes/board/card-textures/cardsheet.png" id="2_buevv"]
[ext_resource type="PackedScene" path="res://logic-scenes/board/void_stuff.tscn" id="3_ipd1f"] [ext_resource type="PackedScene" uid="uid://b2st6v25p0ley" path="res://logic-scenes/board/void_stuff.tscn" id="3_ipd1f"]
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_aqrbw"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_ipd1f"]
radius = 110.0 size = Vector2(277, 231)
height = 336.0
[sub_resource type="GDScript" id="GDScript_8bs16"]
script/source = "extends Node2D
@onready var particles = $BackgroundSprite/GPUParticles2D
@onready var initial_position = position
var noise_position = randf()
var noise: Noise = FastNoiseLite.new()
func _process(delta):
if not State.reduce_motion:
noise_position += delta * 10
var random_position = Vector2(noise.get_noise_1d(noise_position*2), noise.get_noise_1d(-noise_position))
random_position = random_position.normalized() * pow(random_position.length()*2, 3) * 5
position = initial_position - random_position
rotation = noise.get_noise_1d(noise_position*10) * random_position.length() * 0.01
particles.position = random_position
else: position = initial_position
"
[sub_resource type="AtlasTexture" id="AtlasTexture_aqrbw"] [sub_resource type="AtlasTexture" id="AtlasTexture_aqrbw"]
atlas = ExtResource("2_buevv") atlas = ExtResource("2_buevv")
@ -79,28 +51,27 @@ animations = [{
}] }]
[node name="c_void" type="Area2D"] [node name="c_void" type="Area2D"]
collision_layer = 4
collision_mask = 0
priority = 50
script = ExtResource("1_6ceun") script = ExtResource("1_6ceun")
text = "card" text = "card"
metadata/type = "card" metadata/type = "card"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(-0.0713516, 0.997451) position = Vector2(5.5, 0)
rotation = 1.5708 shape = SubResource("RectangleShape2D_ipd1f")
shape = SubResource("CapsuleShape2D_aqrbw")
[node name="Visual" type="Node2D" parent="."] [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
scale = Vector2(0.6, 0.6)
script = SubResource("GDScript_8bs16")
[node name="BackgroundSprite" type="AnimatedSprite2D" parent="Visual"]
unique_name_in_owner = true unique_name_in_owner = true
clip_children = 2 clip_children = 2
scale = Vector2(0.6, 0.6)
sprite_frames = SubResource("SpriteFrames_cu2at") sprite_frames = SubResource("SpriteFrames_cu2at")
frame = 1 frame = 1
[node name="void_stuff" parent="Visual/BackgroundSprite" instance=ExtResource("3_ipd1f")] [node name="void_stuff" parent="AnimatedSprite2D" instance=ExtResource("3_ipd1f")]
[node name="StickyNoteAncor" type="Node2D" parent="Visual/BackgroundSprite"] [node name="StickyNoteAncor" type="Node2D" parent="AnimatedSprite2D"]
unique_name_in_owner = true unique_name_in_owner = true
position = Vector2(-109.413, 100.642) position = Vector2(-109.413, 100.642)
scale = Vector2(1.66667, 1.66667) scale = Vector2(1.66667, 1.66667)

Some files were not shown because too many files have changed in this diff Show More