|
| 1 | +@tool |
| 2 | +extends Node3D |
| 3 | +class_name MaszynaSwitch3D |
| 4 | + |
| 5 | +enum SwitchState { STRAIGHT, DIVERGING } |
| 6 | + |
| 7 | +@export var state: SwitchState = SwitchState.STRAIGHT: |
| 8 | + set(x): |
| 9 | + state = x |
| 10 | + _update_switch() |
| 11 | + |
| 12 | +@export_group("Tracks") |
| 13 | +@export var straight_track: MaszynaTrack3D: |
| 14 | + set(x): |
| 15 | + straight_track = x |
| 16 | + update_configuration_warnings() |
| 17 | + _update_switch() |
| 18 | + |
| 19 | +@export var diverging_track: MaszynaTrack3D: |
| 20 | + set(x): |
| 21 | + diverging_track = x |
| 22 | + update_configuration_warnings() |
| 23 | + _update_switch() |
| 24 | + |
| 25 | +@export var common_track: MaszynaTrack3D: |
| 26 | + set(x): |
| 27 | + common_track = x |
| 28 | + update_configuration_warnings() |
| 29 | + _update_switch() |
| 30 | + |
| 31 | +func _ready(): |
| 32 | + _update_switch() |
| 33 | + |
| 34 | +func _get_configuration_warnings(): |
| 35 | + var warnings = [] |
| 36 | + if not straight_track: |
| 37 | + warnings.append("No straight track node assigned.") |
| 38 | + if not diverging_track: |
| 39 | + warnings.append("No diverging track node assigned.") |
| 40 | + if not common_track: |
| 41 | + warnings.append("No common track node assigned.") |
| 42 | + |
| 43 | + if straight_track and diverging_track and common_track: |
| 44 | + if not straight_track.curve or not diverging_track.curve or not common_track.curve: |
| 45 | + warnings.append("One or more tracks are missing curves.") |
| 46 | + else: |
| 47 | + var inlet_pos = _get_inlet_position() |
| 48 | + var s_start = straight_track.to_global(straight_track.curve.get_point_position(0)) |
| 49 | + var s_end = straight_track.to_global(straight_track.curve.get_point_position(straight_track.curve.point_count - 1)) |
| 50 | + |
| 51 | + if s_start.distance_to(inlet_pos) > 0.5 and s_end.distance_to(inlet_pos) > 0.5: |
| 52 | + warnings.append("Straight track does not seem to connect to the switch inlet.") |
| 53 | + |
| 54 | + return warnings |
| 55 | + |
| 56 | +func _get_inlet_position() -> Vector3: |
| 57 | + if common_track and common_track.curve: |
| 58 | + # inlet is at the end of common track (usually) |
| 59 | + return common_track.to_global(common_track.curve.get_point_position(common_track.curve.point_count - 1)) |
| 60 | + if straight_track and straight_track.curve: |
| 61 | + # or at the start of straight track |
| 62 | + return straight_track.to_global(straight_track.curve.get_point_position(0)) |
| 63 | + return global_position |
| 64 | + |
| 65 | +func resolve_track(incoming_track: Node3D) -> MaszynaTrack3D: |
| 66 | + if incoming_track == common_track: |
| 67 | + return straight_track if state == SwitchState.STRAIGHT else diverging_track |
| 68 | + elif incoming_track == straight_track or incoming_track == diverging_track: |
| 69 | + return common_track |
| 70 | + return null |
| 71 | + |
| 72 | +func _update_switch(): |
| 73 | + if not is_inside_tree(): return |
| 74 | + update_configuration_warnings() |
| 75 | + |
| 76 | + if common_track: _auto_link_track(common_track) |
| 77 | + if straight_track: _auto_link_track(straight_track) |
| 78 | + if diverging_track: _auto_link_track(diverging_track) |
| 79 | + |
| 80 | +func _auto_link_track(track: MaszynaTrack3D): |
| 81 | + if not track or not track.curve: return |
| 82 | + var inlet_pos = _get_inlet_position() |
| 83 | + var p_start = track.to_global(track.curve.get_point_position(0)) |
| 84 | + var p_end = track.to_global(track.curve.get_point_position(track.curve.point_count - 1)) |
| 85 | + |
| 86 | + # Only link the end that is actually AT the switch junction |
| 87 | + if p_start.distance_to(inlet_pos) < 0.5: |
| 88 | + if track.previous_track.is_empty(): |
| 89 | + track.previous_track = track.get_path_to(self) |
| 90 | + elif p_end.distance_to(inlet_pos) < 0.5: |
| 91 | + if track.next_track.is_empty(): |
| 92 | + track.next_track = track.get_path_to(self) |
| 93 | + |
| 94 | +func toggle(): |
| 95 | + state = SwitchState.DIVERGING if state == SwitchState.STRAIGHT else SwitchState.STRAIGHT |
0 commit comments