From 72b4e44c43db4c4a9d32250da9aa5f29589854c7 Mon Sep 17 00:00:00 2001 From: maj00r Date: Sun, 4 Oct 2026 18:08:14 +0200 Subject: [PATCH] Hand the driver over when a locomotive is moved to the head The locomotive put first takes the driver, in cab A; the one it pushed behind is left unstaffed. Stepping a card left or right is now an ordinary move, so it also recouples the train and frees the coupler at its back. --- StarterNG.Tests/ConsistCrewTests.cs | 36 +++++++++++++++++++++++++++++ StarterNG/Domain/Consist.cs | 31 ++++++++++++++++++------- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/StarterNG.Tests/ConsistCrewTests.cs b/StarterNG.Tests/ConsistCrewTests.cs index c694884..839086b 100644 --- a/StarterNG.Tests/ConsistCrewTests.cs +++ b/StarterNG.Tests/ConsistCrewTests.cs @@ -87,6 +87,42 @@ public class ConsistCrewTests Assert.Equal(eDriverType.Nobody, second.Cars[0].DriverType); } + [Fact] + public void A_locomotive_moved_to_the_head_takes_the_driver_from_the_one_it_put_behind() + { + var first = Add("ep07-001", 0); + var second = Add("ep07-002", 1); + + _consist.Move(1, 0); + + Assert.Equal(eDriverType.Headdriver, second.Cars[0].DriverType); + Assert.Equal(eDriverType.Nobody, first.Cars[0].DriverType); + Assert.Equal(eDriverType.Nobody, first.Driver); + } + + [Fact] + public void Stepping_a_locomotive_left_onto_the_head_hands_over_the_same_way() + { + var first = Add("ep07-001", 0); + var second = Add("ep07-002", 1); + + _consist.MoveLeft(second); + + Assert.Equal(eDriverType.Headdriver, second.Cars[0].DriverType); + Assert.Equal(eDriverType.Nobody, first.Cars[0].DriverType); + } + + [Fact] + public void A_wagon_moved_to_the_head_leaves_the_driver_where_he_is() + { + var loco = Add("ep07-001", 0); + Add("b111-01", 1); + + _consist.Move(1, 0); + + Assert.Equal(eDriverType.Headdriver, loco.Cars[0].DriverType); + } + private ConsistItem Add(string skin, int at) { var item = Item(skin); diff --git a/StarterNG/Domain/Consist.cs b/StarterNG/Domain/Consist.cs index 24af9c5..a52f148 100644 --- a/StarterNG/Domain/Consist.cs +++ b/StarterNG/Domain/Consist.cs @@ -289,36 +289,51 @@ public sealed class Consist : IReadOnlyList { int i = _items.IndexOf(item); if (i > 0) - { - (_items[i - 1], _items[i]) = (_items[i], _items[i - 1]); - Raise(); - } + Move(i, i - 1); } public void MoveRight(ConsistItem item) { int i = _items.IndexOf(item); if (i >= 0 && i < _items.Count - 1) - { - (_items[i + 1], _items[i]) = (_items[i], _items[i + 1]); - Raise(); - } + Move(i, i + 1); } public void Move(int from, int to) { if (from < 0 || from >= _items.Count) return; + var previousHead = _items[0]; var item = _items[from]; _items.RemoveAt(from); to = Math.Clamp(to, 0, _items.Count); _items.Insert(to, item); + HandOverLead(previousHead); Selected = item; AutoConnectAll(); Raise(); } + /// + /// A locomotive that comes to the head of the train takes over the driver of + /// the one it put behind, which is left unstaffed: the train is driven from its + /// front, from cab A. + /// + private void HandOverLead(ConsistItem previousHead) + { + var head = _items[0]; + if (ReferenceEquals(head, previousHead) || !IsPowered(head) || + previousHead.Driver is not (eDriverType.Headdriver or eDriverType.Reardriver)) + return; + + previousHead.Driver = eDriverType.Nobody; + foreach (var car in previousHead.Cars) + car.DriverType = eDriverType.Nobody; + + Crew(head, eDriverType.Headdriver); + } + public void Remove(ConsistItem item) { int gap = _items.IndexOf(item);