## A dolly tweens all contents to and from two destination points, and to its origin. class_name Dolly extends Node3D @export var index : int = -1 @export var signage_group : String @export var pre_arrival_time : float = 17.0 @export var arrival_time : float = 15.0 @export var pre_leave_time : float = 20.0 @export var door_close_time : float = 1.0 @export var leave_time : float = 16.0 @export var post_leave_time : float = 5.0 @onready var origination : Node3D = $Origination @onready var destination : Node3D = $Destination @onready var subway : SubwayTrain = $Train var tween : Tween = null signal departure(index : int) func _ready() -> void: reset() ## One arrival and departure func cycle() -> void: await arrive() await leave() func reset() -> void: if tween: tween.kill() for child in get_children(true): if not child.visible: continue child.global_position = origination.global_position func _seat_player_if_inside() -> bool: if %EntryDetect.overlaps_body(State.player): prints("Player asleep inside Train", self.name) State.player.sleeping = true var s1 := %Seat1 var s2 := %Seat2 var seat : Node3D = s1 if (s1.global_position-State.player.global_position).length() < (s2.global_position-State.player.global_position).length() else s2 State.player.reparent(seat) return true return false func _unseat_player_if_inside() -> void: if %EntryDetect.overlaps_body(State.player): prints("Player no longer asleep on Train", self.name) State.player.sleeping = false State.player.reparent(get_parent()) func arrive() -> void: %SubwayTrainAudio.play(0) %SubwayTrainAudioIntense.play(0) await get_tree().create_timer(pre_arrival_time).timeout if tween: tween.kill() tween = create_tween().set_trans(Tween.TRANS_CIRC).set_ease(Tween.EASE_OUT) for child in get_children(true): if not child.visible: continue tween.parallel().tween_property(child, "global_position", self.global_position, arrival_time) await tween.finished subway.door_open = true _unseat_player_if_inside() func leave() -> void: await get_tree().create_timer(pre_leave_time).timeout subway.door_open = false await get_tree().create_timer(door_close_time).timeout var seated := _seat_player_if_inside() if tween: tween.kill() tween = create_tween().set_trans(Tween.TRANS_QUART).set_ease(Tween.EASE_IN) for child in get_children(true): if not child.visible: continue tween.parallel().tween_property(child, "global_position", destination.global_position, leave_time) await tween.finished await %SubwayTrainAudio.finished # Player was on board and has left the station if seated: departure.emit(index) # Reset is called by Fahrplan