Skip to content

Commit e66b25c

Browse files
committed
Rebasing autopilot for timetable
1 parent af8fb30 commit e66b25c

File tree

23 files changed

+444
-81
lines changed

23 files changed

+444
-81
lines changed

Source/Documentation/Manual/driving.rst

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,8 +1262,7 @@ or unloading operation is ongoing.
12621262
Autopilot Mode
12631263
==============
12641264

1265-
When in activity mode or in Explore in activity mode, through this feature
1266-
it is possible to stay
1265+
Through this feature it is possible to stay
12671266
in the cab of the player train, but to let Open Rails move the train,
12681267
respecting path, signals, speeds and station stops.
12691268

@@ -1276,8 +1275,8 @@ but it can also be used to run an activity (or part of it, as it is
12761275
possible to turn autopilot mode on or off at runtime) as a trainspotter or
12771276
a visitor within the cab.
12781277

1279-
Autopilot mode is active only in activity mode (i.e. not in explorer or
1280-
timetable modes).
1278+
Autopilot mode is available in activity, timetable and explore in activity
1279+
mode (i.e. not in explorer mode).
12811280

12821281
When starting the game with any activity, you are in player driving mode.
12831282
If you press Alt+A, you enter the autopilot mode: you are in the loco's
@@ -1300,7 +1299,7 @@ auto mode.
13001299
Station stops, waiting points and reverse points are synchronized as far as
13011300
possible in the two modes.
13021301

1303-
Cars can also be uncoupled in autopilot mode (but check that the train will
1302+
In activity mode cars can also be uncoupled in autopilot mode (but check that the train will
13041303
stop in enough time, otherwise it is better to change to player driven
13051304
mode). A static consist can also be coupled in autopilot mode.
13061305

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ public AI(Simulator simulator, List<TTTrain> allTrains, ref double ClockTime, in
138138

139139
// Prerun trains
140140
PrerunAI(playerTrainOriginalTrain, playerTrainFormedOfType, playerTrain, cancellation);
141+
if (playerTrain != null && (AITrains.Count == 0 || AITrains[0] != playerTrain))
142+
AITrains.Insert(0, playerTrain);
141143

142144
ClockTime = clockTime;
143145
localTime = false;
@@ -169,7 +171,7 @@ public AI(Simulator simulator, BinaryReader inf)
169171
{
170172
// Timetable mode trains
171173
TTTrain aiTrain = new TTTrain(Simulator, inf, this);
172-
if (aiTrain.TrainType != Train.TRAINTYPE.PLAYER) // Add to AITrains except when it is player train
174+
if (!(AITrains.Count > 0 && aiTrain.Number == AITrains[0].Number)) // Add to AITrains except when it is player train
173175
{
174176
AITrains.Add(aiTrain);
175177
}
@@ -692,6 +694,7 @@ public bool AITTUpdate(float elapsedClockSeconds, bool preUpdate, ref bool activ
692694
Simulator.StartReference.Remove(thisTrain.Number);
693695
if (thisTrain.TrainType == Train.TRAINTYPE.AI_NOTSTARTED) thisTrain.TrainType = Train.TRAINTYPE.AI;
694696
endPreRun = AddToWorldTT(thisTrain, newTrains);
697+
aiListChanged = true;
695698
if (endPreRun) break;
696699
}
697700
}
@@ -705,11 +708,13 @@ public bool AITTUpdate(float elapsedClockSeconds, bool preUpdate, ref bool activ
705708
if (acttrain.MovementState != AITrain.AI_MOVEMENT_STATE.AI_STATIC && acttrain.TrainType != Train.TRAINTYPE.PLAYER)
706709
{
707710
activeTrains = true;
711+
aiListChanged = true;
708712
break;
709713
}
710714
else if (acttrain.MovementState == AITrain.AI_MOVEMENT_STATE.AI_STATIC && actTTTrain.ActivateTime < clockTime)
711715
{
712716
activeTrains = true;
717+
aiListChanged = true;
713718
break;
714719
}
715720
}
@@ -1313,14 +1318,22 @@ private void AddTTTrains()
13131318
if (Simulator.NameDictionary.ContainsKey(train.Name.ToLower())) Simulator.NameDictionary.Remove(train.Name.ToLower());
13141319
Simulator.NameDictionary.Add(train.Name.ToLower(), train);
13151320
if (train.TrainType == Train.TRAINTYPE.PLAYER || train.TrainType == Train.TRAINTYPE.INTENDED_PLAYER)
1321+
{
1322+
if (AITrains[0].TrainType == Train.TRAINTYPE.PLAYER)
1323+
AITrains.RemoveAt(0);
1324+
AITrains.Insert(0, train);
1325+
}
1326+
else if (train.Number == 0)
13161327
{
13171328
AITrains.Insert(0, train);
1329+
Simulator.Trains.Add(train);
13181330
}
13191331
else
13201332
{
13211333
AITrains.Add(train);
13221334
Simulator.Trains.Add(train);
13231335
}
1336+
aiListChanged = true;
13241337
}
13251338
TrainsToAdd.Clear();
13261339
}

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ public void AIUpdate(float elapsedClockSeconds, double clockTime, bool preUpdate
701701
SetReversalAction();
702702

703703
// Check if out of control - if so, remove
704-
if (ControlMode == TRAIN_CONTROL.OUT_OF_CONTROL && TrainType != TRAINTYPE.AI_PLAYERHOSTING)
704+
if (ControlMode == TRAIN_CONTROL.OUT_OF_CONTROL && !(TrainType == TRAINTYPE.AI_PLAYERHOSTING || Autopilot))
705705
{
706706
Trace.TraceInformation("Train {0} ({1}) is removed for out of control, reason : {2}", Name, Number, OutOfControlReason.ToString());
707707
RemoveTrain();
@@ -3589,7 +3589,7 @@ public void AdjustControlsBrakeOff()
35893589
if (FirstCar != null)
35903590
{
35913591
FirstCar.BrakeSystem.AISetPercent(AITrainBrakePercent);
3592-
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING)
3592+
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING || Autopilot)
35933593
{
35943594
if (FirstCar is MSTSLocomotive)
35953595
((MSTSLocomotive)FirstCar).SetTrainBrakePercent(AITrainBrakePercent);
@@ -3610,7 +3610,7 @@ public void AdjustControlsBrakeFull()
36103610
if (FirstCar != null)
36113611
{
36123612
FirstCar.BrakeSystem.AISetPercent(AITrainBrakePercent);
3613-
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING)
3613+
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING || Autopilot)
36143614
{
36153615
if (FirstCar is MSTSLocomotive)
36163616
((MSTSLocomotive)FirstCar).SetTrainBrakePercent(AITrainBrakePercent);
@@ -3630,7 +3630,7 @@ public void AdjustControlsThrottleOff()
36303630
if (FirstCar != null)
36313631
{
36323632
FirstCar.ThrottlePercent = AITrainThrottlePercent;
3633-
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING)
3633+
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING || Autopilot)
36343634
{
36353635
if (FirstCar is MSTSLocomotive)
36363636
{
@@ -3731,7 +3731,7 @@ public void SetPercentsFromTrainToTrainset()
37313731
{
37323732
FirstCar.ThrottlePercent = AITrainThrottlePercent;
37333733
FirstCar.BrakeSystem.AISetPercent(AITrainBrakePercent);
3734-
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING)
3734+
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING || Autopilot)
37353735
{
37363736
if (FirstCar is MSTSLocomotive)
37373737
{
@@ -4366,6 +4366,7 @@ public void CoupleAI(Train attachTrain, bool thisTrainFront, bool attachTrainFro
43664366
(attachTrain as AITrain).SwitchToPlayerControl();
43674367
Simulator.OnPlayerLocomotiveChanged();
43684368
AI.AITrains.Add(this);
4369+
AI.aiListChanged = true;
43694370
}
43704371
if (!UncondAttach)
43714372
{
@@ -6167,7 +6168,7 @@ public virtual String[] AddMovementState(String[] stateString, bool metric)
61676168
/// When in autopilot mode, switches to player control
61686169
/// </summary>
61696170
///
6170-
public bool SwitchToPlayerControl()
6171+
public virtual bool SwitchToPlayerControl()
61716172
{
61726173
bool success = false;
61736174
int leadLocomotiveIndex = -1;
@@ -6206,10 +6207,10 @@ public bool SwitchToPlayerControl()
62066207

62076208
//================================================================================================//
62086209
/// <summary>
6209-
/// When in autopilot mode, switches to autopilot control
6210+
/// When in player mode, switches to autopilot control
62106211
/// </summary>
62116212
///
6212-
public bool SwitchToAutopilotControl()
6213+
public virtual bool SwitchToAutopilotControl()
62136214
{
62146215
bool success = false;
62156216
// MUDirection set within following method call

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ public bool IsPlayerDriven
311311
}
312312
}
313313

314+
public bool Autopilot; // true if autopiloted
314315
public bool IsPlayable = false;
315316
public bool IsPathless = false;
316317

@@ -567,7 +568,7 @@ public Train(Simulator simulator)
567568
{
568569
Init(simulator);
569570

570-
if (Simulator.IsAutopilotMode && TotalNumber == 1 && Simulator.TrainDictionary.Count == 0) TotalNumber = 0; //The autopiloted train has number 0
571+
if (Simulator.IsAutopilotMode && TotalNumber == 1 && Simulator.TrainDictionary.Count == 0 && !Simulator.TimetableMode) TotalNumber = 0; //The autopiloted train has number 0
571572
Number = TotalNumber;
572573
TotalNumber++;
573574
SignalObjectItems = new List<ObjectItemInfo>();
@@ -885,6 +886,7 @@ public Train(Simulator simulator, BinaryReader inf)
885886
PreviousPosition[0] = new TCPosition();
886887
PreviousPosition[0].RestorePreviousPositionDummy(inf);
887888
}
889+
Autopilot = inf.ReadBoolean();
888890
travelled = DistanceTravelledM;
889891
int activeActions = inf.ReadInt32();
890892
for (int iAction = 0; iAction < activeActions; iAction++)
@@ -1191,6 +1193,7 @@ public virtual void Save(BinaryWriter outf)
11911193
PresentPosition[0].Save(outf);
11921194
PresentPosition[1].Save(outf);
11931195
PreviousPosition[0].Save(outf);
1196+
outf.Write(Autopilot);
11941197
// Save requiredAction, the original actions
11951198
outf.Write(requiredActions.Count);
11961199
foreach (DistanceTravelledItem thisAction in requiredActions)
@@ -1282,9 +1285,6 @@ public TrainCar GetNextCab()
12821285
// negative numbers used if rear cab selected
12831286
// because '0' has no negative, all indices are shifted by 1!!!!
12841287

1285-
int presentIndex = LeadLocomotiveIndex + 1;
1286-
if (((MSTSLocomotive)LeadLocomotive).UsingRearCab) presentIndex = -presentIndex;
1287-
12881288
List<int> cabList = new List<int>();
12891289

12901290
for (int i = 0; i < Cars.Count; i++)
@@ -1303,8 +1303,13 @@ public TrainCar GetNextCab()
13031303
if (hasFrontCab) cabList.Add(i + 1);
13041304
if (hasRearCab) cabList.Add(-(i + 1));
13051305
}
1306+
if (LeadLocomotiveIndex == -1 && Simulator.PlayerLocomotive == Cars[i])
1307+
LeadLocomotiveIndex = i;
13061308
}
13071309

1310+
int presentIndex = LeadLocomotiveIndex + 1;
1311+
if (((MSTSLocomotive)LeadLocomotive).UsingRearCab) presentIndex = -presentIndex;
1312+
13081313
int lastIndex = cabList.IndexOf(presentIndex);
13091314
if (lastIndex >= cabList.Count - 1) lastIndex = -1;
13101315

@@ -1329,6 +1334,8 @@ public TrainCar GetNextCab()
13291334
if (Simulator.PlayerLocomotive != null && Simulator.PlayerLocomotive.Train == this)
13301335

13311336
Simulator.PlayerLocomotive = newLead;
1337+
if (Autopilot || TrainType == TRAINTYPE.AI_PLAYERHOSTING)
1338+
LeadLocomotiveIndex = -1;
13321339

13331340
return newLead;
13341341
}
@@ -10181,7 +10188,7 @@ public virtual void SwitchToNodeControl(int thisSectionIndex)
1018110188

1018210189
public void RequestToggleManualMode()
1018310190
{
10184-
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING)
10191+
if (TrainType == TRAINTYPE.AI_PLAYERHOSTING || Autopilot)
1018510192
{
1018610193
if (Simulator.Confirmer != null) // As Confirmer may not be created until after a restore.
1018710194
Simulator.Confirmer.Message(ConfirmLevel.Warning, Simulator.Catalog.GetString("You cannot enter manual mode when autopiloted"));
@@ -21009,7 +21016,7 @@ public int ComputeStationBoardingTime(Train stopTrain)
2100921016
if (passengerCarsWithinPlatform > 0)
2101021017
{
2101121018
var actualNumPassengersWaiting = PlatformItem.NumPassengersWaiting;
21012-
if (stopTrain.TrainType != TRAINTYPE.AI_PLAYERHOSTING) RandomizePassengersWaiting(ref actualNumPassengersWaiting, stopTrain);
21019+
if (stopTrain.TrainType != TRAINTYPE.AI_PLAYERHOSTING && !stopTrain.Autopilot) RandomizePassengersWaiting(ref actualNumPassengersWaiting, stopTrain);
2101321020
stopTime = Math.Max(NumSecPerPass * actualNumPassengersWaiting / passengerCarsWithinPlatform, DefaultFreightStopTime);
2101421021
}
2101521022
else stopTime = 0; // no passenger car stopped within platform: sorry, no countdown starts

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5543,14 +5543,14 @@ public virtual float GetDataOf(CabViewControl cvc)
55435543
case CABViewControlTypes.THROTTLE:
55445544
{
55455545
if (CruiseControl != null && CruiseControl.SkipThrottleDisplay) break;
5546-
data = GetThrottleHandleValue(Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING ? ThrottlePercent / 100f : LocalThrottlePercent / 100f);
5546+
data = GetThrottleHandleValue((Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING || Train.Autopilot) ? ThrottlePercent / 100f : LocalThrottlePercent / 100f);
55475547
break;
55485548
}
55495549
case CABViewControlTypes.THROTTLE_DISPLAY:
55505550
case CABViewControlTypes.CPH_DISPLAY:
55515551
{
55525552
if (CruiseControl != null && CruiseControl.SkipThrottleDisplay) break;
5553-
data = Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING? ThrottlePercent / 100f : LocalThrottlePercent / 100f;
5553+
data = (Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING || Train.Autopilot) ? ThrottlePercent / 100f : LocalThrottlePercent / 100f;
55545554
break;
55555555
}
55565556
case CABViewControlTypes.ENGINE_BRAKE:
@@ -5722,7 +5722,7 @@ public virtual float GetDataOf(CabViewControl cvc)
57225722
var activeloco = ControlActiveLocomotive as MSTSDieselLocomotive;
57235723
if (activeloco.DieselEngines[0] != null)
57245724
{
5725-
if (activeloco.AdvancedAdhesionModel && Train.TrainType != Train.TRAINTYPE.AI_PLAYERHOSTING)
5725+
if (activeloco.AdvancedAdhesionModel && Train.TrainType != Train.TRAINTYPE.AI_PLAYERHOSTING && !Train.Autopilot)
57265726
data = activeloco.HuDIsWheelSlipWarninq ? 1 : 0;
57275727
else
57285728
data = activeloco.HuDIsWheelSlip ? 1 : 0;
@@ -5732,7 +5732,7 @@ public virtual float GetDataOf(CabViewControl cvc)
57325732
}
57335733
else
57345734
{
5735-
if (AdvancedAdhesionModel && Train.TrainType != Train.TRAINTYPE.AI_PLAYERHOSTING)
5735+
if (AdvancedAdhesionModel && Train.TrainType != Train.TRAINTYPE.AI_PLAYERHOSTING && !Train.Autopilot)
57365736
data = HuDIsWheelSlipWarninq ? 1 : 0;
57375737
else
57385738
data = HuDIsWheelSlip ? 1 : 0;

Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5710,7 +5710,7 @@ private void UpdateSteamTractiveForce(float elapsedClockSeconds, float locomotiv
57105710
// Typically tangential force will be greater at starting then when the locomotive is at speed, as interia and reduce steam pressure will decrease the value.
57115711
// By default this model uses information based upon a "NYC 4-4-2 locomotive", for smaller locomotives this data is changed in the OR initialisation phase.
57125712

5713-
if (Simulator.UseAdvancedAdhesion && !Simulator.Settings.SimpleControlPhysics && IsPlayerTrain && this.Train.TrainType != Train.TRAINTYPE.AI_PLAYERHOSTING)
5713+
if (Simulator.UseAdvancedAdhesion && !Simulator.Settings.SimpleControlPhysics && IsPlayerTrain && Train.TrainType != Train.TRAINTYPE.AI_PLAYERHOSTING && !Train.Autopilot)
57145714
// only set advanced wheel slip when advanced adhesion, and simplecontrols/physics is not set and is in the the player train, AI locomotive will not work to this model.
57155715
// Don't use slip model when train is in auto pilot
57165716
{

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/PowerSupplies/CircuitBreaker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public void InitializeMoving()
164164

165165
public void Update(float elapsedSeconds)
166166
{
167-
if (Locomotive.Train.TrainType == Train.TRAINTYPE.AI || Locomotive.Train.TrainType == Train.TRAINTYPE.AI_AUTOGENERATE
167+
if (Locomotive.Train.TrainType == Train.TRAINTYPE.AI && !Locomotive.Train.Autopilot || Locomotive.Train.TrainType == Train.TRAINTYPE.AI_AUTOGENERATE
168168
|| Locomotive.Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING)
169169
{
170170
State = CircuitBreakerState.Closed;

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/TrainControlSystem.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,8 @@ public void Initialize()
280280
};
281281

282282
// TrainControlSystem getters
283-
Script.IsTrainControlEnabled = () => Locomotive == Locomotive.Train.LeadLocomotive && Locomotive.Train.TrainType != Train.TRAINTYPE.AI_PLAYERHOSTING;
284-
Script.IsAutopiloted = () => Locomotive == Simulator.PlayerLocomotive && Locomotive.Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING;
283+
Script.IsTrainControlEnabled = () => Locomotive == Locomotive.Train.LeadLocomotive && Locomotive.Train.TrainType != Train.TRAINTYPE.AI_PLAYERHOSTING && !Locomotive.Train.Autopilot;
284+
Script.IsAutopiloted = () => Locomotive == Simulator.PlayerLocomotive && (Locomotive.Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING || Locomotive.Train.Autopilot);
285285
Script.IsAlerterEnabled = () =>
286286
{
287287
return Simulator.Settings.Alerter
@@ -822,6 +822,8 @@ public void Update(float elapsedClockSeconds)
822822
case Train.TRAINTYPE.AI_AUTOGENERATE:
823823
case Train.TRAINTYPE.REMOTE:
824824
case Train.TRAINTYPE.AI_INCORPORATED:
825+
if (Locomotive.Train.Autopilot && Locomotive == Simulator.PlayerLocomotive)
826+
Locomotive.Train.UpdatePlayerTrainData();
825827
DisableRestrictions();
826828
break;
827829

Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ public float ConvectionFactor
288288
// instance variables set by train physics when it creates the traincar
289289
public Train Train; // the car is connected to this train
290290
// public bool IsPlayerTrain { get { return Train.TrainType == ORTS.Train.TRAINTYPE.PLAYER ? true : false; } set { } }
291-
public bool IsPlayerTrain { get { return Train.IsPlayerDriven; } set { } }
291+
public bool IsPlayerTrain { get { return Train != null && Train.IsPlayerDriven; } set { } }
292292
public bool Flipped; // the car is reversed in the consist
293293
public int UiD;
294294
public string CarID = "AI"; //CarID = "0 - UID" if player train, "ActivityID - UID" if loose consist, "AI" if AI train

0 commit comments

Comments
 (0)