101 lines
3.5 KiB
GDScript
101 lines
3.5 KiB
GDScript
class_name Fahrplan extends Node3D
|
|
|
|
## easy graph: <station> : [Track1Train1 (next halt), Track1Train2], [Track2Train1(next halt), ...]
|
|
## CAVEAT: These must be direct children of the fahrplan!
|
|
@onready var fahrplan : Dictionary[Station, Array] = {
|
|
$hirschfeld: [["u2", $uni_mensa, "u1", $parity_square],[]],
|
|
$uni_mensa : [["u2", $uni_main],[]],
|
|
$uni_main: [["u2", $ministry],["u8", $rosenthal, "u2", $uni_mensa, "u1", $saint_exupery]],
|
|
$parity_square : [["u4", $saint_exupery, "u1", $saint_exupery], []],
|
|
$saint_exupery : [["u4", $rosenthal], ["u1", $uni_main]],
|
|
|
|
$ministry : [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]
|
|
|
|
@export var empty_train_random_delay : Vector2 = Vector2(5.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:
|
|
await get_tree().process_frame
|
|
|
|
tracks[0].train_left.connect(_player_train_left)
|
|
tracks[1].train_left.connect(_player_train_left)
|
|
_unparent_all_stations_except($hirschfeld)
|
|
enter_station(current)
|
|
|
|
|
|
## The current station
|
|
var current : Station
|
|
var stop := false
|
|
|
|
var destinations : Array[Station] = [null, null]
|
|
|
|
## 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
|
|
track.arrive(true)
|
|
_set_signage_texts(track.signage_group, "Endstation")
|
|
return
|
|
|
|
var routes : Array = fahrplan[current][track.index]
|
|
if routes.is_empty():
|
|
_set_signage_texts(track.signage_group, "Verkehr z. Zt.\nunregelmäßig")
|
|
return
|
|
|
|
while true:
|
|
if cancel.is_empty(): return # abort the loop
|
|
|
|
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
|
|
|
|
destinations[track.index] = next
|
|
track.set_line(line)
|
|
_set_signage_texts(track.signage_group, current.get_label(line, next)) # TODO: load nice string
|
|
|
|
# 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
|
|
await track.cycle() # arrive and depart
|
|
|
|
|
|
var cancellation_token : Array
|
|
|
|
func enter_station(station: Station):
|
|
prints("------------", "ENTER STATION", station, station.name, "------------")
|
|
remove_child(current)
|
|
current = station
|
|
add_child(station)
|
|
|
|
cancellation_token = ["go"] # Allocate a new stopping token
|
|
_begin_traffic_loop(tracks[0], cancellation_token)
|
|
_begin_traffic_loop(tracks[1], cancellation_token)
|
|
|
|
|
|
func _player_train_left(track: Dolly) -> void:
|
|
cancellation_token.clear()
|
|
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)
|