Skip to content

Commit f34a04c

Browse files
committed
Merge branch 'master' into refactor-user-settings-loc/export-settings
Included manual resolution of conflict in Source/ORTS.sln.
2 parents 57abd7b + 5522fc5 commit f34a04c

File tree

142 files changed

+21968
-4182
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+21968
-4182
lines changed

Build.cmd

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ FOR /F "usebackq tokens=1* delims==" %%A IN (`CALL GetVersion.cmd %Mode%`) DO SE
8383
REM Restore NuGet packages.
8484
nuget restore Source\ORTS.sln || GOTO :error
8585

86-
REM Recreate Program directory for output.
86+
REM Recreate Program directory for output and delete previous build files.
8787
CALL :recreate "Program" || GOTO :error
88+
CALL :delete "OpenRails-%Mode%*" || GOTO :error
8889

8990
REM Build main program.
9091
REM Disable warning CS1591 "Missing XML comment for publicly visible type or member".
@@ -126,11 +127,14 @@ IF NOT "%Mode%" == "Unstable" (
126127
NET stop ClickToRunSvc
127128
NET start ClickToRunSvc
128129

129-
REM Recreate Documentation folder for output.
130-
CALL :recreate "Program\Documentation" || GOTO :error
130+
REM Create the documentation folders for output.
131+
CALL :create "Program\Documentation" || GOTO :error
132+
CALL :create "Program\Documentation\Online" || GOTO :error
133+
CALL :create "Program\Documentation\es" || GOTO :error
131134

132135
REM Compile the documentation.
133136
FOR %%E IN (doc docx docm xls xlsx xlsm odt) DO FOR %%F IN ("Source\Documentation\*.%%E") DO ECHO %%~F && OfficeToPDF.exe /bookmarks /print "%%~F" "Program\Documentation\%%~nF.pdf" || GOTO :error
137+
FOR %%E IN (doc docx docm xls xlsx xlsm odt) DO FOR %%F IN ("Source\Documentation\Online\*.%%E") DO ECHO %%~F && OfficeToPDF.exe /bookmarks /print "%%~F" "Program\Documentation\Online\%%~nF.pdf" || GOTO :error
134138
>"Source\Documentation\Manual\version.py" ECHO version = '%OpenRails_Version%' || GOTO :error
135139
>>"Source\Documentation\Manual\version.py" ECHO release = '%OpenRails_Revision%' || GOTO :error
136140
PUSHD "Source\Documentation\Manual" && CALL make.bat clean & POPD || GOTO :error
@@ -139,13 +143,13 @@ IF NOT "%Mode%" == "Unstable" (
139143
REM Copy the documentation.
140144
FOR %%F IN ("Source\Documentation\*.pdf") DO CALL :copy "%%~F" "Program\Documentation\%%~nF.pdf" || GOTO :error
141145
CALL :copy "Source\Documentation\Manual\_build\latex\Manual.pdf" "Program\Documentation\Manual.pdf" || GOTO :error
142-
CALL :create "Program\Documentation\es"
143146
CALL :copy "Source\Documentation\Manual\es\Manual.pdf" "Program\Documentation\es\Manual.pdf" || GOTO :error
144147
ROBOCOPY /MIR /NJH /NJS "Source\Documentation\SampleFiles" "Program\Documentation\SampleFiles"
145148
IF %ERRORLEVEL% GEQ 8 GOTO :error
146149

147150
REM Copy the documentation separately.
148151
FOR %%F IN ("Program\Documentation\*.pdf") DO CALL :copy "%%~F" "OpenRails-%Mode%-%%~nxF" || GOTO :error
152+
FOR %%F IN ("Program\Documentation\Online\*.pdf") DO CALL :copy "%%~F" "OpenRails-%Mode%-%%~nxF" || GOTO :error
149153
)
150154

151155
IF "%Mode%" == "Stable" (
@@ -161,8 +165,7 @@ IF "%Mode%" == "Stable" (
161165
)
162166

163167
REM Create binary and source zips.
164-
CALL :delete "OpenRails-%Mode%*.zip" || GOTO :error
165-
PUSHD "Program" && 7za.exe a -r -tzip -x^^!*.xml "..\OpenRails-%Mode%.zip" . && POPD || GOTO :error
168+
PUSHD "Program" && 7za.exe a -r -tzip -x^^!*.xml -x^^!Online "..\OpenRails-%Mode%.zip" . && POPD || GOTO :error
166169
7za.exe a -r -tzip -x^^!.* -x^^!obj -x^^!lib -x^^!_build -x^^!*.bak "OpenRails-%Mode%-Source.zip" "Source" || GOTO :error
167170

168171
ENDLOCAL

Source/Contrib/ContentManager/ContentInfo.cs

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,24 @@ public static string GetText(Content content)
188188
details.AppendFormat("Name:\t{1}{0}", Environment.NewLine, data.Name);
189189
details.AppendFormat("NumEngines:\t{1}{0}", Environment.NewLine, data.NumEngines);
190190
details.AppendFormat("NumCars:\t{1}{0}", Environment.NewLine, data.NumCars);
191-
details.AppendFormat("MaxSpeed:\t{1}{0}", Environment.NewLine, FormatStrings.FormatSpeedLimit(data.MaxSpeedMps, IsMetric));
192-
details.AppendFormat("Weight:\t{1}{0}", Environment.NewLine, FormatStrings.FormatLargeMass(data.MassKG, IsMetric, IsUK));
191+
details.AppendFormat("Axles:\t{1}{0}", Environment.NewLine, data.NumAxles);
192+
details.AppendFormat("Weight:\t{1} (trailing: {2}){0}", Environment.NewLine, FormatStrings.FormatLargeMass(data.MassKG, IsMetric, IsUK),
193+
FormatStrings.FormatLargeMass(data.TrailingMassKG, IsMetric, IsUK));
193194
details.AppendFormat("Length:\t{1}{0}", Environment.NewLine, FormatStrings.FormatShortDistanceDisplay(data.LengthM, IsMetric));
194-
details.AppendFormat("Power:\t{1}{0}", Environment.NewLine, FormatStrings.FormatPower(data.MaxPowerW, IsMetric, IsImperialBHP, IsImperialBTUpS));
195+
details.AppendFormat("MaxPower:\t{1}{0}", Environment.NewLine, FormatStrings.FormatPower(data.MaxPowerW, IsMetric, IsImperialBHP, IsImperialBTUpS));
195196
details.AppendFormat("MaxTE:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MaxTractiveForceN, IsMetric));
197+
details.AppendFormat("MaxContTE:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MaxContinuousTractiveForceN, IsMetric));
198+
details.AppendFormat("MaxDynBrk:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MaxDynamicBrakeForceN, IsMetric));
199+
if (!IsMetric && !IsUK)
200+
{
201+
details.AppendFormat("HPT:\t{1}{0}", Environment.NewLine, FormatHPT(data.MaxPowerW, data.TrailingMassKG));
202+
details.AppendFormat("TpOB:\t{1}{0}", Environment.NewLine, FormatTPOB(data.TrailingMassKG, data.NumOperativeBrakes));
203+
details.AppendFormat("TpEPA:\t{1}{0}", Environment.NewLine, FormatTonsPerEPA(data.TrailingMassKG, data.MaxContinuousTractiveForceN));
204+
details.AppendFormat("TpEDBA:\t{1}{0}", Environment.NewLine, FormatTonsPerEDBA(data.TrailingMassKG, data.MaxDynamicBrakeForceN));
205+
}
206+
details.AppendFormat("MaxSpeed:\t{1}{0}", Environment.NewLine, FormatStrings.FormatSpeedLimit(data.MaxSpeedMps, IsMetric));
196207
details.AppendFormat("MinCouplerStrength:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MinCouplerStrengthN, IsMetric));
197-
if (!IsMetric && !IsUK) { details.AppendFormat("HPT:\t{1}{0}", Environment.NewLine, FormatHPT(data.MaxPowerW, data.MassKG)); }
198-
if (!IsMetric && !IsUK) { details.AppendFormat("TPOB:\t{1}{0}", Environment.NewLine, FormatTPOB(data.MassKG, data.NumOperativeBrakes)); }
208+
details.AppendFormat("MinDerailForce:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MinDerailForceN, IsMetric));
199209
details.AppendLine();
200210
details.AppendFormat("Car ID:\tDirection:\tWeight:\tName:\t{0}", Environment.NewLine);
201211
foreach (var car in data.Cars)
@@ -208,16 +218,24 @@ public static string GetText(Content content)
208218
details.AppendFormat("Type:\t{1}{0}", Environment.NewLine, data.Type);
209219
details.AppendFormat("SubType:\t{1}{0}", Environment.NewLine, data.SubType);
210220
details.AppendFormat("Name:\t{1}{0}", Environment.NewLine, data.Name);
211-
details.AppendFormat("Weight:\t{1} ({2}){0}", Environment.NewLine, FormatStrings.FormatMass(data.MassKG, IsMetric), FormatStrings.FormatLargeMass(data.MassKG, IsMetric, IsUK));
221+
details.AppendFormat("Weight:\t{1} ({2}){0}", Environment.NewLine, FormatStrings.FormatMass(data.MassKG, IsMetric), FormatStrings.FormatLargeMass(data.MassKG, IsMetric, IsUK));
212222
details.AppendFormat("Length:\t{1}{0}", Environment.NewLine, FormatStrings.FormatShortDistanceDisplay(data.LengthM, IsMetric));
213-
if (data.Type == CarType.Engine)
223+
if (data.Type != CarType.Engine)
214224
{
215-
details.AppendFormat("MaxPowerW:\t{1}{0}", Environment.NewLine, FormatStrings.FormatPower(data.MaxPowerW, IsMetric, IsImperialBHP, IsImperialBTUpS));
216-
details.AppendFormat("MaxForce:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MaxForceN, IsMetric));
217-
details.AppendFormat("MaxSpeed:\t{1}{0}", Environment.NewLine, FormatStrings.FormatSpeedLimit(data.MaxSpeedMps, IsMetric));
225+
details.AppendFormat("Axles:\t{1}{0}", Environment.NewLine, data.NumAllAxles);
218226
}
219-
details.AppendFormat("MaxBrakeF:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MaxBarkeForceN, IsMetric));
227+
else
228+
{
229+
details.AppendFormat("Axles:\t{1}+{2}{0}", Environment.NewLine, data.NumDriveAxles, data.NumAllAxles - data.NumDriveAxles);
230+
details.AppendFormat("MaxPower:\t{1}{0}", Environment.NewLine, FormatStrings.FormatPower(data.MaxPowerW, IsMetric, IsImperialBHP, IsImperialBTUpS));
231+
details.AppendFormat("MaxTE:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MaxForceN, IsMetric));
232+
details.AppendFormat("MaxContTE:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MaxContinuousForceN, IsMetric));
233+
details.AppendFormat("MaxDynBrk:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MaxDynamicBrakeForceN, IsMetric));
234+
}
235+
details.AppendFormat("MaxBrakeF:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MaxBrakeForceN, IsMetric));
236+
if (data.MaxSpeedMps > 0f) { details.AppendFormat("MaxSpeed:\t{1}{0}", Environment.NewLine, FormatStrings.FormatSpeedLimit(data.MaxSpeedMps, IsMetric)); }
220237
details.AppendFormat("MinCouplerStrength:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MinCouplerStrengthN, IsMetric));
238+
details.AppendFormat("MinDerailForce:\t{1}{0}", Environment.NewLine, FormatStrings.FormatForce(data.MinDerailForceN, IsMetric));
221239
details.AppendLine();
222240
details.AppendFormat("Description:\t{0}{0}{1}{0}{0}", Environment.NewLine, data.Description);
223241
}
@@ -264,9 +282,6 @@ static string FormatMassBar(float massKg)
264282
/// <summary>
265283
/// Calculate and format horsepower per ton for consist, rounded to one decimal.
266284
/// </summary>
267-
/// <param name="consistPowerW"></param>
268-
/// <param name="consistMassKG"></param>
269-
/// <returns>horsepower-per-ton formated to one decimal.</returns>
270285
//TODO: implement UK and metric version
271286
static string FormatHPT(float consistPowerW, float consistMassKG)
272287
{
@@ -277,14 +292,33 @@ static string FormatHPT(float consistPowerW, float consistMassKG)
277292
/// <summary>
278293
/// Calculate and format tons per operative brake for consist, rounded to an integer.
279294
/// </summary>
280-
/// <param name="consistMassKG"></param>
281-
/// <param name="consistNumOpBrakes"></param>
282-
/// <returns>tons-per-operative-brake formated to an integer.</returns>
283295
//TODO: implement UK and metric version
284296
static string FormatTPOB(float consistMassKG, float consistNumOpBrakes)
285297
{
286298
var tpob = consistNumOpBrakes > 0 ? Kg.ToTUS(consistMassKG) / consistNumOpBrakes : 0;
287299
return string.Format("{0:0}", tpob);
288300
}
301+
302+
/// <summary>
303+
/// Calculate and format tons per equivalent powered axle, rounded to an integer.
304+
/// Based on UP convention, of 10k lbf counting as one axle.
305+
/// Strictly, EPA should be defined in the eng file. May be done in future.
306+
/// </summary>
307+
static string FormatTonsPerEPA(float consistMassKG, float consistMaxTractiveEffortN)
308+
{
309+
var tpepa = consistMaxTractiveEffortN > 0 ? Kg.ToTUS(consistMassKG) / (N.ToLbf(consistMaxTractiveEffortN) / 10000f) : 0;
310+
return string.Format("{0:0}", tpepa);
311+
}
312+
313+
/// <summary>
314+
/// Calculate and format tons per equivalent dynamic brake axle, rounded to an integer.
315+
/// Based on UP convention, of 10k lbf counting as one axle.
316+
/// Strictly, EDBA should be defined in the eng file. May be done in future.
317+
/// </summary>
318+
static string FormatTonsPerEDBA(float consistMassKG, float consistMaxDynamicBrakeForceN)
319+
{
320+
var tpedba = consistMaxDynamicBrakeForceN > 0 ? Kg.ToTUS(consistMassKG) / (N.ToLbf(consistMaxDynamicBrakeForceN) / 10000f) : 0;
321+
return string.Format("{0:0}", tpedba);
322+
}
289323
}
290324
}

Source/Contrib/ContentManager/ContentMSTS.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ public override IEnumerable<Content> Get(ContentType type)
127127
foreach (var item in Enumerable.Concat(Directory.GetFiles(pathOR, "*.timetable_or"), Directory.GetFiles(pathOR, "*.timetable-or")))
128128
yield return new ContentORTimetableActivity(this, Path.Combine(pathOR, item));
129129
}
130+
else if (type == ContentType.Path)
131+
{
132+
var path = Path.Combine(PathName, "Paths");
133+
if (Directory.Exists(path))
134+
foreach (var item in Directory.GetFiles(path, "*.pat"))
135+
yield return new ContentMSTSPath(this, Path.Combine(path, item));
136+
}
130137
}
131138

132139
public override Content Get(string name, ContentType type)

Source/Contrib/ContentManager/Models/Car.cs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@
1515
// You should have received a copy of the GNU General Public License
1616
// along with Open Rails. If not, see <http://www.gnu.org/licenses/>.
1717

18+
// MSTS Wheels and ORTS Axles
19+
// * ORTS uses unpowered and drive axles. Eg. 2 and 4 for an ES44C4
20+
// * MSTS uses a mix of wheels and axle. The Wagon section has the total,
21+
// the Engine section the driven only.
22+
// Values greater than 6 are wheels, less than 6 are axles. Some are
23+
// intentionally wrong to work around MSTS issues.
24+
1825
using Orts.Formats.Msts;
1926
using System;
20-
using System.Collections.Generic;
2127
using System.Diagnostics;
22-
using System.Linq;
23-
using System.Text;
2428

2529
namespace ORTS.ContentManager.Models
2630
{
@@ -38,24 +42,32 @@ public class Car
3842
public readonly string Description;
3943
public readonly float MassKG;
4044
public readonly float LengthM;
41-
public readonly float MaxBarkeForceN;
45+
public readonly int NumDriveAxles;
46+
public readonly int NumIdleAxles;
47+
public readonly int NumAllAxles;
48+
public readonly float MaxBrakeForceN;
4249
public readonly float MaxPowerW;
4350
public readonly float MaxForceN;
51+
public readonly float MaxContinuousForceN;
52+
public readonly float MaxDynamicBrakeForceN;
4453
public readonly float MaxSpeedMps;
4554
public readonly float MinCouplerStrengthN;
55+
public readonly float MinDerailForceN;
4656

4757
public Car(Content content)
4858
{
4959
Debug.Assert(content.Type == ContentType.Car);
5060

61+
const float GravitationalAccelerationMpS2 = 9.80665f;
62+
5163
// .eng files also have a wagon block
5264
var wagFile = new WagonFile(content.PathName);
5365
Type = CarType.Wagon;
5466
SubType = wagFile.WagonType;
5567
Name = wagFile.Name;
5668
MassKG = wagFile.MassKG;
5769
LengthM = wagFile.WagonSize.LengthM;
58-
MaxBarkeForceN = wagFile.MaxBrakeForceN;
70+
MaxBrakeForceN = wagFile.MaxBrakeForceN;
5971
MinCouplerStrengthN = wagFile.MinCouplerStrengthN;
6072

6173
if (System.IO.Path.GetExtension(content.PathName).Equals(".eng", StringComparison.OrdinalIgnoreCase))
@@ -66,9 +78,38 @@ public Car(Content content)
6678
Name = engFile.Name;
6779
MaxPowerW = engFile.MaxPowerW;
6880
MaxForceN = engFile.MaxForceN;
81+
MaxContinuousForceN = engFile.MaxContinuousForceN;
82+
MaxDynamicBrakeForceN = engFile.MaxDynamicBrakeForceN;
6983
MaxSpeedMps = engFile.MaxSpeedMps;
7084
Description = engFile.Description;
85+
86+
// see MSTSLocomotive.Initialize()
87+
NumDriveAxles = engFile.NumDriveAxles;
88+
if (NumDriveAxles == 0)
89+
{
90+
if (engFile.NumEngWheels != 0 && engFile.NumEngWheels < 7) { NumDriveAxles = (int)engFile.NumEngWheels; }
91+
else { NumDriveAxles = 4; }
92+
}
7193
}
94+
95+
// see MSTSWagon.LoadFromWagFile()
96+
NumIdleAxles = wagFile.NumWagAxles;
97+
if ((NumIdleAxles == 0) && Type != CarType.Engine)
98+
{
99+
if (wagFile.NumWagWheels != 0 && wagFile.NumWagWheels < 6) { NumIdleAxles = (int)wagFile.NumWagWheels; }
100+
else { NumIdleAxles = 4; }
101+
}
102+
103+
// correction for steam engines; see TrainCar.Update()
104+
// this is not always correct as TrainCar uses the WheelAxles array for the count; that is too complex to do here
105+
if (SubType.Equals("Steam") && NumDriveAxles >= (NumDriveAxles + NumIdleAxles)) { NumDriveAxles /= 2; }
106+
107+
// see TrainCar.UpdateTrainDerailmentRisk(), ~ line 1609
108+
NumAllAxles = NumDriveAxles + NumIdleAxles;
109+
110+
// see TrainCar.UpdateTrainDerailmentRisk()
111+
var numWheels = NumAllAxles * 2;
112+
if (numWheels > 0) { MinDerailForceN = MassKG / numWheels * GravitationalAccelerationMpS2; }
72113
}
73114
}
74115
}

0 commit comments

Comments
 (0)