Skip to content

Commit b429cf5

Browse files
committed
Cab controls from active locomotive in control car
1 parent 902506c commit b429cf5

File tree

7 files changed

+193
-48
lines changed

7 files changed

+193
-48
lines changed

Source/Documentation/Manual/physics.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2419,7 +2419,7 @@ To allow the auxiliary tender to be filled at a water fuelling point, a water fr
24192419
Unpowered Control Car
24202420
---------------------
24212421

2422-
This module simulates the control cab of a DMU set of cars. The cab typically would be located in an unpowered
2422+
This module simulates the control cab of a MU set of cars. The cab typically would be located in an unpowered
24232423
trailer car which is attached to a powered car for the provision of its motive force to drive the train forward.
24242424

24252425
Apart from producing motive force the car (and cabin controls) should behave exactly the same as a locomotive.

Source/Orts.Simulation/Simulation/RollingStocks/MSTSControlTrailerCar.cs

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// COPYRIGHT 2009, 2010, 2011, 2012, 2013 by the Open Rails project.
1+
// COPYRIGHT 2009 by the Open Rails project.
22
//
33
// This file is part of Open Rails.
44
//
@@ -15,19 +15,6 @@
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-
/* DIESEL LOCOMOTIVE CLASSES
19-
*
20-
* The Locomotive is represented by two classes:
21-
* MSTSDieselLocomotiveSimulator - defines the behaviour, ie physics, motion, power generated etc
22-
* MSTSDieselLocomotiveViewer - defines the appearance in a 3D viewer. The viewer doesn't
23-
* get attached to the car until it comes into viewing range.
24-
*
25-
* Both these classes derive from corresponding classes for a basic locomotive
26-
* LocomotiveSimulator - provides for movement, basic controls etc
27-
* LocomotiveViewer - provides basic animation for running gear, wipers, etc
28-
*
29-
*/
30-
3118
using System.Diagnostics;
3219
using System.IO;
3320
using System.Text;
@@ -37,6 +24,7 @@
3724
using Orts.Simulation.RollingStocks.SubSystems.Controllers;
3825
using Orts.Simulation.RollingStocks.SubSystems.PowerSupplies;
3926
using Orts.Simulation.RollingStocks.SubSystems.PowerTransmissions;
27+
using ORTS.Common;
4028

4129
namespace Orts.Simulation.RollingStocks
4230
{
@@ -234,7 +222,12 @@ public override string GetStatus()
234222
status.AppendFormat("{0} = {1}\n", Simulator.Catalog.GetString("Gear"),
235223
ControlGearIndex < 0 ? Simulator.Catalog.GetParticularString("Gear", "N") : (ControlGearIndication).ToString());
236224
status.AppendLine();
237-
225+
status.AppendFormat("{0} = {1}\n",
226+
Simulator.Catalog.GetString("Battery switch"),
227+
LocomotivePowerSupply.BatterySwitch.On ? Simulator.Catalog.GetString("On") : Simulator.Catalog.GetString("Off"));
228+
status.AppendFormat("{0} = {1}\n",
229+
Simulator.Catalog.GetString("Master key"),
230+
LocomotivePowerSupply.MasterKey.On ? Simulator.Catalog.GetString("On") : Simulator.Catalog.GetString("Off"));
238231
return status.ToString();
239232
}
240233

@@ -318,14 +311,22 @@ public override float GetDataOf(CabViewControl cvc)
318311
float data;
319312
switch (cvc.ControlType.Type)
320313
{
314+
// Locomotive controls
321315
case CABViewControlTypes.AMMETER:
322316
case CABViewControlTypes.AMMETER_ABS:
323317
case CABViewControlTypes.DYNAMIC_BRAKE_FORCE:
324318
case CABViewControlTypes.LOAD_METER:
325-
case CABViewControlTypes.ORTS_DIESEL_TEMPERATURE:
326-
case CABViewControlTypes.ORTS_OIL_PRESSURE:
327319
case CABViewControlTypes.ORTS_SIGNED_TRACTION_BRAKING:
328320
case CABViewControlTypes.ORTS_SIGNED_TRACTION_TOTAL_BRAKING:
321+
case CABViewControlTypes.TRACTION_BRAKING:
322+
case CABViewControlTypes.WHEELSLIP:
323+
data = ControlActiveLocomotive?.GetDataOf(cvc) ?? 0;
324+
break;
325+
// Diesel locomotive controls
326+
case CABViewControlTypes.FUEL_GAUGE:
327+
case CABViewControlTypes.ORTS_DIESEL_TEMPERATURE:
328+
case CABViewControlTypes.ORTS_OIL_PRESSURE:
329+
case CABViewControlTypes.ORTS_PLAYER_DIESEL_ENGINE:
329330
case CABViewControlTypes.ORTS_TRACTION_CUT_OFF_RELAY_AUTHORIZED:
330331
case CABViewControlTypes.ORTS_TRACTION_CUT_OFF_RELAY_CLOSED:
331332
case CABViewControlTypes.ORTS_TRACTION_CUT_OFF_RELAY_DRIVER_CLOSING_AUTHORIZATION:
@@ -336,9 +337,32 @@ public override float GetDataOf(CabViewControl cvc)
336337
case CABViewControlTypes.ORTS_TRACTION_CUT_OFF_RELAY_STATE:
337338
case CABViewControlTypes.RPM:
338339
case CABViewControlTypes.RPM_2:
339-
case CABViewControlTypes.TRACTION_BRAKING:
340-
case CABViewControlTypes.WHEELSLIP:
341-
data = ControlActiveLocomotive?.GetDataOf(cvc) ?? 0;
340+
data = (ControlActiveLocomotive as MSTSDieselLocomotive)?.GetDataOf(cvc) ?? 0;
341+
break;
342+
// Electric locomotive controls
343+
case CABViewControlTypes.LINE_VOLTAGE:
344+
case CABViewControlTypes.ORTS_PANTOGRAPH_VOLTAGE_AC:
345+
case CABViewControlTypes.ORTS_PANTOGRAPH_VOLTAGE_DC:
346+
case CABViewControlTypes.PANTO_DISPLAY:
347+
case CABViewControlTypes.PANTOGRAPH:
348+
case CABViewControlTypes.PANTOGRAPH2:
349+
case CABViewControlTypes.ORTS_PANTOGRAPH3:
350+
case CABViewControlTypes.ORTS_PANTOGRAPH4:
351+
case CABViewControlTypes.PANTOGRAPHS_4:
352+
case CABViewControlTypes.PANTOGRAPHS_4C:
353+
case CABViewControlTypes.PANTOGRAPHS_5:
354+
case CABViewControlTypes.ORTS_VOLTAGE_SELECTOR:
355+
case CABViewControlTypes.ORTS_PANTOGRAPH_SELECTOR:
356+
case CABViewControlTypes.ORTS_POWER_LIMITATION_SELECTOR:
357+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_DRIVER_CLOSING_ORDER:
358+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_DRIVER_OPENING_ORDER:
359+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_DRIVER_CLOSING_AUTHORIZATION:
360+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_STATE:
361+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_CLOSED:
362+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_OPEN:
363+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_AUTHORIZED:
364+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_OPEN_AND_AUTHORIZED:
365+
data = (ControlActiveLocomotive as MSTSElectricLocomotive)?.GetDataOf(cvc) ?? 0;
342366
break;
343367
default:
344368
data = base.GetDataOf(cvc);

Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2820,10 +2820,8 @@ protected virtual void UpdateCompressor(float elapsedClockSeconds)
28202820
{
28212821
FindControlActiveLocomotive();
28222822

2823-
if (ControlActiveLocomotive != null)
2823+
if (ControlActiveLocomotive is MSTSDieselLocomotive activeloco)
28242824
{
2825-
var activeloco = ControlActiveLocomotive as MSTSDieselLocomotive;
2826-
28272825
// Set charging rate depending upon compressor rpm
28282826
reservoirChargingRate = (activeloco.DieselEngines[0].RealRPM / activeloco.DieselEngines[0].MaxRPM) * MainResChargingRatePSIpS;
28292827
}

Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3733,36 +3733,49 @@ public void FindControlActiveLocomotive()
37333733
ControlActiveLocomotive = null;
37343734
return;
37353735
}
3736-
var controlIndex = 0;
3737-
var activeIndex = 0;
3738-
bool controlCar = false;
3739-
bool activeLocomotive = false;
3740-
3741-
// Check to see if this car is an active locomotive, if so then set linkage to relevant control car.
3742-
// Note this only checks the "closest" locomotive to the control car. Hence it could be "fooled" if there is another locomotive besides the two DMU locomotives.
3743-
3744-
for (var i = 0; i < Train.Cars.Count; i++)
3736+
MSTSLocomotive unmatchedLocomotive = null;
3737+
MSTSLocomotive unmatchedControlCar = null;
3738+
foreach (var car in Train.Cars)
37453739
{
3746-
3747-
if (activeIndex == 0 && Train.Cars[i].EngineType == TrainCar.EngineTypes.Diesel)
3740+
if (car.EngineType == TrainCar.EngineTypes.Electric || car.EngineType == TrainCar.EngineTypes.Diesel)
37483741
{
3749-
activeIndex = i;
3750-
activeLocomotive = true;
3751-
}
3752-
3753-
if (controlIndex == 0 && Train.Cars[i].EngineType == TrainCar.EngineTypes.Control)
3754-
{
3755-
controlIndex = i;
3756-
controlCar = true;
3742+
if (unmatchedControlCar != null)
3743+
{
3744+
if (unmatchedControlCar == this)
3745+
{
3746+
unmatchedLocomotive = car as MSTSLocomotive;
3747+
break;
3748+
}
3749+
else
3750+
{
3751+
unmatchedControlCar = null;
3752+
}
3753+
}
3754+
else
3755+
{
3756+
unmatchedLocomotive = car as MSTSLocomotive;
3757+
}
37573758
}
3758-
3759-
// As soon as the control and active locomotive have been identified, then stop loop.
3760-
if (activeLocomotive && controlCar)
3759+
if (car.EngineType == TrainCar.EngineTypes.Control)
37613760
{
3762-
ControlActiveLocomotive = Train.Cars[activeIndex] as MSTSDieselLocomotive;
3763-
return;
3761+
if (unmatchedLocomotive != null)
3762+
{
3763+
if (car == this)
3764+
{
3765+
break;
3766+
}
3767+
else
3768+
{
3769+
unmatchedLocomotive = null;
3770+
}
3771+
}
3772+
else
3773+
{
3774+
unmatchedControlCar = car as MSTSLocomotive;
3775+
}
37643776
}
37653777
}
3778+
ControlActiveLocomotive = unmatchedLocomotive;
37663779
}
37673780

37683781
public void FindTendersSteamLocomotive()
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// COPYRIGHT 2024 by the Open Rails project.
2+
//
3+
// This file is part of Open Rails.
4+
//
5+
// Open Rails is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// Open Rails is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with Open Rails. If not, see <http://www.gnu.org/licenses/>.
17+
18+
using System;
19+
using Orts.Common;
20+
using Orts.Simulation.Physics;
21+
using Orts.Simulation.RollingStocks;
22+
using ORTS.Common;
23+
using ORTS.Common.Input;
24+
25+
namespace Orts.Viewer3D.RollingStock
26+
{
27+
public class MSTSControlTrailerCarViewer : MSTSLocomotiveViewer
28+
{
29+
30+
MSTSControlTrailerCar ControlCar;
31+
MSTSLocomotive ControlActiveLocomotive => ControlCar.ControlActiveLocomotive;
32+
33+
public MSTSControlTrailerCarViewer(Viewer viewer, MSTSControlTrailerCar car)
34+
: base(viewer, car)
35+
{
36+
ControlCar = car;
37+
}
38+
39+
public override void InitializeUserInputCommands()
40+
{
41+
UserInputCommands.Add(UserCommand.ControlBatterySwitchClose, new Action[] {
42+
() => new BatterySwitchCloseButtonCommand(Viewer.Log, false),
43+
() => {
44+
new BatterySwitchCloseButtonCommand(Viewer.Log, true);
45+
new BatterySwitchCommand(Viewer.Log, !ControlCar.LocomotivePowerSupply.BatterySwitch.CommandSwitch);
46+
}
47+
});
48+
UserInputCommands.Add(UserCommand.ControlBatterySwitchOpen, new Action[] {
49+
() => new BatterySwitchOpenButtonCommand(Viewer.Log, false),
50+
() => new BatterySwitchOpenButtonCommand(Viewer.Log, true)
51+
});
52+
UserInputCommands.Add(UserCommand.ControlMasterKey, new Action[] { Noop, () => new ToggleMasterKeyCommand(Viewer.Log, !ControlCar.LocomotivePowerSupply.MasterKey.CommandSwitch) });
53+
UserInputCommands.Add(UserCommand.ControlServiceRetention, new Action[] { () => new ServiceRetentionButtonCommand(Viewer.Log, false), () => new ServiceRetentionButtonCommand(Viewer.Log, true) });
54+
UserInputCommands.Add(UserCommand.ControlServiceRetentionCancellation, new Action[] { () => new ServiceRetentionCancellationButtonCommand(Viewer.Log, false), () => new ServiceRetentionCancellationButtonCommand(Viewer.Log, true) });
55+
UserInputCommands.Add(UserCommand.ControlElectricTrainSupply, new Action[] { Noop, () => new ElectricTrainSupplyCommand(Viewer.Log, !ControlActiveLocomotive.LocomotivePowerSupply.ElectricTrainSupplySwitch.CommandSwitch) });
56+
UserInputCommands.Add(UserCommand.ControlCircuitBreakerClosingOrder, new Action[] {
57+
() => new CircuitBreakerClosingOrderButtonCommand(Viewer.Log, false),
58+
() => {
59+
new CircuitBreakerClosingOrderCommand(Viewer.Log, !((ControlActiveLocomotive as MSTSElectricLocomotive)?.ElectricPowerSupply.CircuitBreaker.DriverClosingOrder ?? false));
60+
new CircuitBreakerClosingOrderButtonCommand(Viewer.Log, true);
61+
}
62+
});
63+
UserInputCommands.Add(UserCommand.ControlCircuitBreakerOpeningOrder, new Action[] { () => new CircuitBreakerOpeningOrderButtonCommand(Viewer.Log, false), () => new CircuitBreakerOpeningOrderButtonCommand(Viewer.Log, true)});
64+
UserInputCommands.Add(UserCommand.ControlCircuitBreakerClosingAuthorization, new Action[] { Noop, () => new CircuitBreakerClosingAuthorizationCommand(Viewer.Log, !((ControlActiveLocomotive as MSTSElectricLocomotive)?.ElectricPowerSupply.CircuitBreaker.DriverClosingAuthorization ?? false)) });
65+
UserInputCommands.Add(UserCommand.ControlTractionCutOffRelayClosingOrder, new Action[] {
66+
() => new TractionCutOffRelayClosingOrderButtonCommand(Viewer.Log, false),
67+
() => {
68+
new TractionCutOffRelayClosingOrderCommand(Viewer.Log, !((ControlActiveLocomotive as MSTSDieselLocomotive)?.DieselPowerSupply.TractionCutOffRelay.DriverClosingOrder ?? false));
69+
new TractionCutOffRelayClosingOrderButtonCommand(Viewer.Log, true);
70+
}
71+
});
72+
UserInputCommands.Add(UserCommand.ControlTractionCutOffRelayOpeningOrder, new Action[] { () => new TractionCutOffRelayOpeningOrderButtonCommand(Viewer.Log, false), () => new TractionCutOffRelayOpeningOrderButtonCommand(Viewer.Log, true) });
73+
UserInputCommands.Add(UserCommand.ControlTractionCutOffRelayClosingAuthorization, new Action[] { Noop, () => new TractionCutOffRelayClosingAuthorizationCommand(Viewer.Log, !((ControlActiveLocomotive as MSTSDieselLocomotive)?.DieselPowerSupply.TractionCutOffRelay.DriverClosingAuthorization ?? false)) });
74+
UserInputCommands.Add(UserCommand.ControlDieselPlayer, new Action[] { Noop, () => new TogglePlayerEngineCommand(Viewer.Log) });
75+
base.InitializeUserInputCommands();
76+
}
77+
}
78+
}

Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2366,6 +2366,37 @@ public string GetControlName()
23662366

23672367
public void HandleUserInput()
23682368
{
2369+
var Locomotive = this.Locomotive;
2370+
if (Locomotive is MSTSControlTrailerCar controlCar)
2371+
{
2372+
switch (Control.ControlType.Type)
2373+
{
2374+
// Diesel locomotive controls
2375+
case CABViewControlTypes.ORTS_PLAYER_DIESEL_ENGINE:
2376+
case CABViewControlTypes.ORTS_TRACTION_CUT_OFF_RELAY_DRIVER_CLOSING_AUTHORIZATION:
2377+
case CABViewControlTypes.ORTS_TRACTION_CUT_OFF_RELAY_DRIVER_CLOSING_ORDER:
2378+
case CABViewControlTypes.ORTS_TRACTION_CUT_OFF_RELAY_DRIVER_OPENING_ORDER:
2379+
Locomotive = controlCar.ControlActiveLocomotive as MSTSDieselLocomotive;
2380+
break;
2381+
// Electric locomotive controls
2382+
case CABViewControlTypes.PANTOGRAPH:
2383+
case CABViewControlTypes.PANTOGRAPH2:
2384+
case CABViewControlTypes.ORTS_PANTOGRAPH3:
2385+
case CABViewControlTypes.ORTS_PANTOGRAPH4:
2386+
case CABViewControlTypes.PANTOGRAPHS_4:
2387+
case CABViewControlTypes.PANTOGRAPHS_4C:
2388+
case CABViewControlTypes.PANTOGRAPHS_5:
2389+
case CABViewControlTypes.ORTS_VOLTAGE_SELECTOR:
2390+
case CABViewControlTypes.ORTS_PANTOGRAPH_SELECTOR:
2391+
case CABViewControlTypes.ORTS_POWER_LIMITATION_SELECTOR:
2392+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_DRIVER_CLOSING_ORDER:
2393+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_DRIVER_OPENING_ORDER:
2394+
case CABViewControlTypes.ORTS_CIRCUIT_BREAKER_DRIVER_CLOSING_AUTHORIZATION:
2395+
Locomotive = controlCar.ControlActiveLocomotive as MSTSElectricLocomotive;
2396+
break;
2397+
}
2398+
if (Locomotive == null) return;
2399+
}
23692400
switch (Control.ControlType.Type)
23702401
{
23712402
case CABViewControlTypes.REGULATOR:

Source/RunActivity/Viewer3D/Trains.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ TrainCarViewer LoadCar(TrainCar car)
152152
car is MSTSDieselLocomotive ? new MSTSDieselLocomotiveViewer(Viewer, car as MSTSDieselLocomotive) :
153153
car is MSTSElectricLocomotive ? new MSTSElectricLocomotiveViewer(Viewer, car as MSTSElectricLocomotive) :
154154
car is MSTSSteamLocomotive ? new MSTSSteamLocomotiveViewer(Viewer, car as MSTSSteamLocomotive) :
155+
car is MSTSControlTrailerCar ? new MSTSControlTrailerCarViewer(Viewer, car as MSTSControlTrailerCar) :
155156
car is MSTSLocomotive ? new MSTSLocomotiveViewer(Viewer, car as MSTSLocomotive) :
156157
car is MSTSWagon ? new MSTSWagonViewer(Viewer, car as MSTSWagon) :
157158
null;

0 commit comments

Comments
 (0)