Restore the three-state consist override in settings

Keeps the old starter's starter.batterydefault key and its three states. The
setting wins over the depot checkbox, which greys out and says so while an
override is in force.
This commit is contained in:
maj00r
2026-09-04 23:24:45 +02:00
parent cef00c4e3c
commit c0cc696dc9
12 changed files with 104 additions and 3 deletions

View File

@@ -82,6 +82,32 @@ public class SettingsStoreTests
Assert.Contains("lang zh", installation.Files.ReadAllText(UserIni));
}
[Fact]
public void The_consist_state_override_keeps_the_key_the_old_starter_used()
{
var installation = WithHome(new InMemoryFileSystem()
.WithFile(UserIni, "starter.batterydefault 2\n"));
installation.SettingsStore.Load();
Assert.Equal(ConsistReadyOverride.AlwaysReady, installation.SettingsStore.Settings.ReadyOverride);
installation.SettingsStore.Settings.ReadyOverride = ConsistReadyOverride.AlwaysCold;
installation.SettingsStore.Save();
Assert.Contains("starter.batterydefault 1", installation.Files.ReadAllText(UserIni));
}
[Fact]
public void An_out_of_range_override_falls_back_to_leaving_the_scenery_alone()
{
var installation = WithHome(new InMemoryFileSystem()
.WithFile(UserIni, "starter.batterydefault 9\n"));
installation.SettingsStore.Load();
Assert.Equal(ConsistReadyOverride.Scenery, installation.SettingsStore.Settings.ReadyOverride);
}
[Fact]
public void A_first_run_falls_back_to_the_ini_shipped_with_the_installation()
{

View File

@@ -79,6 +79,18 @@ public sealed class StartSimulation
if (scenery is null || trainset is null)
return new SimulationStartResult(SimulationStartOutcome.NothingSelected);
// The depot checkbox is the consist's own state; this setting is a blanket
// override for people who always want the same thing, and it wins.
switch (_settings.Settings.ReadyOverride)
{
case ConsistReadyOverride.AlwaysCold:
trainset.ReadyToGo = false;
break;
case ConsistReadyOverride.AlwaysReady:
trainset.ReadyToGo = true;
break;
}
string? vehicle = TrainsetDisplay.UniquifyForLaunch(trainset, scenery, _state.StartingVehicleName)
?? StartableVehicle(trainset, _state.StartingVehicleName);
_state.StartingVehicleName = vehicle;

View File

@@ -2,6 +2,9 @@ using System;
namespace StarterNG.Domain.Settings;
// Values match the key eu07.ini has carried since the old starter.
public enum ConsistReadyOverride { Scenery = 0, AlwaysCold = 1, AlwaysReady = 2 }
public enum ExeProblem { None, NotFound, NotExecutable, WrongPlatform }
public sealed class SimulatorSettings
@@ -106,6 +109,8 @@ public sealed class SimulatorSettings
public bool LargeThumbnails;
public bool AutoExpandSceneryTree;
public ConsistReadyOverride ReadyOverride = ConsistReadyOverride.Scenery;
public bool ShowAiVehicles = true;
public bool DrivableOnly = true;
public bool ShowArchivalSceneries = true;

View File

@@ -136,6 +136,14 @@ public sealed class SettingsSerializer
s.AutoCloseStarter = c.GetBool("starter.autoclose", false);
s.LargeThumbnails = c.GetBool("starter.largethumbnails", false);
s.AutoExpandSceneryTree = c.GetBool("starter.expandtree", false);
// An unrecognised value means "do not interfere" rather than the nearest
// state: clamping upwards would silently force every consist ready.
s.ReadyOverride = c.GetInt("starter.batterydefault", 0) switch
{
1 => ConsistReadyOverride.AlwaysCold,
2 => ConsistReadyOverride.AlwaysReady,
_ => ConsistReadyOverride.Scenery
};
s.ShowAiVehicles = c.GetBool("starter.show.ai", true);
s.DrivableOnly = c.GetBool("starter.drivableonly", true);
s.ShowArchivalSceneries = c.GetBool("starter.show.archival", true);
@@ -264,6 +272,7 @@ public sealed class SettingsSerializer
c.SetBool("starter.autoclose", s.AutoCloseStarter);
c.SetBool("starter.largethumbnails", s.LargeThumbnails);
c.SetBool("starter.expandtree", s.AutoExpandSceneryTree);
c.SetInt("starter.batterydefault", (int)s.ReadyOverride);
c.SetBool("starter.show.ai", s.ShowAiVehicles);
c.SetBool("starter.drivableonly", s.DrivableOnly);
c.SetBool("starter.show.archival", s.ShowArchivalSceneries);

View File

@@ -12,6 +12,7 @@ using Avalonia.Media;
using StarterNG.Classes;
using StarterNG.Controls;
using StarterNG.Domain;
using StarterNG.Domain.Settings;
using StarterNG.Domain.Vehicles;
using StarterNG.Application;
@@ -579,14 +580,21 @@ public sealed class VehicleDetails
private Control ReadyToGoRow()
{
var trainset = _consist.EditingTrainset;
var over = AppServices.Current.Settings.ReadyOverride;
bool overridden = over != ConsistReadyOverride.Scenery;
var ready = new CheckBox
{
Content = App.Loc["ConsistReady"],
FontSize = 12,
IsEnabled = trainset is not null,
IsChecked = trainset?.ReadyToGo ?? false
IsEnabled = trainset is not null && !overridden,
IsChecked = overridden
? over == ConsistReadyOverride.AlwaysReady
: trainset?.ReadyToGo ?? false
};
ToolTip.SetTip(ready, App.Loc["ConsistReadyDesc"]);
ToolTip.SetTip(ready, overridden
? App.Loc["ConsistReadyOverridden"]
: App.Loc["ConsistReadyDesc"]);
ready.IsCheckedChanged += (_, _) =>
{

View File

@@ -118,6 +118,15 @@
<ctl:SettingRow ConfigKey="starter.expandtree">
<CheckBox x:Name="AutoExpandTreeCb" Content="{Binding [AutoExpandSceneryTree], Source={x:Static starterNg:App.Loc}}" />
</ctl:SettingRow>
<ctl:SettingRow ConfigKey="starter.batterydefault"
Label="{Binding [ReadyOverride], Source={x:Static starterNg:App.Loc}}"
Description="{Binding [ReadyOverrideDesc], Source={x:Static starterNg:App.Loc}}">
<ComboBox x:Name="ReadyOverrideCb" SelectedIndex="0">
<ComboBoxItem Content="{Binding [ReadyOverrideScenery], Source={x:Static starterNg:App.Loc}}" />
<ComboBoxItem Content="{Binding [ReadyOverrideCold], Source={x:Static starterNg:App.Loc}}" />
<ComboBoxItem Content="{Binding [ReadyOverrideReady], Source={x:Static starterNg:App.Loc}}" />
</ComboBox>
</ctl:SettingRow>
</StackPanel>
</ctl:SettingsSection>

View File

@@ -260,6 +260,7 @@ public partial class Settings : UserControl, ISettingsCapture
AutoCloseStarterCb.IsChecked = s.AutoCloseStarter;
LargeThumbnailsCb.IsChecked = s.LargeThumbnails;
AutoExpandTreeCb.IsChecked = s.AutoExpandSceneryTree;
ReadyOverrideCb.SelectedIndex = (int)s.ReadyOverride;
}
finally
{
@@ -357,6 +358,7 @@ public partial class Settings : UserControl, ISettingsCapture
s.AutoCloseStarter = IsChecked(AutoCloseStarterCb);
s.LargeThumbnails = IsChecked(LargeThumbnailsCb);
s.AutoExpandSceneryTree = IsChecked(AutoExpandTreeCb);
s.ReadyOverride = (ConsistReadyOverride)Math.Clamp(ReadyOverrideCb.SelectedIndex, 0, 2);
}
private void ComButton_OnClick(object? sender, RoutedEventArgs e)

View File

@@ -216,6 +216,12 @@
<String key="ConsistLoadTools">Náklad celé soupravy</String>
<String key="ConsistReady">Consist ready to go</String>
<String key="ConsistReadyDesc">The consist starts prepared: brake pipe charged, driver’s brake valve set, batteries closed. Unchecked it starts cold and braked.</String>
<String key="ReadyOverride">Force the consist state on launch</String>
<String key="ReadyOverrideDesc">Overrides the depot’s "consist ready to go" box for every scenario you start.</String>
<String key="ReadyOverrideScenery">As authored</String>
<String key="ReadyOverrideCold">Always cold</String>
<String key="ReadyOverrideReady">Always ready</String>
<String key="ConsistReadyOverridden">Overridden by "Force the consist state on launch" in Settings.</String>
<String key="ConsistRandomType">Náhodný druh</String>
<String key="ConsistMaxAmount">Maximální množství</String>
<String key="ConsistRandomAmount">Náhodné množství</String>

View File

@@ -216,6 +216,12 @@
<String key="ConsistLoadTools">Whole-consist load</String>
<String key="ConsistReady">Consist ready to go</String>
<String key="ConsistReadyDesc">The consist starts prepared: brake pipe charged, driver’s brake valve set, batteries closed. Unchecked it starts cold and braked.</String>
<String key="ReadyOverride">Force the consist state on launch</String>
<String key="ReadyOverrideDesc">Overrides the depot’s "consist ready to go" box for every scenario you start.</String>
<String key="ReadyOverrideScenery">As authored</String>
<String key="ReadyOverrideCold">Always cold</String>
<String key="ReadyOverrideReady">Always ready</String>
<String key="ConsistReadyOverridden">Overridden by "Force the consist state on launch" in Settings.</String>
<String key="ConsistRandomType">Random type</String>
<String key="ConsistMaxAmount">Maximum amount</String>
<String key="ConsistRandomAmount">Random amount</String>

View File

@@ -216,6 +216,12 @@
<String key="ConsistLoadTools">A teljes szerelvény rakománya</String>
<String key="ConsistReady">Consist ready to go</String>
<String key="ConsistReadyDesc">The consist starts prepared: brake pipe charged, driver’s brake valve set, batteries closed. Unchecked it starts cold and braked.</String>
<String key="ReadyOverride">Force the consist state on launch</String>
<String key="ReadyOverrideDesc">Overrides the depot’s "consist ready to go" box for every scenario you start.</String>
<String key="ReadyOverrideScenery">As authored</String>
<String key="ReadyOverrideCold">Always cold</String>
<String key="ReadyOverrideReady">Always ready</String>
<String key="ConsistReadyOverridden">Overridden by "Force the consist state on launch" in Settings.</String>
<String key="ConsistRandomType">Véletlen típus</String>
<String key="ConsistMaxAmount">Legnagyobb mennyiség</String>
<String key="ConsistRandomAmount">Véletlen mennyiség</String>

View File

@@ -216,6 +216,12 @@
<String key="ConsistLoadTools">Ładunki zestawienia</String>
<String key="ConsistReady">Skład gotowy do jazdy</String>
<String key="ConsistReadyDesc">Skład startuje przygotowany: przewód główny napełniony, kran maszynisty ustawiony, akumulatory załączone. Odznaczony startuje zimny i zahamowany.</String>
<String key="ReadyOverride">Wymuś stan składu przy starcie</String>
<String key="ReadyOverrideDesc">Nadpisuje pole „Skład gotowy do jazdy” w zajezdni dla każdego uruchamianego scenariusza.</String>
<String key="ReadyOverrideScenery">Jak w scenerii</String>
<String key="ReadyOverrideCold">Zawsze zimny</String>
<String key="ReadyOverrideReady">Zawsze gotowy</String>
<String key="ConsistReadyOverridden">Nadpisane opcją „Wymuś stan składu przy starcie” w Ustawieniach.</String>
<String key="ConsistRandomType">Losowy rodzaj</String>
<String key="ConsistMaxAmount">Maksymalna ilość</String>
<String key="ConsistRandomAmount">Losowa ilość</String>

View File

@@ -216,6 +216,12 @@
<String key="ConsistLoadTools">Груз всего состава</String>
<String key="ConsistReady">Consist ready to go</String>
<String key="ConsistReadyDesc">The consist starts prepared: brake pipe charged, driver’s brake valve set, batteries closed. Unchecked it starts cold and braked.</String>
<String key="ReadyOverride">Force the consist state on launch</String>
<String key="ReadyOverrideDesc">Overrides the depot’s "consist ready to go" box for every scenario you start.</String>
<String key="ReadyOverrideScenery">As authored</String>
<String key="ReadyOverrideCold">Always cold</String>
<String key="ReadyOverrideReady">Always ready</String>
<String key="ConsistReadyOverridden">Overridden by "Force the consist state on launch" in Settings.</String>
<String key="ConsistRandomType">Случайный тип</String>
<String key="ConsistMaxAmount">Максимальное количество</String>
<String key="ConsistRandomAmount">Случайное количество</String>