Compare commits

..

2 Commits

Author SHA1 Message Date
tiger tiger tiger 0d150d31fc fix: need to clean again? 2026-01-20 22:53:12 +01:00
tiger tiger tiger 6fcc13abe7 feat: fahrplan, but needs fixes 2026-01-20 22:47:44 +01:00
8 changed files with 382 additions and 269 deletions

View File

@ -2,6 +2,8 @@
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
@ -15,21 +17,25 @@ extends Node3D
@onready var subway : SubwayTrain = $Train
var tween : Tween = null
signal departure(index : int)
func _ready() -> void:
for child in get_children(true):
if not child.visible: continue
child.global_position = origination.global_position
reset()
## One arrival and departure
func cycle() -> void:
await arrive()
await leave()
func _seat_player_if_inside() -> void:
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
@ -38,6 +44,8 @@ func _seat_player_if_inside() -> void:
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:
@ -66,7 +74,7 @@ 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
_seat_player_if_inside()
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):
@ -74,8 +82,7 @@ func leave() -> void:
tween.parallel().tween_property(child, "global_position", destination.global_position, leave_time)
await tween.finished
await %SubwayTrainAudio.finished
for child in get_children(true):
if not child.visible: continue
# Warp back
child.global_position = origination.global_position
arrive()
# Player was on board and has left the station
if seated: departure.emit(index)
# Reset is called by Fahrplan

View File

@ -0,0 +1,73 @@
class_name Fahrplan
extends Node3D
## easy graph: <station> : [Track1Train1 (next halt), Track1Train2], [Track2Train1(next halt), ...]
@onready var fahrplan : Dictionary[Node3D, Array] = {
$station_hirschfeld: [[$station_university_mensa, $station_parity_square],[]],
$station_hirschfeld : [[$station_university_mensa, $station_parity_square],[]],
$station_university_mensa : [[$station_university_main],[]],
$station_university_main: [[$station_ministry],[$station_rosenthal, $station_university_mensa]],
$station_parity_square : [[$station_saint_exupery],[$station_rosenthal]],
$station_saint_exupery : [[$station_saint_exupery],[$station_rosenthal]],
$station_ministry : [[],[]], # Endstation
$station_rosenthal : [[],[]], # Endstation
}
@onready var tracks : Array[Dolly] = [%Track0Dolly, %Track1Dolly]
@export var random_wait : Vector2 = Vector2(10.0, 20.0)
func _set_signage_texts(group: StringName, message: String) -> void:
get_tree().call_group(group, "set_text", "")
for i in range(len(message)):
get_tree().call_group(group, "set_text", message.substr(0, i+1))
await get_tree().create_timer(0.05).timeout
func _ready() -> void:
tracks[0].departure.connect(player_departed)
tracks[1].departure.connect(player_departed)
enter_station($station_hirschfeld)
var current_station : Node3D = null
var stop := false
var destinations : Array[Node3D] = [null, null]
func train_traffic_loop(track: Dolly, cancel: Array) -> void:
var routes : Array = fahrplan[current_station][track.index]
if routes.is_empty():
_set_signage_texts(track.signage_group, "Verkehr z. Zt.\nunregelmäßig")
return
while true:
var next : Node = routes.pop_front()
routes.append(next) # It's a ring buffer
destinations[track.index] = next
_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
if cancel.is_empty(): return # abort the loop
track.cycle()
var cancellation_token : Array
func enter_station(station: Node):
prints("------------", "ENTER STATION", station, station.name, "------------")
current_station.visible = false
current_station = station
current_station.visible = true
cancellation_token = ["go"] # Allocate a new stopping token
train_traffic_loop(tracks[0], cancellation_token)
train_traffic_loop(tracks[1], cancellation_token)
func player_departed(track_index : int) -> void:
cancellation_token.clear()
for track in tracks:
track.reset() # Warps the player to the entry point for that track, too
enter_station(destinations[track_index])

View File

@ -10,66 +10,14 @@ func _ready() -> void:
func start_room():
super.start_room()
#%LeftDetection.body_entered.connect(on_left_train_enter)
#%RightDetection.body_entered.connect(on_right_train_enter)
#%LeftDetection.body_exited.connect(on_left_train_exit)
#%RightDetection.body_exited.connect(on_right_train_exit)
%burnout_station.leave_room.connect(func():
%station_ministry.leave_room.connect(func():
proceed.emit(Main.adulthood_room_path))
%PlayerController.process_mode = Node.PROCESS_MODE_INHERIT
# Give player control immediately, then open
Scenes.player_enable.emit(true)
on_first_station()
_set_signage_texts("signage1", "Gleis 1\naußer Betrieb")
_set_signage_texts("signage2", "Bitte Ansage\nbeachten")
await Main.curtain.open()
$Track2Dolly.cycle()
await get_tree().create_timer(20).timeout
_set_signage_texts("signage2", "Verkehr z. Zt.\nunregelmäßig")
$Track1Dolly.cycle()
await get_tree().create_timer(10).timeout
_set_signage_texts("signage1", "Bitte Ansage\nbeachten")
func _set_signage_texts(group: StringName, message: String) -> void:
get_tree().call_group(group, "set_text", "")
for i in range(len(message)):
get_tree().call_group(group, "set_text", message.substr(0, i+1))
await get_tree().create_timer(0.05).timeout
var left_first_station: bool = false
func on_first_station() -> void:
return
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_DND
await get_tree().create_timer(5.0).timeout
%ShedulePlayer_R.play("train_arriving")
await get_tree().create_timer(12.0).timeout
if left_first_station: return
%ShedulePlayer_R.play("train_leaving")
await get_tree().create_timer(3.0).timeout
%RightLabel.text = "do not board"
await get_tree().create_timer(6.0).timeout
%ShedulePlayer_L.play("train_arriving")
var on_second_platform: bool = false
func on_first_transition(_is_left: bool = false):
%StationPlayer.play("first_transition")
await get_tree().create_timer(1.0).timeout
on_second_platform = true
func on_second_transition():
%StationPlayer.play("second_transition")
func on_third_transition():
%StationPlayer.play("third_transition")
func pull_save_state(save: SaveGame) -> void:
#FIXME
@ -80,127 +28,145 @@ func pull_save_state(save: SaveGame) -> void:
# Call parent to restore player position
super.pull_save_state(save)
func prepare_transition():
for child in %Stations.get_children():
if child is Node3D:
if not child.name == "burnout_station":
child.queue_free()
func unload():
pass
func on_left_train_enter(_body) -> void:
if not left_first_station:
left_first_station = true
await get_tree().create_timer(2.0).timeout
%Train2.get_child(0).door_open = false
on_first_transition(true)
await get_tree().create_timer(5.0).timeout
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_VOLUNTARY
%SubwayMap.current_station = Scenes.id.ADULT_VOLUNTARY
%RightLabel.text = "U3 Gesundquell \n via Rosenthal Hospital"
await get_tree().create_timer(5.0).timeout
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_AUTISM
%SubwayMap.current_station = Scenes.id.ADULT_AUTISM
await get_tree().create_timer(5.0).timeout
%Train2.get_child(0).door_open = true
await get_tree().create_timer(5.0).timeout
if not changeover:
%Train2.get_child(0).door_open = false
on_second_transition()
await get_tree().create_timer(5.0).timeout
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_SELF_ADVOCACY
%SubwayMap.current_station = Scenes.id.ADULT_SELF_ADVOCACY
%RightLabel.text = "do not board"
%LeftLabel.text = "do not board"
on_final = true
await get_tree().create_timer(5.0).timeout
%Train2.get_child(0).door_open = true
else:
%ShedulePlayer_L.play("train_leaving")
%LeftLabel.text = "do not board"
return
if changeover:
%ShedulePlayer_R.play("train_leaving")
await get_tree().create_timer(2.0).timeout
%Train2.get_child(0).door_open = false
on_second_transition()
await get_tree().create_timer(5.0).timeout
save_game.seen.append(str(Scenes.id.ADULT_THERAPY_UNI))
%SubwayMap.current_station = Scenes.id.ADULT_THERAPY_UNI
%RightLabel.text = "do not board"
%LeftLabel.text = "do not board"
on_final = true
await get_tree().create_timer(5.0).timeout
%Train2.get_child(0).door_open = true
var on_final: bool = false:
set(final):
#FIXME: this needs to be a proper sequence!
on_final = final
await get_tree().create_timer(0.5).timeout
if final: prepare_transition()
var on_direct_path: bool = false
func on_right_train_enter(_body) -> void:
if not left_first_station:
on_direct_path = true
%Train.get_child(0).door_open = false
await get_tree().create_timer(2.0).timeout
left_first_station = true
on_first_transition(false)
await get_tree().create_timer(5.0).timeout
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_EATING
%SubwayMap.current_station = Scenes.id.ADULT_EATING
%LeftLabel.text = "U8 Gesundquell \n via Rosenthal Hospital"
await get_tree().create_timer(5.0).timeout
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_SELF_ADVOCACY
%SubwayMap.current_station = Scenes.id.ADULT_SELF_ADVOCACY
await get_tree().create_timer(5.0).timeout
%Train.get_child(0).door_open = true
await get_tree().create_timer(5.0).timeout
if not changeover:
%Train.get_child(0).door_open = false
on_second_transition()
await get_tree().create_timer(5.0).timeout
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_BURNOUT
%SubwayMap.current_station = Scenes.id.ADULT_BURNOUT
%RightLabel.text = "do not board"
%LeftLabel.text = "do not board"
on_final = true
await get_tree().create_timer(5.0).timeout
%Train.get_child(0).door_open = true
else:
%ShedulePlayer_R.play("train_leaving")
%RightLabel.text = "do not board"
return
if changeover:
on_second_transition()
if on_direct_path: %ShedulePlayer_L.play("train_leaving")
await get_tree().create_timer(5.0).timeout
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_AUTISM
%SubwayMap.current_station = Scenes.id.ADULT_AUTISM
await get_tree().create_timer(2.0).timeout
%Train2.get_child(0).door_open = false
%RightLabel.text = "do not board"
%LeftLabel.text = "do not board"
on_final = true
await get_tree().create_timer(5.0).timeout
%Train.get_child(0).door_open = true
var changeover: bool = false
func on_left_train_exit(_body):
if on_second_platform and not on_final:
changeover = true
%ShedulePlayer_R.play("train_arriving")
func on_right_train_exit(_body):
if on_second_platform and not on_final:
changeover = true
%ShedulePlayer_L.play("train_arriving")
await get_tree().create_timer(10).timeout
%RightLabel.text = "U1 weissnicht \n via Saint-Exupery Sq."
await get_tree().create_timer(5).timeout
%ShedulePlayer_R.play("train_arriving")
## left here for reference... the ~35 lines of code above should be enoough
#var left_first_station: bool = false
#func on_first_station() -> void:
# return
# Scenes.enabled_sequences += 1 << Scenes.id.ADULT_DND
# await get_tree().create_timer(5.0).timeout
# %ShedulePlayer_R.play("train_arriving")
# await get_tree().create_timer(12.0).timeout
# if left_first_station: return
# %ShedulePlayer_R.play("train_leaving")
# await get_tree().create_timer(3.0).timeout
# %RightLabel.text = "do not board"
# await get_tree().create_timer(6.0).timeout
# %ShedulePlayer_L.play("train_arriving")
#
#var on_second_platform: bool = false
#func on_first_transition(_is_left: bool = false):
# %StationPlayer.play("first_transition")
# await get_tree().create_timer(1.0).timeout
# on_second_platform = true
#
#func on_second_transition():
# %StationPlayer.play("second_transition")
#
#func on_third_transition():
# %StationPlayer.play("third_transition")
#
#func on_left_train_enter(_body) -> void:
# if not left_first_station:
# left_first_station = true
# await get_tree().create_timer(2.0).timeout
# %Train2.get_child(0).door_open = false
# on_first_transition(true)
# await get_tree().create_timer(5.0).timeout
# Scenes.enabled_sequences += 1 << Scenes.id.ADULT_VOLUNTARY
# %SubwayMap.current_station = Scenes.id.ADULT_VOLUNTARY
# %RightLabel.text = "U3 Gesundquell \n via Rosenthal Hospital"
# await get_tree().create_timer(5.0).timeout
# Scenes.enabled_sequences += 1 << Scenes.id.ADULT_AUTISM
# %SubwayMap.current_station = Scenes.id.ADULT_AUTISM
# await get_tree().create_timer(5.0).timeout
# %Train2.get_child(0).door_open = true
#
# await get_tree().create_timer(5.0).timeout
# if not changeover:
# %Train2.get_child(0).door_open = false
# on_second_transition()
# await get_tree().create_timer(5.0).timeout
# Scenes.enabled_sequences += 1 << Scenes.id.ADULT_SELF_ADVOCACY
# %SubwayMap.current_station = Scenes.id.ADULT_SELF_ADVOCACY
# %RightLabel.text = "do not board"
# %LeftLabel.text = "do not board"
# on_final = true
# await get_tree().create_timer(5.0).timeout
# %Train2.get_child(0).door_open = true
# else:
# %ShedulePlayer_L.play("train_leaving")
# %LeftLabel.text = "do not board"
# return
# if changeover:
# %ShedulePlayer_R.play("train_leaving")
# await get_tree().create_timer(2.0).timeout
# %Train2.get_child(0).door_open = false
# on_second_transition()
# await get_tree().create_timer(5.0).timeout
# save_game.seen.append(str(Scenes.id.ADULT_THERAPY_UNI))
# %SubwayMap.current_station = Scenes.id.ADULT_THERAPY_UNI
# %RightLabel.text = "do not board"
# %LeftLabel.text = "do not board"
# on_final = true
# await get_tree().create_timer(5.0).timeout
# %Train2.get_child(0).door_open = true
#
#var on_final: bool = false:
# set(final):
# #FIXME: this needs to be a proper sequence!
# on_final = final
# await get_tree().create_timer(0.5).timeout
# if final: prepare_transition()
#var on_direct_path: bool = false
#func on_right_train_enter(_body) -> void:
# if not left_first_station:
# on_direct_path = true
# %Train.get_child(0).door_open = false
# await get_tree().create_timer(2.0).timeout
# left_first_station = true
# on_first_transition(false)
# await get_tree().create_timer(5.0).timeout
# Scenes.enabled_sequences += 1 << Scenes.id.ADULT_EATING
# %SubwayMap.current_station = Scenes.id.ADULT_EATING
# %LeftLabel.text = "U8 Gesundquell \n via Rosenthal Hospital"
# await get_tree().create_timer(5.0).timeout
# Scenes.enabled_sequences += 1 << Scenes.id.ADULT_SELF_ADVOCACY
# %SubwayMap.current_station = Scenes.id.ADULT_SELF_ADVOCACY
# await get_tree().create_timer(5.0).timeout
# %Train.get_child(0).door_open = true
#
# await get_tree().create_timer(5.0).timeout
#
# if not changeover:
# %Train.get_child(0).door_open = false
# on_second_transition()
# await get_tree().create_timer(5.0).timeout
# Scenes.enabled_sequences += 1 << Scenes.id.ADULT_BURNOUT
# %SubwayMap.current_station = Scenes.id.ADULT_BURNOUT
# %RightLabel.text = "do not board"
# %LeftLabel.text = "do not board"
# on_final = true
# await get_tree().create_timer(5.0).timeout
# %Train.get_child(0).door_open = true
# else:
# %ShedulePlayer_R.play("train_leaving")
# %RightLabel.text = "do not board"
# return
# if changeover:
# on_second_transition()
# if on_direct_path: %ShedulePlayer_L.play("train_leaving")
# await get_tree().create_timer(5.0).timeout
# Scenes.enabled_sequences += 1 << Scenes.id.ADULT_AUTISM
# %SubwayMap.current_station = Scenes.id.ADULT_AUTISM
# await get_tree().create_timer(2.0).timeout
# %Train2.get_child(0).door_open = false
# %RightLabel.text = "do not board"
# %LeftLabel.text = "do not board"
# on_final = true
# await get_tree().create_timer(5.0).timeout
# %Train.get_child(0).door_open = true
#
#var changeover: bool = false
#func on_left_train_exit(_body):
# if on_second_platform and not on_final:
# changeover = true
# %ShedulePlayer_R.play("train_arriving")
#
#func on_right_train_exit(_body):
# if on_second_platform and not on_final:
# changeover = true
# %ShedulePlayer_L.play("train_arriving")
# await get_tree().create_timer(10).timeout
# %RightLabel.text = "U1 weissnicht \n via Saint-Exupery Sq."
# await get_tree().create_timer(5).timeout
# %ShedulePlayer_R.play("train_arriving")

View File

@ -1,6 +0,0 @@
extends Node3D
class_name StationSwapper
const fahplan : Dictionary[Node3D, Array] = {
%station_hirschfeld : [[%station_university],[%station_parity_square]]
}

File diff suppressed because one or more lines are too long

View File

@ -16,7 +16,7 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true
[application]
config/name="Frame of Mind"
run/main_scene="uid://ccdfkvtu6sb36"
run/main_scene="uid://fgp3tbah7msy"
config/use_custom_user_dir=true
config/features=PackedStringArray("4.5", "Forward Plus")
boot_splash/bg_color=Color(0.0313726, 0.0117647, 0.129412, 1)
@ -70,8 +70,8 @@ import/blender/enabled=false
[global_group]
interactables=""
signage1=""
signage2=""
signage1=""
[gui]

View File

@ -6,8 +6,8 @@ var _tween : Tween = null
func _ready() -> void:
print_debug("curtain.gd: ready()")
visible = true
## Conceals the Game Stage
## Conceals the Game Stage
func close() -> void:
visible = true
print_debug("curtain.gd: show()")
@ -16,7 +16,7 @@ func close() -> void:
_tween.tween_property(self, "modulate", Color.WHITE, 0.7)
await _tween.finished
## Conceals the Game Stage
## Conceals the Game Stage
func black() -> void:
visible = true
print_debug("curtain.gd: show()")
@ -25,8 +25,8 @@ func black() -> void:
_tween.tween_property(self, "modulate", Color.BLACK, 0.7)
await _tween.finished
## Makes the Game Stage Visible
func open() -> void:
## Makes the Game Stage Visible
func open() -> void:
print_debug("curtain.gd: hide()")
if _tween: _tween.kill()
_tween = create_tween()