Skip to content

Commit fd34961

Browse files
committed
Sync turntables and transfertables in multiplayer mode https://blueprints.launchpad.net/or/+spec/sync-turntables-in-multiplayer
1 parent 1455952 commit fd34961

File tree

5 files changed

+267
-76
lines changed

5 files changed

+267
-76
lines changed

Source/Orts.Simulation/MultiPlayer/Message.cs

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
using Orts.Simulation.Signalling;
2727
using ORTS.Common;
2828
using ORTS.Scripting.Api;
29+
using Microsoft.Xna.Framework;
2930
using System;
3031
using System.Collections.Generic;
3132
using System.Diagnostics;
@@ -76,6 +77,7 @@ public static Message Decode(string m)
7677
else if (key == "SIGNALCHANGE") return new MSGSignalChange(m.Substring(index + 1));
7778
else if (key == "EXHAUST") return new MSGExhaust(m.Substring(index + 1));
7879
else if (key == "FLIP") return new MSGFlip(m.Substring(index + 1));
80+
else if (key == "MOVINGTBL") return new MSGMovingTbl(m.Substring(index + 1));
7981
else throw new Exception("Unknown Keyword" + key);
8082
}
8183

@@ -2345,7 +2347,7 @@ public override void HandleMsg()
23452347
}
23462348

23472349
}
2348-
#endregion MSGGetTrain
2350+
#endregion MSGGetTrain
23492351

23502352
#region MSGUncouple
23512353

@@ -2779,8 +2781,9 @@ public override void HandleMsg()
27792781
}
27802782
}
27812783
}
2782-
#endregion MSGUncouple
2784+
#endregion MSGUncouple
27832785

2786+
27842787
#region MSGCouple
27852788
public class MSGCouple : Message
27862789
{
@@ -3893,4 +3896,104 @@ public override string ToString()
38933896

38943897
#endregion MSGFlip
38953898

3896-
}
3899+
#region MSGMovingTbl
3900+
3901+
public class MSGMovingTbl : Message
3902+
{
3903+
public string user, newTrainName, carID, firstCarIDOld, firstCarIDNew;
3904+
public MovingTable.submessagecode subMessageCode;
3905+
public int movingTableIndex;
3906+
public bool clockwise;
3907+
public float yangle;
3908+
3909+
public MSGMovingTbl(string m)
3910+
{
3911+
string[] areas = m.Split('\t');
3912+
3913+
movingTableIndex = int.Parse(areas[0].Trim());
3914+
user = areas[1].Trim();
3915+
subMessageCode = (MovingTable.submessagecode) int.Parse(areas[2].Trim());
3916+
clockwise = int.Parse(areas[3].Trim()) == 0 ? false : true;
3917+
yangle = float.Parse(areas[4].Trim());
3918+
3919+
}
3920+
3921+
public MSGMovingTbl(int mti, string u, MovingTable.submessagecode smc, bool cw, float y)
3922+
{
3923+
movingTableIndex = mti;
3924+
user = u;
3925+
subMessageCode = smc;
3926+
clockwise = cw;
3927+
yangle = y;
3928+
}
3929+
3930+
public override string ToString()
3931+
{
3932+
if (user == "") return "5: ALIVE"; //wrong, so just return an ALIVE string
3933+
string tmp = "MOVINGTBL " + movingTableIndex + "\t" + user + "\t" + (int)subMessageCode + "\t" + (clockwise ? 1 : 0) + "\t" + yangle + "\t";
3934+
return " " + tmp.Length + ": " + tmp;
3935+
}
3936+
3937+
public override void HandleMsg()
3938+
{
3939+
if (user != MPManager.GetUserName())
3940+
{
3941+
MPManager.Simulator.ActiveMovingTable = MPManager.Simulator.MovingTables[movingTableIndex];
3942+
if (MPManager.Simulator.ActiveMovingTable is Turntable turntable)
3943+
{
3944+
switch (subMessageCode)
3945+
{
3946+
case MovingTable.submessagecode.GoToTarget:
3947+
turntable.RemotelyControlled = true;
3948+
if (Math.Abs(MathHelper.WrapAngle(turntable.YAngle - yangle)) > 0.2f)
3949+
{
3950+
turntable.YAngle = yangle;
3951+
turntable.TargetY = yangle;
3952+
turntable.AlignToRemote = true;
3953+
}
3954+
turntable.GeneralComputeTarget(clockwise);
3955+
break;
3956+
case MovingTable.submessagecode.StartingContinuous:
3957+
turntable.YAngle = yangle;
3958+
turntable.TargetY = yangle;
3959+
turntable.AlignToRemote = true;
3960+
turntable.GeneralStartContinuous(clockwise);
3961+
break;
3962+
default:
3963+
break;
3964+
}
3965+
}
3966+
else if (MPManager.Simulator.ActiveMovingTable is Transfertable transfertable)
3967+
{
3968+
switch (subMessageCode)
3969+
{
3970+
case MovingTable.submessagecode.GoToTarget:
3971+
transfertable.RemotelyControlled = true;
3972+
if (Math.Abs(transfertable.OffsetPos - yangle) > 2.8f)
3973+
{
3974+
transfertable.OffsetPos = yangle;
3975+
transfertable.TargetOffset = yangle;
3976+
transfertable.AlignToRemote = true;
3977+
}
3978+
transfertable.GeneralComputeTarget(clockwise);
3979+
break;
3980+
case MovingTable.submessagecode.StartingContinuous:
3981+
transfertable.OffsetPos = yangle;
3982+
transfertable.TargetOffset = yangle;
3983+
transfertable.AlignToRemote = true;
3984+
transfertable.GeneralStartContinuous(clockwise);
3985+
break;
3986+
default:
3987+
break;
3988+
}
3989+
}
3990+
if (MPManager.IsServer())
3991+
{
3992+
MPManager.BroadCast(this.ToString());//if server receives this, will tell others, including whoever sent the information
3993+
}
3994+
}
3995+
}
3996+
}
3997+
3998+
#endregion MSGMovingTbl
3999+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1821,7 +1821,7 @@ public virtual void Update(float elapsedClockSeconds, bool auxiliaryUpdate = tru
18211821
{
18221822
if (!auxiliaryUpdate)
18231823
FormationReversed = false;
1824-
if (IsActualPlayerTrain && Simulator.ActiveMovingTable != null)
1824+
if ((IsActualPlayerTrain || TrainType == TRAINTYPE.REMOTE) && Simulator.ActiveMovingTable != null)
18251825
Simulator.ActiveMovingTable.CheckTrainOnMovingTable(this);
18261826

18271827
if (IsActualPlayerTrain && Simulator.OriginalPlayerTrain != this && !CheckStations) // if player train is to check own stations

Source/Orts.Simulation/Simulation/Transfertables.cs

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public float CenterOffsetComponent
4747
{
4848
get => VerticalTransfer ? CenterOffset.Y : CenterOffset.X;
4949
}
50+
public float OffsetDiff = 1.4f;
5051
// Dynamic data
5152
public bool Forward; // forward motion on
5253
public bool Reverse; // reverse motion on
@@ -172,15 +173,27 @@ protected void InitializeOffsetsAndTrackNodes()
172173
/// Returns the Y angle to be compared.
173174
/// </summary>
174175
public override void ComputeTarget(bool isForward)
176+
{
177+
if (!Continuous) return;
178+
if (MultiPlayer.MPManager.IsMultiPlayer())
179+
{
180+
SubMessageCode = submessagecode.GoToTarget;
181+
MultiPlayer.MPManager.Notify(new MultiPlayer.MSGMovingTbl(Simulator.ActiveMovingTableIndex, Orts.MultiPlayer.MPManager.GetUserName(), SubMessageCode, isForward, OffsetPos).ToString());
182+
}
183+
RemotelyControlled = false;
184+
GeneralComputeTarget(isForward);
185+
}
186+
187+
public void GeneralComputeTarget(bool isForward)
175188
{
176189
if (!Continuous) return;
177190
Continuous = false;
178191
GoToTarget = false;
179192
Forward = isForward;
180193
Reverse = !isForward;
194+
OffsetDiff = RemotelyControlled ? 2.8f : 1.4f;
181195
if (Forward)
182196
{
183-
var offsetDiff = 1.4f;
184197
Connected = false;
185198
if (Offsets.Count <= 0)
186199
{
@@ -194,7 +207,7 @@ public override void ComputeTarget(bool isForward)
194207
if (MyTrackNodesIndex[iOffset] != -1 && MyTrVectorSectionsIndex[iOffset] != -1)
195208
{
196209
var thisOffsetDiff = Offsets[iOffset] - OffsetPos;
197-
if (thisOffsetDiff < offsetDiff && thisOffsetDiff >= 0)
210+
if (thisOffsetDiff < OffsetDiff && thisOffsetDiff >= 0)
198211
{
199212
ConnectedTarget = iOffset;
200213
break;
@@ -211,7 +224,6 @@ public override void ComputeTarget(bool isForward)
211224
}
212225
else if (Reverse)
213226
{
214-
var offsetDiff = -1.4f;
215227
Connected = false;
216228
if (Offsets.Count <= 0)
217229
{
@@ -225,7 +237,7 @@ public override void ComputeTarget(bool isForward)
225237
if (MyTrackNodesIndex[iOffset] != -1 && MyTrVectorSectionsIndex[iOffset] != -1)
226238
{
227239
var thisOffsetDiff = Offsets[iOffset] - OffsetPos;
228-
if (thisOffsetDiff > offsetDiff && thisOffsetDiff <= 0)
240+
if (thisOffsetDiff > -OffsetDiff && thisOffsetDiff <= 0)
229241
{
230242
ConnectedTarget = iOffset;
231243
break;
@@ -241,6 +253,7 @@ public override void ComputeTarget(bool isForward)
241253
}
242254

243255
}
256+
RemotelyControlled = false;
244257
return;
245258
}
246259

@@ -250,6 +263,28 @@ public override void ComputeTarget(bool isForward)
250263
/// </summary>
251264
///
252265
public override void StartContinuous(bool isForward)
266+
{
267+
if (TrainsOnMovingTable.Count == 1 && TrainsOnMovingTable[0].FrontOnBoard && TrainsOnMovingTable[0].BackOnBoard)
268+
{
269+
// Preparing for rotation
270+
var train = TrainsOnMovingTable[0].Train;
271+
if (Math.Abs(train.SpeedMpS) > 0.1 || (train.LeadLocomotiveIndex != -1 && (train.LeadLocomotive.ThrottlePercent >= 1 || train.TrainType != Train.TRAINTYPE.REMOTE && !(train.LeadLocomotive.Direction == Direction.N
272+
|| Math.Abs(train.MUReverserPercent) <= 1))) || (train.ControlMode != Train.TRAIN_CONTROL.MANUAL && train.ControlMode != Train.TRAIN_CONTROL.TURNTABLE &&
273+
train.ControlMode != Train.TRAIN_CONTROL.EXPLORER && train.ControlMode != Train.TRAIN_CONTROL.UNDEFINED))
274+
{
275+
if (SendNotifications) Simulator.Confirmer.Warning(Simulator.Catalog.GetStringFmt("Rotation can't start: check throttle, speed, direction and control mode"));
276+
return;
277+
}
278+
}
279+
if (MultiPlayer.MPManager.IsMultiPlayer())
280+
{
281+
SubMessageCode = submessagecode.StartingContinuous;
282+
MultiPlayer.MPManager.Notify(new MultiPlayer.MSGMovingTbl(Simulator.ActiveMovingTableIndex, Orts.MultiPlayer.MPManager.GetUserName(), SubMessageCode, isForward, OffsetPos).ToString());
283+
}
284+
GeneralStartContinuous(isForward);
285+
}
286+
287+
public void GeneralStartContinuous(bool isForward)
253288
{
254289
if (TrainsOnMovingTable.Count > 1 || (TrainsOnMovingTable.Count == 1 && TrainsOnMovingTable[0].FrontOnBoard ^ TrainsOnMovingTable[0].BackOnBoard))
255290
{
@@ -263,13 +298,6 @@ public override void StartContinuous(bool isForward)
263298
{
264299
// Preparing for transfer
265300
var train = TrainsOnMovingTable[0].Train;
266-
if (Math.Abs(train.SpeedMpS) > 0.1 || (train.LeadLocomotiveIndex != -1 && (train.LeadLocomotive.ThrottlePercent >= 1 || !(train.LeadLocomotive.Direction == Direction.N
267-
|| Math.Abs(train.MUReverserPercent) <= 1))) || (train.ControlMode != Train.TRAIN_CONTROL.MANUAL && train.ControlMode != Train.TRAIN_CONTROL.TURNTABLE &&
268-
train.ControlMode != Train.TRAIN_CONTROL.EXPLORER && train.ControlMode != Train.TRAIN_CONTROL.UNDEFINED))
269-
{
270-
Simulator.Confirmer.Warning(Simulator.Catalog.GetStringFmt("Transfer can't start: check throttle, speed, direction and control mode"));
271-
return;
272-
}
273301
if (train.ControlMode == Train.TRAIN_CONTROL.MANUAL || train.ControlMode == Train.TRAIN_CONTROL.EXPLORER || train.ControlMode == Train.TRAIN_CONTROL.UNDEFINED)
274302
{
275303
SaveConnected = Connected ^ !MyTrackNodesOrientation[ConnectedTrackEnd];

0 commit comments

Comments
 (0)