@@ -511,6 +511,9 @@ public TrainCar LeadLocomotive
511511 //if (lead.EngineBrakeController != null)
512512 // lead.EngineBrakeController.UpdateEngineBrakePressure(ref BrakeLine3PressurePSI, 1000);
513513 }
514+
515+ // If lead locomotive changes, distributed power needs to be updated
516+ SetDPUnitIDs(true);
514517 }
515518 }
516519
@@ -1535,27 +1538,43 @@ public void SetDPUnitIDs(bool keepRemoteGroups = false)
15351538 {
15361539 // List to keep track of new 'lead' DP units
15371540 // 'Lead' DP units follow the air brake commands of the master loco, 'trail' DP units do not
1538- List<TrainCar> tempDPLead = new List<TrainCar>();
1541+ List<TrainCar> tempDPLeads = new List<TrainCar>();
1542+ TrainCar tempDPLead = null;
1543+ // Value judging how compatible this locomotive is to the lead locomotive for DP purposes
1544+ float dpRating = 0;
15391545
15401546 // List of each DP group's locomotives
15411547 List<List<TrainCar>> tempLocoGroups = new List<List<TrainCar>>();
15421548
15431549 var prevId = -1;
1544-
15451550 var id = 0;
1551+
15461552 foreach (var car in Cars)
15471553 {
1548- //Console.WriteLine("___{0} {1}", car.CarID, id);
15491554 if (car is MSTSLocomotive loco)
15501555 {
1556+ float thisDPRating = DetermineDPCompatibility(LeadLocomotive, car);
1557+
15511558 loco.DPUnitID = id;
15521559
1553- if (id != prevId && !tempDPLead.Contains(car)) // If this is a new ID, that means we found a 'lead' unit
1560+ if (id != prevId) // New locomotive group
15541561 {
1555- tempDPLead.Add(car);
1562+ // Add the most suitable unit from the previous group as a DP lead unit
1563+ if (tempDPLead != null && !tempDPLeads.Contains(tempDPLead))
1564+ tempDPLeads.Add(tempDPLead);
1565+
1566+ dpRating = thisDPRating;
1567+ tempDPLead = car;
15561568
15571569 prevId = id;
15581570 }
1571+ else // Same locomotive group
1572+ // Check to see if this locomotive is more compatible than previous ones
1573+ if (thisDPRating > dpRating)
1574+ {
1575+ dpRating = thisDPRating;
1576+ tempDPLead = car;
1577+ }
15591578
15601579 if (car.RemoteControlGroup == 1 && !keepRemoteGroups)
15611580 car.RemoteControlGroup = 0;
@@ -1564,20 +1583,24 @@ public void SetDPUnitIDs(bool keepRemoteGroups = false)
15641583 id++;
15651584 }
15661585
1567- foreach (TrainCar locoCar in tempDPLead)
1586+ // Add final DP lead unit
1587+ if (tempDPLead != null && !tempDPLeads.Contains(tempDPLead))
1588+ tempDPLeads.Add(tempDPLead);
1589+
1590+ foreach (TrainCar locoCar in tempDPLeads)
15681591 {
15691592 // The train's lead unit should always be a DP lead unit, even if not at the front
15701593 // If a different locomotive in the lead loco's group has been declared DP lead, replace that loco with the lead loco
15711594 if (LeadLocomotive is MSTSLocomotive lead && locoCar is MSTSLocomotive loco)
15721595 if (loco.DPUnitID == lead.DPUnitID && locoCar != LeadLocomotive)
15731596 {
1574- tempDPLead .Insert(tempDPLead .IndexOf(locoCar), LeadLocomotive);
1575- tempDPLead .Remove(locoCar);
1597+ tempDPLeads .Insert(tempDPLeads .IndexOf(locoCar), LeadLocomotive);
1598+ tempDPLeads .Remove(locoCar);
15761599 break; // foreach doesn't like it when the collection is modified during the loop, break to mitigate error
15771600 }
15781601 }
15791602
1580- DPLeadUnits = tempDPLead ;
1603+ DPLeadUnits = tempDPLeads ;
15811604
15821605 foreach (TrainCar loco in DPLeadUnits)
15831606 {
@@ -4335,6 +4358,58 @@ public TrainCar DetermineDPLeadLocomotive(TrainCar locoCar)
43354358 return null;
43364359 }
43374360
4361+ //================================================================================================//
4362+ /// <summary>
4363+ /// Find compatibility of DP connection between two locomotives
4364+ /// <\summary>
4365+
4366+ // Returns a score judging the compatibility of a lead locomotive (first input as a TrainCar)
4367+ // and remote locomotive (second input as a TrainCar). The more capabilities the two locomotives
4368+ // share, the higher the number returned. There is an additional slight bias for remote
4369+ // locomotives having higher capabilities than the lead locomotive.
4370+ // Returns -1 if one of the input TrainCars isn't a locomotive
4371+
4372+ public float DetermineDPCompatibility(TrainCar leadCar, TrainCar remoteCar)
4373+ {
4374+ float score = 0;
4375+
4376+ if (leadCar is MSTSLocomotive lead && remoteCar is MSTSLocomotive remote)
4377+ {
4378+ if (remote.DPSyncTrainApplication)
4379+ {
4380+ if (lead.DPSyncTrainApplication)
4381+ score++;
4382+ else
4383+ score += 0.1f;
4384+ }
4385+ if (remote.DPSyncTrainRelease)
4386+ {
4387+ if (lead.DPSyncTrainRelease)
4388+ score++;
4389+ else
4390+ score += 0.1f;
4391+ }
4392+ if (remote.DPSyncEmergency)
4393+ {
4394+ if (lead.DPSyncEmergency)
4395+ score++;
4396+ else
4397+ score += 0.1f;
4398+ }
4399+ if (remote.DPSyncIndependent)
4400+ {
4401+ if (lead.DPSyncIndependent)
4402+ score++;
4403+ else
4404+ score += 0.1f;
4405+ }
4406+
4407+ return score;
4408+ }
4409+ else
4410+ return -1;
4411+ }
4412+
43384413 //================================================================================================//
43394414 /// <summary>
43404415 /// Propagate brake pressure
0 commit comments