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 class_name Dolly
extends Node3D extends Node3D
@export var index : int = -1
@export var signage_group : String
@export var pre_arrival_time : float = 17.0 @export var pre_arrival_time : float = 17.0
@export var arrival_time : float = 15.0 @export var arrival_time : float = 15.0
@ -15,21 +17,25 @@ extends Node3D
@onready var subway : SubwayTrain = $Train @onready var subway : SubwayTrain = $Train
var tween : Tween = null var tween : Tween = null
signal departure(index : int)
func _ready() -> void: func _ready() -> void:
for child in get_children(true): reset()
if not child.visible: continue
child.global_position = origination.global_position
## One arrival and departure ## One arrival and departure
func cycle() -> void: func cycle() -> void:
await arrive() await arrive()
await leave() 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): if %EntryDetect.overlaps_body(State.player):
prints("Player asleep inside Train", self.name) prints("Player asleep inside Train", self.name)
State.player.sleeping = true 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 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) State.player.reparent(seat)
return true
return false
func _unseat_player_if_inside() -> void: func _unseat_player_if_inside() -> void:
@ -66,7 +74,7 @@ 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
_seat_player_if_inside() var seated := _seat_player_if_inside()
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)
for child in get_children(true): 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) tween.parallel().tween_property(child, "global_position", destination.global_position, leave_time)
await tween.finished await tween.finished
await %SubwayTrainAudio.finished await %SubwayTrainAudio.finished
for child in get_children(true):
if not child.visible: continue # Player was on board and has left the station
# Warp back if seated: departure.emit(index)
child.global_position = origination.global_position # Reset is called by Fahrplan
arrive()

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(): func start_room():
super.start_room() super.start_room()
#%LeftDetection.body_entered.connect(on_left_train_enter) %station_ministry.leave_room.connect(func():
#%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():
proceed.emit(Main.adulthood_room_path)) proceed.emit(Main.adulthood_room_path))
%PlayerController.process_mode = Node.PROCESS_MODE_INHERIT
# Give player control immediately, then open # Give player control immediately, then open
Scenes.player_enable.emit(true) 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() 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: func pull_save_state(save: SaveGame) -> void:
#FIXME #FIXME
@ -80,127 +28,145 @@ func pull_save_state(save: SaveGame) -> void:
# Call parent to restore player position # Call parent to restore player position
super.pull_save_state(save) super.pull_save_state(save)
func prepare_transition(): ## left here for reference... the ~35 lines of code above should be enoough
for child in %Stations.get_children(): #var left_first_station: bool = false
if child is Node3D: #func on_first_station() -> void:
if not child.name == "burnout_station": # return
child.queue_free() # Scenes.enabled_sequences += 1 << Scenes.id.ADULT_DND
# await get_tree().create_timer(5.0).timeout
func unload(): # %ShedulePlayer_R.play("train_arriving")
pass # await get_tree().create_timer(12.0).timeout
# if left_first_station: return
func on_left_train_enter(_body) -> void: # %ShedulePlayer_R.play("train_leaving")
if not left_first_station: # await get_tree().create_timer(3.0).timeout
left_first_station = true # %RightLabel.text = "do not board"
await get_tree().create_timer(2.0).timeout # await get_tree().create_timer(6.0).timeout
%Train2.get_child(0).door_open = false # %ShedulePlayer_L.play("train_arriving")
on_first_transition(true) #
await get_tree().create_timer(5.0).timeout #var on_second_platform: bool = false
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_VOLUNTARY #func on_first_transition(_is_left: bool = false):
%SubwayMap.current_station = Scenes.id.ADULT_VOLUNTARY # %StationPlayer.play("first_transition")
%RightLabel.text = "U3 Gesundquell \n via Rosenthal Hospital" # await get_tree().create_timer(1.0).timeout
await get_tree().create_timer(5.0).timeout # on_second_platform = true
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_AUTISM #
%SubwayMap.current_station = Scenes.id.ADULT_AUTISM #func on_second_transition():
await get_tree().create_timer(5.0).timeout # %StationPlayer.play("second_transition")
%Train2.get_child(0).door_open = true #
#func on_third_transition():
await get_tree().create_timer(5.0).timeout # %StationPlayer.play("third_transition")
if not changeover: #
%Train2.get_child(0).door_open = false #func on_left_train_enter(_body) -> void:
on_second_transition() # if not left_first_station:
await get_tree().create_timer(5.0).timeout # left_first_station = true
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_SELF_ADVOCACY # await get_tree().create_timer(2.0).timeout
%SubwayMap.current_station = Scenes.id.ADULT_SELF_ADVOCACY # %Train2.get_child(0).door_open = false
%RightLabel.text = "do not board" # on_first_transition(true)
%LeftLabel.text = "do not board" # await get_tree().create_timer(5.0).timeout
on_final = true # Scenes.enabled_sequences += 1 << Scenes.id.ADULT_VOLUNTARY
await get_tree().create_timer(5.0).timeout # %SubwayMap.current_station = Scenes.id.ADULT_VOLUNTARY
%Train2.get_child(0).door_open = true # %RightLabel.text = "U3 Gesundquell \n via Rosenthal Hospital"
else: # await get_tree().create_timer(5.0).timeout
%ShedulePlayer_L.play("train_leaving") # Scenes.enabled_sequences += 1 << Scenes.id.ADULT_AUTISM
%LeftLabel.text = "do not board" # %SubwayMap.current_station = Scenes.id.ADULT_AUTISM
return # await get_tree().create_timer(5.0).timeout
if changeover: # %Train2.get_child(0).door_open = true
%ShedulePlayer_R.play("train_leaving") #
await get_tree().create_timer(2.0).timeout # await get_tree().create_timer(5.0).timeout
%Train2.get_child(0).door_open = false # if not changeover:
on_second_transition() # %Train2.get_child(0).door_open = false
await get_tree().create_timer(5.0).timeout # on_second_transition()
save_game.seen.append(str(Scenes.id.ADULT_THERAPY_UNI)) # await get_tree().create_timer(5.0).timeout
%SubwayMap.current_station = Scenes.id.ADULT_THERAPY_UNI # Scenes.enabled_sequences += 1 << Scenes.id.ADULT_SELF_ADVOCACY
%RightLabel.text = "do not board" # %SubwayMap.current_station = Scenes.id.ADULT_SELF_ADVOCACY
%LeftLabel.text = "do not board" # %RightLabel.text = "do not board"
on_final = true # %LeftLabel.text = "do not board"
await get_tree().create_timer(5.0).timeout # on_final = true
%Train2.get_child(0).door_open = true # await get_tree().create_timer(5.0).timeout
# %Train2.get_child(0).door_open = true
var on_final: bool = false: # else:
set(final): # %ShedulePlayer_L.play("train_leaving")
#FIXME: this needs to be a proper sequence! # %LeftLabel.text = "do not board"
on_final = final # return
await get_tree().create_timer(0.5).timeout # if changeover:
if final: prepare_transition() # %ShedulePlayer_R.play("train_leaving")
var on_direct_path: bool = false # await get_tree().create_timer(2.0).timeout
func on_right_train_enter(_body) -> void: # %Train2.get_child(0).door_open = false
if not left_first_station: # on_second_transition()
on_direct_path = true # await get_tree().create_timer(5.0).timeout
%Train.get_child(0).door_open = false # save_game.seen.append(str(Scenes.id.ADULT_THERAPY_UNI))
await get_tree().create_timer(2.0).timeout # %SubwayMap.current_station = Scenes.id.ADULT_THERAPY_UNI
left_first_station = true # %RightLabel.text = "do not board"
on_first_transition(false) # %LeftLabel.text = "do not board"
await get_tree().create_timer(5.0).timeout # on_final = true
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_EATING # await get_tree().create_timer(5.0).timeout
%SubwayMap.current_station = Scenes.id.ADULT_EATING # %Train2.get_child(0).door_open = true
%LeftLabel.text = "U8 Gesundquell \n via Rosenthal Hospital" #
await get_tree().create_timer(5.0).timeout #var on_final: bool = false:
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_SELF_ADVOCACY # set(final):
%SubwayMap.current_station = Scenes.id.ADULT_SELF_ADVOCACY # #FIXME: this needs to be a proper sequence!
await get_tree().create_timer(5.0).timeout # on_final = final
%Train.get_child(0).door_open = true # await get_tree().create_timer(0.5).timeout
# if final: prepare_transition()
await get_tree().create_timer(5.0).timeout #var on_direct_path: bool = false
#func on_right_train_enter(_body) -> void:
if not changeover: # if not left_first_station:
%Train.get_child(0).door_open = false # on_direct_path = true
on_second_transition() # %Train.get_child(0).door_open = false
await get_tree().create_timer(5.0).timeout # await get_tree().create_timer(2.0).timeout
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_BURNOUT # left_first_station = true
%SubwayMap.current_station = Scenes.id.ADULT_BURNOUT # on_first_transition(false)
%RightLabel.text = "do not board" # await get_tree().create_timer(5.0).timeout
%LeftLabel.text = "do not board" # Scenes.enabled_sequences += 1 << Scenes.id.ADULT_EATING
on_final = true # %SubwayMap.current_station = Scenes.id.ADULT_EATING
await get_tree().create_timer(5.0).timeout # %LeftLabel.text = "U8 Gesundquell \n via Rosenthal Hospital"
%Train.get_child(0).door_open = true # await get_tree().create_timer(5.0).timeout
else: # Scenes.enabled_sequences += 1 << Scenes.id.ADULT_SELF_ADVOCACY
%ShedulePlayer_R.play("train_leaving") # %SubwayMap.current_station = Scenes.id.ADULT_SELF_ADVOCACY
%RightLabel.text = "do not board" # await get_tree().create_timer(5.0).timeout
return # %Train.get_child(0).door_open = true
if changeover: #
on_second_transition() # await get_tree().create_timer(5.0).timeout
if on_direct_path: %ShedulePlayer_L.play("train_leaving") #
await get_tree().create_timer(5.0).timeout # if not changeover:
Scenes.enabled_sequences += 1 << Scenes.id.ADULT_AUTISM # %Train.get_child(0).door_open = false
%SubwayMap.current_station = Scenes.id.ADULT_AUTISM # on_second_transition()
await get_tree().create_timer(2.0).timeout # await get_tree().create_timer(5.0).timeout
%Train2.get_child(0).door_open = false # Scenes.enabled_sequences += 1 << Scenes.id.ADULT_BURNOUT
%RightLabel.text = "do not board" # %SubwayMap.current_station = Scenes.id.ADULT_BURNOUT
%LeftLabel.text = "do not board" # %RightLabel.text = "do not board"
on_final = true # %LeftLabel.text = "do not board"
await get_tree().create_timer(5.0).timeout # on_final = true
%Train.get_child(0).door_open = true # await get_tree().create_timer(5.0).timeout
# %Train.get_child(0).door_open = true
var changeover: bool = false # else:
func on_left_train_exit(_body): # %ShedulePlayer_R.play("train_leaving")
if on_second_platform and not on_final: # %RightLabel.text = "do not board"
changeover = true # return
%ShedulePlayer_R.play("train_arriving") # if changeover:
# on_second_transition()
func on_right_train_exit(_body): # if on_direct_path: %ShedulePlayer_L.play("train_leaving")
if on_second_platform and not on_final: # await get_tree().create_timer(5.0).timeout
changeover = true # Scenes.enabled_sequences += 1 << Scenes.id.ADULT_AUTISM
%ShedulePlayer_L.play("train_arriving") # %SubwayMap.current_station = Scenes.id.ADULT_AUTISM
await get_tree().create_timer(10).timeout # await get_tree().create_timer(2.0).timeout
%RightLabel.text = "U1 weissnicht \n via Saint-Exupery Sq." # %Train2.get_child(0).door_open = false
await get_tree().create_timer(5).timeout # %RightLabel.text = "do not board"
%ShedulePlayer_R.play("train_arriving") # %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] [application]
config/name="Frame of Mind" config/name="Frame of Mind"
run/main_scene="uid://ccdfkvtu6sb36" run/main_scene="uid://fgp3tbah7msy"
config/use_custom_user_dir=true config/use_custom_user_dir=true
config/features=PackedStringArray("4.5", "Forward Plus") config/features=PackedStringArray("4.5", "Forward Plus")
boot_splash/bg_color=Color(0.0313726, 0.0117647, 0.129412, 1) boot_splash/bg_color=Color(0.0313726, 0.0117647, 0.129412, 1)
@ -70,8 +70,8 @@ import/blender/enabled=false
[global_group] [global_group]
interactables="" interactables=""
signage1=""
signage2="" signage2=""
signage1=""
[gui] [gui]

View File

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