@@ -36,6 +36,7 @@ export class Train {
3636 }
3737
3838 // TODO - make delay reduction visible by adjusting train speeds to be more accurate
39+ // TODO - fix user delays if not at the station (before it)
3940 // TODO - make train speeds reduce before meeting stations
4041 step ( ) {
4142 if ( ! this . #isWaiting) {
@@ -47,6 +48,9 @@ export class Train {
4748 }
4849 }
4950
51+ /**
52+ * Train movement logic
53+ */
5054 move ( ) {
5155 if ( this . #position instanceof TrainPositionOnRail ) {
5256 // updating position based on velocity and acceleration
@@ -63,30 +67,39 @@ export class Train {
6367 }
6468 }
6569
70+ /** Approaching the next station logic */
6671 handleNextStationArrival ( ) {
6772 if ( this . #nextStation) {
6873 if ( ! ( this . #position instanceof TrainPositionOnRail ) ) return ; // safety check
6974 const arrived = ( this . #position as TrainPositionOnRail ) . distance >= this . #position. rail . length ( ) ;
75+
7076 // checking if the train reached its next station
7177 const nextSchedule = this . #nextStation. trainsSchedule . get ( this . trainTemplate ) ;
72- if ( arrived && nextSchedule ?. arrivalTime ) {
73- // TODO ^ - idk if it should be like this - depends on TrainPositionOnRail management
74- const trackAtTheStation = this . #nextStation. assignTrack ( this . trainTemplate , nextSchedule . track ) ;
75- if ( trackAtTheStation == null ) {
76- // cannot arrive at the station - track full; waiting
77- // Z jaką prędkością może czekać pociąg?
78- this . #isWaiting = true ;
79- this . #delay. addConflictDelay ( this . calculateConflictDelay ( ) ) ;
80-
81- return ;
82- } else {
83- this . #isWaiting = false ;
78+ if ( arrived ) {
79+ if ( nextSchedule ) {
80+ const trackAtTheStation = this . #nextStation. assignTrack ( this . trainTemplate , nextSchedule . track ) ;
81+
82+ if ( trackAtTheStation == null ) {
83+ // cannot arrive at the station - track full; waiting
84+ // Z jaką prędkością może czekać pociąg?
85+ this . #isWaiting = true ;
86+ this . #delay. addConflictDelay ( this . calculateConflictDelay ( ) ) ;
87+ return ;
88+ } else {
89+ this . #isWaiting = false ;
90+ this . #position = trackAtTheStation ; // TrainPositionOnRail no longer useful
91+ this . #nextStation = null ;
92+
93+ // only if this is a real stop
94+ if ( nextSchedule . arrivalTime ) {
95+ this . stop ( ) ;
96+ this . #acceleration = AccelerationStatus . Constant ;
97+ }
8498
85- this . #position = trackAtTheStation ; // TrainPositionOnRail no longer useful
86- this . #position. trainArrival ( this , nextSchedule . arrivalTime ) ;
87- this . stop ( ) ;
88- this . #nextStation = null ;
89- this . #acceleration = AccelerationStatus . Constant ;
99+ this . #position. trainArrival ( this , nextSchedule . arrivalTime ) ;
100+ }
101+ } else {
102+ throw new Error ( "Train schedule missing for the next station" ) ;
90103 }
91104 }
92105 } else {
@@ -118,37 +131,25 @@ export class Train {
118131 this . #acceleration = newAccelerationStatus ;
119132 }
120133
134+ /**
135+ * Calculates delay due to (track occupancy) conflicts at the next station
136+ * @returns delay time in seconds
137+ */
121138 calculateConflictDelay ( ) : number {
122139 let conflictDelay : number = 0 ;
123140 if ( this . #nextStation) {
124- const firstTrackTrain = this . #nextStation. tracks [ 0 ] . train ;
125- if ( firstTrackTrain ) {
126- let firstTrackTrainSchedule = this . #nextStation. trainsSchedule . get ( firstTrackTrain . trainTemplate ) ;
127- if ( firstTrackTrainSchedule ) {
128- if ( firstTrackTrainSchedule . departureTime ) {
141+ const trackNumber = this . #nextStation. trainsSchedule . get ( this . trainTemplate ) ?. track . trackNumber ;
142+ const trackTrain = this . #nextStation. tracks . find ( ( t ) => t . trackNumber === trackNumber ) ?. train ;
143+
144+ if ( trackTrain ) {
145+ let trackTrainSchedule = this . #nextStation! . trainsSchedule . get ( trackTrain . trainTemplate ) ;
146+ if ( trackTrainSchedule ) {
147+ if ( trackTrainSchedule . departureTime ) {
129148 conflictDelay =
130- firstTrackTrainSchedule . departureTime . toSeconds ( ) - simulation . currentTime . toSeconds ( ) ;
149+ trackTrainSchedule . departureTime . toSeconds ( ) - simulation . currentTime . toSeconds ( ) ;
131150 }
132151 }
133152 }
134-
135- this . #nextStation. tracks . forEach ( ( track ) => {
136- const trackTrain = track . train ;
137- if ( trackTrain ) {
138- let trackTrainSchedule = this . #nextStation! . trainsSchedule . get ( trackTrain . trainTemplate ) ;
139- if ( trackTrainSchedule ) {
140- if ( trackTrainSchedule . departureTime ) {
141- if (
142- trackTrainSchedule . departureTime . toSeconds ( ) - simulation . currentTime . toSeconds ( ) <
143- conflictDelay
144- ) {
145- conflictDelay =
146- trackTrainSchedule . departureTime . toSeconds ( ) - simulation . currentTime . toSeconds ( ) ;
147- }
148- }
149- }
150- }
151- } ) ;
152153 }
153154 return conflictDelay ;
154155 }
@@ -169,6 +170,11 @@ export class Train {
169170 return this . trainTemplate . displayName ( ) ;
170171 }
171172
173+ /**
174+ * Determines if the train should wait longer at the station for other trains with specific priorities
175+ * @param otherTrain train to wait for (or not to wait for)
176+ * @returns boolean indicating whether to wait longer
177+ */
172178 shouldWaitLonger ( otherTrain : Train ) : boolean {
173179 const timeLeft = this . trainTemplate . type . maxWaitingTime - this . #delay. currentWaitingTimeAtTheStationInSeconds ;
174180 if (
0 commit comments