Skip to content

Commit 95e36ea

Browse files
authored
Merge pull request #896 from Csantucci/AI-Train-Sound-official
First implementation of https://blueprints.launchpad.net/or/+spec/specific-sounds-for-ai-trains
2 parents ade0195 + 335f998 commit 95e36ea

File tree

7 files changed

+201
-8
lines changed

7 files changed

+201
-8
lines changed

Source/Documentation/Manual/sound.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,22 @@ Trigger Function
430430
322 BoosterCylinderCocksClose
431431
========= =====================================
432432

433+
Following triggers referring to locomotive and train type are available:
434+
435+
========= =====================================
436+
Trigger Function
437+
========= =====================================
438+
330 AITrainLeadLoco
439+
331 AITrainHelperLoco
440+
332 PlayerTrainLeadLoco
441+
333 PlayerTrainHelperLoco
442+
334 AITrainApproachingStation
443+
335 AITrainLeavingStation
444+
336 StaticTrainLoco
445+
337 EndAITrainLeadLoco
446+
========= =====================================
447+
448+
433449
Variable Triggers
434450
-----------------
435451

Source/Orts.Simulation/Common/Events.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ public interface EventHandler
2727
public enum Event
2828
{
2929
None,
30+
AITrainApproachingStation,
31+
AITrainHelperLoco,
32+
AITrainLeadLoco,
33+
AITrainLeavingStation,
34+
PlayerTrainHelperLoco,
35+
PlayerTrainLeadLoco,
36+
StaticTrainLoco,
37+
EndAITrainLeadLoco,
3038
BatterySwitchOff,
3139
BatterySwitchOn,
3240
BatterySwitchCommandOff,
@@ -572,6 +580,16 @@ public static Event From(Source source, int eventID)
572580
case 321: return Event.BoosterCylinderCocksOpen;
573581
case 322: return Event.BoosterCylinderCocksClose;
574582

583+
// AI train related events
584+
case 330: return Event.AITrainLeadLoco;
585+
case 331: return Event.AITrainHelperLoco;
586+
case 332: return Event.PlayerTrainLeadLoco;
587+
case 333: return Event.PlayerTrainHelperLoco;
588+
case 334: return Event.AITrainApproachingStation;
589+
case 335: return Event.AITrainLeavingStation;
590+
case 336: return Event.StaticTrainLoco;
591+
case 337: return Event.EndAITrainLeadLoco;
592+
575593
default: return 0;
576594
}
577595
case Source.MSTSCrossing:

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public class AITrain : Train
7575
public float DoorOpenTimer = -1f;
7676
public float DoorCloseTimer = -1f;
7777
public AILevelCrossingHornPattern LevelCrossingHornPattern { get; set; }
78+
public bool ApproachTriggerSet = false; // station approach trigger for AI trains has been set
7879

7980
public float PathLength;
8081

@@ -246,6 +247,7 @@ public AITrain(Simulator simulator, BinaryReader inf, AI airef)
246247
UncondAttach = inf.ReadBoolean();
247248
DoorCloseTimer = inf.ReadSingle();
248249
DoorOpenTimer = inf.ReadSingle();
250+
ApproachTriggerSet = inf.ReadBoolean();
249251
if (!Simulator.TimetableMode && DoorOpenTimer <= 0 && DoorCloseTimer > 0 && Simulator.OpenDoorsInAITrains &&
250252
MovementState == AI_MOVEMENT_STATE.STATION_STOP && StationStops.Count > 0)
251253
{
@@ -339,6 +341,7 @@ public override void Save(BinaryWriter outf)
339341
outf.Write(UncondAttach);
340342
outf.Write(DoorCloseTimer);
341343
outf.Write(DoorOpenTimer);
344+
outf.Write(ApproachTriggerSet);
342345
if (LevelCrossingHornPattern != null)
343346
{
344347
outf.Write(0);
@@ -1302,6 +1305,7 @@ public virtual void SetNextStationAction(bool fromAutopilotSwitch = false)
13021305
AIActionItem newAction = new AIActionItem(null, AIActionItem.AI_ACTION_TYPE.STATION_STOP);
13031306
newAction.SetParam(distancesM[1], 0.0f, distancesM[0], DistanceTravelledM);
13041307
requiredActions.InsertAction(newAction);
1308+
ApproachTriggerSet = false;
13051309

13061310
#if DEBUG_REPORTS
13071311
if (StationStops[0].ActualStopType == StationStop.STOPTYPE.STATION_STOP)
@@ -2061,6 +2065,7 @@ public virtual void UpdateStationState(float elapsedClockSeconds, int presentTim
20612065

20622066
Delay = TimeSpan.FromSeconds((presentTime - thisStation.DepartTime) % (24 * 3600));
20632067
}
2068+
if (Cars[0] is MSTSLocomotive) Cars[0].SignalEvent(Event.AITrainLeavingStation);
20642069

20652070
#if DEBUG_REPORTS
20662071
DateTime baseDTd = new DateTime();
@@ -2622,6 +2627,13 @@ public virtual void UpdateBrakingState(float elapsedClockSeconds, int presentTim
26222627
}
26232628
}
26242629

2630+
if (nextActionInfo != null && nextActionInfo.NextAction == AIActionItem.AI_ACTION_TYPE.STATION_STOP &&
2631+
distanceToGoM < 150 + StationStops[0].PlatformItem.Length && !ApproachTriggerSet)
2632+
{
2633+
if (Cars[0] is MSTSLocomotive) Cars[0].SignalEvent(Event.AITrainApproachingStation);
2634+
ApproachTriggerSet = true;
2635+
}
2636+
26252637
if (nextActionInfo != null && nextActionInfo.NextAction == AIActionItem.AI_ACTION_TYPE.STATION_STOP)
26262638
creepDistanceM = 0.0f;
26272639
if (nextActionInfo == null && requiredSpeedMpS == 0)
@@ -4369,6 +4381,8 @@ public void CoupleAI(Train attachTrain, bool thisTrainFront, bool attachTrainFro
43694381
AI.AITrains.Add(this);
43704382
AI.aiListChanged = true;
43714383
}
4384+
else
4385+
attachTrain.RedefineSoundTriggers();
43724386
if (!UncondAttach)
43734387
{
43744388
RemoveTrain();
@@ -4477,6 +4491,7 @@ public void CoupleAIToStatic(Train attachTrain, bool thisTrainFront, bool attach
44774491
AddTrackSections();
44784492
ResetActions(true);
44794493
physicsUpdate(0);
4494+
RedefineSoundTriggers();
44804495
}
44814496

44824497
//================================================================================================//
@@ -4718,7 +4733,8 @@ public void TerminateCoupling(Train attachTrain, bool thisTrainFront, bool attac
47184733
// Move WP, if any, just under the loco;
47194734
AuxActionsContain.MoveAuxActionAfterReversal(this);
47204735
ResetActions(true);
4721-
4736+
RedefineSoundTriggers();
4737+
attachTrain.RedefineSoundTriggers();
47224738
physicsUpdate(0);// Stop the wheels from moving etc
47234739

47244740
}

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

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public enum TRAINTYPE
215215
AI_NOTSTARTED,
216216
AI_AUTOGENERATE,
217217
REMOTE,
218-
AI_PLAYERDRIVEN, //Player is on board and is durrently driving train
218+
AI_PLAYERDRIVEN, //Player is on board and is currently driving train
219219
AI_PLAYERHOSTING, //Player is on board, but train is currently autopiloted
220220
AI_INCORPORATED // AI train is incorporated in other train
221221
}
@@ -1504,6 +1504,7 @@ public void ReverseFormation(bool setMUParameters)
15041504
MUReverserPercent = -MUReverserPercent;
15051505
}
15061506
if (!((this is AITrain && Simulator.PreUpdate) || this.TrainType == TRAINTYPE.STATIC)) FormationReversed = true;
1507+
RedefineSoundTriggers();
15071508
}
15081509

15091510
//================================================================================================//
@@ -1536,6 +1537,7 @@ public void ReverseCars()
15361537
// Update flipped state of each car.
15371538
for (var i = 0; i < Cars.Count; i++)
15381539
Cars[i].Flipped = !Cars[i].Flipped;
1540+
RedefineSoundTriggers();
15391541
}
15401542

15411543
/// <summary>
@@ -13829,6 +13831,81 @@ public string GetTrainName(string ID)
1382913831
return ID.Substring(0, location - 1);
1383013832
}
1383113833

13834+
//================================================================================================//
13835+
/// <summary>
13836+
/// Redefine sound triggers for AI trains
13837+
/// </summary>
13838+
public void RedefineAITriggers()
13839+
{
13840+
var leadFound = false;
13841+
foreach (var car in Cars)
13842+
{
13843+
if (car is MSTSLocomotive)
13844+
{
13845+
if (!leadFound)
13846+
{
13847+
car.SignalEvent(Event.AITrainLeadLoco);
13848+
leadFound = true;
13849+
}
13850+
else
13851+
{
13852+
car.SignalEvent(Event.AITrainHelperLoco);
13853+
car.SignalEvent(Event.EndAITrainLeadLoco);
13854+
}
13855+
}
13856+
}
13857+
}
13858+
13859+
//================================================================================================//
13860+
/// <summary>
13861+
/// Redefine sound triggers for Player Train
13862+
/// </summary>
13863+
public void RedefinePlayerTrainTriggers()
13864+
{
13865+
Simulator.PlayerLocomotive.SignalEvent(Event.PlayerTrainLeadLoco);
13866+
foreach (var car in Cars)
13867+
{
13868+
if (car is MSTSLocomotive)
13869+
{
13870+
if (car != Simulator.PlayerLocomotive)
13871+
{
13872+
car.SignalEvent(Event.PlayerTrainHelperLoco);
13873+
}
13874+
car.SignalEvent(Event.EndAITrainLeadLoco);
13875+
}
13876+
}
13877+
}
13878+
13879+
//================================================================================================//
13880+
/// <summary>
13881+
/// Redefine sound triggers for static trains
13882+
/// </summary>
13883+
public void RedefineStaticTrainTriggers()
13884+
{
13885+
foreach (var car in Cars)
13886+
{
13887+
if (car is MSTSLocomotive)
13888+
{
13889+
car.SignalEvent(Event.StaticTrainLoco);
13890+
car.SignalEvent(Event.EndAITrainLeadLoco);
13891+
}
13892+
}
13893+
}
13894+
13895+
//================================================================================================//
13896+
/// <summary>
13897+
/// Redefine sound triggers
13898+
/// </summary>
13899+
public void RedefineSoundTriggers()
13900+
{
13901+
if (TrainType == TRAINTYPE.PLAYER || TrainType == TRAINTYPE.AI_PLAYERDRIVEN || TrainType == TRAINTYPE.AI_PLAYERHOSTING)
13902+
RedefinePlayerTrainTriggers();
13903+
else if (TrainType == TRAINTYPE.AI)
13904+
RedefineAITriggers();
13905+
else
13906+
RedefineStaticTrainTriggers();
13907+
}
13908+
1383213909
//================================================================================================//
1383313910

1383413911
/// <summary>

Source/Orts.Simulation/Simulation/Simulator.cs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,14 +755,20 @@ public void SetWagonCommandReceivers(MSTSWagon wag)
755755
public TrainCar SetPlayerLocomotive(Train playerTrain)
756756
{
757757
TrainCar PlayerLocomotive = null;
758+
var leadFound = false;
758759
foreach (TrainCar car in playerTrain.Cars)
759760
if (car.IsDriveable) // first loco is the one the player drives
760761
{
761-
PlayerLocomotive = car;
762-
playerTrain.LeadLocomotive = car;
763-
playerTrain.InitializeBrakes();
764-
PlayerLocomotive.LocalThrottlePercent = playerTrain.AITrainThrottlePercent;
765-
break;
762+
if (!leadFound)
763+
{
764+
PlayerLocomotive = car;
765+
playerTrain.LeadLocomotive = car;
766+
playerTrain.InitializeBrakes();
767+
PlayerLocomotive.LocalThrottlePercent = playerTrain.AITrainThrottlePercent;
768+
PlayerLocomotive.SignalEvent(Event.PlayerTrainLeadLoco);
769+
leadFound = true;
770+
}
771+
else car.SignalEvent(Event.PlayerTrainHelperLoco);
766772
}
767773
if (PlayerLocomotive == null)
768774
throw new InvalidDataException("Can't find player locomotive in activity");
@@ -982,6 +988,7 @@ private void FinishCoupling(Train drivenTrain, Train train, bool couple_to_front
982988
}
983989
drivenTrain.Cars.Clear();
984990
AI.TrainsToRemoveFromAI.Add((AITrain)train);
991+
PlayerLocomotive.SignalEvent(Event.PlayerTrainHelperLoco);
985992
PlayerLocomotive = SetPlayerLocomotive(train);
986993
(train as AITrain).SwitchToPlayerControl();
987994
OnPlayerLocomotiveChanged();
@@ -1096,6 +1103,7 @@ public void CheckForCoupling(Train drivenTrain, float elapsedClockSeconds)
10961103
{
10971104
drivenTrain.Cars.Add(car);
10981105
car.Train = drivenTrain;
1106+
if (car is MSTSLocomotive) car.SignalEvent(Event.PlayerTrainHelperLoco);
10991107
}
11001108
FinishRearCoupling(drivenTrain, train, true);
11011109
return;
@@ -1126,6 +1134,7 @@ public void CheckForCoupling(Train drivenTrain, float elapsedClockSeconds)
11261134
drivenTrain.Cars.Add(car);
11271135
car.Train = drivenTrain;
11281136
car.Flipped = !car.Flipped;
1137+
if (car is MSTSLocomotive) car.SignalEvent(Event.PlayerTrainHelperLoco);
11291138
}
11301139
FinishRearCoupling(drivenTrain, train, false);
11311140
return;
@@ -1190,6 +1199,7 @@ public void CheckForCoupling(Train drivenTrain, float elapsedClockSeconds)
11901199
TrainCar car = train.Cars[i];
11911200
drivenTrain.Cars.Insert(i, car);
11921201
car.Train = drivenTrain;
1202+
if (car is MSTSLocomotive) car.SignalEvent(Event.PlayerTrainHelperLoco);
11931203
}
11941204
if (drivenTrain.LeadLocomotiveIndex >= 0) drivenTrain.LeadLocomotiveIndex += train.Cars.Count;
11951205
FinishFrontCoupling(drivenTrain, train, lead, true);
@@ -1223,6 +1233,7 @@ public void CheckForCoupling(Train drivenTrain, float elapsedClockSeconds)
12231233
drivenTrain.Cars.Insert(0, car);
12241234
car.Train = drivenTrain;
12251235
car.Flipped = !car.Flipped;
1236+
if (car is MSTSLocomotive) car.SignalEvent(Event.PlayerTrainHelperLoco);
12261237
}
12271238
if (drivenTrain.LeadLocomotiveIndex >= 0) drivenTrain.LeadLocomotiveIndex += train.Cars.Count;
12281239
FinishFrontCoupling(drivenTrain, train, lead, false);
@@ -1831,6 +1842,19 @@ public void UncoupleBehind(TrainCar car, bool keepFront)
18311842
train2.TrainType = Train.TRAINTYPE.AI;
18321843
train.IncorporatedTrainNo = -1;
18331844
train2.MUDirection = Direction.Forward;
1845+
var leadFound = false;
1846+
foreach (var trainCar in train2.Cars)
1847+
{
1848+
if (trainCar is MSTSLocomotive)
1849+
{
1850+
if (!leadFound)
1851+
{
1852+
trainCar.SignalEvent(Event.AITrainLeadLoco);
1853+
leadFound = true;
1854+
}
1855+
}
1856+
else trainCar.SignalEvent(Event.AITrainHelperLoco);
1857+
}
18341858
}
18351859
else train2.TrainType = Train.TRAINTYPE.STATIC;
18361860
train2.LeadLocomotive = null;
@@ -1959,6 +1983,7 @@ private void StartSwitchPlayerTrain()
19591983
playerTrain.TrainType = Train.TRAINTYPE.AI;
19601984
if (!TimetableMode) AI.AITrains.Add(playerTrain);
19611985
playerTrain.Autopilot = false;
1986+
playerTrain.RedefineAITriggers();
19621987
if (TrainSwitcher.SuspendOldPlayer)
19631988
{
19641989
playerTrain.MovementState = AITrain.AI_MOVEMENT_STATE.SUSPENDED;
@@ -2158,6 +2183,7 @@ private void CompleteSwitchPlayerTrain()
21582183
PlayerLocomotive.Train.CreatePathlessPlayerTrain();
21592184
}
21602185
var playerLocomotive = PlayerLocomotive as MSTSLocomotive;
2186+
PlayerLocomotive.Train.RedefinePlayerTrainTriggers();
21612187
playerLocomotive.UsingRearCab = (PlayerLocomotive.Flipped ^ PlayerLocomotive.Train.MUDirection == Direction.Reverse) && (playerLocomotive.HasRearCab || playerLocomotive.HasRear3DCab);
21622188
OnPlayerLocomotiveChanged();
21632189
playerSwitchOngoing = false;

0 commit comments

Comments
 (0)