Compare commits

..

2 Commits

6 changed files with 112 additions and 67 deletions

View File

@ -17,13 +17,32 @@ extends Node3D
@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()
## One arrival and departure ## One arrival and departure
func cycle() -> void: func cycle() -> void:
await arrive() await arrive()
@ -33,34 +52,40 @@ 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(Tween.TRANS_CIRC).set_ease(Tween.EASE_OUT)
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()
@ -68,13 +93,19 @@ func leave() -> void:
await get_tree().create_timer(pre_leave_time).timeout await get_tree().create_timer(pre_leave_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(Tween.TRANS_QUART).set_ease(Tween.EASE_IN)
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,6 +1,7 @@
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), ...]
## CAVEAT: These must be direct children of the fahrplan!
@onready var fahrplan : Dictionary[Node3D, Array] = { @onready var fahrplan : Dictionary[Node3D, Array] = {
$station_hirschfeld: [[$station_university_mensa, $station_parity_square],[]], $station_hirschfeld: [[$station_university_mensa, $station_parity_square],[]],
$station_hirschfeld : [[$station_university_mensa, $station_parity_square],[]], $station_hirschfeld : [[$station_university_mensa, $station_parity_square],[]],
@ -13,10 +14,11 @@ class_name Fahrplan extends Node3D
$station_rosenthal : [null,null], # Endstation $station_rosenthal : [null,null], # Endstation
} }
## List of all registered station nodes, used to unparent them
@onready var stations : Array[Node3D] = 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().call_group(group, "set_text", "")
@ -29,9 +31,10 @@ func _ready() -> void:
print(x.name) 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($station_hirschfeld)
enter_station(current_station)
var current_station : Node3D = null var current_station : Node3D = null
@ -39,8 +42,8 @@ var stop := false
var destinations : Array[Node3D] = [null, null] var destinations : Array[Node3D] = [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 fahrplan[current_station][track.index] == null: # empty array (just no routes) would be falsy if fahrplan[current_station][track.index] == null: # empty array (just no routes) would be falsy
track.arrive(true) track.arrive(true)
_set_signage_texts(track.signage_group, "Endstation") _set_signage_texts(track.signage_group, "Endstation")
@ -60,7 +63,9 @@ func train_traffic_loop(track: Dolly, cancel: Array) -> void:
destinations[track.index] = next destinations[track.index] = next
_set_signage_texts(track.signage_group, next.name) # TODO: load nice string _set_signage_texts(track.signage_group, next.name) # 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
@ -70,14 +75,24 @@ var cancellation_token : Array
func enter_station(station: Node): func enter_station(station: Node):
prints("------------", "ENTER STATION", station, station.name, "------------") prints("------------", "ENTER STATION", station, station.name, "------------")
if current_station: current_station.visible = false remove_child(current_station)
current_station = station current_station = station
current_station.visible = true add_child(current_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:
if station == except:
current_station = station
continue
assert(station.get_parent() == self, "A station that isn't a child of Fahrplan is in the Fahrplan: %s" % station.name)
remove_child(station)
station.visible = true # Make visible by default, parenting handles visibility and collision

View File

@ -160,19 +160,22 @@ 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.03272724, -0.06909847, -11.098316)
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, 1.162013, -0.12873906, 10.907985)
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

View File

@ -374,7 +374,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")

File diff suppressed because one or more lines are too long

View File

@ -81,6 +81,14 @@ func _ready() -> void:
progress = progress progress = progress
if animation_player.has_animation("RESET"): animation_player.play("RESET") if animation_player.has_animation("RESET"): animation_player.play("RESET")
if get_parent() is not CanvasLayer:
push_warning("-------------- ", "DEBUG MODE ", self, " --------------")
await Main.curtain.open()
await appear()
await play()
push_warning("-------------- ", "FINISHED ", self, " --------------")
func _rebuild(): func _rebuild():
print_debug("StoryPlayable.gd: %s._rebuild()" % self.name) print_debug("StoryPlayable.gd: %s._rebuild()" % self.name)
if is_node_ready(): if is_node_ready():