mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2026-07-21 01:59:44 +00:00
Feature: Add default road and tram selection (#15585)
- Merged with the existing default rail type selection
This commit is contained in:
+3
-1
@@ -41,6 +41,7 @@
|
||||
#include "timer/timer_game_economy.h"
|
||||
#include "timer/timer_game_tick.h"
|
||||
#include "timer/timer_window.h"
|
||||
#include "road_gui.h"
|
||||
|
||||
#include "widgets/statusbar_widget.h"
|
||||
|
||||
@@ -141,8 +142,9 @@ void SetLocalCompany(CompanyID new_company, bool switching_game)
|
||||
}
|
||||
|
||||
if (switching_company || switching_game) {
|
||||
/* Update the default rail based on most used */
|
||||
/* Update the default rail and road types */
|
||||
SetDefaultRailGui();
|
||||
SetDefaultRoadGui();
|
||||
}
|
||||
|
||||
if (!switching_game) {
|
||||
|
||||
@@ -1805,12 +1805,12 @@ STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Display anticip
|
||||
STR_CONFIG_SETTING_QUICKGOTO :Quick creation of vehicle orders: {STRING2}
|
||||
STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :Pre-select the 'goto cursor' when opening the orders window
|
||||
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :Default rail type (after new game/game load): {STRING2}
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :Rail type to select after starting or loading a game. 'first available' selects the oldest type of tracks, 'last available' selects the newest type of tracks, and 'most used' selects the type which is currently most in use
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_ROAD_TYPE :Default rail, road, and tram type (after new game/game load): {STRING2}
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_ROAD_TYPE_HELPTEXT :Rail, road, and tram type to select after starting or loading a game. 'first available' selects the oldest type of tracks, 'last available' selects the newest type of tracks, and 'most used' selects the type which is currently most in use
|
||||
###length 3
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :First available
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_LAST :Last available
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_MOST_USED :Most used
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_ROAD_TYPE_FIRST :First available
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_ROAD_TYPE_LAST :Last available
|
||||
STR_CONFIG_SETTING_DEFAULT_RAIL_ROAD_TYPE_MOST_USED :Most used
|
||||
|
||||
STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION :Show path reservations for tracks: {STRING2}
|
||||
STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT :Give reserved tracks a different colour to assist in problems with trains refusing to enter path-based blocks
|
||||
|
||||
+4
-4
@@ -1989,8 +1989,8 @@ void SetDefaultRailGui()
|
||||
if (_local_company == COMPANY_SPECTATOR || !Company::IsValidID(_local_company)) return;
|
||||
|
||||
RailType rt;
|
||||
switch (_settings_client.gui.default_rail_type) {
|
||||
case 2: {
|
||||
switch (_settings_client.gui.default_rail_road_type) {
|
||||
case DefaultRailRoadType::MostUsed: {
|
||||
/* Find the most used rail type */
|
||||
std::array<uint, RAILTYPE_END> count{};
|
||||
for (const auto t : Map::Iterate()) {
|
||||
@@ -2006,14 +2006,14 @@ void SetDefaultRailGui()
|
||||
/* No rail, just get the first available one */
|
||||
[[fallthrough]];
|
||||
}
|
||||
case 0: {
|
||||
case DefaultRailRoadType::FirstAvailable: {
|
||||
/* Use first available type */
|
||||
std::vector<RailType>::const_iterator it = std::find_if(_sorted_railtypes.begin(), _sorted_railtypes.end(),
|
||||
[](RailType r) { return HasRailTypeAvail(_local_company, r); });
|
||||
rt = it != _sorted_railtypes.end() ? *it : RAILTYPE_BEGIN;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
case DefaultRailRoadType::LastAvailable: {
|
||||
/* Use last available type */
|
||||
std::vector<RailType>::const_reverse_iterator it = std::find_if(_sorted_railtypes.rbegin(), _sorted_railtypes.rend(),
|
||||
[](RailType r){ return HasRailTypeAvail(_local_company, r); });
|
||||
|
||||
@@ -1927,3 +1927,49 @@ DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts)
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the default road type to use for a given RoadTramType.
|
||||
* @param rtt Whether to find a road or tram type.
|
||||
* @return The default RoadType based on the setting.
|
||||
*/
|
||||
static RoadType GetDefaultRoadType(RoadTramType rtt)
|
||||
{
|
||||
const auto find_available = [rtt]<typename It>(It begin, It end) {
|
||||
const RoadTypes mask = GetMaskForRoadTramType(rtt);
|
||||
auto it = std::find_if(begin, end, [&](RoadType r) {
|
||||
return HasRoadTypeAvail(_local_company, r) && mask.Test(r);
|
||||
});
|
||||
return it != end ? *it : ROADTYPE_BEGIN;
|
||||
};
|
||||
|
||||
switch (_settings_client.gui.default_rail_road_type) {
|
||||
case DefaultRailRoadType::MostUsed: {
|
||||
const Company *c = Company::Get(_local_company);
|
||||
std::array<uint, ROADTYPE_END> count{};
|
||||
for (RoadType rt : GetMaskForRoadTramType(rtt)) {
|
||||
count[rt] = c->infrastructure.road[rt];
|
||||
}
|
||||
auto best = static_cast<RoadType>(std::distance(std::begin(count), std::ranges::max_element(count)));
|
||||
if (c->infrastructure.road[best] > 0) return best;
|
||||
|
||||
/* No tile of this kind has been built yet, fall through to first available. */
|
||||
[[fallthrough]];
|
||||
}
|
||||
case DefaultRailRoadType::FirstAvailable:
|
||||
return find_available(_sorted_roadtypes.begin(), _sorted_roadtypes.end());
|
||||
case DefaultRailRoadType::LastAvailable:
|
||||
return find_available(_sorted_roadtypes.rbegin(), _sorted_roadtypes.rend());
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
/** Set the initial (default) road & tram type to use. */
|
||||
void SetDefaultRoadGui()
|
||||
{
|
||||
if (_local_company == COMPANY_SPECTATOR || !Company::IsValidID(_local_company)) return;
|
||||
|
||||
_last_built_roadtype = GetDefaultRoadType(RoadTramType::Road);
|
||||
_last_built_tramtype = GetDefaultRoadType(RoadTramType::Tram);
|
||||
}
|
||||
|
||||
@@ -21,5 +21,6 @@ struct Window *ShowBuildRoadScenToolbar(RoadType roadtype);
|
||||
void ConnectRoadToStructure(TileIndex tile, DiagDirection direction);
|
||||
DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement = false, bool all_option = false);
|
||||
DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts);
|
||||
void SetDefaultRoadGui();
|
||||
|
||||
#endif /* ROAD_GUI_H */
|
||||
|
||||
@@ -647,7 +647,7 @@ SettingsContainer &GetSettingsTree()
|
||||
{
|
||||
construction->Add(new SettingEntry("gui.link_terraform_toolbar"));
|
||||
construction->Add(new SettingEntry("gui.persistent_buildingtools"));
|
||||
construction->Add(new SettingEntry("gui.default_rail_type"));
|
||||
construction->Add(new SettingEntry("gui.default_rail_road_type"));
|
||||
construction->Add(new SettingEntry("gui.semaphore_build_before"));
|
||||
construction->Add(new SettingEntry("gui.signal_gui_mode"));
|
||||
construction->Add(new SettingEntry("gui.cycle_signal_types"));
|
||||
|
||||
@@ -176,12 +176,35 @@ enum IniFileVersion : uint32_t {
|
||||
IFV_AUTOSAVE_RENAME, ///< 5 PR#11143 Renamed values of autosave to be in minutes.
|
||||
IFV_RIGHT_CLICK_CLOSE, ///< 6 PR#10204 Add alternative right click to close windows setting.
|
||||
IFV_REMOVE_GENERATION_SEED, ///< 7 PR#11927 Remove "generation_seed" from configuration.
|
||||
IFV_DEFAULT_RAIL_ROAD, ///< 8 PR#15585 Update default rail type setting to support road and tram tiles
|
||||
|
||||
IFV_MAX_VERSION, ///< Highest possible ini-file version.
|
||||
};
|
||||
|
||||
const uint16_t INIFILE_VERSION = (IniFileVersion)(IFV_MAX_VERSION - 1); ///< Current ini-file version of OpenTTD.
|
||||
|
||||
/**
|
||||
* Find whether a string was a valid int setting
|
||||
*
|
||||
* @param str the current value of the setting
|
||||
* @param min the min value for the setting
|
||||
* @param max the max value for the setting
|
||||
* @return Either the parsed value, or nullopt if no value found within range.
|
||||
*/
|
||||
std::optional<int32_t> IntSettingDesc::ParseSingleValue(std::string_view str, int32_t min, uint32_t max)
|
||||
{
|
||||
StringConsumer consumer{str};
|
||||
/* The actual settings value might be int32 or uint32. Read as int64 and just cast away the high bits. */
|
||||
auto value = consumer.TryReadIntegerBase<int64_t>(10);
|
||||
/* check if it's an integer */
|
||||
if (!value.has_value()) return std::nullopt;
|
||||
|
||||
if (value < min || value > max) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index value of a ONEofMANY type in a string
|
||||
* @param str the current value of the setting for which a value needs found
|
||||
@@ -1449,6 +1472,11 @@ void LoadFromConfig(bool startup)
|
||||
_settings_client.gui.right_click_wnd_close = old_value.value_or(false) ? RightClickClose::Yes : RightClickClose::No;
|
||||
}
|
||||
|
||||
if (generic_version < IFV_DEFAULT_RAIL_ROAD && IsConversionNeeded(generic_ini, "gui", "default_rail_type", "default_rail_road_type", &old_item)) {
|
||||
auto old_value = IntSettingDesc::ParseSingleValue(*old_item->value, 0, 2);
|
||||
_settings_client.gui.default_rail_road_type = static_cast<DefaultRailRoadType>(old_value.value_or(0));
|
||||
}
|
||||
|
||||
_grfconfig_newgame = GRFLoadConfig(generic_ini, "newgrf", false);
|
||||
_grfconfig_static = GRFLoadConfig(generic_ini, "newgrf-static", true);
|
||||
AILoadConfig(generic_ini, "ai_players");
|
||||
|
||||
@@ -288,6 +288,8 @@ struct IntSettingDesc : SettingDesc {
|
||||
virtual int32_t ParseValue(std::string_view str) const;
|
||||
std::string FormatValue(const void *object) const override;
|
||||
void ParseValue(const IniItem *item, void *object) const override;
|
||||
static std::optional<int32_t> ParseSingleValue(std::string_view str, int32_t min, uint32_t max);
|
||||
|
||||
bool IsSameValue(const IniItem *item, void *object) const override;
|
||||
bool IsDefaultValue(void *object) const override;
|
||||
void ResetToDefault(void *object) const override;
|
||||
|
||||
+8
-1
@@ -202,6 +202,13 @@ enum class OskActivation : uint8_t {
|
||||
Immediately, ///< Focusing click already opens OSK.
|
||||
};
|
||||
|
||||
/** How to select the default rail/road types */
|
||||
enum class DefaultRailRoadType : uint8_t {
|
||||
FirstAvailable, ///< Use the first available to the player
|
||||
LastAvailable, ///< Use the latest available to the player
|
||||
MostUsed, ///< Use the most used by the company controlled by the player
|
||||
};
|
||||
|
||||
/** Settings related to the GUI and other stuff that is not saved in the savegame. */
|
||||
struct GUISettings {
|
||||
bool sg_full_load_any; ///< new full load calculation, any cargo must be full read from pre v93 savegames
|
||||
@@ -226,7 +233,7 @@ struct GUISettings {
|
||||
bool prefer_teamchat; ///< choose the chat message target with \<ENTER\>, true=all clients, false=your team
|
||||
uint8_t advanced_vehicle_list; ///< use the "advanced" vehicle list
|
||||
uint8_t loading_indicators; ///< show loading indicators
|
||||
uint8_t default_rail_type; ///< the default rail type for the rail GUI
|
||||
DefaultRailRoadType default_rail_road_type; ///< the default rail type for the rail/road/tram GUI
|
||||
uint8_t toolbar_pos; ///< position of toolbars, 0=left, 1=center, 2=right
|
||||
uint8_t statusbar_pos; ///< position of statusbar, 0=left, 1=center, 2=right
|
||||
uint8_t window_snap_radius; ///< windows snap at each other if closer than this
|
||||
|
||||
@@ -20,6 +20,7 @@ static void SpriteZoomMinChanged(int32_t new_value);
|
||||
static constexpr std::initializer_list<std::string_view> _osk_activation{"disabled"sv, "double"sv, "single"sv, "immediately"sv};
|
||||
static constexpr std::initializer_list<std::string_view> _savegame_date{"long"sv, "short"sv, "iso"sv};
|
||||
static constexpr std::initializer_list<std::string_view> _right_click_close{"no"sv, "yes"sv, "except sticky"sv};
|
||||
static constexpr std::initializer_list<std::string_view> _default_rail_road_type{"first available"sv, "last available"sv, "most used"sv};
|
||||
|
||||
static const SettingVariant _gui_settings_table[] = {
|
||||
[post-amble]
|
||||
@@ -479,16 +480,17 @@ strval = STR_CONFIG_SETTING_COMPANIES_OFF
|
||||
post_cb = [](auto) { MarkWholeScreenDirty(); }
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDTC_VAR]
|
||||
var = gui.default_rail_type
|
||||
[SDTC_OMANY]
|
||||
var = gui.default_rail_road_type
|
||||
type = SLE_UINT8
|
||||
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown
|
||||
def = 0
|
||||
min = 0
|
||||
max = 2
|
||||
str = STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE
|
||||
strhelp = STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT
|
||||
strval = STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST
|
||||
def = DefaultRailRoadType::FirstAvailable
|
||||
min = DefaultRailRoadType::FirstAvailable
|
||||
max = DefaultRailRoadType::MostUsed
|
||||
full = _default_rail_road_type
|
||||
str = STR_CONFIG_SETTING_DEFAULT_RAIL_ROAD_TYPE
|
||||
strhelp = STR_CONFIG_SETTING_DEFAULT_RAIL_ROAD_TYPE_HELPTEXT
|
||||
strval = STR_CONFIG_SETTING_DEFAULT_RAIL_ROAD_TYPE_FIRST
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDTC_VAR]
|
||||
|
||||
@@ -2618,10 +2618,6 @@ static WindowDesc _toolb_scen_desc(
|
||||
/** Allocate the toolbar. */
|
||||
void AllocateToolbar()
|
||||
{
|
||||
/* Clean old GUI values; railtype is (re)set by rail_gui.cpp */
|
||||
_last_built_roadtype = ROADTYPE_ROAD;
|
||||
_last_built_tramtype = ROADTYPE_TRAM;
|
||||
|
||||
if (_game_mode == GameMode::Editor) {
|
||||
new ScenarioEditorToolbarWindow(_toolb_scen_desc);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user