Skip to content

Commit 1852fcb

Browse files
committed
Update turntable pools
1 parent 3ffb9bc commit 1852fcb

File tree

1 file changed

+64
-38
lines changed

1 file changed

+64
-38
lines changed

Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,21 @@ public TimetableTurntablePool(TimetableReader fileContents, ref int lineindex, S
183183
if (pathValid)
184184
{
185185
Train.TCRoutePath fullRoute = new Train.TCRoutePath(newPath, -2, 1, Simulatorref.Signals, -1, Simulatorref.Settings);
186-
// if last element is end of track, remove it from path
186+
187+
// if first element is end of track, remove it from path (path is defined outbound)
187188
Train.TCSubpathRoute usedRoute = fullRoute.TCRouteSubpaths[0];
188-
int lastIndex = usedRoute.Count - 1;
189-
int lastSectionIndex = usedRoute[lastIndex].TCSectionIndex;
190-
if (Simulatorref.Signals.TrackCircuitList[lastSectionIndex].CircuitType == TrackCircuitSection.TrackCircuitType.EndOfTrack)
189+
if (Simulatorref.Signals.TrackCircuitList[usedRoute.First().TCSectionIndex].CircuitType == TrackCircuitSection.TrackCircuitType.EndOfTrack)
190+
{
191+
usedRoute.RemoveAt(0);
192+
}
193+
194+
// if last element is send of track, remove it from path (if path has no junction it may be in reverse direction)
195+
if (Simulatorref.Signals.TrackCircuitList[usedRoute.Last().TCSectionIndex].CircuitType == TrackCircuitSection.TrackCircuitType.EndOfTrack)
191196
{
192-
lastIndex = usedRoute.Count - 2;
197+
usedRoute.RemoveAt(usedRoute.Count - 1);
193198
}
194199

200+
// create path list if required
195201
if (AdditionalTurntableDetails.AccessPaths == null)
196202
{
197203
AdditionalTurntableDetails.AccessPaths = new List<AccessPathDetails>();
@@ -615,14 +621,6 @@ private void CalculateAccessOffsets(int ipath, Turntable thisTurntable)
615621
{
616622
AccessPathDetails thisPath = AdditionalTurntableDetails.AccessPaths[ipath];
617623

618-
float baseLength = 0;
619-
620-
// calculate total length of path sections except first section
621-
for (int isection = 1; isection < thisPath.AccessPath.Count; isection++)
622-
{
623-
baseLength += Simulatorref.Signals.TrackCircuitList[thisPath.AccessPath[isection].TCSectionIndex].Length;
624-
}
625-
626624
// calculate total length of track sections in first section backward upto turntable section
627625
TrackCircuitSection thisSection = Simulatorref.Signals.TrackCircuitList[thisPath.AccessPath[0].TCSectionIndex];
628626
int trackNodeIndex = thisSection.OriginalIndex;
@@ -656,13 +654,11 @@ private void CalculateAccessOffsets(int ipath, Turntable thisTurntable)
656654
thisPath.AccessTraveller.Direction = Traveller.TravellerDirection.Backward;
657655
}
658656

659-
float totalLength = baseLength + entrySectionLength;
660-
661657
// deduct clearance for turntable
662658
// if no explicit clearance defined, use length of last vector before turntable
663659

664-
thisPath.TableApproachOffset = totalLength - AdditionalTurntableDetails.TurntableApproachClearanceM;
665-
thisPath.TableMiddleEntry = totalLength + (thisTurntable.Length / 2.0f);
660+
thisPath.TableApproachOffset = entrySectionLength - AdditionalTurntableDetails.TurntableApproachClearanceM;
661+
thisPath.TableMiddleEntry = entrySectionLength + (thisTurntable.Length / 2.0f);
666662
thisPath.TableMiddleExit = exitSectionLength + (thisTurntable.Length / 2.0f);
667663

668664
#if DEBUG_TURNTABLEINFO
@@ -847,7 +843,6 @@ public override bool TestPoolExit(TTTrain train)
847843
bool validPath = TestPoolAccess(train, out testAccess);
848844
return (validPath);
849845
}
850-
851846
public bool TestPoolAccess(TTTrain train, out int accessIndex)
852847
{
853848
bool validPool = false;
@@ -864,24 +859,27 @@ public bool TestPoolAccess(TTTrain train, out int accessIndex)
864859
for (int iSection = train.TCRoute.TCRouteSubpaths.Last().Count - 1; iSection >= 0 && reqPath == -1; iSection--)
865860
{
866861
int lastSectionIndex = train.TCRoute.TCRouteSubpaths.Last()[iSection].TCSectionIndex;
867-
int lastSectionDirection = train.TCRoute.TCRouteSubpaths.Last().Last().Direction;
862+
int lastSectionDirection = train.TCRoute.TCRouteSubpaths.Last()[iSection].Direction;
868863

869-
for (int iPath = 0; iPath < AdditionalTurntableDetails.AccessPaths.Count && reqPath < 0; iPath++)
864+
if (train.signalRef.TrackCircuitList[lastSectionIndex].CircuitType == TrackCircuitSection.TrackCircuitType.Normal)
870865
{
871-
Train.TCSubpathRoute accessPath = AdditionalTurntableDetails.AccessPaths[iPath].AccessPath;
872-
reqPathIndex = accessPath.GetRouteIndex(lastSectionIndex, 0);
873-
874-
// path is defined outbound, so directions must be opposite
875-
if (reqPathIndex >= 0 && accessPath[reqPathIndex].Direction != lastSectionDirection)
866+
for (int iPath = 0; iPath < AdditionalTurntableDetails.AccessPaths.Count && reqPath < 0; iPath++)
876867
{
877-
reqPath = iPath;
878-
lastValidSectionIndex = iSection;
868+
Train.TCSubpathRoute accessPath = AdditionalTurntableDetails.AccessPaths[iPath].AccessPath;
869+
reqPathIndex = accessPath.GetRouteIndex(lastSectionIndex, 0);
870+
871+
// path is defined outbound, so directions must be opposite
872+
if (reqPathIndex >= 0 && accessPath[reqPathIndex].Direction != lastSectionDirection)
873+
{
874+
reqPath = iPath;
875+
lastValidSectionIndex = iSection;
876+
}
879877
}
880878
}
881879
}
882880

883881
// remove sections from train route if required
884-
if (lastValidSectionIndex < train.TCRoute.TCRouteSubpaths.Last().Count - 1)
882+
if (reqPath >= 0 && lastValidSectionIndex < train.TCRoute.TCRouteSubpaths.Last().Count - 1)
885883
{
886884
for (int iSection = train.TCRoute.TCRouteSubpaths.Last().Count - 1; iSection > lastValidSectionIndex; iSection--)
887885
{
@@ -1007,7 +1005,7 @@ override public TrainFromPool ExtractTrain(ref TTTrain train, int presentTime)
10071005
#if DEBUG_POOLINFO
10081006
sob = new StringBuilder();
10091007
sob.AppendFormat("Pool {0} : cannot find train {1} for {2} ({3}) \n", PoolName, selectedTrainNumber, train.Number, train.Name);
1010-
sob.AppendFormat(" stored units : {0}", reqStorage.StoredUnits.Count);
1008+
sob.AppendFormat(" stored units : {0}", StoragePool[selectedStorage].StoredUnits.Count);
10111009
File.AppendAllText(@"C:\temp\PoolAnal.csv", sob.ToString() + "\n");
10121010
#endif
10131011
return (TrainFromPool.Delayed);
@@ -1023,7 +1021,7 @@ override public TrainFromPool ExtractTrain(ref TTTrain train, int presentTime)
10231021
#if DEBUG_POOLINFO
10241022
sob = new StringBuilder();
10251023
sob.AppendFormat("Pool {0} : train {1} ({2}) extracted as {3} ({4}) \n", PoolName, selectedTrain.Number, selectedTrain.Name, train.Number, train.Name);
1026-
sob.AppendFormat(" stored units : {0}", reqStorage.StoredUnits.Count);
1024+
sob.AppendFormat(" stored units : {0}", StoragePool[selectedStorage].StoredUnits.Count);
10271025
File.AppendAllText(@"C:\temp\PoolAnal.csv", sob.ToString() + "\n");
10281026
#endif
10291027

@@ -1299,8 +1297,9 @@ override public Train.TCSubpathRoute SetPoolExit(TTTrain train, out int poolStor
12991297
// no action if state is poolClaimed - state will resolve as train ahead is stabled in pool
13001298

13011299
// valid pool
1302-
else if (reqPool > 0)
1300+
else if (reqPool >= 0)
13031301
{
1302+
// train approaches from exit path - train is moving toward turntable and is stored after turntable movement
13041303
if (checkAccessPath)
13051304
{
13061305
bool validPath = TestPoolAccess(train, out reqPath);
@@ -1331,16 +1330,32 @@ override public Train.TCSubpathRoute SetPoolExit(TTTrain train, out int poolStor
13311330
}
13321331
}
13331332

1334-
poolStorageIndex = reqPool;
1333+
train.PoolStorageIndex = poolStorageIndex = reqPool;
1334+
1335+
// set approach to turntable
1336+
// also add unit to storage as claim
1337+
newRoute.Last().MovingTableApproachPath = reqPath;
1338+
AddUnit(train, true);
1339+
StoragePool[poolStorageIndex].ClaimUnits.Add(train.Number);
13351340
}
13361341
}
1342+
13371343
// create new route from access track only
13381344
// use first defined access track
1339-
// reverse path as path is outbound
1345+
// if only one unit allowed on storage, reverse path so train stands at allocated position
1346+
// if multiple units allowed on storage, do not reverse path so train moves to end of storage location
13401347
else
13411348
{
1342-
newRoute = new Train.TCSubpathRoute(AdditionalTurntableDetails.AccessPaths[0].AccessPath.ReversePath(train.signalRef));
1343-
poolStorageIndex = reqPool;
1349+
if (StoragePool[poolStorageIndex].maxStoredUnits == 1)
1350+
{
1351+
newRoute = new Train.TCSubpathRoute(AdditionalTurntableDetails.AccessPaths[0].AccessPath.ReversePath(train.signalRef));
1352+
}
1353+
else
1354+
{
1355+
newRoute = new Train.TCSubpathRoute(AdditionalTurntableDetails.AccessPaths[0].AccessPath);
1356+
}
1357+
1358+
train.PoolStorageIndex = poolStorageIndex = reqPool;
13441359
}
13451360
}
13461361

@@ -1365,6 +1380,12 @@ override public float GetEndOfRouteDistance(Train.TCSubpathRoute thisRoute, Trai
13651380
// get distance to approach point from present position of train
13661381
int turntableSectionIndex = thisRoute.GetRouteIndex(AdditionalTurntableDetails.AccessPaths[pathIndex].AccessPath[0].TCSectionIndex, 0);
13671382
float startoffset = signalRef.TrackCircuitList[frontPosition.TCSectionIndex].Length - frontPosition.TCOffset;
1383+
if (frontPosition.RouteListIndex < 0 && turntableSectionIndex < 0)
1384+
{
1385+
Trace.TraceInformation("Invalid check on turntable approach : present position and turntable index both < 0; for pool : " + PoolName);
1386+
return (-1);
1387+
}
1388+
13681389
float distanceToTurntable = thisRoute.GetDistanceAlongRoute(frontPosition.RouteListIndex, startoffset,
13691390
turntableSectionIndex, AdditionalTurntableDetails.AccessPaths[pathIndex].TableApproachOffset, true, signalRef);
13701391

@@ -2493,6 +2514,8 @@ public void PrepareMoveOffTable()
24932514
parentTrain.ControlMode = Train.TRAIN_CONTROL.AUTO_NODE;
24942515
parentTrain.DistanceTravelledM = 0;
24952516
parentTrain.DelayedStartMoving(AITrain.AI_START_MOVEMENT.PATH_ACTION);
2517+
parentTrain.EndAuthorityType[0] = Train.END_AUTHORITY.NO_PATH_RESERVED;
2518+
parentTrain.EndAuthorityType[1] = Train.END_AUTHORITY.NO_PATH_RESERVED;
24962519

24972520
// actions for mode access (train going into storage)
24982521
if (MovingTableAction == MovingTableActionEnum.FromAccess)
@@ -2505,7 +2528,7 @@ public void PrepareMoveOffTable()
25052528
float endOffset = parentPool.StoragePool[StoragePathIndex].StoragePathTraveller.TrackNodeOffset + parentTrain.Length;
25062529
if (endOffset < parentTrain.DistanceToEndNodeAuthorityM[0])
25072530
{
2508-
parentTrain.DistanceToEndNodeAuthorityM[0] = endOffset;
2531+
parentTrain.DistanceToEndNodeAuthorityM[0] = parentTrain.NextStopDistanceM = endOffset;
25092532
}
25102533
}
25112534

@@ -2532,14 +2555,17 @@ public void PrepareMoveOffTable()
25322555
public void RemoveTrainFromTurntable()
25332556
{
25342557
// clear table
2558+
2559+
if (parentTurntable == null) parentTurntable = parentPool.Simulatorref.MovingTables[parentIndex] as Turntable;
2560+
25352561
parentTurntable.TrainsOnMovingTable.Clear();
25362562
parentTurntable.InUse = false;
25372563
parentTurntable.GoToAutoTarget = false;
25382564
trainOnTable = null;
25392565

25402566
// reset train speed
25412567
parentTrain.TrainMaxSpeedMpS = originalTrainMaxSpeedMpS;
2542-
Train.ActivateSpeedLimit activeSpeeds = new Train.ActivateSpeedLimit(0.0f, originalSpeedLimitMpS, originalSpeedSignalMpS);
2568+
Train.ActivateSpeedLimit activeSpeeds = new Train.ActivateSpeedLimit(0.0f, originalSpeedLimitMpS, originalSpeedSignalMpS, originalSpeedLimitMpS);
25432569

25442570
if (parentTrain.TrainType == Train.TRAINTYPE.PLAYER)
25452571
{
@@ -2586,4 +2612,4 @@ public bool TestTrainFormation (TTTrain parentTrain)
25862612
return (reqReverse);
25872613
}
25882614
}
2589-
}
2615+
}

0 commit comments

Comments
 (0)