stop only if station is available on chunk
This commit is contained in:
@@ -2,6 +2,7 @@ extends Path3D
|
|||||||
|
|
||||||
const STEAM_DISTANCE_STAT: String = "stat_distance_km"
|
const STEAM_DISTANCE_STAT: String = "stat_distance_km"
|
||||||
const DISTANCE_KM_PER_UNIT: float = 0.01
|
const DISTANCE_KM_PER_UNIT: float = 0.01
|
||||||
|
const STATION_STOP_GROUP: StringName = &"railway_station"
|
||||||
|
|
||||||
@export_group("Train")
|
@export_group("Train")
|
||||||
##train speed
|
##train speed
|
||||||
@@ -48,6 +49,10 @@ const DISTANCE_KM_PER_UNIT: float = 0.01
|
|||||||
@export_group("Train Stops")
|
@export_group("Train Stops")
|
||||||
##if true the train stop the ran on stops
|
##if true the train stop the ran on stops
|
||||||
@export var enable_stops: bool = true
|
@export var enable_stops: bool = true
|
||||||
|
##if true the train only stops on markers with a generated station nearby
|
||||||
|
@export var require_station_for_stop: bool = true
|
||||||
|
##max horizontal distance between a stop marker and a station chunk
|
||||||
|
@export var station_stop_detection_radius: float = 35.0
|
||||||
##time of stop
|
##time of stop
|
||||||
@export var stop_time: float = 4.0
|
@export var stop_time: float = 4.0
|
||||||
##distance when the train start to brake
|
##distance when the train start to brake
|
||||||
@@ -284,6 +289,9 @@ func build_rails() -> void:
|
|||||||
rail_piece.add_child(rail_dx)
|
rail_piece.add_child(rail_dx)
|
||||||
|
|
||||||
func _plan_stops() -> void:
|
func _plan_stops() -> void:
|
||||||
|
stop_offset.clear()
|
||||||
|
stops_position.clear()
|
||||||
|
|
||||||
var current_stops = []
|
var current_stops = []
|
||||||
for child in get_children():
|
for child in get_children():
|
||||||
if child is Marker3D:
|
if child is Marker3D:
|
||||||
@@ -297,6 +305,53 @@ func _plan_stops() -> void:
|
|||||||
stop_offset.append(data["offset"])
|
stop_offset.append(data["offset"])
|
||||||
stops_position.append(data["position"])
|
stops_position.append(data["position"])
|
||||||
|
|
||||||
|
func _advance_next_stop_index(go_forward: bool) -> void:
|
||||||
|
if stop_offset.is_empty():
|
||||||
|
next_stop_index = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
if go_forward:
|
||||||
|
next_stop_index += 1
|
||||||
|
if next_stop_index >= stop_offset.size():
|
||||||
|
next_stop_index = 0
|
||||||
|
else:
|
||||||
|
next_stop_index -= 1
|
||||||
|
if next_stop_index < 0:
|
||||||
|
next_stop_index = stop_offset.size() - 1
|
||||||
|
|
||||||
|
func _find_next_valid_stop(go_forward: bool) -> bool:
|
||||||
|
if stop_offset.is_empty():
|
||||||
|
return false
|
||||||
|
|
||||||
|
for i in range(stop_offset.size()):
|
||||||
|
if _is_stop_valid(next_stop_index):
|
||||||
|
return true
|
||||||
|
_advance_next_stop_index(go_forward)
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
func _is_stop_valid(stop_index: int) -> bool:
|
||||||
|
if not require_station_for_stop:
|
||||||
|
return true
|
||||||
|
if stop_index < 0 or stop_index >= stops_position.size():
|
||||||
|
return false
|
||||||
|
|
||||||
|
return _has_station_near_position(stops_position[stop_index])
|
||||||
|
|
||||||
|
func _has_station_near_position(stop_position: Vector3) -> bool:
|
||||||
|
var radius_sq := station_stop_detection_radius * station_stop_detection_radius
|
||||||
|
for station in get_tree().get_nodes_in_group(STATION_STOP_GROUP):
|
||||||
|
var station_node := station as Node3D
|
||||||
|
if station_node == null or not is_instance_valid(station_node):
|
||||||
|
continue
|
||||||
|
|
||||||
|
var delta := station_node.global_position - stop_position
|
||||||
|
var horizontal_dist_sq := delta.x * delta.x + delta.z * delta.z
|
||||||
|
if horizontal_dist_sq <= radius_sq:
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
func _input(event: InputEvent) -> void:
|
func _input(event: InputEvent) -> void:
|
||||||
if EnvironmentManagerRoot.is_keyboard_input_blocked(get_tree()):
|
if EnvironmentManagerRoot.is_keyboard_input_blocked(get_tree()):
|
||||||
return
|
return
|
||||||
@@ -329,6 +384,9 @@ func _test_manual_fireworks() -> void:
|
|||||||
func _goto_next_stop() -> void:
|
func _goto_next_stop() -> void:
|
||||||
if stop_offset.size() == 0 or stop_ongoing or is_restarting:
|
if stop_offset.size() == 0 or stop_ongoing or is_restarting:
|
||||||
return
|
return
|
||||||
|
if not _find_next_valid_stop(train_speed >= 0.0):
|
||||||
|
return
|
||||||
|
|
||||||
var target_offset = stop_offset[next_stop_index]
|
var target_offset = stop_offset[next_stop_index]
|
||||||
train_progress = target_offset
|
train_progress = target_offset
|
||||||
_execute_stop(train_speed >= 0)
|
_execute_stop(train_speed >= 0)
|
||||||
@@ -355,15 +413,20 @@ func train_move(delta: float) -> void:
|
|||||||
|
|
||||||
if not stop_ongoing:
|
if not stop_ongoing:
|
||||||
var last_progress = train_progress
|
var last_progress = train_progress
|
||||||
|
var has_valid_stop := false
|
||||||
|
|
||||||
if enable_stops and stop_offset.size() > 0 and not is_restarting:
|
if enable_stops and stop_offset.size() > 0 and not is_restarting:
|
||||||
var target_offset = stop_offset[next_stop_index]
|
has_valid_stop = _find_next_valid_stop(train_speed >= 0.0)
|
||||||
var dist = target_offset - train_progress
|
if has_valid_stop:
|
||||||
dist = wrapf(dist + total_length / 2.0, 0.0, total_length) - total_length / 2.0
|
var target_offset = stop_offset[next_stop_index]
|
||||||
|
var dist = target_offset - train_progress
|
||||||
if abs(dist) < brake_distance and sign(dist) == sign(train_speed):
|
dist = wrapf(dist + total_length / 2.0, 0.0, total_length) - total_length / 2.0
|
||||||
var t = abs(dist) / brake_distance
|
|
||||||
stop_multiply = max(smoothstep(0.0, 1.0, t), 0.05)
|
if abs(dist) < brake_distance and sign(dist) == sign(train_speed):
|
||||||
|
var t = abs(dist) / brake_distance
|
||||||
|
stop_multiply = max(smoothstep(0.0, 1.0, t), 0.05)
|
||||||
|
else:
|
||||||
|
stop_multiply = 1.0
|
||||||
else:
|
else:
|
||||||
stop_multiply = 1.0
|
stop_multiply = 1.0
|
||||||
|
|
||||||
@@ -371,7 +434,7 @@ func train_move(delta: float) -> void:
|
|||||||
train_progress += current_speed * delta
|
train_progress += current_speed * delta
|
||||||
_track_steam_distance(abs(current_speed) * delta)
|
_track_steam_distance(abs(current_speed) * delta)
|
||||||
|
|
||||||
if enable_stops and stop_offset.size() > 0:
|
if enable_stops and stop_offset.size() > 0 and has_valid_stop:
|
||||||
var target_offset = stop_offset[next_stop_index]
|
var target_offset = stop_offset[next_stop_index]
|
||||||
var exceeded_forward = (current_speed > 0 and last_progress < target_offset and train_progress >= target_offset)
|
var exceeded_forward = (current_speed > 0 and last_progress < target_offset and train_progress >= target_offset)
|
||||||
var exceeded_back = (current_speed < 0 and last_progress > target_offset and train_progress <= target_offset)
|
var exceeded_back = (current_speed < 0 and last_progress > target_offset and train_progress <= target_offset)
|
||||||
@@ -458,19 +521,16 @@ func _check_distance_achievements(total_distance_km: int) -> void:
|
|||||||
AchievementManager.unlock("ACH_DISTANCE_200")
|
AchievementManager.unlock("ACH_DISTANCE_200")
|
||||||
|
|
||||||
func _execute_stop(go_forward: bool = true) -> void:
|
func _execute_stop(go_forward: bool = true) -> void:
|
||||||
|
if not _find_next_valid_stop(go_forward):
|
||||||
|
stop_multiply = 1.0
|
||||||
|
return
|
||||||
|
|
||||||
stop_ongoing = true
|
stop_ongoing = true
|
||||||
stop_multiply = 0.0
|
stop_multiply = 0.0
|
||||||
|
|
||||||
var current_stop_index = next_stop_index
|
var current_stop_index = next_stop_index
|
||||||
|
|
||||||
if go_forward:
|
_advance_next_stop_index(go_forward)
|
||||||
next_stop_index += 1
|
|
||||||
if next_stop_index >= stop_offset.size():
|
|
||||||
next_stop_index = 0
|
|
||||||
else:
|
|
||||||
next_stop_index -= 1
|
|
||||||
if next_stop_index < 0:
|
|
||||||
next_stop_index = stop_offset.size() - 1
|
|
||||||
|
|
||||||
if fireworks_scene != null:
|
if fireworks_scene != null:
|
||||||
var marker_position = stops_position[current_stop_index]
|
var marker_position = stops_position[current_stop_index]
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -119,7 +119,7 @@ shader_parameter/glint_sharpness = 32.0
|
|||||||
shader_parameter/emission_color = Color(0, 0, 0, 1)
|
shader_parameter/emission_color = Color(0, 0, 0, 1)
|
||||||
shader_parameter/emission_energy = 0.0
|
shader_parameter/emission_energy = 0.0
|
||||||
|
|
||||||
[node name="chunk_railway_station_doubleside" unique_id=1591869611 groups=["weather_node"] instance=ExtResource("1_nkssc")]
|
[node name="chunk_railway_station_doubleside" unique_id=1591869611 groups=["railway_station", "weather_node"] instance=ExtResource("1_nkssc")]
|
||||||
script = ExtResource("2_i3rfy")
|
script = ExtResource("2_i3rfy")
|
||||||
chunk_type = 1
|
chunk_type = 1
|
||||||
est = true
|
est = true
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ shader_parameter/glint_sharpness = 32.0
|
|||||||
shader_parameter/emission_color = Color(0, 0, 0, 1)
|
shader_parameter/emission_color = Color(0, 0, 0, 1)
|
||||||
shader_parameter/emission_energy = 0.0
|
shader_parameter/emission_energy = 0.0
|
||||||
|
|
||||||
[node name="chunk_railway_station_oneside" unique_id=310632835 node_paths=PackedStringArray("connection_left", "connection_right") groups=["weather_node"] instance=ExtResource("1_38ujo")]
|
[node name="chunk_railway_station_oneside" unique_id=310632835 node_paths=PackedStringArray("connection_left", "connection_right") groups=["railway_station", "weather_node"] instance=ExtResource("1_38ujo")]
|
||||||
script = ExtResource("2_a8mxs")
|
script = ExtResource("2_a8mxs")
|
||||||
chunk_type = 1
|
chunk_type = 1
|
||||||
west = true
|
west = true
|
||||||
|
|||||||
Reference in New Issue
Block a user