Skip to content

Commit be04a6a

Browse files
Merge branch 'openrails:master' into master
2 parents edcd0d0 + 9079364 commit be04a6a

File tree

23 files changed

+1125
-483
lines changed

23 files changed

+1125
-483
lines changed

Source/Documentation/Manual/compatibility.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Within the ``\GLOBAL`` folder two sub-folders are required::
129129
Within the ``\TRAINS`` folder two subfolders are required::
130130

131131
\CONSISTS
132-
\TRAINSETS
132+
\TRAINSET
133133

134134
Original MSTS Files Usually Needed for Added MSTS-Compatible Content
135135
====================================================================

Source/Documentation/Manual/features-route.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,18 @@ TrackShape block within the tsection.dat file. You only have to insert the diame
208208
the turntable and the degree step. Of course you have to take only the lines up to the
209209
one preceding the one with degrees = 180.
210210

211+
Also turntables which may rotate less than 360 degrees can be implemented, like the one in
212+
the picture here below:
213+
214+
.. image:: images/features-partial-turntable.png
215+
216+
In this case following line has to be added at the end of the ``Turntable()`` block
217+
in file ``turntables.dat`` for a turntable that can rotate only between 0 and 40 degrees::
218+
219+
MaxAngle ( 40 )
220+
221+
Angles increase clockwise.
222+
211223
Already many existing turntables have been successfully animated and many new other
212224
have been created. More can be read
213225
`in this forum thread <http://www.elvastower.com/forums/index.php?/topic/28591-operational-turntable/>`_ .
Loading

Source/Documentation/Manual/intro.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ called an *MSTS installation* for convenience, even if this wording is not
8686
completely correct.
8787

8888
A proof that Open Rails itself does not need an MSTS installation at all to
89-
run is `this route <http://www.burrinjuck.coalstonewcastle.com.au/route/route-install/>`.
89+
run is `this route <http://www.burrinjuck.coalstonewcastle.com.au/route/route-install/>`_ (Burrinjuck Railway).
9090

9191
Community
9292
=========

Source/Documentation/Manual/multiplayer.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,13 @@ information of train positions. If two player trains couple together, one of
160160
them will become a helper, and a message will be shown on the left indicating
161161
that the player is in Helper mode. A player in Helper mode cannot control
162162
his consist as it falls under control of the lead locomotive. By pressing
163-
``<Shift+E>`` you can swap Helper status with another player on the train.
163+
``<Alt+E>`` you can swap Helper status with another player on the train.
164164
Always press ``<\>`` and ``<Shift+/>`` to reset brakes each time after
165165
coupling/uncoupling. Note that two trains can't couple together before two
166166
minutes are passed from their presence in the Dispatcher's computer.
167167

168168
Players can uncouple their own trains. Players in the uncoupled trains may
169-
need to press ``<Shift+E>`` to gain control; otherwise, the uncoupled
169+
need to press ``<Alt+E>`` to gain control; otherwise, the uncoupled
170170
trains may become a loose consist. Always stop completely before uncoupling,
171171
otherwise weird things may happen. Players may also need to press keys for
172172
resetting brake state after uncoupling (see :ref:`here <driving-brakes-init>`).
@@ -248,7 +248,7 @@ Summary of Multi-Player Procedures
248248
8. Use ``<\>`` and ``<Shift+/>`` (on English keyboards) just after your
249249
train is coupled or uncoupled, or when you just gain back the control of
250250
your own train.
251-
9. Use ``<Shift+E>`` to gain control of your own train after uncoupling.
251+
9. Use ``<Alt+E>`` to gain control of your own train after uncoupling.
252252
10. Use other communication tools (such as Ventrillo or Skype) to communicate
253253
with other players.
254254
11. Always completely stop before uncoupling trains with two players coupled

Source/Orts.Formats.Msts/SignalConfigurationFile.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1114,7 +1114,8 @@ public ApproachControlLimits(STFReader stf)
11141114
new STFReader.TokenProcessor("positionyd", ()=>{ ApproachControlPositionM = Me.FromYd(stf.ReadFloatBlock(STFReader.UNITS.None, 0)); }),
11151115
new STFReader.TokenProcessor("speedmph", ()=>{ ApproachControlSpeedMpS = MpS.FromMpH(stf.ReadFloatBlock(STFReader.UNITS.None, 0)); }),
11161116
new STFReader.TokenProcessor("speedkph", ()=>{ ApproachControlSpeedMpS = MpS.FromKpH(stf.ReadFloatBlock(STFReader.UNITS.None, 0)); }),
1117-
});
1117+
new STFReader.TokenProcessor("speedmps", ()=>{ ApproachControlSpeedMpS = stf.ReadFloatBlock(STFReader.UNITS.None, 0); }),
1118+
});
11181119
}
11191120
}
11201121

Source/Orts.Simulation/Simulation/AIs/AI.cs

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,54 +1159,13 @@ private bool AddToWorldTT(TTTrain thisTrain, List<TTTrain> nextTrains)
11591159
int presentTime = Convert.ToInt32(Math.Floor(clockTime));
11601160
TimetablePool thisPool = Simulator.PoolHolder.Pools[thisTrain.CreateInPool];
11611161

1162-
int PoolStorageState = (int)TTTrain.PoolAccessState.PoolInvalid;
1163-
thisTrain.TCRoute.TCRouteSubpaths[0] = thisPool.CreateInPool(thisTrain, out PoolStorageState, false);
1164-
thisTrain.ValidRoute[0] = new Train.TCSubpathRoute(thisTrain.TCRoute.TCRouteSubpaths[0]);
1165-
thisTrain.TCRoute.activeSubpath = 0;
1162+
int PoolStorageState = thisPool.CreateInPool(thisTrain, nextTrains);
11661163

1167-
// if no storage available - abondone train
11681164
if (PoolStorageState < 0)
11691165
{
11701166
Trace.TraceInformation("Train : " + thisTrain.Name + " : no storage room available in pool : " + thisPool.PoolName + " ; engine not created");
11711167
return (endPreRun);
11721168
}
1173-
1174-
// use stored traveller
1175-
thisTrain.PoolStorageIndex = PoolStorageState;
1176-
thisTrain.RearTDBTraveller = new Traveller(thisPool.StoragePool[thisTrain.PoolStorageIndex].StoragePathTraveller);
1177-
1178-
// if storage available check for other engines on storage track
1179-
if (thisPool.StoragePool[thisTrain.PoolStorageIndex].StoredUnits.Count > 0)
1180-
{
1181-
int lastTrainNumber = thisPool.StoragePool[thisTrain.PoolStorageIndex].StoredUnits[thisPool.StoragePool[thisTrain.PoolStorageIndex].StoredUnits.Count - 1];
1182-
TTTrain lastTrain = thisTrain.GetOtherTTTrainByNumber(lastTrainNumber);
1183-
if (lastTrain == null)
1184-
{
1185-
lastTrain = thisTrain.Simulator.GetAutoGenTTTrainByNumber(lastTrainNumber);
1186-
}
1187-
if (lastTrain != null)
1188-
{
1189-
thisTrain.CreateAhead = String.Copy(lastTrain.Name).ToLower();
1190-
}
1191-
}
1192-
1193-
tempRoute = thisTrain.CalculateInitialTTTrainPosition(ref validPosition, nextTrains);
1194-
1195-
if (validPosition)
1196-
{
1197-
thisTrain.SetInitialTrainRoute(tempRoute);
1198-
thisTrain.CalculatePositionOfCars();
1199-
for (int i = 0; i < thisTrain.Cars.Count; i++)
1200-
thisTrain.Cars[i].WorldPosition.XNAMatrix.M42 -= 1000;
1201-
thisTrain.ResetInitialTrainRoute(tempRoute);
1202-
1203-
// set train route and position so proper position in pool can be calculated
1204-
thisTrain.UpdateTrainPosition();
1205-
1206-
// add unit to pool
1207-
thisPool.AddUnit(thisTrain, false);
1208-
validPosition = thisTrain.PostInit(false); // post init train but do not activate
1209-
}
12101169
}
12111170

12121171
// clear track and align switches - check state
@@ -1408,6 +1367,12 @@ public class StartTrains : LinkedList<AITrain>
14081367

14091368
public void InsertTrain(AITrain thisTrain)
14101369
{
1370+
if (thisTrain.StartTime == null)
1371+
{
1372+
Trace.TraceInformation("Train : " + thisTrain.Name + " : missing start time, train not included");
1373+
return;
1374+
}
1375+
14111376
if (this.Count == 0)
14121377
{
14131378
this.AddFirst(thisTrain);
@@ -1554,11 +1519,11 @@ public TTTrain GetNotStartedTTTrainByNumber(int reqNumber, bool remove)
15541519
LinkedListNode<AITrain> AITrainNode = First;
15551520
while (AITrainNode != null)
15561521
{
1557-
if (AITrainNode.Value.Number == reqNumber)
1522+
TTTrain tttrain = AITrainNode.Value as TTTrain;
1523+
if (tttrain.Number == reqNumber || tttrain.OrgAINumber == reqNumber)
15581524
{
1559-
TTTrain reqTrain = AITrainNode.Value as TTTrain;
15601525
if (remove) Remove(AITrainNode);
1561-
return (reqTrain);
1526+
return (tttrain);
15621527
}
15631528
else
15641529
{

Source/Orts.Simulation/Simulation/AIs/AITrain.cs

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ public void AIUpdate(float elapsedClockSeconds, double clockTime, bool preUpdate
684684

685685
if (MovementState == AI_MOVEMENT_STATE.AI_STATIC)
686686
{
687-
physicsUpdate(0); //required to make train visible ; set elapsed time to zero to avoid actual movement
687+
CalculatePositionOfCars(0, 0); //required to make train visible ; set elapsed time to zero to avoid actual movement
688688
}
689689
else
690690
{
@@ -5100,6 +5100,32 @@ public void CreateTrainAction(float presentSpeedMpS, float reqSpeedMpS, float di
51005100
// correct trigger for approach distance but not backward beyond present position
51015101
triggerDistanceM = Math.Max(PresentPosition[0].DistanceTravelledM, triggerDistanceM - (3.0f * signalApproachDistanceM));
51025102

5103+
// for signal stop item : check if action allready in list, if so, remove (can be result of restore action)
5104+
LinkedListNode<DistanceTravelledItem> thisItemLink = requiredActions.First;
5105+
bool itemFound = false;
5106+
5107+
while (thisItemLink != null && !itemFound)
5108+
{
5109+
DistanceTravelledItem thisDTItem = thisItemLink.Value;
5110+
if (thisDTItem is AIActionItem)
5111+
{
5112+
AIActionItem thisActionItem = thisDTItem as AIActionItem;
5113+
if (thisActionItem.ActiveItem != null && thisActionItem.NextAction == thisAction)
5114+
{
5115+
if (thisActionItem.ActiveItem.ObjectDetails.thisRef == thisItem.ObjectDetails.thisRef)
5116+
{
5117+
// equal item, so remove it
5118+
requiredActions.Remove(thisDTItem);
5119+
itemFound = true;
5120+
}
5121+
}
5122+
}
5123+
if (!itemFound)
5124+
{
5125+
thisItemLink = thisItemLink.Next;
5126+
}
5127+
}
5128+
51035129
// create and insert action
51045130

51055131
AIActionItem newAction = new AIActionItem(thisItem, thisAction);
@@ -5298,7 +5324,7 @@ public override void PerformActions(List<DistanceTravelledItem> nowActions)
52985324
}
52995325
else if (thisAction is ClearMovingTableAction)
53005326
{
5301-
ClearMovingTable();
5327+
ClearMovingTable(thisAction);
53025328
}
53035329
else if (thisAction is AIActionItem && !(thisAction is AuxActionItem))
53045330
{
@@ -5345,7 +5371,7 @@ public void SetAIPendingSpeedLimit(ActivateSpeedLimit speedInfo)
53455371
else
53465372
AllowedMaxSpeedMpS = Math.Min(speedInfo.MaxSpeedMpSLimit, Math.Min(allowedMaxSpeedSignalMpS, allowedMaxTempSpeedLimitMpS));
53475373
}
5348-
if (speedInfo.MaxTempSpeedMpSLimit > 0 && !Simulator.TimetableMode)
5374+
if (speedInfo.MaxTempSpeedMpSLimit > 0)
53495375
{
53505376
allowedMaxTempSpeedLimitMpS = allowedAbsoluteMaxTempSpeedLimitMpS;
53515377
AllowedMaxSpeedMpS = Math.Min(speedInfo.MaxTempSpeedMpSLimit, Math.Min(allowedMaxSpeedSignalMpS, allowedMaxSpeedLimitMpS));
@@ -5453,22 +5479,41 @@ public void ProcessActionItem(AIActionItem thisItem)
54535479
if (thisItem.ActiveItem.signal_state == MstsSignalAspect.STOP &&
54545480
thisItem.ActiveItem.ObjectDetails.holdState == HoldState.StationStop)
54555481
{
5456-
actionValid = false;
5482+
// check if train is approaching or standing at station and has not yet departed
5483+
if (StationStops != null && StationStops.Count >= 1 && AtStation && StationStops[0].ExitSignal == thisItem.ActiveItem.ObjectDetails.thisRef)
5484+
{
5485+
actionValid = false;
54575486

54585487
#if DEBUG_REPORTS
54595488
File.AppendAllText(@"C:\temp\printproc.txt", "Train " +
54605489
Number.ToString() + " : signal " +
54615490
thisItem.ActiveItem.ObjectDetails.thisRef.ToString() + " at " +
54625491
thisItem.ActivateDistanceM.ToString() + " is held for station stop\n");
54635492
#endif
5464-
if (CheckTrain)
5493+
if (CheckTrain)
5494+
{
5495+
File.AppendAllText(@"C:\temp\checktrain.txt", "Train " +
5496+
Number.ToString() + " : signal " +
5497+
thisItem.ActiveItem.ObjectDetails.thisRef.ToString() + " at " +
5498+
thisItem.ActivateDistanceM.ToString() + " is held for station stop\n");
5499+
}
5500+
}
5501+
else
54655502
{
5466-
File.AppendAllText(@"C:\temp\checktrain.txt", "Train " +
5467-
Number.ToString() + " : signal " +
5468-
thisItem.ActiveItem.ObjectDetails.thisRef.ToString() + " at " +
5469-
thisItem.ActivateDistanceM.ToString() + " is held for station stop\n");
5503+
#if DEBUG_REPORTS
5504+
File.AppendAllText(@"C:\temp\printproc.txt", "Train " +
5505+
Number.ToString() + " : signal " +
5506+
thisItem.ActiveItem.ObjectDetails.thisRef.ToString() + " at " +
5507+
thisItem.ActivateDistanceM.ToString() + " is held for station stop but train is no longer stopped in station\n");
5508+
#endif
5509+
if (CheckTrain)
5510+
{
5511+
File.AppendAllText(@"C:\temp\checktrain.txt", "Train " +
5512+
Number.ToString() + " : signal " +
5513+
thisItem.ActiveItem.ObjectDetails.thisRef.ToString() + " at " +
5514+
thisItem.ActivateDistanceM.ToString() + " is held for station stop but train is no longer stopped in station\n");
5515+
}
54705516
}
5471-
54725517
}
54735518

54745519
// check if cleared

Source/Orts.Simulation/Simulation/Physics/Train.cs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,10 @@ public Train(Simulator simulator, BinaryReader inf)
904904
requiredActions.InsertAction(auxAction);
905905
Trace.TraceWarning("DistanceTravelledItem type 4 restored as AuxActionItem");
906906
break;
907+
case 5:
908+
ClearMovingTableAction cmtAction = new ClearMovingTableAction(inf);
909+
requiredActions.InsertAction(cmtAction);
910+
break;
907911
default:
908912
Trace.TraceWarning("Unknown type of DistanceTravelledItem (type {0}",
909913
actionType.ToString());
@@ -11038,7 +11042,7 @@ public void SetPendingSpeedLimit(ActivateSpeedLimit speedInfo)
1103811042
else
1103911043
AllowedMaxSpeedMpS = Math.Min(speedInfo.MaxSpeedMpSLimit, Math.Min(allowedMaxSpeedSignalMpS, allowedMaxTempSpeedLimitMpS));
1104011044
}
11041-
if (speedInfo.MaxTempSpeedMpSLimit > 0 && !Simulator.TimetableMode)
11045+
if (speedInfo.MaxTempSpeedMpSLimit > 0)
1104211046
{
1104311047
allowedMaxTempSpeedLimitMpS = allowedAbsoluteMaxTempSpeedLimitMpS;
1104411048
AllowedMaxSpeedMpS = Math.Min(speedInfo.MaxTempSpeedMpSLimit, Math.Min(allowedMaxSpeedSignalMpS, allowedMaxSpeedLimitMpS));
@@ -11214,19 +11218,17 @@ public void RemoveFromTrack()
1121411218
LastReservedSection[0] = -1;
1121511219
LastReservedSection[1] = -1;
1121611220

11217-
// clear outstanding clear sections
11221+
// clear outstanding clear sections and remove them from queue as they are no longer required
1121811222

11219-
foreach (DistanceTravelledItem thisAction in requiredActions)
11223+
List<DistanceTravelledItem> activeActions = requiredActions.GetActions(99999999f, typeof(ClearSectionItem));
11224+
foreach (DistanceTravelledItem thisAction in activeActions)
1122011225
{
11221-
if (thisAction is ClearSectionItem)
11222-
{
11223-
ClearSectionItem thisItem = thisAction as ClearSectionItem;
11224-
TrackCircuitSection thisSection = signalRef.TrackCircuitList[thisItem.TrackSectionIndex];
11225-
thisSection.ClearOccupied(this, true);
11226-
}
11226+
ClearSectionItem thisItem = thisAction as ClearSectionItem;
11227+
TrackCircuitSection thisSection = signalRef.TrackCircuitList[thisItem.TrackSectionIndex];
11228+
thisSection.ClearOccupied(this, true);
1122711229
}
1122811230
}
11229-
11231+
1123011232
//================================================================================================//
1123111233
//
1123211234
// Update track actions after coupling
@@ -15838,7 +15840,7 @@ public StationStop CalculateStationStop(int platformStartID, int arrivalTime, in
1583815840
{
1583915841
int otherSectionIndex = thisElement.Direction == 0 ?
1584015842
otherPlatform.TCSectionIndex[0] :
15841-
otherPlatform.TCSectionIndex[thisPlatform.TCSectionIndex.Count - 1];
15843+
otherPlatform.TCSectionIndex[otherPlatform.TCSectionIndex.Count - 1];
1584215844
if (otherSectionIndex == beginSectionIndex)
1584315845
{
1584415846
if (otherPlatform.TCOffset[0, thisElement.Direction] < actualBegin)
@@ -16236,7 +16238,7 @@ public virtual bool CheckPoolAccess(int sectionIndex)
1623616238
/// Clear moving table after moving table actions
1623716239
/// Dummy method to allow virtualization by child classes
1623816240
/// </summary>
16239-
public virtual void ClearMovingTable()
16241+
public virtual void ClearMovingTable(DistanceTravelledItem action)
1624016242
{
1624116243
}
1624216244

@@ -19170,7 +19172,7 @@ public float GetDistanceAlongRoute(int startSectionIndex, float startOffset,
1917019172
{
1917119173
float totalLength = startOffset;
1917219174

19173-
if (startSectionIndex == endSectionIndex)
19175+
if (startSectionIndex == endSectionIndex && startSectionIndex > -1)
1917419176
{
1917519177
TrackCircuitSection thisSection = signals.TrackCircuitList[this[startSectionIndex].TCSectionIndex];
1917619178
totalLength = startOffset - (thisSection.Length - endOffset);
@@ -20348,6 +20350,13 @@ public void Save(BinaryWriter outf)
2034820350
AuxActionItem thisAction = this as AuxActionItem;
2034920351
thisAction.SaveItem(outf);
2035020352
}
20353+
else if (this is ClearMovingTableAction)
20354+
{
20355+
outf.Write(5);
20356+
outf.Write(RequiredDistance);
20357+
ClearMovingTableAction thisAction = this as ClearMovingTableAction;
20358+
thisAction.SaveItem(outf);
20359+
}
2035120360
else
2035220361
{
2035320362
outf.Write(-1);

0 commit comments

Comments
 (0)