From a5c8365aa470f6c18981c6e9a87a80380fbc1102 Mon Sep 17 00:00:00 2001 From: mrmbernardi Date: Sat, 2 Sep 2023 12:46:24 +0200 Subject: [PATCH 01/72] Feature: Setting to disallow level crossings with competitors (#10755) --- src/lang/english.txt | 3 +++ src/rail_cmd.cpp | 5 +++++ src/road_cmd.cpp | 5 +++++ src/settings_gui.cpp | 1 + src/settings_type.h | 1 + src/table/settings/world_settings.ini | 7 +++++++ 6 files changed, 22 insertions(+) diff --git a/src/lang/english.txt b/src/lang/english.txt index caec9c7aa6..674eacbc4b 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1426,6 +1426,9 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :None* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduced STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Allow level crossings with roads or rails owned by competitors: {STRING2} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Allow construction of level crossings on roads or rails owned by competitors + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Allow drive-through road stops on roads owned by towns: {STRING2} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Allow construction of drive-through road stops on roads owned by towns STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Allow drive-through road stops on roads owned by competitors: {STRING2} diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 684bdf639e..7c0e52dd1f 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -507,6 +507,11 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType rai /* Level crossings may only be built on these slopes */ if (!HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh)) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); + if (!_settings_game.construction.crossing_with_competitor && _current_company != OWNER_DEITY) { + CommandCost ret = CheckTileOwnership(tile); + if (ret.Failed()) return ret; + } + CommandCost ret = EnsureNoVehicleOnGround(tile); if (ret.Failed()) return ret; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 00394750a9..7bfbce0970 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -737,6 +737,11 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, R return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); } + if (!_settings_game.construction.crossing_with_competitor && company != OWNER_TOWN && company != OWNER_DEITY) { + CommandCost ret = CheckTileOwnership(tile); + if (ret.Failed()) return ret; + } + if (GetRailTileType(tile) != RAIL_TILE_NORMAL) goto do_clear; if (RoadNoLevelCrossing(rt)) { diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 8718f70e24..2f1fedf05d 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1932,6 +1932,7 @@ static SettingsContainer &GetSettingsTree() limitations->Add(new SettingEntry("station.distant_join_stations")); limitations->Add(new SettingEntry("construction.road_stop_on_town_road")); limitations->Add(new SettingEntry("construction.road_stop_on_competitor_road")); + limitations->Add(new SettingEntry("construction.crossing_with_competitor")); limitations->Add(new SettingEntry("vehicle.disable_elrails")); } diff --git a/src/settings_type.h b/src/settings_type.h index d31381bbe2..b345caae11 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -368,6 +368,7 @@ struct ConstructionSettings { bool extra_dynamite; ///< extra dynamite bool road_stop_on_town_road; ///< allow building of drive-through road stops on town owned roads bool road_stop_on_competitor_road; ///< allow building of drive-through road stops on roads owned by competitors + bool crossing_with_competitor; ///< allow building of level crossings with competitor roads or rails uint8_t raw_industry_construction; ///< type of (raw) industry construction (none, "normal", prospecting) uint8_t industry_platform; ///< the amount of flat land around an industry bool freeform_edges; ///< allow terraforming the tiles at the map edges diff --git a/src/table/settings/world_settings.ini b/src/table/settings/world_settings.ini index 490221dc0a..ba698ba756 100644 --- a/src/table/settings/world_settings.ini +++ b/src/table/settings/world_settings.ini @@ -523,6 +523,13 @@ str = STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD strhelp = STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT cat = SC_BASIC +[SDT_BOOL] +var = construction.crossing_with_competitor +def = true +str = STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR +strhelp = STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT +cat = SC_BASIC + [SDT_VAR] var = construction.raw_industry_construction type = SLE_UINT8 From 1c5699121373e99f657e630560167c34f1809d89 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 16 Jul 2023 21:34:42 +0200 Subject: [PATCH 02/72] Add: [Script] Game script control of industry production level. --- src/command_type.h | 1 + src/industry.h | 4 +- src/industry_cmd.cpp | 62 +++++++++++++++++++++++++++++- src/industry_cmd.h | 2 + src/script/api/game_changelog.hpp | 2 + src/script/api/script_industry.cpp | 16 ++++++++ src/script/api/script_industry.hpp | 25 ++++++++++++ 7 files changed, 110 insertions(+), 2 deletions(-) diff --git a/src/command_type.h b/src/command_type.h index 828d64a074..6ec5748c12 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -246,6 +246,7 @@ enum Commands : uint16_t { CMD_INDUSTRY_SET_FLAGS, ///< change industry control flags CMD_INDUSTRY_SET_EXCLUSIVITY, ///< change industry exclusive consumer/supplier CMD_INDUSTRY_SET_TEXT, ///< change additional text for the industry + CMD_INDUSTRY_SET_PRODUCTION, ///< change industry production CMD_SET_COMPANY_MANAGER_FACE, ///< set the manager's face of the company CMD_SET_COMPANY_COLOUR, ///< set the colour of the company diff --git a/src/industry.h b/src/industry.h index 7842e8c0c4..b3783ef3bf 100644 --- a/src/industry.h +++ b/src/industry.h @@ -51,8 +51,10 @@ enum IndustryControlFlags : byte { * Industry can not close regardless of production level or time since last delivery. * This does not prevent a closure already announced. */ INDCTL_NO_CLOSURE = 1 << 2, + /** Indicates that the production level of the industry is externally controlled. */ + INDCTL_EXTERNAL_PROD_LEVEL = 1 << 3, /** Mask of all flags set */ - INDCTL_MASK = INDCTL_NO_PRODUCTION_DECREASE | INDCTL_NO_PRODUCTION_INCREASE | INDCTL_NO_CLOSURE, + INDCTL_MASK = INDCTL_NO_PRODUCTION_DECREASE | INDCTL_NO_PRODUCTION_INCREASE | INDCTL_NO_CLOSURE | INDCTL_EXTERNAL_PROD_LEVEL, }; DECLARE_ENUM_AS_BIT_SET(IndustryControlFlags); diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 8c0ef4773e..3dfa7405f3 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -68,6 +68,8 @@ IndustrySpec _industry_specs[NUM_INDUSTRYTYPES]; IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES]; IndustryBuildData _industry_builder; ///< In-game manager of industries. +static int WhoCanServiceIndustry(Industry *ind); + /** * This function initialize the spec arrays of both * industry and industry tiles. @@ -2115,6 +2117,59 @@ CommandCost CmdIndustrySetFlags(DoCommandFlag flags, IndustryID ind_id, Industry return CommandCost(); } +/** + * Set industry production. + * @param flags Type of operation. + * @param ind_id IndustryID + * @param prod_level Production level. + * @param show_news Show a news message on production change. + * @return Empty cost or an error. + */ +CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byte prod_level, bool show_news) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; + if (prod_level < PRODLEVEL_MINIMUM || prod_level > PRODLEVEL_MAXIMUM) return CMD_ERROR; + + Industry *ind = Industry::GetIfValid(ind_id); + if (ind == nullptr) return CMD_ERROR; + + if (flags & DC_EXEC) { + StringID str = STR_NULL; + if (prod_level > ind->prod_level) { + str = GetIndustrySpec(ind->type)->production_up_text; + } else if (prod_level < ind->prod_level) { + str = GetIndustrySpec(ind->type)->production_down_text; + } + + ind->ctlflags |= INDCTL_EXTERNAL_PROD_LEVEL; + ind->prod_level = prod_level; + ind->RecomputeProductionMultipliers(); + + /* Show news message if requested. */ + if (show_news && str != STR_NULL) { + NewsType nt; + switch (WhoCanServiceIndustry(ind)) { + case 0: nt = NT_INDUSTRY_NOBODY; break; + case 1: nt = NT_INDUSTRY_OTHER; break; + case 2: nt = NT_INDUSTRY_COMPANY; break; + default: NOT_REACHED(); + } + + /* Set parameters of news string */ + if (str > STR_LAST_STRINGID) { + SetDParam(0, STR_TOWN_NAME); + SetDParam(1, ind->town->index); + SetDParam(2, GetIndustrySpec(ind->type)->name); + } else { + SetDParam(0, ind->index); + } + AddIndustryNewsItem(str, nt, ind->index); + } + } + + return CommandCost(); +} + /** * Change exclusive consumer or supplier for the industry. * @param flags Type of operation. @@ -2618,7 +2673,7 @@ static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accept * service the industry, and 1 otherwise (only competitors can service the * industry) */ -static int WhoCanServiceIndustry(Industry *ind) +int WhoCanServiceIndustry(Industry *ind) { if (ind->stations_near.size() == 0) return 0; // No stations found at all => nobody services @@ -2820,6 +2875,11 @@ static void ChangeIndustryProduction(Industry *i, bool monthly) /* If override flags are set, prevent actually changing production if any was decided on */ if ((i->ctlflags & INDCTL_NO_PRODUCTION_DECREASE) && (div > 0 || increment < 0)) return; if ((i->ctlflags & INDCTL_NO_PRODUCTION_INCREASE) && (mul > 0 || increment > 0)) return; + if (i->ctlflags & INDCTL_EXTERNAL_PROD_LEVEL) { + div = 0; + mul = 0; + increment = 0; + } if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) { if (TimerGameCalendar::year - i->last_prod_year >= PROCESSING_INDUSTRY_ABANDONMENT_YEARS && Chance16(1, original_economy ? 2 : 180)) { diff --git a/src/industry_cmd.h b/src/industry_cmd.h index d58b09678a..eed708b2bd 100644 --- a/src/industry_cmd.h +++ b/src/industry_cmd.h @@ -20,11 +20,13 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i CommandCost CmdIndustrySetFlags(DoCommandFlag flags, IndustryID ind_id, IndustryControlFlags ctlflags); CommandCost CmdIndustrySetExclusivity(DoCommandFlag flags, IndustryID ind_id, Owner company_id, bool consumer); CommandCost CmdIndustrySetText(DoCommandFlag flags, IndustryID ind_id, const std::string &text); +CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byte prod_level, bool show_news); DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_INDUSTRY_SET_FLAGS, CmdIndustrySetFlags, CMD_DEITY, CMDT_OTHER_MANAGEMENT) DEF_CMD_TRAIT(CMD_INDUSTRY_SET_EXCLUSIVITY, CmdIndustrySetExclusivity, CMD_DEITY, CMDT_OTHER_MANAGEMENT) DEF_CMD_TRAIT(CMD_INDUSTRY_SET_TEXT, CmdIndustrySetText, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_INDUSTRY_SET_PRODUCTION, CmdIndustrySetProduction, CMD_DEITY, CMDT_OTHER_MANAGEMENT) void CcBuildIndustry(Commands cmd, const CommandCost &result, TileIndex tile, IndustryType indtype, uint32_t, bool, uint32_t); diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index fdd9d4ec8c..d6267c7aab 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -78,6 +78,8 @@ * \li GSVehicleList_DefaultGroup * \li GSGoal::IsValidGoalDestination * \li GSGoal::SetDestination + * \li GSIndustry::GetProductionLevel + * \li GSIndustry::SetProductionLevel * * API removals: * \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore. diff --git a/src/script/api/script_industry.cpp b/src/script/api/script_industry.cpp index b332accc02..a39d3328d1 100644 --- a/src/script/api/script_industry.cpp +++ b/src/script/api/script_industry.cpp @@ -294,3 +294,19 @@ ::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company); return ScriptObject::Command::Do(industry_id, owner, true); } + +/* static */ SQInteger ScriptIndustry::GetProductionLevel(IndustryID industry_id) +{ + Industry *i = Industry::GetIfValid(industry_id); + if (i == nullptr) return 0; + return i->prod_level; +} + +/* static */ bool ScriptIndustry::SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news) +{ + EnforceDeityMode(false); + EnforcePrecondition(false, IsValidIndustry(industry_id)); + EnforcePrecondition(false, prod_level >= PRODLEVEL_MINIMUM && prod_level <= PRODLEVEL_MAXIMUM); + + return ScriptObject::Command::Do(industry_id, prod_level, show_news); +} diff --git a/src/script/api/script_industry.hpp b/src/script/api/script_industry.hpp index 8edd76fa93..531c978f8f 100644 --- a/src/script/api/script_industry.hpp +++ b/src/script/api/script_industry.hpp @@ -47,6 +47,10 @@ public: * This does not prevent a closure already announced. */ INDCTL_NO_CLOSURE = ::INDCTL_NO_CLOSURE, + /** + * Indicates that the production level of the industry is controlled by a game script. + */ + INDCTL_EXTERNAL_PROD_LEVEL = ::INDCTL_EXTERNAL_PROD_LEVEL, }; /** @@ -323,6 +327,27 @@ public: */ static bool SetExclusiveConsumer(IndustryID industry_id, ScriptCompany::CompanyID company_id); + /** + * Gets the current production level of an industry. + * @param industry_id The index of the industry. + * @api -ai + */ + static SQInteger GetProductionLevel(IndustryID industry_id); + + /** + * Sets the current production level of an industry. + * @note Setting the production level automatically sets the control flag INDCTL_EXTERNAL_PROD_LEVEL if it wasn't already set. + * Normal production behaviour can be restored by clearing the control flag. + * @param industry_id The index of the industry. + * @param prod_level The production level to set. + * @param show_news If set to true and the production changed, generate a production change news message. If set to false, no news message is shown. + * @pre IsValidIndustry(industry_id). + * @pre ScriptCompanyMode::IsDeity(). + * @pre prod_level >= 4 && prod_level <= 128. + * @return True if the action succeeded. + * @api -ai + */ + static bool SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news); }; #endif /* SCRIPT_INDUSTRY_HPP */ From 0089323542bc60d3b3f7b1f627a3d6c0f886d103 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 6 Aug 2023 16:05:04 +0200 Subject: [PATCH 03/72] Add: [Script] Custom news message text for industry SetProductionLevel. --- src/industry_cmd.cpp | 12 +++++++++--- src/industry_cmd.h | 2 +- src/news_func.h | 4 ++-- src/script/api/script_industry.cpp | 6 ++++-- src/script/api/script_industry.hpp | 3 ++- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 3dfa7405f3..a45b3f581b 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -2123,9 +2123,10 @@ CommandCost CmdIndustrySetFlags(DoCommandFlag flags, IndustryID ind_id, Industry * @param ind_id IndustryID * @param prod_level Production level. * @param show_news Show a news message on production change. + * @param custom_news Custom news message text. * @return Empty cost or an error. */ -CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byte prod_level, bool show_news) +CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byte prod_level, bool show_news, const std::string &custom_news) { if (_current_company != OWNER_DEITY) return CMD_ERROR; if (prod_level < PRODLEVEL_MINIMUM || prod_level > PRODLEVEL_MAXIMUM) return CMD_ERROR; @@ -2140,6 +2141,7 @@ CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byt } else if (prod_level < ind->prod_level) { str = GetIndustrySpec(ind->type)->production_down_text; } + if (prod_level != ind->prod_level && !custom_news.empty()) str = STR_NEWS_CUSTOM_ITEM; ind->ctlflags |= INDCTL_EXTERNAL_PROD_LEVEL; ind->prod_level = prod_level; @@ -2156,14 +2158,18 @@ CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byt } /* Set parameters of news string */ - if (str > STR_LAST_STRINGID) { + NewsAllocatedData *data = nullptr; + if (str == STR_NEWS_CUSTOM_ITEM) { + NewsStringData *news = new NewsStringData(custom_news); + SetDParamStr(0, news->string); + } else if (str > STR_LAST_STRINGID) { SetDParam(0, STR_TOWN_NAME); SetDParam(1, ind->town->index); SetDParam(2, GetIndustrySpec(ind->type)->name); } else { SetDParam(0, ind->index); } - AddIndustryNewsItem(str, nt, ind->index); + AddIndustryNewsItem(str, nt, ind->index, data); } } diff --git a/src/industry_cmd.h b/src/industry_cmd.h index eed708b2bd..955ca68628 100644 --- a/src/industry_cmd.h +++ b/src/industry_cmd.h @@ -20,7 +20,7 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i CommandCost CmdIndustrySetFlags(DoCommandFlag flags, IndustryID ind_id, IndustryControlFlags ctlflags); CommandCost CmdIndustrySetExclusivity(DoCommandFlag flags, IndustryID ind_id, Owner company_id, bool consumer); CommandCost CmdIndustrySetText(DoCommandFlag flags, IndustryID ind_id, const std::string &text); -CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byte prod_level, bool show_news); +CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byte prod_level, bool show_news, const std::string &text); DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_INDUSTRY_SET_FLAGS, CmdIndustrySetFlags, CMD_DEITY, CMDT_OTHER_MANAGEMENT) diff --git a/src/news_func.h b/src/news_func.h index 466f4befec..941e6b54c9 100644 --- a/src/news_func.h +++ b/src/news_func.h @@ -47,9 +47,9 @@ static inline void AddTileNewsItem(StringID string, NewsType type, TileIndex til AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_TILE, static_cast(tile), station == INVALID_STATION ? NR_NONE : NR_STATION, station, data); } -static inline void AddIndustryNewsItem(StringID string, NewsType type, IndustryID industry) +static inline void AddIndustryNewsItem(StringID string, NewsType type, IndustryID industry, const NewsAllocatedData *data = nullptr) { - AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_INDUSTRY, industry); + AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_INDUSTRY, industry, NR_NONE, UINT32_MAX, data); } void NewsLoop(); diff --git a/src/script/api/script_industry.cpp b/src/script/api/script_industry.cpp index a39d3328d1..3196e9c698 100644 --- a/src/script/api/script_industry.cpp +++ b/src/script/api/script_industry.cpp @@ -302,11 +302,13 @@ return i->prod_level; } -/* static */ bool ScriptIndustry::SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news) +/* static */ bool ScriptIndustry::SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news, Text *custom_news) { + CCountedPtr counter(custom_news); + EnforceDeityMode(false); EnforcePrecondition(false, IsValidIndustry(industry_id)); EnforcePrecondition(false, prod_level >= PRODLEVEL_MINIMUM && prod_level <= PRODLEVEL_MAXIMUM); - return ScriptObject::Command::Do(industry_id, prod_level, show_news); + return ScriptObject::Command::Do(industry_id, prod_level, show_news, custom_news != nullptr ? custom_news->GetEncodedText() : std::string{}); } diff --git a/src/script/api/script_industry.hpp b/src/script/api/script_industry.hpp index 531c978f8f..bedb3504d1 100644 --- a/src/script/api/script_industry.hpp +++ b/src/script/api/script_industry.hpp @@ -341,13 +341,14 @@ public: * @param industry_id The index of the industry. * @param prod_level The production level to set. * @param show_news If set to true and the production changed, generate a production change news message. If set to false, no news message is shown. + * @param custom_news Custom news message text to override the default news text with. Pass null to use the default text. Only used if \c show_news is set to true. * @pre IsValidIndustry(industry_id). * @pre ScriptCompanyMode::IsDeity(). * @pre prod_level >= 4 && prod_level <= 128. * @return True if the action succeeded. * @api -ai */ - static bool SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news); + static bool SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news, Text *custom_news); }; #endif /* SCRIPT_INDUSTRY_HPP */ From 7e544180222d6c19441c3b4c7ef3bfe821e671b7 Mon Sep 17 00:00:00 2001 From: Bouke Haarsma Date: Sat, 2 Sep 2023 19:46:52 +0200 Subject: [PATCH 04/72] Codechange: workaround CMake/Xcode duplicate file name issue (#11186) Having a library with files with the same name isn't supported in CMake's Xcode project file generation: https://gitlab.kitware.com/cmake/cmake/-/issues/20501. One of the files is renamed to work around this bug. --- src/console_cmds.cpp | 2 +- src/network/core/CMakeLists.txt | 4 ++-- src/network/core/{game_info.cpp => network_game_info.cpp} | 2 +- src/network/core/{game_info.h => network_game_info.h} | 0 src/network/core/tcp_coordinator.h | 2 +- src/network/core/tcp_turn.h | 2 +- src/network/core/udp.cpp | 2 +- src/network/network_admin.cpp | 2 +- src/network/network_gamelist.h | 2 +- src/network/network_query.cpp | 2 +- src/network/network_server.cpp | 2 +- src/network/network_udp.cpp | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) rename src/network/core/{game_info.cpp => network_game_info.cpp} (99%) rename src/network/core/{game_info.h => network_game_info.h} (100%) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 702a774ba9..b3e3607bce 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -13,7 +13,7 @@ #include "engine_func.h" #include "landscape.h" #include "saveload/saveload.h" -#include "network/core/game_info.h" +#include "network/core/network_game_info.h" #include "network/network.h" #include "network/network_func.h" #include "network/network_base.h" diff --git a/src/network/core/CMakeLists.txt b/src/network/core/CMakeLists.txt index 9e7a2ed506..b547b6fa95 100644 --- a/src/network/core/CMakeLists.txt +++ b/src/network/core/CMakeLists.txt @@ -5,8 +5,8 @@ add_files( config.h core.cpp core.h - game_info.cpp - game_info.h + network_game_info.cpp + network_game_info.h host.cpp host.h http.h diff --git a/src/network/core/game_info.cpp b/src/network/core/network_game_info.cpp similarity index 99% rename from src/network/core/game_info.cpp rename to src/network/core/network_game_info.cpp index fd95fe1dfb..0993e1ad15 100644 --- a/src/network/core/game_info.cpp +++ b/src/network/core/network_game_info.cpp @@ -10,7 +10,7 @@ */ #include "../../stdafx.h" -#include "game_info.h" +#include "network_game_info.h" #include "../../core/bitmath_func.hpp" #include "../../company_base.h" #include "../../timer/timer_game_calendar.h" diff --git a/src/network/core/game_info.h b/src/network/core/network_game_info.h similarity index 100% rename from src/network/core/game_info.h rename to src/network/core/network_game_info.h diff --git a/src/network/core/tcp_coordinator.h b/src/network/core/tcp_coordinator.h index 545cdb281d..6e6b98f5c1 100644 --- a/src/network/core/tcp_coordinator.h +++ b/src/network/core/tcp_coordinator.h @@ -15,7 +15,7 @@ #include "os_abstraction.h" #include "tcp.h" #include "packet.h" -#include "game_info.h" +#include "network_game_info.h" /** * Enum with all types of TCP Game Coordinator packets. The order MUST not be changed. diff --git a/src/network/core/tcp_turn.h b/src/network/core/tcp_turn.h index b35d26ad7b..b54a857982 100644 --- a/src/network/core/tcp_turn.h +++ b/src/network/core/tcp_turn.h @@ -15,7 +15,7 @@ #include "os_abstraction.h" #include "tcp.h" #include "packet.h" -#include "game_info.h" +#include "network_game_info.h" /** Enum with all types of TCP TURN packets. The order MUST not be changed. **/ enum PacketTurnType { diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index 9f4a09e67c..4c226f0115 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -12,7 +12,7 @@ #include "../../stdafx.h" #include "../../timer/timer_game_calendar.h" #include "../../debug.h" -#include "game_info.h" +#include "network_game_info.h" #include "udp.h" #include "../../safeguards.h" diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 2ad53d972e..ae42156d29 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -11,7 +11,7 @@ #include "../strings_func.h" #include "../timer/timer_game_calendar.h" #include "../timer/timer_game_calendar.h" -#include "core/game_info.h" +#include "core/network_game_info.h" #include "network_admin.h" #include "network_base.h" #include "network_server.h" diff --git a/src/network/network_gamelist.h b/src/network/network_gamelist.h index 1c4a68e5c7..cabedd8ff7 100644 --- a/src/network/network_gamelist.h +++ b/src/network/network_gamelist.h @@ -11,7 +11,7 @@ #define NETWORK_GAMELIST_H #include "core/address.h" -#include "core/game_info.h" +#include "core/network_game_info.h" #include "network_type.h" /** The status a server can be in. */ diff --git a/src/network/network_query.cpp b/src/network/network_query.cpp index 139daafe45..441c22e816 100644 --- a/src/network/network_query.cpp +++ b/src/network/network_query.cpp @@ -8,7 +8,7 @@ /** @file network_query.cpp Query part of the network protocol. */ #include "../stdafx.h" -#include "core/game_info.h" +#include "core/network_game_info.h" #include "network_query.h" #include "network_gamelist.h" #include "../error.h" diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 24c6537530..a81fe597c5 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -9,7 +9,7 @@ #include "../stdafx.h" #include "../strings_func.h" -#include "core/game_info.h" +#include "core/network_game_info.h" #include "network_admin.h" #include "network_server.h" #include "network_udp.h" diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 6975d1c767..7e7509fd70 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -16,7 +16,7 @@ #include "../timer/timer_game_calendar.h" #include "../map_func.h" #include "../debug.h" -#include "core/game_info.h" +#include "core/network_game_info.h" #include "network_gamelist.h" #include "network_internal.h" #include "network_udp.h" From c77184aa35937c3309d2aab95a5e099c1d72c7c1 Mon Sep 17 00:00:00 2001 From: glx22 Date: Mon, 14 Aug 2023 19:25:26 +0200 Subject: [PATCH 05/72] Codechange: [CMake] reduce code duplication --- cmake/SourceList.cmake | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/cmake/SourceList.cmake b/cmake/SourceList.cmake index af87c09e82..7be406050e 100644 --- a/cmake/SourceList.cmake +++ b/cmake/SourceList.cmake @@ -1,12 +1,4 @@ -# Add a file to be compiled. -# -# add_files([file1 ...] CONDITION condition [condition ...]) -# -# CONDITION is a complete statement that can be evaluated with if(). -# If it evaluates true, the source files will be added; otherwise not. -# For example: ADD_IF SDL_FOUND AND Allegro_FOUND -# -function(add_files) +function(_add_files_tgt tgt) cmake_parse_arguments(PARAM "" "" "CONDITION" ${ARGN}) set(PARAM_FILES "${PARAM_UNPARSED_ARGUMENTS}") @@ -21,6 +13,18 @@ function(add_files) endforeach() endfunction() +# Add a file to be compiled. +# +# add_files([file1 ...] CONDITION condition [condition ...]) +# +# CONDITION is a complete statement that can be evaluated with if(). +# If it evaluates true, the source files will be added; otherwise not. +# For example: ADD_IF SDL_FOUND AND Allegro_FOUND +# +function(add_files) + _add_files_tgt(openttd_lib ${ARGV}) +endfunction() + # Add a test file to be compiled. # # add_test_files([file1 ...] CONDITION condition [condition ...]) @@ -30,18 +34,7 @@ endfunction() # For example: ADD_IF SDL_FOUND AND Allegro_FOUND # function(add_test_files) - cmake_parse_arguments(PARAM "" "" "CONDITION" ${ARGN}) - set(PARAM_FILES "${PARAM_UNPARSED_ARGUMENTS}") - - if(PARAM_CONDITION) - if(NOT (${PARAM_CONDITION})) - return() - endif() - endif() - - foreach(FILE IN LISTS PARAM_FILES) - target_sources(openttd_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}) - endforeach() + _add_files_tgt(openttd_test ${ARGV}) endfunction() # This function works around an 'issue' with CMake, where From b0f8890ba5da2afb384b793259b8884eefcb37b8 Mon Sep 17 00:00:00 2001 From: glx22 Date: Mon, 14 Aug 2023 19:26:43 +0200 Subject: [PATCH 06/72] Codechange: [CMake] detect source files with duplicate names --- cmake/SourceList.cmake | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmake/SourceList.cmake b/cmake/SourceList.cmake index 7be406050e..f01f5db86b 100644 --- a/cmake/SourceList.cmake +++ b/cmake/SourceList.cmake @@ -9,7 +9,17 @@ function(_add_files_tgt tgt) endif() foreach(FILE IN LISTS PARAM_FILES) - target_sources(openttd_lib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}) + # Some IDEs are not happy with duplicated filenames, so we detect that before adding the file. + get_target_property(${tgt}_FILES ${tgt} SOURCES) + if(${tgt}_FILES MATCHES "/${FILE}(;|$)") + string(REGEX REPLACE "(^|.+;)([^;]+/${FILE})(;.+|$)" "\\2" RES "${${tgt}_FILES}") + # Ignore header files duplicates in 3rdparty. + if(NOT (${FILE} MATCHES "\.h" AND (${RES} MATCHES "3rdparty" OR ${CMAKE_CURRENT_SOURCE_DIR} MATCHES "3rdparty"))) + message(FATAL_ERROR "${tgt}: ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} filename is a duplicate of ${RES}") + endif() + endif() + + target_sources(${tgt} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}) endforeach() endfunction() From 5c2e4ee6feb9d50628dde439fe76d23559fd210a Mon Sep 17 00:00:00 2001 From: translators Date: Sat, 2 Sep 2023 18:38:13 +0000 Subject: [PATCH 07/72] Update: Translations from eints --- src/lang/afrikaans.txt | 1 + src/lang/arabic_egypt.txt | 1 + src/lang/basque.txt | 1 + src/lang/belarusian.txt | 1 + src/lang/brazilian_portuguese.txt | 1 + src/lang/bulgarian.txt | 1 + src/lang/catalan.txt | 1 + src/lang/chuvash.txt | 1 + src/lang/croatian.txt | 1 + src/lang/czech.txt | 1 + src/lang/danish.txt | 1 + src/lang/dutch.txt | 1 + src/lang/english_AU.txt | 1 + src/lang/english_US.txt | 1 + src/lang/esperanto.txt | 1 + src/lang/estonian.txt | 1 + src/lang/faroese.txt | 1 + src/lang/finnish.txt | 1 + src/lang/french.txt | 1 + src/lang/frisian.txt | 1 + src/lang/gaelic.txt | 1 + src/lang/galician.txt | 1 + src/lang/german.txt | 1 + src/lang/greek.txt | 1 + src/lang/hebrew.txt | 1 + src/lang/hindi.txt | 1 + src/lang/hungarian.txt | 1 + src/lang/icelandic.txt | 1 + src/lang/ido.txt | 1 + src/lang/indonesian.txt | 1 + src/lang/irish.txt | 1 + src/lang/italian.txt | 1 + src/lang/japanese.txt | 1 + src/lang/korean.txt | 1 + src/lang/latin.txt | 1 + src/lang/latvian.txt | 1 + src/lang/lithuanian.txt | 1 + src/lang/luxembourgish.txt | 1 + src/lang/macedonian.txt | 1 + src/lang/malay.txt | 1 + src/lang/maltese.txt | 1 + src/lang/marathi.txt | 1 + src/lang/norwegian_bokmal.txt | 1 + src/lang/norwegian_nynorsk.txt | 1 + src/lang/persian.txt | 1 + src/lang/polish.txt | 1 + src/lang/portuguese.txt | 1 + src/lang/romanian.txt | 1 + src/lang/russian.txt | 1 + src/lang/serbian.txt | 1 + src/lang/simplified_chinese.txt | 1 + src/lang/slovak.txt | 1 + src/lang/slovenian.txt | 1 + src/lang/spanish.txt | 1 + src/lang/spanish_MX.txt | 1 + src/lang/swedish.txt | 1 + src/lang/tamil.txt | 1 + src/lang/thai.txt | 1 + src/lang/traditional_chinese.txt | 1 + src/lang/turkish.txt | 1 + src/lang/ukrainian.txt | 1 + src/lang/urdu.txt | 1 + src/lang/vietnamese.txt | 1 + src/lang/welsh.txt | 1 + 64 files changed, 64 insertions(+) diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index 9e8347e53c..74a3a38622 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -1309,6 +1309,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Geen STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Verminderd STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normaal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Laat deur-ry padhalte op dorp besite paaie toe: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Laat Bouery van deur-ry pad stasies op dorp beheerde paaie STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Laat deur-ry padhalte toe op paaie wat deur ander deelnemers besit word: {STRING} diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 6bf4abe1cb..dce0e0c2c9 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -1252,6 +1252,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :بدون STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :منخفض STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :طبيعي + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :السماح للعربات بالعبور خلال المواقف المملوكة داخل المدن: {STRING} STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :السماح بمرور العربات خلال المحطات المملوكة للمنافسين: {STRING} STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :السماح ببناء مواقف السيارات على الطرق المملوكة لشركات أخرى diff --git a/src/lang/basque.txt b/src/lang/basque.txt index a1d2cfd6fc..6ff3b5481f 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -1267,6 +1267,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ezer ez STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Mugatua STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Arrunta + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Herrien errepideetan zehar-pasatzeko geltokiak baimendu: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Herrien menpe dauden errepideetan zehar-pasatzeko geltokiak baimendu STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Arerioen errepideetan zehar-pasatzeko geltokiak baimendu: {STRING} diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 6ba80ca5f0..bfaa588f65 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -1622,6 +1622,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :адсутні STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :зьніжаная STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :звычайная + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Дазволіць будаўніцтва прыпынкаў Ro-Ro на дарогах гарадзкой уласнасьці: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Дазволіць пабудову на дарогах, якія належаць гораду, прыпынкаў, празь якія можна проста праехаць (не заязжаючы "унутар"). STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Дазволіць будаўніцтва прыпынкаў Ro-Ro на дарогах канкурэнтаў: {STRING} diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 7c9df473b4..b51e2755a5 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -1427,6 +1427,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nenhum STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduzido STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permitir estações de passagem nas estradas pertencentes às localidades: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permitir a construção de estações de passagem com paradas nas ruas pertencentes a localidades. STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir estações drive-through nas ruas de outros competidores: {STRING} diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index fd075afa52..2b126154d7 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -1290,6 +1290,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Никакви STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Намалени STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Нормални + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Преминаване през спирки на градски пътища: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Позволява строежа на ЖП линии пресичащи път притежаван от даден град STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Преминаване през спирки на пътища, собственост на конкуренти: {STRING} diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 733dbd40df..8f483ce2c1 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -1427,6 +1427,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Cap* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduït STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permet situar parades en carreteres que són propietat de les poblacions: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permet la construcció de passos a nivell als carrers propietat de les poblacions STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permet circular a través de les parades en carreteres propietat de competidors: {STRING} diff --git a/src/lang/chuvash.txt b/src/lang/chuvash.txt index a6ab0e1511..1ed6f31a21 100644 --- a/src/lang/chuvash.txt +++ b/src/lang/chuvash.txt @@ -648,6 +648,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :ҫук + STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Аэропорт кивел мар: {STRING} diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 79b31977ab..d6fcc985b6 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -1413,6 +1413,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ništa* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Smanjeno STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalno + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Dopusti prolazne postaje na cestama u vlasništvu gradova: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Dopusti izgradnju prolaznih postaja na cestama u vlasništvu grada STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Dopusti prolazne postaje na cestama koje su u vlasništvu konkurencije: {STRING} diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 81e9f02e7d..d92fcde04d 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -1477,6 +1477,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Žádná* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Redukovaný STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Obvyklý + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Stavba průjezdných zastávek na obecních silnicích: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Povoluje stavbu průjezdných stanic na městem vlastněných silnicích STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Stavba průjezdných zastávek na silnicích vlastněných konkurencí: {STRING} diff --git a/src/lang/danish.txt b/src/lang/danish.txt index f2c1c66c5a..41f34ec01d 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -1426,6 +1426,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ingen* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :reduceret STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Tillad gennemkørsels-stop på veje ejet af en by: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Tillad konstruktion af gennemkørsels-stop på by-ejede veje STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Tillad gennemkørsels-stoppesteder på veje ejet af konkurrenter: {STRING} diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index e23d49287b..32965faf2c 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -1426,6 +1426,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Geen* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Verminderd STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normaal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Doorrijhaltes op stedelijke wegen toestaan: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Bouwen van doorrijhaltes op stedelijke wegen toestaan STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Haltes op wegen van tegenstanders toestaan: {STRING} diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 0b8328cef6..d9dbc24c45 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -1426,6 +1426,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :None STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduced STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Allow drive-through road stops on roads owned by towns: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Allow construction of drive-through road stops on roads owned by towns STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Allow drive-through road stops on roads owned by competitors: {STRING} diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index ca1a68438f..1539b620c5 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -1426,6 +1426,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :None* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduced STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Allow drive-through road stops on roads owned by towns: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Allow construction of drive-through road stops on roads owned by towns STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Allow drive-through road stops on roads owned by competitors: {STRING} diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index 29d6dc06b9..5d06a6c9cf 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -1470,6 +1470,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :neniu STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :reduktita STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :normala + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permesu trairajn bushaltejojn sur urboposedataj stratoj: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permesu konstrui trairajn strathaltejojn sur stratoj posedataj de urboj STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permesu trairajn strathaltejojn sur stratoj posedataj de konkurantoj: {STRING} diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index bd31b8ea35..48c2e742eb 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -1436,6 +1436,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ei STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Vähem STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Keskmiselt + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Läbisõidupeatused asulate kuuluvatel teedel: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Lubab asulatele kuuluvatele teedele ehitada läbisõidupeatuseid STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Läbisõidupeatused konkurentide teedel: {STRING} diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 996ae6b458..7f1cb37a26 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -1246,6 +1246,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Einki STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Færri STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Vanligt + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Loyv gjøgnumkoyrings steðgum á vegum ið bygdir eiga: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Loyv bygging av gjøgnumkoyrings steðgum á vegum ið bygdir eiga STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Loyv gjøgnumkoyrings steðgum á vegum ið kappingarneytar eiga: {STRING} diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 28550f6220..e2dbfea75d 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -1426,6 +1426,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ei yhtään¹ STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Vähennetty STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Tavallinen + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Salli läpiajettavat pysäkit kuntien omistamilla teillä: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Sallii läpiajettavien pysäkkien rakentamisen kuntien omistamille teille STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Salli läpiajettavat pysäkit kilpailijoiden omistamilla teillä: {STRING} diff --git a/src/lang/french.txt b/src/lang/french.txt index bf905ef2f1..f8390d63f8 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -1427,6 +1427,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Aucun* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Réduit STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Autoriser les arrêts de bus sur les routes appartenant aux municipalités{NBSP}: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Autoriser la construction des arrêts de bus sur les routes appartenant aux municipalités STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Autoriser les arrêts de bus sur les routes des concurrents{NBSP}: {STRING} diff --git a/src/lang/frisian.txt b/src/lang/frisian.txt index 26489ea1c9..23a2dbb205 100644 --- a/src/lang/frisian.txt +++ b/src/lang/frisian.txt @@ -1308,6 +1308,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Gjin STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Minder STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Gewoan + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Stean it bouwen fan haltes op troch de stêd behearde diken ta: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Stean it bouwen fan haltes op troch de stêd behearde diken ta STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Stean it bouwen fan haltes op troch in tsjinstanner behearde diken ta {STRING} diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index fe7dd8ddd8..8a4ce61d58 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -1491,6 +1491,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Cha tachair seo STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Ainneamh STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Àbhaisteach + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Ceadaich stèiseanan ri taobh an rathaid air rathaidean a bhuineas ri baile: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Ceadaich gun tèid stèiseanan ri taobh an rathaid a thogail air rathaidean a bhuineas ri baile STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Ceadaich stèiseanan ri taobh an rathaid air rathaidean a bhuineas ri co-fharpaisiche: {STRING} diff --git a/src/lang/galician.txt b/src/lang/galician.txt index bf259dd793..8cb1f4f046 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -1408,6 +1408,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ningún* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reducido STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permiti-la construción de estacións pasantes nas rúas de titularidade municipal: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permite a construcción de estacións pasantes sobre as rúas propiedade da cidade STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir estacións pasantes sobre estradas propiedade dos competidores: {STRING} diff --git a/src/lang/german.txt b/src/lang/german.txt index 1b17160338..0e1484fbb4 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -1427,6 +1427,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Keine STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Verringert STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Bus- und Lkw-Haltestellen auf Straßen im Stadteigentum erlauben: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Erlaubt die Errichtung von Bus- und Lkw-Haltestellen auf Straßen im Stadteigentum STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Bus- und Lkw-Haltestellen auf Straßen von Mitbewerbern erlauben: {STRING} diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 9d2593360e..de709130a1 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -1484,6 +1484,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Κανένα* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Μειωμένη STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Κανονική + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Επιτρέπονται οι στάσεις σε δρόμους που είναι ιδιοκτησία των πόλεων : {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Επιτρέπεται η κατασκευή στάσεων πάνω σε δρόμους που είναι ιδιοκτησία των πόλεων STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Επιτρέπονται οι στάσεις σε δρόμους που ανήκουν σε ανταγωνιστές: {STRING} diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index 1d2559b2c8..8cd5aab358 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -1324,6 +1324,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :ללא STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :מופחת STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :רגיל + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :{STRING} :אפשר מעבר דרך תחנות על כבישים בבעלות עירונית STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :אפשר בנייה של תחנות "על הדרך" בכבישים בבעלות עיירות STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :אפשר נסיעה דרך תמרורי-עצירה על דרכים בבעלות מתחרים: {STRING} diff --git a/src/lang/hindi.txt b/src/lang/hindi.txt index ff6ff00782..df829af161 100644 --- a/src/lang/hindi.txt +++ b/src/lang/hindi.txt @@ -417,6 +417,7 @@ STR_CONFIG_SETTING_BRIBE_HELPTEXT :कंपनि + STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT :सक्षम होने पर वाहनों के निर्देशों की आवधिक जाँच की जाती है, और कुछ सुस्पष्ट मामलों का पता चलते ही एक संदेश द्वारा बताया जाता है। ###length 3 STR_CONFIG_SETTING_ORDER_REVIEW_OFF :नहीं diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 5c682de726..267a8153e3 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -1464,6 +1464,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :nincs* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :csökkentett STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :normál + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Áthaladó megállóhelyek engedélyezése települési tulajdonú utakon: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Áthaladó megállóhelyek építésének engedélyezése települési tulajdonú utakon STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Áthaladó megállóhelyek engedélyezése ellenfél tulajdonában lévő utakon: {STRING} diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index 99ccc532a9..c0d096259c 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -1245,6 +1245,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Engin STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :fækkuð STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :miðlungs + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Leyfa stoppistöðvar sem keyrt er í gegnum, á vegum í eigu bæja: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Leyfa byggingu stoppistöðvar sem keyrt er í gegnum, á vegum í eigu bæja STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Leyfa stoppistöðvar sem keyrt er í gegnum, á vegum í eigu samkeppnisaðila: {STRING} diff --git a/src/lang/ido.txt b/src/lang/ido.txt index 298e58717f..387351ef71 100644 --- a/src/lang/ido.txt +++ b/src/lang/ido.txt @@ -624,6 +624,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :normala + ###length 3 diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index ce85731162..532b16603f 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -1404,6 +1404,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nihil STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Dikurangi STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Ijinkan terminal drive-thru pada jalan milik kota: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Membolehkan konstruksi halte di jalan kota STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Ijinkan terminal drive-thru pada jalan milik pesaing: {STRING} diff --git a/src/lang/irish.txt b/src/lang/irish.txt index df23eb316d..3fc19f8ffe 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -1354,6 +1354,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ceann ar bith STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Laghdaithe STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Gnáth + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Ceadaigh stadanna bóthair 'tiomáin tríd' ar bhóithre ar le bailte iad: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Ceadaigh stopann bóthair 'tiomáin tríd' a thógáil ar bhóithre ar le bailte iad STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Ceadaigh stopanna bóthair 'tiomáin tríd' ar bhóithre ar le hiomaitheoirí iad: {STRING} diff --git a/src/lang/italian.txt b/src/lang/italian.txt index a22164fd36..d957744df3 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -1461,6 +1461,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nessuno* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Ridotto STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normale + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Consenti fermate passanti sulle strade di proprietà delle città: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permettere la costruzione di fermate stradali passanti sulle strade di proprietà delle città. STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Consenti fermate passanti sulle strade di proprietà degli avversari: {STRING} diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index 227fae7bed..0f2625d762 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -1399,6 +1399,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :なし STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :軽減 STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :普通 + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :街有道路での路側型バス停/荷役所建設: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :路側型バス停/荷役所を街が所有する道路上に建設できるようにします STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :他社の道路上での路側型バス停/荷役所設置: {STRING} diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 6119ef5f76..761b8ef8d8 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -1427,6 +1427,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :없음* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :적음 STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :보통 + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :도시 소유의 도로 위에 버스 정류장 건설 허용: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :도시 소유의 도로 위에 버스 정류장 건설을 허용합니다. STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :경쟁자 소유의 도로 위에 버스 정류장 건설 허용: {STRING} diff --git a/src/lang/latin.txt b/src/lang/latin.txt index 2098840297..890becc191 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -1484,6 +1484,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Numquam* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Raro STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Mediocriter + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Sinere stationes viarias pervias esse in viis oppidorum: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Sinere struere stationes viarias pervias in viis quas oppida possident STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Sinere stationes viarias pervias esse in viis competitorum: {STRING} diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index c6147b4e24..61bec71e37 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -1382,6 +1382,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nav* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :samazināts STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :parasts + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Atļaut caurbraucamas pieturvietas uz pilsētai piederošiem ceļiem: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Ļauj būvēt caurbraucamas pieturvietas uz pilsētai piederošiem ceļiem STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Atļaut caurbraucamas pieturvietas uz sāncenšu ceļiem: {STRING} diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index e22539d671..cd68b8fc9f 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -1571,6 +1571,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Jokių STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Retesni STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalus + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Leisti pravažiuojamąsias stoteles miesto keliuose: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Leidžia statyti pravažiuojamojo tipo stoteles miestams priklausiančiuose keliuose STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Leisti pravažiuojamąsias stoteles priešininko keliuose: {STRING} diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 0386f7498f..e8087fb62e 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -1380,6 +1380,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Keng* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduzéiert STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Erlaabt d'Iwwerfueren vu Stopschëlder op Stroossen vun der Stad: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Erlaabt d'Bauen vu säitlechen Busarrêten op Stroossen déi der Stad gehéieren STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Erlaabt d'Iwwerfueren vu Stopschëlder op Stroossen vun der Konkurrenz: {STRING} diff --git a/src/lang/macedonian.txt b/src/lang/macedonian.txt index 878123f739..008126b85a 100644 --- a/src/lang/macedonian.txt +++ b/src/lang/macedonian.txt @@ -924,6 +924,7 @@ STR_CONFIG_SETTING_SMOKE_AMOUNT :Износ на ###length 3 + STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Инфраструктура за одржување: {STRING} diff --git a/src/lang/malay.txt b/src/lang/malay.txt index a7df785386..1951977a18 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -1243,6 +1243,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Tiada STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Dikurangkan STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Benarkan hentian pandu-lalu di jalanraya bandar: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Benarkan pembinaan untuk jalan pemanduan berhenti di jalan milik bandaran STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Benarkan hentian pandu-lalu di jalanraya yang dimiliki oleh pesaing: {STRING} diff --git a/src/lang/maltese.txt b/src/lang/maltese.txt index f7e98114d0..95a892cb1f 100644 --- a/src/lang/maltese.txt +++ b/src/lang/maltese.txt @@ -552,6 +552,7 @@ STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Iddeċiedi kemm + STR_CONFIG_SETTING_WARN_LOST_VEHICLE :Avza jekk jintilef il-vehikolu: {STRING} ###length 3 diff --git a/src/lang/marathi.txt b/src/lang/marathi.txt index 47be4d8a24..9488ed01cc 100644 --- a/src/lang/marathi.txt +++ b/src/lang/marathi.txt @@ -862,6 +862,7 @@ STR_CONFIG_SETTING_SMOKE_AMOUNT :वाहना + STR_CONFIG_SETTING_WARN_LOST_VEHICLE : वाहन हरवल्यास सूचित करा: {STRING} ###length 3 diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 9755ceadff..4fcfcf2356 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -1361,6 +1361,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ingen* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Redusert STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalt + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Tillat stoppesteder med gjennomkjøring på by-eide veier: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Tillat bygging av stoppesteder med gjennomkjøring på by-eide veier STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Tillat stoppesteder med gjennomkjøring på motstander-eide veier: {STRING} diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index 578b9d1b10..cda94c1823 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -1276,6 +1276,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ingen STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Redusert STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalt + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Tillet stoppestadar med gjennomkøyring på by-eigde vegar: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Tillat bygging av stoppestadar med gjennomkøyring på vegar eigd av byen STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Tillet stoppestadar med gjennomkøyring på konkurent-eigde vegar: {STRING} diff --git a/src/lang/persian.txt b/src/lang/persian.txt index feaf8a2d2e..6843e22193 100644 --- a/src/lang/persian.txt +++ b/src/lang/persian.txt @@ -1214,6 +1214,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :هیچکدام STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :کاهش STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :عادی + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :اجازه رانندگی در خیابان‌های شهر{STRING} STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :اجازه استفاده از جاده یک بازیکن توسط دیگر رقیبان: {STRING} STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}تغییر دادن این تنظیم هنگامی که خودرو وجود دارد ممکن نیست diff --git a/src/lang/polish.txt b/src/lang/polish.txt index be0867cfdb..fcd92b40ae 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -1806,6 +1806,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Brak* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Zredukowana STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalna + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Pozwól na budowę przystanków przelotowych na drogach miejskich: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Pozwalaj budować przystanki przelotowe na drogach będących własnością miast STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Pozwól na budowę przystanków przelotowych na drogach innych firm: {STRING} diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 854ca90d92..bad1d34ef1 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -1427,6 +1427,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nenhum* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduzido STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permite estações de passagem nas estradas pertencentes às localidades: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permite a construção de estações de passagem nas ruas pertencentes a localidades. STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir estações de passagem nas estradas detidas pelos competidores: {STRING} diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index 0a06468da4..6bc056c16b 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -1425,6 +1425,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :niciunul STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :redus STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permite construirea stațiilor pe drumurile deținute de orașe: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permite construirea de stații pe drumurile aflate în proprietatea orașelor STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permite construirea staţiilor pe drumurile competitorilor: {STRING} diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 7a15b4c237..b28fc98e62 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -1577,6 +1577,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :отсутст STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :сниженная STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :обычная + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Позволять строить остановки на муниципальных дорогах: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Разрешить компаниям строить сквозные остановки на дорогах, построенных за счёт городского бюджета STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Разрешить проезд через остановки соперников по их дорогам: {STRING} diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index db010ee6d2..f6b90d1c4b 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -1573,6 +1573,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :nikakav STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :umanjen STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :normalan + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Dozvoljene ulične stanice na kolovozima u vlasništvu naselja: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Dozvoljava izgradnju protočnih drumskih stanica na putevima čiji je vlasnik naselje STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Dozvoljene ulične stanice na kolovozima u vlasništvu drugih preduzeća: {STRING} diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 3ab1d4a9df..6ef66da510 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -1380,6 +1380,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :不出现* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :较少出现 STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :正常 + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :允许在城镇所属的道路上建通过式车站: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :“打开”时允许在城市所属的道路上建设通过式车站 STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :允许在竞争对手所属的道路上建通过式车站: {STRING} diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 30a0de0918..bba2ad0079 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -1485,6 +1485,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Žiadne STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Obmedzené STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normálny + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Povoliť prejazdné zastávky na mestských cestách: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Povoliť budovanie "prejazdných" nakládok a zastávok na cestách vlastnených mestom STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Výstavba zastávok na cestách vlastnených konkurenciou: {STRING} diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index d9100f8f66..be10379592 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -1443,6 +1443,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Brez STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Zmanjšano STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalno + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Dovoli prehodne postaje na cestah v lasti mest: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Dovoli gradnjo pretočnih postaj na cesti, ki je v lasti mesta. STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Dovoli prevoženja postaj na tekmečevih cestah: {STRING} diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 5cde0e9f2c..da82f64f0b 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -1381,6 +1381,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ninguno* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reducida STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permitir construir paradas sobre carreteras de los municipios: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permite construir estaciones de paso en carreteras que sean propiedad de los municipios STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir pasar a través de las paradas de carretera de los competidores: {STRING} diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index e06a453645..ac5c36a23b 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -1381,6 +1381,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ninguno* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reducida STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permitir construcción de paradas de paso en localidades: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Se podrán construir paradas de paso en las carreteras que sean propiedad de las localidades STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir construcción de paradas de paso en carreteras de la competencia: {STRING} diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index a8516f2e3a..f041518176 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -1426,6 +1426,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Inga* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reducerad STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Tillåt genomfartshållplatser på vägar som ägs av städer: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Tillåt konstruktion av genomfartshållplatser på vägar som ägs av städer STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Tillåt dina fordon att köra genom motståndarens hållplatser: {STRING} diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index ded256d64f..3ee6e622ce 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -1291,6 +1291,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :ஒன்று STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :குறைக்கப்பட்ட STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :இயல்பான + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :வழிசெல்லக்கூடிய சாலை நிறுத்தங்களை நகராட்சியின் சாலைகளில் அமைக்க அனுமதி: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :நகரத்திற்குச் சொந்தமான சாலைகளில் டிரைவ்-த்ரோ சாலை நிறுத்தங்களை உருவாக்க அனுமதிக்கவும் STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}வாகனங்கள் இருக்கும் பொது இந்த அமைப்பினை மாற்ற இயலாது diff --git a/src/lang/thai.txt b/src/lang/thai.txt index d865b51cbb..76661760cc 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -1303,6 +1303,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :ไม่มี STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :ลดลง STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :ปกติ + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :อนุญาตให้มีที่หยุดรถแบบขับผ่านบนถนนที่เมืองเป็นเจ้าของ: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :สามารถสร้างป้ายหยุดรถบนถนนของเมืองได้ STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :อนุญาตให้มีที่หยุดรถแบบขับผ่านบนถนนของบริษัทอื่นๆ: {STRING} diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index e051a6c260..7630725a05 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -1380,6 +1380,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :無 STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :減少 STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :正常 + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :可在市鎮所屬道路上建設路邊車站:{STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :容許在市鎮擁有的道路上建造直通型車站。 STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :可在競爭對手所有的道路上建設路邊車站:{STRING} diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index 0ac18bb857..53c1e23f2d 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -1427,6 +1427,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Hiç STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Azaltılmış STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Kasabaların sahip olduğu yollarda arabalı yol duraklarına izin ver: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Kasabaların sahip olduğu yollarda arabalı yol duraklarının inşasına izin ver STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Rakiplerin yolu üzerinde durak yapmaya izin ver: {STRING} diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index 43eb39c60d..52fd59ed19 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -1528,6 +1528,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Немає STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Низька STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Нормальна + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Дозволити встановлення зупинок на дорогах міста: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Дозволяє встановлення зупинок на дорогах, якими володіє місто. STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Дозволити встановлення зупинок на дорогах конкурентів: {STRING} diff --git a/src/lang/urdu.txt b/src/lang/urdu.txt index edf2f30855..782528ce6e 100644 --- a/src/lang/urdu.txt +++ b/src/lang/urdu.txt @@ -1158,6 +1158,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :کوئی نہی STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :کم STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :نارمل + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :شہر کی ملکیت سڑکوں پر ڈرائیو تھرو اڈے بنانے کی اجازت: {STRING} STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :مد مقابلوں کی ملکیت سڑکوں پر ڈرائیو تھرو اڈے بنانے کی اجازت: {STRING} STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}جب گاڑیاں موجود ہوں تو یہ سیٹنگ بدلنا ممکن نہیں diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index df19d6e25f..c7cd7caf17 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -1426,6 +1426,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :không* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :giảm bớt STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :bình thường + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Cho phép xây điểm dừng xe buýt trên đường sở hữu bởi thị trấn: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Cho phép xây dựng điểm dừng xe buýt trên đường thuộc sở hữu của địa phương STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Cho phép xây điểm dừng xe buýt trên đường của đối thủ: {STRING} diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 95035f7fbf..4b834f049a 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -1329,6 +1329,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Dim STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Llai STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Arferol + STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Caniatáu arosfannau gyrru-trwodd ar ffyrdd sy'n eiddo i drefi: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Caniatáu adeiladu arosfannau gyrru-trwodd ar ffyrdd sy'n eiddo i drefi STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Caniatáu arosfannau gyrru-trwodd ar ffyrdd sy'n eiddo i gystadleuwyr: {STRING} From bd150df9148c346f7fa133ca3f286257c015ae32 Mon Sep 17 00:00:00 2001 From: PeterN Date: Sat, 2 Sep 2023 21:56:36 +0100 Subject: [PATCH 08/72] Codechange: Reorder some high-use structs to reduce their size. (#11201) This reduces GoodsEntry from 144 to 136 bytes (thereby reducing Station from 9704 bytes to 9192 bytes), and CargoPacket from 40 bytes to 32 bytes. --- src/cargopacket.cpp | 16 ++++++++-------- src/cargopacket.h | 8 ++++---- src/station_base.h | 37 +++++++++++++------------------------ 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index d921960bb0..1bec3b99f3 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -42,16 +42,16 @@ CargoPacket::CargoPacket() * that, in contrary to all other pools, does not memset to 0. */ CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id) : - feeder_share(0), count(count), periods_in_transit(0), + feeder_share(0), + source_xy(source_xy), + loaded_at_xy(0), source_id(source_id), source(source), - source_xy(source_xy), - loaded_at_xy(0) + source_type(source_type) { assert(count != 0); - this->source_type = source_type; } /** @@ -69,16 +69,16 @@ CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16_t count, * that, in contrary to all other pools, does not memset to 0. */ CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share, SourceType source_type, SourceID source_id) : - feeder_share(feeder_share), count(count), periods_in_transit(periods_in_transit), + feeder_share(feeder_share), + source_xy(source_xy), + loaded_at_xy(loaded_at_xy), source_id(source_id), source(source), - source_xy(source_xy), - loaded_at_xy(loaded_at_xy) + source_type(source_type) { assert(count != 0); - this->source_type = source_type; } /** diff --git a/src/cargopacket.h b/src/cargopacket.h index 96cb7fb506..093f2fbda9 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -46,17 +46,17 @@ static_assert(sizeof(TileIndex) == sizeof(StationID_32bit)); */ struct CargoPacket : CargoPacketPool::PoolItem<&_cargopacket_pool> { private: - Money feeder_share; ///< Value of feeder pickup to be paid for on delivery of cargo. uint16_t count; ///< The amount of cargo in this packet. uint16_t periods_in_transit; ///< Amount of cargo aging periods this packet has been in transit. - SourceType source_type; ///< Type of \c source_id. - SourceID source_id; ///< Index of source, INVALID_SOURCE if unknown/invalid. - StationID source; ///< The station where the cargo came from first. + Money feeder_share; ///< Value of feeder pickup to be paid for on delivery of cargo. TileIndex source_xy; ///< The origin of the cargo (first station in feeder chain). union { TileIndex loaded_at_xy; ///< Location where this cargo has been loaded into the vehicle. StationID_32bit next_station; ///< Station where the cargo wants to go next. }; + SourceID source_id; ///< Index of source, INVALID_SOURCE if unknown/invalid. + StationID source; ///< The station where the cargo came from first. + SourceType source_type; ///< Type of \c source_id. /** The CargoList caches, thus needs to know about it. */ template friend class CargoList; diff --git a/src/station_base.h b/src/station_base.h index 649a34414c..8596b38365 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -206,28 +206,23 @@ struct GoodsEntry { GES_ACCEPTED_BIGTICK, }; - GoodsEntry() : - status(0), - time_since_pickup(255), - rating(INITIAL_STATION_RATING), - last_speed(0), - last_age(255), - amount_fract(0), - link_graph(INVALID_LINK_GRAPH), - node(INVALID_NODE), - max_waiting_cargo(0) - {} - - byte status; ///< Status of this cargo, see #GoodsEntryStatus. + StationCargoList cargo{}; ///< The cargo packets of cargo waiting in this station + FlowStatMap flows{}; ///< Planned flows through this station. + + uint max_waiting_cargo{0}; ///< Max cargo from this station waiting at any station. + NodeID node{INVALID_NODE}; ///< ID of node in link graph referring to this goods entry. + LinkGraphID link_graph{INVALID_LINK_GRAPH}; ///< Link graph this station belongs to. + + byte status{0}; ///< Status of this cargo, see #GoodsEntryStatus. /** * Number of rating-intervals (up to 255) since the last vehicle tried to load this cargo. * The unit used is STATION_RATING_TICKS. * This does not imply there was any cargo to load. */ - byte time_since_pickup; + uint8_t time_since_pickup{255}; - byte rating; ///< %Station rating for this cargo. + uint8_t rating{INITIAL_STATION_RATING}; ///< %Station rating for this cargo. /** * Maximum speed (up to 255) of the last vehicle that tried to load this cargo. @@ -238,21 +233,15 @@ struct GoodsEntry { * - Ships: 0.5 * km-ish/h * - Aircraft: 8 * mph */ - byte last_speed; + uint8_t last_speed{0}; /** * Age in years (up to 255) of the last vehicle that tried to load this cargo. * This does not imply there was any cargo to load. */ - byte last_age; - - byte amount_fract; ///< Fractional part of the amount in the cargo list - StationCargoList cargo; ///< The cargo packets of cargo waiting in this station + uint8_t last_age{255}; - LinkGraphID link_graph; ///< Link graph this station belongs to. - NodeID node; ///< ID of node in link graph referring to this goods entry. - FlowStatMap flows; ///< Planned flows through this station. - uint max_waiting_cargo; ///< Max cargo from this station waiting at any station. + uint8_t amount_fract{0}; ///< Fractional part of the amount in the cargo list /** * Reports whether a vehicle has ever tried to load the cargo at this station. From dadf5182d8e14046df49ad845e6987dbc4de0ac1 Mon Sep 17 00:00:00 2001 From: translators Date: Sun, 3 Sep 2023 18:38:15 +0000 Subject: [PATCH 09/72] Update: Translations from eints english (au): 2 changes by krysclarke russian: 3 changes by Ln-Wolf finnish: 2 changes by hpiirai portuguese (brazilian): 2 changes by pasantoro --- src/lang/brazilian_portuguese.txt | 2 ++ src/lang/english_AU.txt | 2 ++ src/lang/finnish.txt | 2 ++ src/lang/russian.txt | 4 +++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index b51e2755a5..8089c1816a 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -1427,6 +1427,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nenhum STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduzido STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Permitir passagens de nível com estradas ou linhas de outras companhias: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Permitir a construção de passagens de nível nas estradas ou linhas de outras companhias STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permitir estações de passagem nas estradas pertencentes às localidades: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permitir a construção de estações de passagem com paradas nas ruas pertencentes a localidades. diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index d9dbc24c45..c3581d224d 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -1426,6 +1426,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :None STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduced STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Allow level crossings with roads or rails owned by competitors: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Allow construction of level crossings on roads or rails owned by competitors STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Allow drive-through road stops on roads owned by towns: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Allow construction of drive-through road stops on roads owned by towns diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index e2dbfea75d..18892d3b61 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -1426,6 +1426,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ei yhtään¹ STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Vähennetty STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Tavallinen +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Salli kilpailijoiden teiden tai raiteiden kanssa risteävät tasoristeykset: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Sallii tasoristeysten rakentamisen kilpailijoiden omistamille teille ja raiteille STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Salli läpiajettavat pysäkit kuntien omistamilla teillä: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Sallii läpiajettavien pysäkkien rakentamisen kuntien omistamille teille diff --git a/src/lang/russian.txt b/src/lang/russian.txt index b28fc98e62..8ab0c77ce1 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -1577,10 +1577,12 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :отсутст STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :сниженная STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :обычная +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Ж/Д переезды на дорогах и путях конкурентов: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Разрешить строить железнодорожные пути сквозь автомобильные и железные дороги конкурентов STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Позволять строить остановки на муниципальных дорогах: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Разрешить компаниям строить сквозные остановки на дорогах, построенных за счёт городского бюджета -STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Разрешить проезд через остановки соперников по их дорогам: {STRING} +STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Разрешить строить остановки на дорогах конкурентов: {STRING} STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :Разрешить компаниям строить сквозные остановки на дорогах, принадлежащих другим транспортным компаниям STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Изменение этого параметра невозможно, если в игре есть транспортные средства. From 3e762af2d1c0143715d5d66bf9127e853637ac4e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 3 Sep 2023 20:33:24 +0100 Subject: [PATCH 10/72] Change: Replace fixed length _grf_text array with vector. Additionally reshuffle GRFTextEntry for better alignment. This removes a mostly-unused static 20MB allocation. --- src/newgrf_text.cpp | 58 +++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index e33a679a71..1544eb4695 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -64,15 +64,14 @@ enum GRFExtendedLanguages { * since it is NOT SUPPOSED to happen. */ struct GRFTextEntry { + GRFTextList textholder; + StringID def_string; uint32_t grfid; uint16_t stringid; - StringID def_string; - GRFTextList textholder; }; -static uint _num_grf_texts = 0; -static GRFTextEntry _grf_text[TAB_SIZE_NEWGRF]; +static std::vector _grf_text; static byte _currentLangID = GRFLX_ENGLISH; ///< by default, english is used. /** @@ -561,27 +560,21 @@ StringID AddGRFString(uint32_t grfid, uint16_t stringid, byte langid_to_add, boo } } - uint id; - for (id = 0; id < _num_grf_texts; id++) { - if (_grf_text[id].grfid == grfid && _grf_text[id].stringid == stringid) { - break; - } - } + auto it = std::find_if(std::begin(_grf_text), std::end(_grf_text), [&grfid, &stringid](const GRFTextEntry &grf_text) { return grf_text.grfid == grfid && grf_text.stringid == stringid; }); + if (it == std::end(_grf_text)) { + /* Too many strings allocated, return empty. */ + if (_grf_text.size() == TAB_SIZE_NEWGRF) return STR_EMPTY; - /* Too many strings allocated, return empty */ - if (id == lengthof(_grf_text)) return STR_EMPTY; + /* We didn't find our stringid and grfid in the list, allocate a new id. */ + it = _grf_text.emplace(std::end(_grf_text)); + it->grfid = grfid; + it->stringid = stringid; + it->def_string = def_string; + } + uint id = static_cast(it - std::begin(_grf_text)); std::string newtext = TranslateTTDPatchCodes(grfid, langid_to_add, allow_newlines, text_to_add); - - /* If we didn't find our stringid and grfid in the list, allocate a new id */ - if (id == _num_grf_texts) _num_grf_texts++; - - if (_grf_text[id].textholder.empty()) { - _grf_text[id].grfid = grfid; - _grf_text[id].stringid = stringid; - _grf_text[id].def_string = def_string; - } - AddGRFTextToList(_grf_text[id].textholder, langid_to_add, newtext); + AddGRFTextToList(it->textholder, langid_to_add, newtext); GrfMsg(3, "Added 0x{:X} grfid {:08X} string 0x{:X} lang 0x{:X} string '{}' ({:X})", id, grfid, stringid, langid_to_add, newtext, MakeStringID(TEXT_TAB_NEWGRF_START, id)); @@ -593,10 +586,10 @@ StringID AddGRFString(uint32_t grfid, uint16_t stringid, byte langid_to_add, boo */ StringID GetGRFStringID(uint32_t grfid, StringID stringid) { - for (uint id = 0; id < _num_grf_texts; id++) { - if (_grf_text[id].grfid == grfid && _grf_text[id].stringid == stringid) { - return MakeStringID(TEXT_TAB_NEWGRF_START, id); - } + auto it = std::find_if(std::begin(_grf_text), std::end(_grf_text), [&grfid, &stringid](const GRFTextEntry &grf_text) { return grf_text.grfid == grfid && grf_text.stringid == stringid; }); + if (it != std::end(_grf_text)) { + uint id = static_cast(it - std::begin(_grf_text)); + return MakeStringID(TEXT_TAB_NEWGRF_START, id); } return STR_UNDEFINED; @@ -645,6 +638,7 @@ const char *GetGRFStringFromGRFText(const GRFTextWrapper &text) */ const char *GetGRFStringPtr(uint16_t stringid) { + assert(stringid < _grf_text.size()); assert(_grf_text[stringid].grfid != 0); const char *str = GetGRFStringFromGRFText(_grf_text[stringid].textholder); @@ -683,19 +677,11 @@ bool CheckGrfLangID(byte lang_id, byte grf_version) /** * House cleaning. - * Remove all strings and reset the text counter. + * Remove all strings. */ void CleanUpStrings() { - uint id; - - for (id = 0; id < _num_grf_texts; id++) { - _grf_text[id].grfid = 0; - _grf_text[id].stringid = 0; - _grf_text[id].textholder.clear(); - } - - _num_grf_texts = 0; + _grf_text.clear(); } struct TextRefStack { From e4613fc04c0c7aca665d7d4f7cf73e7aa03d5e06 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 4 Sep 2023 08:12:51 +0100 Subject: [PATCH 11/72] Codechange: Allow using more than 65536 NewGRF string IDs. NewGRF string allocation allowed up to 524288 strings, however stringid was passed as uint16_t which limits to 2^16. --- src/newgrf_text.cpp | 2 +- src/newgrf_text.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 1544eb4695..506e80a965 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -636,7 +636,7 @@ const char *GetGRFStringFromGRFText(const GRFTextWrapper &text) /** * Get a C-string from a stringid set by a newgrf. */ -const char *GetGRFStringPtr(uint16_t stringid) +const char *GetGRFStringPtr(uint32_t stringid) { assert(stringid < _grf_text.size()); assert(_grf_text[stringid].grfid != 0); diff --git a/src/newgrf_text.h b/src/newgrf_text.h index 21273e3d5e..c3dfa08cee 100644 --- a/src/newgrf_text.h +++ b/src/newgrf_text.h @@ -33,7 +33,7 @@ StringID AddGRFString(uint32_t grfid, uint16_t stringid, byte langid, bool new_s StringID GetGRFStringID(uint32_t grfid, StringID stringid); const char *GetGRFStringFromGRFText(const GRFTextList &text_list); const char *GetGRFStringFromGRFText(const GRFTextWrapper &text); -const char *GetGRFStringPtr(uint16_t stringid); +const char *GetGRFStringPtr(uint32_t stringid); void CleanUpStrings(); void SetCurrentGrfLangID(byte language_id); std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool allow_newlines, const std::string &str, StringControlCode byte80 = SCC_NEWGRF_PRINT_WORD_STRING_ID); From e8015e497de8b672adb3d6388cf2056bdf20362d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 3 Sep 2023 21:54:13 +0100 Subject: [PATCH 12/72] Codechange: Use begin/end of nwidget parts of begin/length. This simplifies processing nwidget parts as, unlike the remaining length, the pointer to the end of the list never changes. This is the same principle as we use(d) for tracking end instead of length for C-style strings. And this removes 160~ instances of the lengthof() macro. --- .github/windowdesc-ini-key.py | 2 +- src/ai/ai_gui.cpp | 2 +- src/airport_gui.cpp | 4 +- src/autoreplace_gui.cpp | 6 +- src/bootstrap_gui.cpp | 8 +- src/bridge_gui.cpp | 2 +- src/build_vehicle_gui.cpp | 2 +- src/cheat_gui.cpp | 2 +- src/company_gui.cpp | 12 +-- src/console_gui.cpp | 2 +- src/date_gui.cpp | 2 +- src/depot_gui.cpp | 8 +- src/dock_gui.cpp | 8 +- src/engine_gui.cpp | 2 +- src/error_gui.cpp | 4 +- src/fios_gui.cpp | 6 +- src/framerate_gui.cpp | 4 +- src/game/game_gui.cpp | 2 +- src/genworld_gui.cpp | 8 +- src/goal_gui.cpp | 10 +-- src/graph_gui.cpp | 16 ++-- src/group_gui.cpp | 4 +- src/highscore_gui.cpp | 4 +- src/industry_gui.cpp | 8 +- src/intro_gui.cpp | 2 +- src/league_gui.cpp | 4 +- src/linkgraph/linkgraph_gui.cpp | 2 +- src/main_gui.cpp | 2 +- src/misc_gui.cpp | 10 +-- src/music_gui.cpp | 4 +- src/network/network_chat_gui.cpp | 2 +- src/network/network_content_gui.cpp | 4 +- src/network/network_gui.cpp | 14 ++-- src/newgrf_debug_gui.cpp | 6 +- src/newgrf_gui.cpp | 14 ++-- src/news_gui.cpp | 12 +-- src/object_gui.cpp | 2 +- src/order_gui.cpp | 6 +- src/osk_gui.cpp | 2 +- src/rail_gui.cpp | 10 +-- src/road_gui.cpp | 14 ++-- src/screenshot_gui.cpp | 2 +- src/script/script_gui.cpp | 6 +- src/settings_gui.cpp | 6 +- src/signs_gui.cpp | 4 +- src/smallmap_gui.cpp | 6 +- src/station_gui.cpp | 6 +- src/statusbar_gui.cpp | 2 +- src/story_gui.cpp | 2 +- src/subsidy_gui.cpp | 2 +- src/terraform_gui.cpp | 4 +- src/textfile_gui.cpp | 2 +- src/timetable_gui.cpp | 2 +- src/toolbar_gui.cpp | 6 +- src/town_gui.cpp | 10 +-- src/transparency_gui.cpp | 2 +- src/tree_gui.cpp | 2 +- src/vehicle_gui.cpp | 14 ++-- src/viewport_gui.cpp | 2 +- src/waypoint_gui.cpp | 2 +- src/widget.cpp | 123 ++++++++++++++-------------- src/widget_type.h | 4 +- src/widgets/dropdown.cpp | 2 +- src/window.cpp | 8 +- src/window_gui.h | 6 +- 65 files changed, 231 insertions(+), 232 deletions(-) diff --git a/.github/windowdesc-ini-key.py b/.github/windowdesc-ini-key.py index 16fa3053d8..36b20f9948 100644 --- a/.github/windowdesc-ini-key.py +++ b/.github/windowdesc-ini-key.py @@ -22,7 +22,7 @@ def scan_source_files(path, ini_keys=None): with open(new_path) as fp: output = fp.read() - for (name, ini_key, widgets) in re.findall(r"^static WindowDesc ([a-zA-Z0-9_]*).*?, (?:\"(.*?)\")?.*?,(?:\s+(.*?),){6}", output, re.S|re.M): + for (name, ini_key, widgets) in re.findall(r"^static WindowDesc ([a-zA-Z0-9_]*).*?, (?:\"(.*?)\")?.*?,(?:\s+.*?,){6}\s+[^\s]+\((.*?)\)", output, re.S|re.M): if ini_key: if ini_key in ini_keys: errors.append(f"{new_path}: {name} ini_key is a duplicate") diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index a74586246d..b3125e8c2e 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -77,7 +77,7 @@ static WindowDesc _ai_config_desc( WDP_CENTER, "settings_script_config", 0, 0, WC_GAME_OPTIONS, WC_NONE, 0, - _nested_ai_config_widgets, lengthof(_nested_ai_config_widgets) + std::begin(_nested_ai_config_widgets), std::end(_nested_ai_config_widgets) ); /** diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index fe0e6f7f39..ac9b0448e3 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -213,7 +213,7 @@ static WindowDesc _air_toolbar_desc( WDP_ALIGN_TOOLBAR, "toolbar_air", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, - _nested_air_toolbar_widgets, lengthof(_nested_air_toolbar_widgets), + std::begin(_nested_air_toolbar_widgets), std::end(_nested_air_toolbar_widgets), &BuildAirToolbarWindow::hotkeys ); @@ -622,7 +622,7 @@ static WindowDesc _build_airport_desc( WDP_AUTO, nullptr, 0, 0, WC_BUILD_STATION, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_build_airport_widgets, lengthof(_nested_build_airport_widgets) + std::begin(_nested_build_airport_widgets), std::end(_nested_build_airport_widgets) ); static void ShowBuildAirportPicker(Window *parent) diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 1be79d5aee..8b342ca712 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -808,7 +808,7 @@ static WindowDesc _replace_rail_vehicle_desc( WDP_AUTO, "replace_vehicle_train", 500, 140, WC_REPLACE_VEHICLE, WC_NONE, WDF_CONSTRUCTION, - _nested_replace_rail_vehicle_widgets, lengthof(_nested_replace_rail_vehicle_widgets) + std::begin(_nested_replace_rail_vehicle_widgets), std::end(_nested_replace_rail_vehicle_widgets) ); static const NWidgetPart _nested_replace_road_vehicle_widgets[] = { @@ -866,7 +866,7 @@ static WindowDesc _replace_road_vehicle_desc( WDP_AUTO, "replace_vehicle_road", 500, 140, WC_REPLACE_VEHICLE, WC_NONE, WDF_CONSTRUCTION, - _nested_replace_road_vehicle_widgets, lengthof(_nested_replace_road_vehicle_widgets) + std::begin(_nested_replace_road_vehicle_widgets), std::end(_nested_replace_road_vehicle_widgets) ); static const NWidgetPart _nested_replace_vehicle_widgets[] = { @@ -920,7 +920,7 @@ static WindowDesc _replace_vehicle_desc( WDP_AUTO, "replace_vehicle", 456, 118, WC_REPLACE_VEHICLE, WC_NONE, WDF_CONSTRUCTION, - _nested_replace_vehicle_widgets, lengthof(_nested_replace_vehicle_widgets) + std::begin(_nested_replace_vehicle_widgets), std::end(_nested_replace_vehicle_widgets) ); /** diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index 063e908a32..386883c1e2 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.cpp @@ -43,7 +43,7 @@ static WindowDesc _background_desc( WDP_MANUAL, nullptr, 0, 0, WC_BOOTSTRAP, WC_NONE, WDF_NO_CLOSE, - _background_widgets, lengthof(_background_widgets) + std::begin(_background_widgets), std::end(_background_widgets) ); /** The background for the game. */ @@ -81,7 +81,7 @@ static WindowDesc _bootstrap_errmsg_desc( WDP_CENTER, nullptr, 0, 0, WC_BOOTSTRAP, WC_NONE, WDF_MODAL | WDF_NO_CLOSE, - _nested_bootstrap_errmsg_widgets, lengthof(_nested_bootstrap_errmsg_widgets) + std::begin(_nested_bootstrap_errmsg_widgets), std::end(_nested_bootstrap_errmsg_widgets) ); /** The window for a failed bootstrap. */ @@ -138,7 +138,7 @@ static WindowDesc _bootstrap_download_status_window_desc( WDP_CENTER, nullptr, 0, 0, WC_NETWORK_STATUS_WINDOW, WC_NONE, WDF_MODAL | WDF_NO_CLOSE, - _nested_bootstrap_download_status_window_widgets, lengthof(_nested_bootstrap_download_status_window_widgets) + std::begin(_nested_bootstrap_download_status_window_widgets), std::end(_nested_bootstrap_download_status_window_widgets) ); @@ -192,7 +192,7 @@ static WindowDesc _bootstrap_query_desc( WDP_CENTER, nullptr, 0, 0, WC_CONFIRM_POPUP_QUERY, WC_NONE, WDF_NO_CLOSE, - _bootstrap_query_widgets, lengthof(_bootstrap_query_widgets) + std::begin(_bootstrap_query_widgets), std::end(_bootstrap_query_widgets) ); /** The window for the query. It can't use the generic query window as that uses sprites that don't exist yet. */ diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index a463f51537..367e634411 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -346,7 +346,7 @@ static WindowDesc _build_bridge_desc( WDP_AUTO, "build_bridge", 200, 114, WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_build_bridge_widgets, lengthof(_nested_build_bridge_widgets) + std::begin(_nested_build_bridge_widgets), std::end(_nested_build_bridge_widgets) ); /** diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 86563ad8d9..7c5a259933 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1885,7 +1885,7 @@ static WindowDesc _build_vehicle_desc( WDP_AUTO, "build_vehicle", 240, 268, WC_BUILD_VEHICLE, WC_NONE, WDF_CONSTRUCTION, - _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets), + std::begin(_nested_build_vehicle_widgets), std::end(_nested_build_vehicle_widgets), &BuildVehicleWindow::hotkeys ); diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 5e5c97c98b..e058a27cf7 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -432,7 +432,7 @@ static WindowDesc _cheats_desc( WDP_AUTO, "cheats", 0, 0, WC_CHEATS, WC_NONE, 0, - _nested_cheat_widgets, lengthof(_nested_cheat_widgets) + std::begin(_nested_cheat_widgets), std::end(_nested_cheat_widgets) ); /** Open cheat window. */ diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 409c57a276..45ca97f8e3 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -542,7 +542,7 @@ static WindowDesc _company_finances_desc( WDP_AUTO, "company_finances", 0, 0, WC_FINANCES, WC_NONE, 0, - _nested_company_finances_widgets, lengthof(_nested_company_finances_widgets) + std::begin(_nested_company_finances_widgets), std::end(_nested_company_finances_widgets) ); /** @@ -1160,7 +1160,7 @@ static WindowDesc _select_company_livery_desc( WDP_AUTO, nullptr, 0, 0, WC_COMPANY_COLOUR, WC_NONE, 0, - _nested_select_company_livery_widgets, lengthof(_nested_select_company_livery_widgets) + std::begin(_nested_select_company_livery_widgets), std::end(_nested_select_company_livery_widgets) ); void ShowCompanyLiveryWindow(CompanyID company, GroupID group) @@ -1777,7 +1777,7 @@ static WindowDesc _select_company_manager_face_desc( WDP_AUTO, nullptr, 0, 0, WC_COMPANY_MANAGER_FACE, WC_NONE, WDF_CONSTRUCTION, - _nested_select_company_manager_face_widgets, lengthof(_nested_select_company_manager_face_widgets) + std::begin(_nested_select_company_manager_face_widgets), std::end(_nested_select_company_manager_face_widgets) ); /** @@ -2149,7 +2149,7 @@ static WindowDesc _company_infrastructure_desc( WDP_AUTO, "company_infrastructure", 0, 0, WC_COMPANY_INFRASTRUCTURE, WC_NONE, 0, - _nested_company_infrastructure_widgets, lengthof(_nested_company_infrastructure_widgets) + std::begin(_nested_company_infrastructure_widgets), std::end(_nested_company_infrastructure_widgets) ); /** @@ -2686,7 +2686,7 @@ static WindowDesc _company_desc( WDP_AUTO, "company", 0, 0, WC_COMPANY, WC_NONE, 0, - _nested_company_widgets, lengthof(_nested_company_widgets) + std::begin(_nested_company_widgets), std::end(_nested_company_widgets) ); /** @@ -2820,7 +2820,7 @@ static WindowDesc _buy_company_desc( WDP_AUTO, nullptr, 0, 0, WC_BUY_COMPANY, WC_NONE, WDF_CONSTRUCTION, - _nested_buy_company_widgets, lengthof(_nested_buy_company_widgets) + std::begin(_nested_buy_company_widgets), std::end(_nested_buy_company_widgets) ); /** diff --git a/src/console_gui.cpp b/src/console_gui.cpp index ce2c0df758..3fc5e68288 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -106,7 +106,7 @@ static WindowDesc _console_window_desc( WDP_MANUAL, nullptr, 0, 0, WC_CONSOLE, WC_NONE, 0, - _nested_console_window_widgets, lengthof(_nested_console_window_widgets) + std::begin(_nested_console_window_widgets), std::end(_nested_console_window_widgets) ); struct IConsoleWindow : Window diff --git a/src/date_gui.cpp b/src/date_gui.cpp index febf505836..cc012f545b 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -200,7 +200,7 @@ static WindowDesc _set_date_desc( WDP_CENTER, nullptr, 0, 0, WC_SET_DATE, WC_NONE, 0, - _nested_set_date_widgets, lengthof(_nested_set_date_widgets) + std::begin(_nested_set_date_widgets), std::end(_nested_set_date_widgets) ); /** diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index b7fb593a45..4a7ada72fb 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -89,28 +89,28 @@ static WindowDesc _train_depot_desc( WDP_AUTO, "depot_train", 362, 123, WC_VEHICLE_DEPOT, WC_NONE, 0, - _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets) + std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets) ); static WindowDesc _road_depot_desc( WDP_AUTO, "depot_roadveh", 316, 97, WC_VEHICLE_DEPOT, WC_NONE, 0, - _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets) + std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets) ); static WindowDesc _ship_depot_desc( WDP_AUTO, "depot_ship", 306, 99, WC_VEHICLE_DEPOT, WC_NONE, 0, - _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets) + std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets) ); static WindowDesc _aircraft_depot_desc( WDP_AUTO, "depot_aircraft", 332, 99, WC_VEHICLE_DEPOT, WC_NONE, 0, - _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets) + std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets) ); extern void DepotSortList(VehicleList *list); diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 6bdaa75d38..f2a4d60305 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -349,7 +349,7 @@ static WindowDesc _build_docks_toolbar_desc( WDP_ALIGN_TOOLBAR, "toolbar_water", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, - _nested_build_docks_toolbar_widgets, lengthof(_nested_build_docks_toolbar_widgets), + std::begin(_nested_build_docks_toolbar_widgets), std::end(_nested_build_docks_toolbar_widgets), &BuildDocksToolbarWindow::hotkeys ); @@ -393,7 +393,7 @@ static WindowDesc _build_docks_scen_toolbar_desc( WDP_AUTO, "toolbar_water_scen", 0, 0, WC_SCEN_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, - _nested_build_docks_scen_toolbar_widgets, lengthof(_nested_build_docks_scen_toolbar_widgets) + std::begin(_nested_build_docks_scen_toolbar_widgets), std::end(_nested_build_docks_scen_toolbar_widgets) ); /** @@ -499,7 +499,7 @@ static WindowDesc _build_dock_station_desc( WDP_AUTO, nullptr, 0, 0, WC_BUILD_STATION, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_build_dock_station_widgets, lengthof(_nested_build_dock_station_widgets) + std::begin(_nested_build_dock_station_widgets), std::end(_nested_build_dock_station_widgets) ); static void ShowBuildDockStationPicker(Window *parent) @@ -597,7 +597,7 @@ static WindowDesc _build_docks_depot_desc( WDP_AUTO, nullptr, 0, 0, WC_BUILD_DEPOT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_build_docks_depot_widgets, lengthof(_nested_build_docks_depot_widgets) + std::begin(_nested_build_docks_depot_widgets), std::end(_nested_build_docks_depot_widgets) ); diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index d909196b8c..ea580ffe31 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -147,7 +147,7 @@ static WindowDesc _engine_preview_desc( WDP_CENTER, nullptr, 0, 0, WC_ENGINE_PREVIEW, WC_NONE, WDF_CONSTRUCTION, - _nested_engine_preview_widgets, lengthof(_nested_engine_preview_widgets) + std::begin(_nested_engine_preview_widgets), std::end(_nested_engine_preview_widgets) ); diff --git a/src/error_gui.cpp b/src/error_gui.cpp index 7702b43578..2aacc1eed8 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -46,7 +46,7 @@ static WindowDesc _errmsg_desc( WDP_MANUAL, nullptr, 0, 0, WC_ERRMSG, WC_NONE, 0, - _nested_errmsg_widgets, lengthof(_nested_errmsg_widgets) + std::begin(_nested_errmsg_widgets), std::end(_nested_errmsg_widgets) ); static const NWidgetPart _nested_errmsg_face_widgets[] = { @@ -66,7 +66,7 @@ static WindowDesc _errmsg_face_desc( WDP_MANUAL, nullptr, 0, 0, WC_ERRMSG, WC_NONE, 0, - _nested_errmsg_face_widgets, lengthof(_nested_errmsg_face_widgets) + std::begin(_nested_errmsg_face_widgets), std::end(_nested_errmsg_face_widgets) ); /** diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 67883c9a9c..8eb5c7255a 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -887,7 +887,7 @@ static WindowDesc _load_dialog_desc( WDP_CENTER, "load_game", 500, 294, WC_SAVELOAD, WC_NONE, 0, - _nested_load_dialog_widgets, lengthof(_nested_load_dialog_widgets) + std::begin(_nested_load_dialog_widgets), std::end(_nested_load_dialog_widgets) ); /** Load heightmap */ @@ -895,7 +895,7 @@ static WindowDesc _load_heightmap_dialog_desc( WDP_CENTER, "load_heightmap", 257, 320, WC_SAVELOAD, WC_NONE, 0, - _nested_load_heightmap_dialog_widgets, lengthof(_nested_load_heightmap_dialog_widgets) + std::begin(_nested_load_heightmap_dialog_widgets), std::end(_nested_load_heightmap_dialog_widgets) ); /** Save game/scenario */ @@ -903,7 +903,7 @@ static WindowDesc _save_dialog_desc( WDP_CENTER, "save_game", 500, 294, WC_SAVELOAD, WC_NONE, 0, - _nested_save_dialog_widgets, lengthof(_nested_save_dialog_widgets) + std::begin(_nested_save_dialog_widgets), std::end(_nested_save_dialog_widgets) ); /** diff --git a/src/framerate_gui.cpp b/src/framerate_gui.cpp index 7b416e750e..453d9f142f 100644 --- a/src/framerate_gui.cpp +++ b/src/framerate_gui.cpp @@ -730,7 +730,7 @@ static WindowDesc _framerate_display_desc( WDP_AUTO, "framerate_display", 0, 0, WC_FRAMERATE_DISPLAY, WC_NONE, 0, - _framerate_window_widgets, lengthof(_framerate_window_widgets) + std::begin(_framerate_window_widgets), std::end(_framerate_window_widgets) ); @@ -1015,7 +1015,7 @@ static WindowDesc _frametime_graph_window_desc( WDP_AUTO, "frametime_graph", 140, 90, WC_FRAMETIME_GRAPH, WC_NONE, 0, - _frametime_graph_window_widgets, lengthof(_frametime_graph_window_widgets) + std::begin(_frametime_graph_window_widgets), std::end(_frametime_graph_window_widgets) ); diff --git a/src/game/game_gui.cpp b/src/game/game_gui.cpp index f926409086..6a1c89596d 100644 --- a/src/game/game_gui.cpp +++ b/src/game/game_gui.cpp @@ -72,7 +72,7 @@ static WindowDesc _gs_config_desc( WDP_CENTER, "settings_gs_config", 500, 350, WC_GAME_OPTIONS, WC_NONE, 0, - _nested_gs_config_widgets, lengthof(_nested_gs_config_widgets) + std::begin(_nested_gs_config_widgets), std::end(_nested_gs_config_widgets) ); /** diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 669e597f78..294b60c55e 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -1025,14 +1025,14 @@ static WindowDesc _generate_landscape_desc( WDP_CENTER, nullptr, 0, 0, WC_GENERATE_LANDSCAPE, WC_NONE, 0, - _nested_generate_landscape_widgets, lengthof(_nested_generate_landscape_widgets) + std::begin(_nested_generate_landscape_widgets), std::end(_nested_generate_landscape_widgets) ); static WindowDesc _heightmap_load_desc( WDP_CENTER, nullptr, 0, 0, WC_GENERATE_LANDSCAPE, WC_NONE, 0, - _nested_heightmap_load_widgets, lengthof(_nested_heightmap_load_widgets) + std::begin(_nested_heightmap_load_widgets), std::end(_nested_heightmap_load_widgets) ); static void _ShowGenerateLandscape(GenerateLandscapeWindowMode mode) @@ -1328,7 +1328,7 @@ static WindowDesc _create_scenario_desc( WDP_CENTER, nullptr, 0, 0, WC_GENERATE_LANDSCAPE, WC_NONE, 0, - _nested_create_scenario_widgets, lengthof(_nested_create_scenario_widgets) + std::begin(_nested_create_scenario_widgets), std::end(_nested_create_scenario_widgets) ); /** Show the window to create a scenario. */ @@ -1354,7 +1354,7 @@ static WindowDesc _generate_progress_desc( WDP_CENTER, nullptr, 0, 0, WC_MODAL_PROGRESS, WC_NONE, 0, - _nested_generate_progress_widgets, lengthof(_nested_generate_progress_widgets) + std::begin(_nested_generate_progress_widgets), std::end(_nested_generate_progress_widgets) ); struct GenWorldStatus { diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index bc640b0209..9ff4a32738 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -306,7 +306,7 @@ static WindowDesc _goals_list_desc( WDP_AUTO, "list_goals", 500, 127, WC_GOALS_LIST, WC_NONE, 0, - _nested_goals_list_widgets, lengthof(_nested_goals_list_widgets) + std::begin(_nested_goals_list_widgets), std::end(_nested_goals_list_widgets) ); /** @@ -521,25 +521,25 @@ static WindowDesc _goal_question_list_desc[] = { WDP_CENTER, nullptr, 0, 0, WC_GOAL_QUESTION, WC_NONE, WDF_CONSTRUCTION, - _nested_goal_question_widgets_question, lengthof(_nested_goal_question_widgets_question), + std::begin(_nested_goal_question_widgets_question), std::end(_nested_goal_question_widgets_question), }, { WDP_CENTER, nullptr, 0, 0, WC_GOAL_QUESTION, WC_NONE, WDF_CONSTRUCTION, - _nested_goal_question_widgets_info, lengthof(_nested_goal_question_widgets_info), + std::begin(_nested_goal_question_widgets_info), std::end(_nested_goal_question_widgets_info), }, { WDP_CENTER, nullptr, 0, 0, WC_GOAL_QUESTION, WC_NONE, WDF_CONSTRUCTION, - _nested_goal_question_widgets_warning, lengthof(_nested_goal_question_widgets_warning), + std::begin(_nested_goal_question_widgets_warning), std::end(_nested_goal_question_widgets_warning), }, { WDP_CENTER, nullptr, 0, 0, WC_GOAL_QUESTION, WC_NONE, WDF_CONSTRUCTION, - _nested_goal_question_widgets_error, lengthof(_nested_goal_question_widgets_error), + std::begin(_nested_goal_question_widgets_error), std::end(_nested_goal_question_widgets_error), }, }; diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index dba31fe4fe..91179e8286 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -145,7 +145,7 @@ static WindowDesc _graph_legend_desc( WDP_AUTO, "graph_legend", 0, 0, WC_GRAPH_LEGEND, WC_NONE, 0, - _nested_graph_legend_widgets, lengthof(_nested_graph_legend_widgets) + std::begin(_nested_graph_legend_widgets), std::end(_nested_graph_legend_widgets) ); static void ShowGraphLegend() @@ -658,7 +658,7 @@ static WindowDesc _operating_profit_desc( WDP_AUTO, "graph_operating_profit", 0, 0, WC_OPERATING_PROFIT, WC_NONE, 0, - _nested_operating_profit_widgets, lengthof(_nested_operating_profit_widgets) + std::begin(_nested_operating_profit_widgets), std::end(_nested_operating_profit_widgets) ); @@ -709,7 +709,7 @@ static WindowDesc _income_graph_desc( WDP_AUTO, "graph_income", 0, 0, WC_INCOME_GRAPH, WC_NONE, 0, - _nested_income_graph_widgets, lengthof(_nested_income_graph_widgets) + std::begin(_nested_income_graph_widgets), std::end(_nested_income_graph_widgets) ); void ShowIncomeGraph() @@ -758,7 +758,7 @@ static WindowDesc _delivered_cargo_graph_desc( WDP_AUTO, "graph_delivered_cargo", 0, 0, WC_DELIVERED_CARGO, WC_NONE, 0, - _nested_delivered_cargo_graph_widgets, lengthof(_nested_delivered_cargo_graph_widgets) + std::begin(_nested_delivered_cargo_graph_widgets), std::end(_nested_delivered_cargo_graph_widgets) ); void ShowDeliveredCargoGraph() @@ -814,7 +814,7 @@ static WindowDesc _performance_history_desc( WDP_AUTO, "graph_performance", 0, 0, WC_PERFORMANCE_HISTORY, WC_NONE, 0, - _nested_performance_history_widgets, lengthof(_nested_performance_history_widgets) + std::begin(_nested_performance_history_widgets), std::end(_nested_performance_history_widgets) ); void ShowPerformanceHistoryGraph() @@ -863,7 +863,7 @@ static WindowDesc _company_value_graph_desc( WDP_AUTO, "graph_company_value", 0, 0, WC_COMPANY_VALUE, WC_NONE, 0, - _nested_company_value_graph_widgets, lengthof(_nested_company_value_graph_widgets) + std::begin(_nested_company_value_graph_widgets), std::end(_nested_company_value_graph_widgets) ); void ShowCompanyValueGraph() @@ -1097,7 +1097,7 @@ static WindowDesc _cargo_payment_rates_desc( WDP_AUTO, "graph_cargo_payment_rates", 0, 0, WC_PAYMENT_RATES, WC_NONE, 0, - _nested_cargo_payment_rates_widgets, lengthof(_nested_cargo_payment_rates_widgets) + std::begin(_nested_cargo_payment_rates_widgets), std::end(_nested_cargo_payment_rates_widgets) ); @@ -1393,7 +1393,7 @@ static WindowDesc _performance_rating_detail_desc( WDP_AUTO, "league_details", 0, 0, WC_PERFORMANCE_DETAIL, WC_NONE, 0, - _nested_performance_rating_detail_widgets, lengthof(_nested_performance_rating_detail_widgets) + std::begin(_nested_performance_rating_detail_widgets), std::end(_nested_performance_rating_detail_widgets) ); void ShowPerformanceRatingDetail() diff --git a/src/group_gui.cpp b/src/group_gui.cpp index cb6959d379..721125d62a 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -1108,14 +1108,14 @@ static WindowDesc _other_group_desc( WDP_AUTO, "list_groups", 460, 246, WC_INVALID, WC_NONE, 0, - _nested_group_widgets, lengthof(_nested_group_widgets) + std::begin(_nested_group_widgets), std::end(_nested_group_widgets) ); static WindowDesc _train_group_desc( WDP_AUTO, "list_groups_train", 525, 246, WC_TRAINS_LIST, WC_NONE, 0, - _nested_group_widgets, lengthof(_nested_group_widgets) + std::begin(_nested_group_widgets), std::end(_nested_group_widgets) ); /** diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index ab6f3b3f52..4b55d65586 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -218,14 +218,14 @@ static WindowDesc _highscore_desc( WDP_MANUAL, nullptr, 0, 0, WC_HIGHSCORE, WC_NONE, 0, - _nested_highscore_widgets, lengthof(_nested_highscore_widgets) + std::begin(_nested_highscore_widgets), std::end(_nested_highscore_widgets) ); static WindowDesc _endgame_desc( WDP_MANUAL, nullptr, 0, 0, WC_ENDSCREEN, WC_NONE, 0, - _nested_highscore_widgets, lengthof(_nested_highscore_widgets) + std::begin(_nested_highscore_widgets), std::end(_nested_highscore_widgets) ); /** diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index cd72c4bc38..e68a6373d7 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -296,7 +296,7 @@ static WindowDesc _build_industry_desc( WDP_AUTO, "build_industry", 170, 212, WC_BUILD_INDUSTRY, WC_NONE, WDF_CONSTRUCTION, - _nested_build_industry_widgets, lengthof(_nested_build_industry_widgets) + std::begin(_nested_build_industry_widgets), std::end(_nested_build_industry_widgets) ); /** Build (fund or prospect) a new industry, */ @@ -1206,7 +1206,7 @@ static WindowDesc _industry_view_desc( WDP_AUTO, "view_industry", 260, 120, WC_INDUSTRY_VIEW, WC_NONE, 0, - _nested_industry_view_widgets, lengthof(_nested_industry_view_widgets) + std::begin(_nested_industry_view_widgets), std::end(_nested_industry_view_widgets) ); void ShowIndustryViewWindow(int industry) @@ -1867,7 +1867,7 @@ static WindowDesc _industry_directory_desc( WDP_AUTO, "list_industries", 428, 190, WC_INDUSTRY_DIRECTORY, WC_NONE, 0, - _nested_industry_directory_widgets, lengthof(_nested_industry_directory_widgets) + std::begin(_nested_industry_directory_widgets), std::end(_nested_industry_directory_widgets) ); void ShowIndustryDirectory() @@ -1905,7 +1905,7 @@ static WindowDesc _industry_cargoes_desc( WDP_AUTO, "industry_cargoes", 300, 210, WC_INDUSTRY_CARGOES, WC_NONE, 0, - _nested_industry_cargoes_widgets, lengthof(_nested_industry_cargoes_widgets) + std::begin(_nested_industry_cargoes_widgets), std::end(_nested_industry_cargoes_widgets) ); /** Available types of field. */ diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp index 2c5acca26d..e5eef652f3 100644 --- a/src/intro_gui.cpp +++ b/src/intro_gui.cpp @@ -495,7 +495,7 @@ static WindowDesc _select_game_desc( WDP_CENTER, nullptr, 0, 0, WC_SELECT_GAME, WC_NONE, WDF_NO_CLOSE, - _nested_select_game_widgets, lengthof(_nested_select_game_widgets) + std::begin(_nested_select_game_widgets), std::end(_nested_select_game_widgets) ); void ShowSelectGameWindow() diff --git a/src/league_gui.cpp b/src/league_gui.cpp index 7a0b2c9b3b..f97a041604 100644 --- a/src/league_gui.cpp +++ b/src/league_gui.cpp @@ -200,7 +200,7 @@ static WindowDesc _performance_league_desc( WDP_AUTO, "performance_league", 0, 0, WC_COMPANY_LEAGUE, WC_NONE, 0, - _nested_performance_league_widgets, lengthof(_nested_performance_league_widgets) + std::begin(_nested_performance_league_widgets), std::end(_nested_performance_league_widgets) ); void ShowPerformanceLeagueTable() @@ -432,7 +432,7 @@ static WindowDesc _script_league_desc( WDP_AUTO, "script_league", 0, 0, WC_COMPANY_LEAGUE, WC_NONE, 0, - _nested_script_league_widgets, lengthof(_nested_script_league_widgets) + std::begin(_nested_script_league_widgets), std::end(_nested_script_league_widgets) ); void ShowScriptLeagueTable(LeagueTableID table) diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 4289389519..abe892d81c 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -541,7 +541,7 @@ static WindowDesc _linkgraph_legend_desc( WDP_AUTO, "toolbar_linkgraph", 0, 0, WC_LINKGRAPH_LEGEND, WC_NONE, 0, - _nested_linkgraph_legend_widgets, lengthof(_nested_linkgraph_legend_widgets) + std::begin(_nested_linkgraph_legend_widgets), std::end(_nested_linkgraph_legend_widgets) ); /** diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 05ec1a5de0..d27976bbcc 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -511,7 +511,7 @@ static WindowDesc _main_window_desc( WDP_MANUAL, nullptr, 0, 0, WC_MAIN_WINDOW, WC_NONE, WDF_NO_CLOSE, - _nested_main_window_widgets, lengthof(_nested_main_window_widgets), + std::begin(_nested_main_window_widgets), std::end(_nested_main_window_widgets), &MainWindow::hotkeys ); diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 9b6e894136..4a58104490 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -62,7 +62,7 @@ static WindowDesc _land_info_desc( WDP_AUTO, nullptr, 0, 0, WC_LAND_INFO, WC_NONE, 0, - _nested_land_info_widgets, lengthof(_nested_land_info_widgets) + std::begin(_nested_land_info_widgets), std::end(_nested_land_info_widgets) ); class LandInfoWindow : public Window { @@ -396,7 +396,7 @@ static WindowDesc _about_desc( WDP_CENTER, nullptr, 0, 0, WC_GAME_OPTIONS, WC_NONE, 0, - _nested_about_widgets, lengthof(_nested_about_widgets) + std::begin(_nested_about_widgets), std::end(_nested_about_widgets) ); static const char * const _credits[] = { @@ -654,7 +654,7 @@ static WindowDesc _tool_tips_desc( WDP_MANUAL, nullptr, 0, 0, // Coordinates and sizes are not used, WC_TOOLTIPS, WC_NONE, WDF_NO_FOCUS | WDF_NO_CLOSE, - _nested_tooltips_widgets, lengthof(_nested_tooltips_widgets) + std::begin(_nested_tooltips_widgets), std::end(_nested_tooltips_widgets) ); /** Window for displaying a tooltip. */ @@ -1067,7 +1067,7 @@ static WindowDesc _query_string_desc( WDP_CENTER, nullptr, 0, 0, WC_QUERY_STRING, WC_NONE, 0, - _nested_query_string_widgets, lengthof(_nested_query_string_widgets) + std::begin(_nested_query_string_widgets), std::end(_nested_query_string_widgets) ); /** @@ -1214,7 +1214,7 @@ static WindowDesc _query_desc( WDP_CENTER, nullptr, 0, 0, WC_CONFIRM_POPUP_QUERY, WC_NONE, WDF_MODAL, - _nested_query_widgets, lengthof(_nested_query_widgets) + std::begin(_nested_query_widgets), std::end(_nested_query_widgets) ); /** diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 8cff204162..1f0d626377 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -645,7 +645,7 @@ static WindowDesc _music_track_selection_desc( WDP_AUTO, nullptr, 0, 0, WC_MUSIC_TRACK_SELECTION, WC_NONE, 0, - _nested_music_track_selection_widgets, lengthof(_nested_music_track_selection_widgets) + std::begin(_nested_music_track_selection_widgets), std::end(_nested_music_track_selection_widgets) ); static void ShowMusicTrackSelection() @@ -905,7 +905,7 @@ static WindowDesc _music_window_desc( WDP_AUTO, "music", 0, 0, WC_MUSIC_WINDOW, WC_NONE, 0, - _nested_music_window_widgets, lengthof(_nested_music_window_widgets) + std::begin(_nested_music_window_widgets), std::end(_nested_music_window_widgets) ); void ShowMusicWindow() diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index c9f0835c62..c43b44172a 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.cpp @@ -510,7 +510,7 @@ static WindowDesc _chat_window_desc( WDP_MANUAL, nullptr, 0, 0, WC_SEND_NETWORK_MSG, WC_NONE, 0, - _nested_chat_window_widgets, lengthof(_nested_chat_window_widgets) + std::begin(_nested_chat_window_widgets), std::end(_nested_chat_window_widgets) ); diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 4b752c62f7..2572b8a7b2 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -96,7 +96,7 @@ static WindowDesc _network_content_download_status_window_desc( WDP_CENTER, nullptr, 0, 0, WC_NETWORK_STATUS_WINDOW, WC_NONE, WDF_MODAL, - _nested_network_content_download_status_window_widgets, lengthof(_nested_network_content_download_status_window_widgets) + std::begin(_nested_network_content_download_status_window_widgets), std::end(_nested_network_content_download_status_window_widgets) ); BaseNetworkContentDownloadStatusWindow::BaseNetworkContentDownloadStatusWindow(WindowDesc *desc) : @@ -1113,7 +1113,7 @@ static WindowDesc _network_content_list_desc( WDP_CENTER, "list_content", 630, 460, WC_NETWORK_WINDOW, WC_NONE, 0, - _nested_network_content_list_widgets, lengthof(_nested_network_content_list_widgets) + std::begin(_nested_network_content_list_widgets), std::end(_nested_network_content_list_widgets) ); /** diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 0f6c5e2dca..0270f60713 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1007,7 +1007,7 @@ static WindowDesc _network_game_window_desc( WDP_CENTER, "list_servers", 1000, 730, WC_NETWORK_WINDOW, WC_NONE, 0, - _nested_network_game_widgets, lengthof(_nested_network_game_widgets) + std::begin(_nested_network_game_widgets), std::end(_nested_network_game_widgets) ); void ShowNetworkGameWindow() @@ -1280,7 +1280,7 @@ static WindowDesc _network_start_server_window_desc( WDP_CENTER, nullptr, 0, 0, WC_NETWORK_WINDOW, WC_NONE, 0, - _nested_network_start_server_window_widgets, lengthof(_nested_network_start_server_window_widgets) + std::begin(_nested_network_start_server_window_widgets), std::end(_nested_network_start_server_window_widgets) ); static void ShowNetworkStartServerWindow() @@ -1359,7 +1359,7 @@ static WindowDesc _client_list_desc( WDP_AUTO, "list_clients", 220, 300, WC_CLIENT_LIST, WC_NONE, 0, - _nested_client_list_widgets, lengthof(_nested_client_list_widgets) + std::begin(_nested_client_list_widgets), std::end(_nested_client_list_widgets) ); /** @@ -2274,7 +2274,7 @@ static WindowDesc _network_join_status_window_desc( WDP_CENTER, nullptr, 0, 0, WC_NETWORK_STATUS_WINDOW, WC_NONE, WDF_MODAL, - _nested_network_join_status_window_widgets, lengthof(_nested_network_join_status_window_widgets) + std::begin(_nested_network_join_status_window_widgets), std::end(_nested_network_join_status_window_widgets) ); void ShowJoinStatusWindow() @@ -2396,7 +2396,7 @@ static WindowDesc _network_company_password_window_desc( WDP_AUTO, nullptr, 0, 0, WC_COMPANY_PASSWORD_WINDOW, WC_NONE, 0, - _nested_network_company_password_window_widgets, lengthof(_nested_network_company_password_window_widgets) + std::begin(_nested_network_company_password_window_widgets), std::end(_nested_network_company_password_window_widgets) ); void ShowNetworkCompanyPasswordWindow(Window *parent) @@ -2499,7 +2499,7 @@ static WindowDesc _network_ask_relay_desc( WDP_CENTER, nullptr, 0, 0, WC_NETWORK_ASK_RELAY, WC_NONE, WDF_MODAL, - _nested_network_ask_relay_widgets, lengthof(_nested_network_ask_relay_widgets) + std::begin(_nested_network_ask_relay_widgets), std::end(_nested_network_ask_relay_widgets) ); /** @@ -2597,7 +2597,7 @@ static WindowDesc _network_ask_survey_desc( WDP_CENTER, nullptr, 0, 0, WC_NETWORK_ASK_SURVEY, WC_NONE, WDF_MODAL, - _nested_network_ask_survey_widgets, lengthof(_nested_network_ask_survey_widgets) + std::begin(_nested_network_ask_survey_widgets), std::end(_nested_network_ask_survey_widgets) ); /** diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index adfce85da9..afef4e9308 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -682,14 +682,14 @@ static WindowDesc _newgrf_inspect_chain_desc( WDP_AUTO, "newgrf_inspect_chain", 400, 300, WC_NEWGRF_INSPECT, WC_NONE, 0, - _nested_newgrf_inspect_chain_widgets, lengthof(_nested_newgrf_inspect_chain_widgets) + std::begin(_nested_newgrf_inspect_chain_widgets), std::end(_nested_newgrf_inspect_chain_widgets) ); static WindowDesc _newgrf_inspect_desc( WDP_AUTO, "newgrf_inspect", 400, 300, WC_NEWGRF_INSPECT, WC_NONE, 0, - _nested_newgrf_inspect_widgets, lengthof(_nested_newgrf_inspect_widgets) + std::begin(_nested_newgrf_inspect_widgets), std::end(_nested_newgrf_inspect_widgets) ); /** @@ -1124,7 +1124,7 @@ static WindowDesc _sprite_aligner_desc( WDP_AUTO, "sprite_aligner", 400, 300, WC_SPRITE_ALIGNER, WC_NONE, 0, - _nested_sprite_aligner_widgets, lengthof(_nested_sprite_aligner_widgets) + std::begin(_nested_sprite_aligner_widgets), std::end(_nested_sprite_aligner_widgets) ); /** diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 375cc0572d..8036a3f629 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -541,7 +541,7 @@ static WindowDesc _newgrf_parameters_desc( WDP_CENTER, "settings_newgrf_config", 500, 208, WC_GRF_PARAMETERS, WC_NONE, 0, - _nested_newgrf_parameter_widgets, lengthof(_nested_newgrf_parameter_widgets) + std::begin(_nested_newgrf_parameter_widgets), std::end(_nested_newgrf_parameter_widgets) ); static void OpenGRFParameterWindow(GRFConfig *c, bool editable) @@ -1926,13 +1926,13 @@ static const NWidgetPart _nested_newgrf_infopanel_widgets[] = { /** Construct nested container widget for managing the lists and the info panel of the NewGRF GUI. */ NWidgetBase* NewGRFDisplay(int *biggest_index) { - NWidgetBase *avs = MakeNWidgets(_nested_newgrf_availables_widgets, lengthof(_nested_newgrf_availables_widgets), biggest_index, nullptr); + NWidgetBase *avs = MakeNWidgets(std::begin(_nested_newgrf_availables_widgets), std::end(_nested_newgrf_availables_widgets), biggest_index, nullptr); int biggest2; - NWidgetBase *acs = MakeNWidgets(_nested_newgrf_actives_widgets, lengthof(_nested_newgrf_actives_widgets), &biggest2, nullptr); + NWidgetBase *acs = MakeNWidgets(std::begin(_nested_newgrf_actives_widgets), std::end(_nested_newgrf_actives_widgets), &biggest2, nullptr); *biggest_index = std::max(*biggest_index, biggest2); - NWidgetBase *inf = MakeNWidgets(_nested_newgrf_infopanel_widgets, lengthof(_nested_newgrf_infopanel_widgets), &biggest2, nullptr); + NWidgetBase *inf = MakeNWidgets(std::begin(_nested_newgrf_infopanel_widgets), std::end(_nested_newgrf_infopanel_widgets), &biggest2, nullptr); *biggest_index = std::max(*biggest_index, biggest2); return new NWidgetNewGRFDisplay(avs, acs, inf); @@ -1960,7 +1960,7 @@ static WindowDesc _newgrf_desc( WDP_CENTER, "settings_newgrf", 300, 263, WC_GAME_OPTIONS, WC_NONE, 0, - _nested_newgrf_widgets, lengthof(_nested_newgrf_widgets) + std::begin(_nested_newgrf_widgets), std::end(_nested_newgrf_widgets) ); /** @@ -2044,7 +2044,7 @@ static WindowDesc _save_preset_desc( WDP_CENTER, "save_preset", 140, 110, WC_SAVE_PRESET, WC_GAME_OPTIONS, WDF_MODAL, - _nested_save_preset_widgets, lengthof(_nested_save_preset_widgets) + std::begin(_nested_save_preset_widgets), std::end(_nested_save_preset_widgets) ); /** Class for the save preset window. */ @@ -2189,7 +2189,7 @@ static WindowDesc _scan_progress_desc( WDP_CENTER, nullptr, 0, 0, WC_MODAL_PROGRESS, WC_NONE, 0, - _nested_scan_progress_widgets, lengthof(_nested_scan_progress_widgets) + std::begin(_nested_scan_progress_widgets), std::end(_nested_scan_progress_widgets) ); /** Window for showing the progress of NewGRF scanning. */ diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 765983c47a..a3cc39b778 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -100,7 +100,7 @@ static WindowDesc _normal_news_desc( WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, - _nested_normal_news_widgets, lengthof(_nested_normal_news_widgets) + std::begin(_nested_normal_news_widgets), std::end(_nested_normal_news_widgets) ); /* New vehicles news items. */ @@ -127,7 +127,7 @@ static WindowDesc _vehicle_news_desc( WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, - _nested_vehicle_news_widgets, lengthof(_nested_vehicle_news_widgets) + std::begin(_nested_vehicle_news_widgets), std::end(_nested_vehicle_news_widgets) ); /* Company news items. */ @@ -155,7 +155,7 @@ static WindowDesc _company_news_desc( WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, - _nested_company_news_widgets, lengthof(_nested_company_news_widgets) + std::begin(_nested_company_news_widgets), std::end(_nested_company_news_widgets) ); /* Thin news items. */ @@ -178,7 +178,7 @@ static WindowDesc _thin_news_desc( WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, - _nested_thin_news_widgets, lengthof(_nested_thin_news_widgets) + std::begin(_nested_thin_news_widgets), std::end(_nested_thin_news_widgets) ); /* Small news items. */ @@ -204,7 +204,7 @@ static WindowDesc _small_news_desc( WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, - _nested_small_news_widgets, lengthof(_nested_small_news_widgets) + std::begin(_nested_small_news_widgets), std::end(_nested_small_news_widgets) ); /** @@ -1231,7 +1231,7 @@ static WindowDesc _message_history_desc( WDP_AUTO, "list_news", 400, 140, WC_MESSAGE_HISTORY, WC_NONE, 0, - _nested_message_history, lengthof(_nested_message_history) + std::begin(_nested_message_history), std::end(_nested_message_history) ); /** Display window with news messages history */ diff --git a/src/object_gui.cpp b/src/object_gui.cpp index f18e1660f1..f7f6fb8de7 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -720,7 +720,7 @@ static WindowDesc _build_object_desc( WDP_AUTO, "build_object", 0, 0, WC_BUILD_OBJECT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_build_object_widgets, lengthof(_nested_build_object_widgets), + std::begin(_nested_build_object_widgets), std::end(_nested_build_object_widgets), &BuildObjectWindow::hotkeys ); diff --git a/src/order_gui.cpp b/src/order_gui.cpp index e3e84f21d5..61595f4391 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1640,7 +1640,7 @@ static WindowDesc _orders_train_desc( WDP_AUTO, "view_vehicle_orders_train", 384, 100, WC_VEHICLE_ORDERS, WC_VEHICLE_VIEW, WDF_CONSTRUCTION, - _nested_orders_train_widgets, lengthof(_nested_orders_train_widgets), + std::begin(_nested_orders_train_widgets), std::end(_nested_orders_train_widgets), &OrdersWindow::hotkeys ); @@ -1713,7 +1713,7 @@ static WindowDesc _orders_desc( WDP_AUTO, "view_vehicle_orders", 384, 100, WC_VEHICLE_ORDERS, WC_VEHICLE_VIEW, WDF_CONSTRUCTION, - _nested_orders_widgets, lengthof(_nested_orders_widgets), + std::begin(_nested_orders_widgets), std::end(_nested_orders_widgets), &OrdersWindow::hotkeys ); @@ -1740,7 +1740,7 @@ static WindowDesc _other_orders_desc( WDP_AUTO, "view_vehicle_orders_competitor", 384, 86, WC_VEHICLE_ORDERS, WC_VEHICLE_VIEW, WDF_CONSTRUCTION, - _nested_other_orders_widgets, lengthof(_nested_other_orders_widgets), + std::begin(_nested_other_orders_widgets), std::end(_nested_other_orders_widgets), &OrdersWindow::hotkeys ); diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp index c43d319b75..6c189e343f 100644 --- a/src/osk_gui.cpp +++ b/src/osk_gui.cpp @@ -338,7 +338,7 @@ static WindowDesc _osk_desc( WDP_CENTER, nullptr, 0, 0, WC_OSK, WC_NONE, 0, - _nested_osk_widgets, lengthof(_nested_osk_widgets) + std::begin(_nested_osk_widgets), std::end(_nested_osk_widgets) ); /** diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index e471cf6ec5..95c84b6d8d 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -841,7 +841,7 @@ static WindowDesc _build_rail_desc( WDP_ALIGN_TOOLBAR, "toolbar_rail", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, - _nested_build_rail_widgets, lengthof(_nested_build_rail_widgets), + std::begin(_nested_build_rail_widgets), std::end(_nested_build_rail_widgets), &BuildRailToolbarWindow::hotkeys ); @@ -1631,7 +1631,7 @@ static WindowDesc _station_builder_desc( WDP_AUTO, "build_station_rail", 350, 0, WC_BUILD_STATION, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_station_builder_widgets, lengthof(_nested_station_builder_widgets), + std::begin(_nested_station_builder_widgets), std::end(_nested_station_builder_widgets), &BuildRailStationWindow::hotkeys ); @@ -1889,7 +1889,7 @@ static WindowDesc _signal_builder_desc( WDP_AUTO, nullptr, 0, 0, WC_BUILD_SIGNAL, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_signal_builder_widgets, lengthof(_nested_signal_builder_widgets) + std::begin(_nested_signal_builder_widgets), std::end(_nested_signal_builder_widgets) ); /** @@ -1980,7 +1980,7 @@ static WindowDesc _build_depot_desc( WDP_AUTO, nullptr, 0, 0, WC_BUILD_DEPOT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_build_depot_widgets, lengthof(_nested_build_depot_widgets) + std::begin(_nested_build_depot_widgets), std::end(_nested_build_depot_widgets) ); static void ShowBuildTrainDepotPicker(Window *parent) @@ -2208,7 +2208,7 @@ static WindowDesc _build_waypoint_desc( WDP_AUTO, "build_waypoint", 0, 0, WC_BUILD_WAYPOINT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_build_waypoint_widgets, lengthof(_nested_build_waypoint_widgets) + std::begin(_nested_build_waypoint_widgets), std::end(_nested_build_waypoint_widgets) ); static void ShowBuildWaypointPicker(Window *parent) diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 056febcf00..5f5acde8d1 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -858,7 +858,7 @@ static WindowDesc _build_road_desc( WDP_ALIGN_TOOLBAR, "toolbar_road", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, - _nested_build_road_widgets, lengthof(_nested_build_road_widgets), + std::begin(_nested_build_road_widgets), std::end(_nested_build_road_widgets), &BuildRoadToolbarWindow::road_hotkeys ); @@ -899,7 +899,7 @@ static WindowDesc _build_tramway_desc( WDP_ALIGN_TOOLBAR, "toolbar_tramway", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, - _nested_build_tramway_widgets, lengthof(_nested_build_tramway_widgets), + std::begin(_nested_build_tramway_widgets), std::end(_nested_build_tramway_widgets), &BuildRoadToolbarWindow::tram_hotkeys ); @@ -954,7 +954,7 @@ static WindowDesc _build_road_scen_desc( WDP_AUTO, "toolbar_road_scen", 0, 0, WC_SCEN_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, - _nested_build_road_scen_widgets, lengthof(_nested_build_road_scen_widgets), + std::begin(_nested_build_road_scen_widgets), std::end(_nested_build_road_scen_widgets), &BuildRoadToolbarWindow::road_hotkeys ); @@ -989,7 +989,7 @@ static WindowDesc _build_tramway_scen_desc( WDP_AUTO, "toolbar_tram_scen", 0, 0, WC_SCEN_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, - _nested_build_tramway_scen_widgets, lengthof(_nested_build_tramway_scen_widgets), + std::begin(_nested_build_tramway_scen_widgets), std::end(_nested_build_tramway_scen_widgets), &BuildRoadToolbarWindow::tram_hotkeys ); @@ -1087,7 +1087,7 @@ static WindowDesc _build_road_depot_desc( WDP_AUTO, nullptr, 0, 0, WC_BUILD_DEPOT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_build_road_depot_widgets, lengthof(_nested_build_road_depot_widgets) + std::begin(_nested_build_road_depot_widgets), std::end(_nested_build_road_depot_widgets) ); static void ShowRoadDepotPicker(Window *parent) @@ -1684,7 +1684,7 @@ static WindowDesc _road_station_picker_desc( WDP_AUTO, "build_station_road", 0, 0, WC_BUS_STATION, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_road_station_picker_widgets, lengthof(_nested_road_station_picker_widgets) + std::begin(_nested_road_station_picker_widgets), std::end(_nested_road_station_picker_widgets) ); /** Widget definition of the build tram station window */ @@ -1769,7 +1769,7 @@ static WindowDesc _tram_station_picker_desc( WDP_AUTO, "build_station_tram", 0, 0, WC_BUS_STATION, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_tram_station_picker_widgets, lengthof(_nested_tram_station_picker_widgets) + std::begin(_nested_tram_station_picker_widgets), std::end(_nested_tram_station_picker_widgets) ); static void ShowRVStationPicker(Window *parent, RoadStopType rs) diff --git a/src/screenshot_gui.cpp b/src/screenshot_gui.cpp index b6d68d0919..2ace881092 100644 --- a/src/screenshot_gui.cpp +++ b/src/screenshot_gui.cpp @@ -65,7 +65,7 @@ static WindowDesc _screenshot_window_desc( WDP_AUTO, "take_a_screenshot", 200, 100, WC_SCREENSHOT, WC_NONE, 0, - _nested_screenshot, lengthof(_nested_screenshot) + std::begin(_nested_screenshot), std::end(_nested_screenshot) ); void ShowScreenshotWindow() diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp index cb9c01b01f..90be17a5d5 100644 --- a/src/script/script_gui.cpp +++ b/src/script/script_gui.cpp @@ -265,7 +265,7 @@ static WindowDesc _script_list_desc( WDP_CENTER, "settings_script_list", 200, 234, WC_SCRIPT_LIST, WC_NONE, 0, - _nested_script_list_widgets, lengthof(_nested_script_list_widgets) + std::begin(_nested_script_list_widgets), std::end(_nested_script_list_widgets) ); /** @@ -608,7 +608,7 @@ static WindowDesc _script_settings_desc( WDP_CENTER, "settings_script", 500, 208, WC_SCRIPT_SETTINGS, WC_NONE, 0, - _nested_script_settings_widgets, lengthof(_nested_script_settings_widgets) + std::begin(_nested_script_settings_widgets), std::end(_nested_script_settings_widgets) ); /** @@ -1195,7 +1195,7 @@ static WindowDesc _script_debug_desc( WDP_AUTO, "script_debug", 600, 450, WC_SCRIPT_DEBUG, WC_NONE, 0, - _nested_script_debug_widgets, lengthof(_nested_script_debug_widgets), + std::begin(_nested_script_debug_widgets), std::end(_nested_script_debug_widgets), &ScriptDebugWindow::hotkeys ); diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 2f1fedf05d..140b3765e7 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -925,7 +925,7 @@ static WindowDesc _game_options_desc( WDP_CENTER, nullptr, 0, 0, WC_GAME_OPTIONS, WC_NONE, 0, - _nested_game_options_widgets, lengthof(_nested_game_options_widgets) + std::begin(_nested_game_options_widgets), std::end(_nested_game_options_widgets) ); /** Open the game options window. */ @@ -2657,7 +2657,7 @@ static WindowDesc _settings_selection_desc( WDP_CENTER, "settings", 510, 450, WC_GAME_OPTIONS, WC_NONE, 0, - _nested_settings_selection_widgets, lengthof(_nested_settings_selection_widgets) + std::begin(_nested_settings_selection_widgets), std::end(_nested_settings_selection_widgets) ); /** Open advanced settings window. */ @@ -2956,7 +2956,7 @@ static WindowDesc _cust_currency_desc( WDP_CENTER, nullptr, 0, 0, WC_CUSTOM_CURRENCY, WC_NONE, 0, - _nested_cust_currency_widgets, lengthof(_nested_cust_currency_widgets) + std::begin(_nested_cust_currency_widgets), std::end(_nested_cust_currency_widgets) ); /** Open custom currency window. */ diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 94a2d2fc9a..e3c9cd84ea 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -389,7 +389,7 @@ static WindowDesc _sign_list_desc( WDP_AUTO, "list_signs", 358, 138, WC_SIGN_LIST, WC_NONE, 0, - _nested_sign_list_widgets, lengthof(_nested_sign_list_widgets), + std::begin(_nested_sign_list_widgets), std::end(_nested_sign_list_widgets), &SignListWindow::hotkeys ); @@ -555,7 +555,7 @@ static WindowDesc _query_sign_edit_desc( WDP_CENTER, nullptr, 0, 0, WC_QUERY_STRING, WC_NONE, WDF_CONSTRUCTION, - _nested_query_sign_edit_widgets, lengthof(_nested_query_sign_edit_widgets) + std::begin(_nested_query_sign_edit_widgets), std::end(_nested_query_sign_edit_widgets) ); /** diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index c928f08b52..4e17c1f55d 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -1833,8 +1833,8 @@ static NWidgetBase *SmallMapDisplay(int *biggest_index) { NWidgetContainer *map_display = new NWidgetSmallmapDisplay; - MakeNWidgets(_nested_smallmap_display, lengthof(_nested_smallmap_display), biggest_index, map_display); - MakeNWidgets(_nested_smallmap_bar, lengthof(_nested_smallmap_bar), biggest_index, map_display); + MakeNWidgets(std::begin(_nested_smallmap_display), std::end(_nested_smallmap_display), biggest_index, map_display); + MakeNWidgets(std::begin(_nested_smallmap_bar), std::end(_nested_smallmap_bar), biggest_index, map_display); return map_display; } @@ -1869,7 +1869,7 @@ static WindowDesc _smallmap_desc( WDP_AUTO, "smallmap", 484, 314, WC_SMALLMAP, WC_NONE, 0, - _nested_smallmap_widgets, lengthof(_nested_smallmap_widgets) + std::begin(_nested_smallmap_widgets), std::end(_nested_smallmap_widgets) ); /** diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 941d309494..fcff2b1e25 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -765,7 +765,7 @@ static WindowDesc _company_stations_desc( WDP_AUTO, "list_stations", 358, 162, WC_STATION_LIST, WC_NONE, 0, - _nested_company_stations_widgets, lengthof(_nested_company_stations_widgets) + std::begin(_nested_company_stations_widgets), std::end(_nested_company_stations_widgets) ); /** @@ -2121,7 +2121,7 @@ static WindowDesc _station_view_desc( WDP_AUTO, "view_station", 249, 117, WC_STATION_VIEW, WC_NONE, 0, - _nested_station_view_widgets, lengthof(_nested_station_view_widgets) + std::begin(_nested_station_view_widgets), std::end(_nested_station_view_widgets) ); /** @@ -2378,7 +2378,7 @@ static WindowDesc _select_station_desc( WDP_AUTO, "build_station_join", 200, 180, WC_SELECT_STATION, WC_NONE, WDF_CONSTRUCTION, - _nested_select_station_widgets, lengthof(_nested_select_station_widgets) + std::begin(_nested_select_station_widgets), std::end(_nested_select_station_widgets) ); diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 848b7ee6b0..be49e19854 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -231,7 +231,7 @@ static WindowDesc _main_status_desc( WDP_MANUAL, nullptr, 0, 0, WC_STATUS_BAR, WC_NONE, WDF_NO_FOCUS | WDF_NO_CLOSE, - _nested_main_status_widgets, lengthof(_nested_main_status_widgets) + std::begin(_nested_main_status_widgets), std::end(_nested_main_status_widgets) ); /** diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 3ed03149c7..9f3db43d1b 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -972,7 +972,7 @@ static WindowDesc _story_book_desc( WDP_CENTER, "view_story", 400, 300, WC_STORY_BOOK, WC_NONE, 0, - _nested_story_book_widgets, lengthof(_nested_story_book_widgets) + std::begin(_nested_story_book_widgets), std::end(_nested_story_book_widgets) ); static CursorID TranslateStoryPageButtonCursor(StoryPageButtonCursor cursor) diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp index d19c6e750d..ff6efbc651 100644 --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.cpp @@ -238,7 +238,7 @@ static WindowDesc _subsidies_list_desc( WDP_AUTO, "list_subsidies", 500, 127, WC_SUBSIDIES_LIST, WC_NONE, 0, - _nested_subsidies_list_widgets, lengthof(_nested_subsidies_list_widgets) + std::begin(_nested_subsidies_list_widgets), std::end(_nested_subsidies_list_widgets) ); diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index ee7a353e58..d24cbcc5d4 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -355,7 +355,7 @@ static WindowDesc _terraform_desc( WDP_MANUAL, "toolbar_landscape", 0, 0, WC_SCEN_LAND_GEN, WC_NONE, WDF_CONSTRUCTION, - _nested_terraform_widgets, lengthof(_nested_terraform_widgets), + std::begin(_nested_terraform_widgets), std::end(_nested_terraform_widgets), &TerraformToolbarWindow::hotkeys ); @@ -743,7 +743,7 @@ static WindowDesc _scen_edit_land_gen_desc( WDP_AUTO, "toolbar_landscape_scen", 0, 0, WC_SCEN_LAND_GEN, WC_NONE, WDF_CONSTRUCTION, - _nested_scen_edit_land_gen_widgets, lengthof(_nested_scen_edit_land_gen_widgets), + std::begin(_nested_scen_edit_land_gen_widgets), std::end(_nested_scen_edit_land_gen_widgets), &ScenarioEditorLandscapeGenerationWindow::hotkeys ); diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index 210cdb3070..37bf6653f2 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -56,7 +56,7 @@ static WindowDesc _textfile_desc( WDP_CENTER, "textfile", 630, 460, WC_TEXTFILE, WC_NONE, 0, - _nested_textfile_widgets, lengthof(_nested_textfile_widgets) + std::begin(_nested_textfile_widgets), std::end(_nested_textfile_widgets) ); TextfileWindow::TextfileWindow(TextfileType file_type) : Window(&_textfile_desc), file_type(file_type) diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 80b49a24f0..e58375d64d 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -746,7 +746,7 @@ static WindowDesc _timetable_desc( WDP_AUTO, "view_vehicle_timetable", 400, 130, WC_VEHICLE_TIMETABLE, WC_VEHICLE_VIEW, WDF_CONSTRUCTION, - _nested_timetable_widgets, lengthof(_nested_timetable_widgets) + std::begin(_nested_timetable_widgets), std::end(_nested_timetable_widgets) ); /** diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index f7f7eccdc1..91c2def043 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -2254,7 +2254,7 @@ static WindowDesc _toolb_normal_desc( WDP_MANUAL, nullptr, 0, 0, WC_MAIN_TOOLBAR, WC_NONE, WDF_NO_FOCUS | WDF_NO_CLOSE, - _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets), + std::begin(_nested_toolbar_normal_widgets), std::end(_nested_toolbar_normal_widgets), &MainToolbarWindow::hotkeys ); @@ -2583,7 +2583,7 @@ static const NWidgetPart _nested_toolb_scen_inner_widgets[] = { static NWidgetBase *MakeScenarioToolbar(int *biggest_index) { - return MakeNWidgets(_nested_toolb_scen_inner_widgets, lengthof(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer()); + return MakeNWidgets(std::begin(_nested_toolb_scen_inner_widgets), std::end(_nested_toolb_scen_inner_widgets), biggest_index, new NWidgetScenarioToolbarContainer()); } static const NWidgetPart _nested_toolb_scen_widgets[] = { @@ -2594,7 +2594,7 @@ static WindowDesc _toolb_scen_desc( WDP_MANUAL, nullptr, 0, 0, WC_MAIN_TOOLBAR, WC_NONE, WDF_NO_FOCUS | WDF_NO_CLOSE, - _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets), + std::begin(_nested_toolb_scen_widgets), std::end(_nested_toolb_scen_widgets), &ScenarioEditorToolbarWindow::hotkeys ); diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 15c1be5b27..8b2a820f57 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -330,7 +330,7 @@ static WindowDesc _town_authority_desc( WDP_AUTO, "view_town_authority", 317, 222, WC_TOWN_AUTHORITY, WC_NONE, 0, - _nested_town_authority_widgets, lengthof(_nested_town_authority_widgets) + std::begin(_nested_town_authority_widgets), std::end(_nested_town_authority_widgets) ); static void ShowTownAuthorityWindow(uint town) @@ -631,7 +631,7 @@ static WindowDesc _town_game_view_desc( WDP_AUTO, "view_town", 260, TownViewWindow::WID_TV_HEIGHT_NORMAL, WC_TOWN_VIEW, WC_NONE, 0, - _nested_town_game_view_widgets, lengthof(_nested_town_game_view_widgets) + std::begin(_nested_town_game_view_widgets), std::end(_nested_town_game_view_widgets) ); static const NWidgetPart _nested_town_editor_view_widgets[] = { @@ -662,7 +662,7 @@ static WindowDesc _town_editor_view_desc( WDP_AUTO, "view_town_scen", 260, TownViewWindow::WID_TV_HEIGHT_NORMAL, WC_TOWN_VIEW, WC_NONE, 0, - _nested_town_editor_view_widgets, lengthof(_nested_town_editor_view_widgets) + std::begin(_nested_town_editor_view_widgets), std::end(_nested_town_editor_view_widgets) ); void ShowTownViewWindow(TownID town) @@ -1037,7 +1037,7 @@ static WindowDesc _town_directory_desc( WDP_AUTO, "list_towns", 208, 202, WC_TOWN_DIRECTORY, WC_NONE, 0, - _nested_town_directory_widgets, lengthof(_nested_town_directory_widgets) + std::begin(_nested_town_directory_widgets), std::end(_nested_town_directory_widgets) ); void ShowTownDirectory() @@ -1287,7 +1287,7 @@ static WindowDesc _found_town_desc( WDP_AUTO, "build_town", 160, 162, WC_FOUND_TOWN, WC_NONE, WDF_CONSTRUCTION, - _nested_found_town_widgets, lengthof(_nested_found_town_widgets) + std::begin(_nested_found_town_widgets), std::end(_nested_found_town_widgets) ); void ShowFoundTownWindow() diff --git a/src/transparency_gui.cpp b/src/transparency_gui.cpp index 8c11803f07..6d998de96b 100644 --- a/src/transparency_gui.cpp +++ b/src/transparency_gui.cpp @@ -152,7 +152,7 @@ static WindowDesc _transparency_desc( WDP_MANUAL, "toolbar_transparency", 0, 0, WC_TRANSPARENCY_TOOLBAR, WC_NONE, 0, - _nested_transparency_widgets, lengthof(_nested_transparency_widgets) + std::begin(_nested_transparency_widgets), std::end(_nested_transparency_widgets) ); /** diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index ac8d0fc962..fb39ab7fd7 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -320,7 +320,7 @@ static WindowDesc _build_trees_desc( WDP_AUTO, "build_tree", 0, 0, WC_BUILD_TREES, WC_NONE, WDF_CONSTRUCTION, - _nested_build_trees_widgets, lengthof(_nested_build_trees_widgets) + std::begin(_nested_build_trees_widgets), std::end(_nested_build_trees_widgets) ); void ShowBuildTreesToolbar() diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 9810c9c17f..71250a5d1e 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1238,7 +1238,7 @@ static WindowDesc _vehicle_refit_desc( WDP_AUTO, "view_vehicle_refit", 240, 174, WC_VEHICLE_REFIT, WC_VEHICLE_VIEW, WDF_CONSTRUCTION, - _nested_vehicle_refit_widgets, lengthof(_nested_vehicle_refit_widgets) + std::begin(_nested_vehicle_refit_widgets), std::end(_nested_vehicle_refit_widgets) ); /** @@ -2171,14 +2171,14 @@ static WindowDesc _vehicle_list_other_desc( WDP_AUTO, "list_vehicles", 260, 246, WC_INVALID, WC_NONE, 0, - _nested_vehicle_list, lengthof(_nested_vehicle_list) + std::begin(_nested_vehicle_list), std::end(_nested_vehicle_list) ); static WindowDesc _vehicle_list_train_desc( WDP_AUTO, "list_vehicles_train", 325, 246, WC_TRAINS_LIST, WC_NONE, 0, - _nested_vehicle_list, lengthof(_nested_vehicle_list) + std::begin(_nested_vehicle_list), std::end(_nested_vehicle_list) ); static void ShowVehicleListWindowLocal(CompanyID company, VehicleListType vlt, VehicleType vehicle_type, uint32_t unique_number) @@ -2680,7 +2680,7 @@ static WindowDesc _train_vehicle_details_desc( WDP_AUTO, "view_vehicle_details_train", 405, 178, WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW, 0, - _nested_train_vehicle_details_widgets, lengthof(_nested_train_vehicle_details_widgets) + std::begin(_nested_train_vehicle_details_widgets), std::end(_nested_train_vehicle_details_widgets) ); /** Vehicle details window descriptor for other vehicles than a train. */ @@ -2688,7 +2688,7 @@ static WindowDesc _nontrain_vehicle_details_desc( WDP_AUTO, "view_vehicle_details", 405, 113, WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW, 0, - _nested_nontrain_vehicle_details_widgets, lengthof(_nested_nontrain_vehicle_details_widgets) + std::begin(_nested_nontrain_vehicle_details_widgets), std::end(_nested_nontrain_vehicle_details_widgets) ); /** Shows the vehicle details window of the given vehicle. */ @@ -3285,7 +3285,7 @@ static WindowDesc _vehicle_view_desc( WDP_AUTO, "view_vehicle", 250, 116, WC_VEHICLE_VIEW, WC_NONE, 0, - _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets), + std::begin(_nested_vehicle_view_widgets), std::end(_nested_vehicle_view_widgets), &VehicleViewWindow::hotkeys ); @@ -3297,7 +3297,7 @@ static WindowDesc _train_view_desc( WDP_AUTO, "view_vehicle_train", 250, 134, WC_VEHICLE_VIEW, WC_NONE, 0, - _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets), + std::begin(_nested_vehicle_view_widgets), std::end(_nested_vehicle_view_widgets), &VehicleViewWindow::hotkeys ); diff --git a/src/viewport_gui.cpp b/src/viewport_gui.cpp index c8bf96157b..c81e4920f6 100644 --- a/src/viewport_gui.cpp +++ b/src/viewport_gui.cpp @@ -163,7 +163,7 @@ static WindowDesc _extra_viewport_desc( WDP_AUTO, "extra_viewport", 300, 268, WC_EXTRA_VIEWPORT, WC_NONE, 0, - _nested_extra_viewport_widgets, lengthof(_nested_extra_viewport_widgets) + std::begin(_nested_extra_viewport_widgets), std::end(_nested_extra_viewport_widgets) ); /** diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp index d8b3c10379..d2042cf90e 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.cpp @@ -187,7 +187,7 @@ static WindowDesc _waypoint_view_desc( WDP_AUTO, "view_waypoint", 260, 118, WC_WAYPOINT_VIEW, WC_NONE, 0, - _nested_waypoint_view_widgets, lengthof(_nested_waypoint_view_widgets) + std::begin(_nested_waypoint_view_widgets), std::end(_nested_waypoint_view_widgets) ); /** diff --git a/src/widget.cpp b/src/widget.cpp index 5d2687f97a..9eabaa8a3c 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -3008,23 +3008,23 @@ bool NWidgetLeaf::ButtonHit(const Point &pt) * settings that follow it, until encountering a #EndContainer, another * #NWidget, or the end of the parts array. * - * @param parts Array with parts of the nested widget. - * @param count Length of the \a parts array. + * @param nwid_begin Pointer to beginning of nested widget parts. + * @param nwid_end Pointer to ending of nested widget parts. * @param dest Address of pointer to use for returning the composed widget. * @param fill_dest Fill the composed widget with child widgets. * @param biggest_index Pointer to biggest nested widget index in the tree encountered so far. * @return Number of widget part elements used to compose the widget. * @pre \c biggest_index != nullptr. */ -static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, bool *fill_dest, int *biggest_index) +static int MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **dest, bool *fill_dest, int *biggest_index) { int num_used = 0; *dest = nullptr; *fill_dest = false; - while (count > num_used) { - switch (parts->type) { + while (nwid_begin < nwid_end) { + switch (nwid_begin->type) { case NWID_SPACER: if (*dest != nullptr) return num_used; *dest = new NWidgetSpacer(0, 0); @@ -3032,13 +3032,13 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case NWID_HORIZONTAL: if (*dest != nullptr) return num_used; - *dest = new NWidgetHorizontal(parts->u.cont_flags); + *dest = new NWidgetHorizontal(nwid_begin->u.cont_flags); *fill_dest = true; break; case NWID_HORIZONTAL_LTR: if (*dest != nullptr) return num_used; - *dest = new NWidgetHorizontalLTR(parts->u.cont_flags); + *dest = new NWidgetHorizontalLTR(nwid_begin->u.cont_flags); *fill_dest = true; break; @@ -3046,14 +3046,14 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WWT_INSET: case WWT_FRAME: if (*dest != nullptr) return num_used; - *dest = new NWidgetBackground(parts->type, parts->u.widget.colour, parts->u.widget.index); - *biggest_index = std::max(*biggest_index, (int)parts->u.widget.index); + *dest = new NWidgetBackground(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index); + *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); *fill_dest = true; break; case NWID_VERTICAL: if (*dest != nullptr) return num_used; - *dest = new NWidgetVertical(parts->u.cont_flags); + *dest = new NWidgetVertical(nwid_begin->u.cont_flags); *fill_dest = true; break; @@ -3062,9 +3062,9 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, NWidgetMatrix *nwm = new NWidgetMatrix(); *dest = nwm; *fill_dest = true; - nwm->SetIndex(parts->u.widget.index); - nwm->SetColour(parts->u.widget.colour); - *biggest_index = std::max(*biggest_index, (int)parts->u.widget.index); + nwm->SetIndex(nwid_begin->u.widget.index); + nwm->SetColour(nwid_begin->u.widget.colour); + *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); break; } @@ -3072,7 +3072,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, if (*dest != nullptr) return num_used; /* Ensure proper functioning even when the called code simply writes its largest index. */ int biggest = -1; - *dest = parts->u.func_ptr(&biggest); + *dest = nwid_begin->u.func_ptr(&biggest); *biggest_index = std::max(*biggest_index, biggest); *fill_dest = false; break; @@ -3081,8 +3081,8 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WPT_RESIZE: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); if (nwrb != nullptr) { - assert(parts->u.xy.x >= 0 && parts->u.xy.y >= 0); - nwrb->SetResize(parts->u.xy.x, parts->u.xy.y); + assert(nwid_begin->u.xy.x >= 0 && nwid_begin->u.xy.y >= 0); + nwrb->SetResize(nwid_begin->u.xy.x, nwid_begin->u.xy.y); } break; } @@ -3090,8 +3090,8 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WPT_MINSIZE: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); if (nwrb != nullptr) { - assert(parts->u.xy.x >= 0 && parts->u.xy.y >= 0); - nwrb->SetMinimalSize(parts->u.xy.x, parts->u.xy.y); + assert(nwid_begin->u.xy.x >= 0 && nwid_begin->u.xy.y >= 0); + nwrb->SetMinimalSize(nwid_begin->u.xy.x, nwid_begin->u.xy.y); } break; } @@ -3099,8 +3099,8 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WPT_MINTEXTLINES: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); if (nwrb != nullptr) { - assert(parts->u.text_lines.size >= FS_BEGIN && parts->u.text_lines.size < FS_END); - nwrb->SetMinimalTextLines(parts->u.text_lines.lines, parts->u.text_lines.spacing, parts->u.text_lines.size); + assert(nwid_begin->u.text_lines.size >= FS_BEGIN && nwid_begin->u.text_lines.size < FS_END); + nwrb->SetMinimalTextLines(nwid_begin->u.text_lines.lines, nwid_begin->u.text_lines.spacing, nwid_begin->u.text_lines.size); } break; } @@ -3108,7 +3108,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WPT_TEXTSTYLE: { NWidgetCore *nwc = dynamic_cast(*dest); if (nwc != nullptr) { - nwc->SetTextStyle(parts->u.text_style.colour, parts->u.text_style.size); + nwc->SetTextStyle(nwid_begin->u.text_style.colour, nwid_begin->u.text_style.size); } break; } @@ -3116,43 +3116,43 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WPT_ALIGNMENT: { NWidgetCore *nwc = dynamic_cast(*dest); if (nwc != nullptr) { - nwc->SetAlignment(parts->u.align.align); + nwc->SetAlignment(nwid_begin->u.align.align); } break; } case WPT_FILL: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); - if (nwrb != nullptr) nwrb->SetFill(parts->u.xy.x, parts->u.xy.y); + if (nwrb != nullptr) nwrb->SetFill(nwid_begin->u.xy.x, nwid_begin->u.xy.y); break; } case WPT_DATATIP: { NWidgetCore *nwc = dynamic_cast(*dest); if (nwc != nullptr) { - nwc->widget_data = parts->u.data_tip.data; - nwc->tool_tip = parts->u.data_tip.tooltip; + nwc->widget_data = nwid_begin->u.data_tip.data; + nwc->tool_tip = nwid_begin->u.data_tip.tooltip; } break; } case WPT_PADDING: - if (*dest != nullptr) (*dest)->SetPadding(parts->u.padding); + if (*dest != nullptr) (*dest)->SetPadding(nwid_begin->u.padding); break; case WPT_PIPSPACE: { NWidgetPIPContainer *nwc = dynamic_cast(*dest); - if (nwc != nullptr) nwc->SetPIP(parts->u.pip.pre, parts->u.pip.inter, parts->u.pip.post); + if (nwc != nullptr) nwc->SetPIP(nwid_begin->u.pip.pre, nwid_begin->u.pip.inter, nwid_begin->u.pip.post); NWidgetBackground *nwb = dynamic_cast(*dest); - if (nwb != nullptr) nwb->SetPIP(parts->u.pip.pre, parts->u.pip.inter, parts->u.pip.post); + if (nwb != nullptr) nwb->SetPIP(nwid_begin->u.pip.pre, nwid_begin->u.pip.inter, nwid_begin->u.pip.post); break; } case WPT_SCROLLBAR: { NWidgetCore *nwc = dynamic_cast(*dest); if (nwc != nullptr) { - nwc->scrollbar_index = parts->u.widget.index; + nwc->scrollbar_index = nwid_begin->u.widget.index; } break; } @@ -3162,15 +3162,15 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case NWID_VIEWPORT: if (*dest != nullptr) return num_used; - *dest = new NWidgetViewport(parts->u.widget.index); - *biggest_index = std::max(*biggest_index, (int)parts->u.widget.index); + *dest = new NWidgetViewport(nwid_begin->u.widget.index); + *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); break; case NWID_HSCROLLBAR: case NWID_VSCROLLBAR: if (*dest != nullptr) return num_used; - *dest = new NWidgetScrollbar(parts->type, parts->u.widget.colour, parts->u.widget.index); - *biggest_index = std::max(*biggest_index, (int)parts->u.widget.index); + *dest = new NWidgetScrollbar(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index); + *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); break; case NWID_SELECTION: { @@ -3178,20 +3178,20 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, NWidgetStacked *nws = new NWidgetStacked(); *dest = nws; *fill_dest = true; - nws->SetIndex(parts->u.widget.index); - *biggest_index = std::max(*biggest_index, (int)parts->u.widget.index); + nws->SetIndex(nwid_begin->u.widget.index); + *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); break; } default: if (*dest != nullptr) return num_used; - assert((parts->type & WWT_MASK) < WWT_LAST || (parts->type & WWT_MASK) == NWID_BUTTON_DROPDOWN); - *dest = new NWidgetLeaf(parts->type, parts->u.widget.colour, parts->u.widget.index, 0x0, STR_NULL); - *biggest_index = std::max(*biggest_index, (int)parts->u.widget.index); + assert((nwid_begin->type & WWT_MASK) < WWT_LAST || (nwid_begin->type & WWT_MASK) == NWID_BUTTON_DROPDOWN); + *dest = new NWidgetLeaf(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index, 0x0, STR_NULL); + *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); break; } num_used++; - parts++; + nwid_begin++; } return num_used; @@ -3199,14 +3199,14 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, /** * Build a nested widget tree by recursively filling containers with nested widgets read from their parts. - * @param parts Array with parts of the nested widgets. - * @param count Length of the \a parts array. + * @param nwid_begin Pointer to beginning of nested widget parts. + * @param nwid_end Pointer to ending of nested widget parts. * @param parent Pointer or container to use for storing the child widgets (*parent == nullptr or *parent == container or background widget). * @param biggest_index Pointer to biggest nested widget index in the tree. * @return Number of widget part elements used to fill the container. * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used. */ -static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase **parent, int *biggest_index) +static int MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **parent, int *biggest_index) { /* If *parent == nullptr, only the first widget is read and returned. Otherwise, *parent must point to either * a #NWidgetContainer or a #NWidgetBackground object, and parts are added as much as possible. */ @@ -3218,8 +3218,8 @@ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase **par for (;;) { NWidgetBase *sub_widget = nullptr; bool fill_sub = false; - int num_used = MakeNWidget(parts, count - total_used, &sub_widget, &fill_sub, biggest_index); - parts += num_used; + int num_used = MakeNWidget(nwid_begin, nwid_end, &sub_widget, &fill_sub, biggest_index); + nwid_begin += num_used; total_used += num_used; /* Break out of loop when end reached */ @@ -3230,8 +3230,8 @@ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase **par if (fill_sub && (tp == NWID_HORIZONTAL || tp == NWID_HORIZONTAL_LTR || tp == NWID_VERTICAL || tp == NWID_MATRIX || tp == WWT_PANEL || tp == WWT_FRAME || tp == WWT_INSET || tp == NWID_SELECTION)) { NWidgetBase *sub_ptr = sub_widget; - num_used = MakeWidgetTree(parts, count - total_used, &sub_ptr, biggest_index); - parts += num_used; + num_used = MakeWidgetTree(nwid_begin, nwid_end, &sub_ptr, biggest_index); + nwid_begin += num_used; total_used += num_used; } @@ -3244,17 +3244,17 @@ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase **par } } - if (count == total_used) return total_used; // Reached the end of the array of parts? + if (nwid_begin == nwid_end) return total_used; // Reached the end of the array of parts? - assert(total_used < count); - assert(parts->type == WPT_ENDCONTAINER); - return total_used + 1; // *parts is also 'used' + assert(nwid_begin < nwid_end); + assert(nwid_begin->type == WPT_ENDCONTAINER); + return total_used + 1; // *nwid_begin is also 'used' } /** * Construct a nested widget tree from an array of parts. - * @param parts Array with parts of the widgets. - * @param count Length of the \a parts array. + * @param nwid_begin Pointer to beginning of nested widget parts. + * @param nwid_end Pointer to ending of nested widget parts. * @param biggest_index Pointer to biggest nested widget index collected in the tree. * @param container Container to add the nested widgets to. In case it is nullptr a vertical container is used. * @return Root of the nested widget tree, a vertical container containing the entire GUI. @@ -3262,12 +3262,12 @@ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase **par * @pre \c biggest_index != nullptr * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used. */ -NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container) +NWidgetContainer *MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, int *biggest_index, NWidgetContainer *container) { *biggest_index = -1; if (container == nullptr) container = new NWidgetVertical(); NWidgetBase *cont_ptr = container; - MakeWidgetTree(parts, count, &cont_ptr, biggest_index); + MakeWidgetTree(nwid_begin, nwid_end, &cont_ptr, biggest_index); return container; } @@ -3275,8 +3275,8 @@ NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest * Make a nested widget tree for a window from a parts array. Besides loading, it inserts a shading selection widget * between the title bar and the window body if the first widget in the parts array looks like a title bar (it is a horizontal * container with a caption widget) and has a shade box widget. - * @param parts Array with parts of the widgets. - * @param count Length of the \a parts array. + * @param nwid_begin Pointer to beginning of nested widget parts. + * @param nwid_end Pointer to ending of nested widget parts. * @param biggest_index Pointer to biggest nested widget index collected in the tree. * @param[out] shade_select Pointer to the inserted shade selection widget (\c nullptr if not unserted). * @return Root of the nested widget tree, a vertical container containing the entire GUI. @@ -3284,20 +3284,19 @@ NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest * @pre \c biggest_index != nullptr * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used. */ -NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index, NWidgetStacked **shade_select) +NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, int *biggest_index, NWidgetStacked **shade_select) { *biggest_index = -1; /* Read the first widget recursively from the array. */ NWidgetBase *nwid = nullptr; - int num_used = MakeWidgetTree(parts, count, &nwid, biggest_index); + int num_used = MakeWidgetTree(nwid_begin, nwid_end, &nwid, biggest_index); assert(nwid != nullptr); - parts += num_used; - count -= num_used; + nwid_begin += num_used; NWidgetContainer *root = new NWidgetVertical; root->Add(nwid); - if (count == 0) { // There is no body at all. + if (nwid_begin == nwid_end) { // There is no body at all. *shade_select = nullptr; return root; } @@ -3318,7 +3317,7 @@ NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int /* Load the remaining parts into 'body'. */ int biggest2 = -1; - MakeNWidgets(parts, count, &biggest2, body); + MakeNWidgets(nwid_begin, nwid_end, &biggest2, body); *biggest_index = std::max(*biggest_index, biggest2); return root; diff --git a/src/widget_type.h b/src/widget_type.h index 6edbdf0533..f00577e9c4 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -1296,8 +1296,8 @@ static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr) return part; } -NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container); -NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index, NWidgetStacked **shade_select); +NWidgetContainer *MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, int *biggest_index, NWidgetContainer *container); +NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, int *biggest_index, NWidgetStacked **shade_select); NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, Colours button_colour, int max_length, StringID button_tooltip); diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index d43e3f995f..137c375dcb 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -104,7 +104,7 @@ static WindowDesc _dropdown_desc( WDP_MANUAL, nullptr, 0, 0, WC_DROPDOWN_MENU, WC_NONE, WDF_NO_FOCUS, - _nested_dropdown_menu_widgets, lengthof(_nested_dropdown_menu_widgets) + std::begin(_nested_dropdown_menu_widgets), std::end(_nested_dropdown_menu_widgets) ); /** Drop-down menu window */ diff --git a/src/window.cpp b/src/window.cpp index ba8a06a1c8..839ccbb469 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -104,14 +104,14 @@ std::string _windows_file; /** Window description constructor. */ WindowDesc::WindowDesc(WindowPosition def_pos, const char *ini_key, int16_t def_width_trad, int16_t def_height_trad, WindowClass window_class, WindowClass parent_class, uint32_t flags, - const NWidgetPart *nwid_parts, int16_t nwid_length, HotkeyList *hotkeys) : + const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, HotkeyList *hotkeys) : default_pos(def_pos), cls(window_class), parent_cls(parent_class), ini_key(ini_key), flags(flags), - nwid_parts(nwid_parts), - nwid_length(nwid_length), + nwid_begin(nwid_begin), + nwid_end(nwid_end), hotkeys(hotkeys), pref_sticky(false), pref_width(0), @@ -1798,7 +1798,7 @@ static Point LocalGetWindowPlacement(const WindowDesc *desc, int16_t sm_width, i void Window::CreateNestedTree(bool fill_nested) { int biggest_index = -1; - this->nested_root = MakeWindowNWidgetTree(this->window_desc->nwid_parts, this->window_desc->nwid_length, &biggest_index, &this->shade_select); + this->nested_root = MakeWindowNWidgetTree(this->window_desc->nwid_begin, this->window_desc->nwid_end, &biggest_index, &this->shade_select); this->nested_array_size = (uint)(biggest_index + 1); if (fill_nested) { diff --git a/src/window_gui.h b/src/window_gui.h index 1d0d884c54..77f6d20429 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -97,7 +97,7 @@ struct WindowDesc : ZeroedMemoryAllocator { WindowDesc(WindowPosition default_pos, const char *ini_key, int16_t def_width_trad, int16_t def_height_trad, WindowClass window_class, WindowClass parent_class, uint32_t flags, - const NWidgetPart *nwid_parts, int16_t nwid_length, HotkeyList *hotkeys = nullptr); + const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, HotkeyList *hotkeys = nullptr); ~WindowDesc(); @@ -106,8 +106,8 @@ struct WindowDesc : ZeroedMemoryAllocator { WindowClass parent_cls; ///< Class of the parent window. @see WindowClass const char *ini_key; ///< Key to store window defaults in openttd.cfg. \c nullptr if nothing shall be stored. uint32_t flags; ///< Flags. @see WindowDefaultFlag - const NWidgetPart *nwid_parts; ///< Nested widget parts describing the window. - int16_t nwid_length; ///< Length of the #nwid_parts array. + const NWidgetPart *nwid_begin; ///< Beginning of nested widget parts describing the window. + const NWidgetPart *nwid_end; ///< Ending of nested widget parts describing the window. HotkeyList *hotkeys; ///< Hotkeys for the window. bool pref_sticky; ///< Preferred stickyness. From 152b0cac3474aa1465b703eca93de5901dd1c12d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 3 Sep 2023 21:55:30 +0100 Subject: [PATCH 13/72] Codechange: Return update nwid_begin instead of count. This avoids needing to keep track of how many widget parts have been consumed, instead we only to ensure nwid_begin < nwid_end. --- src/widget.cpp | 55 +++++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/src/widget.cpp b/src/widget.cpp index 9eabaa8a3c..d5990c847b 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -3013,31 +3013,29 @@ bool NWidgetLeaf::ButtonHit(const Point &pt) * @param dest Address of pointer to use for returning the composed widget. * @param fill_dest Fill the composed widget with child widgets. * @param biggest_index Pointer to biggest nested widget index in the tree encountered so far. - * @return Number of widget part elements used to compose the widget. + * @return Pointer to remaining nested widget parts. * @pre \c biggest_index != nullptr. */ -static int MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **dest, bool *fill_dest, int *biggest_index) +static const NWidgetPart *MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **dest, bool *fill_dest, int *biggest_index) { - int num_used = 0; - *dest = nullptr; *fill_dest = false; while (nwid_begin < nwid_end) { switch (nwid_begin->type) { case NWID_SPACER: - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; *dest = new NWidgetSpacer(0, 0); break; case NWID_HORIZONTAL: - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; *dest = new NWidgetHorizontal(nwid_begin->u.cont_flags); *fill_dest = true; break; case NWID_HORIZONTAL_LTR: - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; *dest = new NWidgetHorizontalLTR(nwid_begin->u.cont_flags); *fill_dest = true; break; @@ -3045,20 +3043,20 @@ static int MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_en case WWT_PANEL: case WWT_INSET: case WWT_FRAME: - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; *dest = new NWidgetBackground(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index); *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); *fill_dest = true; break; case NWID_VERTICAL: - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; *dest = new NWidgetVertical(nwid_begin->u.cont_flags); *fill_dest = true; break; case NWID_MATRIX: { - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; NWidgetMatrix *nwm = new NWidgetMatrix(); *dest = nwm; *fill_dest = true; @@ -3069,7 +3067,7 @@ static int MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_en } case WPT_FUNCTION: { - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; /* Ensure proper functioning even when the called code simply writes its largest index. */ int biggest = -1; *dest = nwid_begin->u.func_ptr(&biggest); @@ -3158,23 +3156,23 @@ static int MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_en } case WPT_ENDCONTAINER: - return num_used; + return nwid_begin; case NWID_VIEWPORT: - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; *dest = new NWidgetViewport(nwid_begin->u.widget.index); *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); break; case NWID_HSCROLLBAR: case NWID_VSCROLLBAR: - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; *dest = new NWidgetScrollbar(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index); *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); break; case NWID_SELECTION: { - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; NWidgetStacked *nws = new NWidgetStacked(); *dest = nws; *fill_dest = true; @@ -3184,17 +3182,16 @@ static int MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_en } default: - if (*dest != nullptr) return num_used; + if (*dest != nullptr) return nwid_begin; assert((nwid_begin->type & WWT_MASK) < WWT_LAST || (nwid_begin->type & WWT_MASK) == NWID_BUTTON_DROPDOWN); *dest = new NWidgetLeaf(nwid_begin->type, nwid_begin->u.widget.colour, nwid_begin->u.widget.index, 0x0, STR_NULL); *biggest_index = std::max(*biggest_index, (int)nwid_begin->u.widget.index); break; } - num_used++; nwid_begin++; } - return num_used; + return nwid_begin; } /** @@ -3203,10 +3200,10 @@ static int MakeNWidget(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_en * @param nwid_end Pointer to ending of nested widget parts. * @param parent Pointer or container to use for storing the child widgets (*parent == nullptr or *parent == container or background widget). * @param biggest_index Pointer to biggest nested widget index in the tree. - * @return Number of widget part elements used to fill the container. + * @return Pointer to remaining nested widget parts. * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used. */ -static int MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **parent, int *biggest_index) +static const NWidgetPart *MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, NWidgetBase **parent, int *biggest_index) { /* If *parent == nullptr, only the first widget is read and returned. Otherwise, *parent must point to either * a #NWidgetContainer or a #NWidgetBackground object, and parts are added as much as possible. */ @@ -3214,13 +3211,10 @@ static int MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid NWidgetBackground *nwid_parent = dynamic_cast(*parent); assert(*parent == nullptr || (nwid_cont != nullptr && nwid_parent == nullptr) || (nwid_cont == nullptr && nwid_parent != nullptr)); - int total_used = 0; for (;;) { NWidgetBase *sub_widget = nullptr; bool fill_sub = false; - int num_used = MakeNWidget(nwid_begin, nwid_end, &sub_widget, &fill_sub, biggest_index); - nwid_begin += num_used; - total_used += num_used; + nwid_begin = MakeNWidget(nwid_begin, nwid_end, &sub_widget, &fill_sub, biggest_index); /* Break out of loop when end reached */ if (sub_widget == nullptr) break; @@ -3230,9 +3224,7 @@ static int MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid if (fill_sub && (tp == NWID_HORIZONTAL || tp == NWID_HORIZONTAL_LTR || tp == NWID_VERTICAL || tp == NWID_MATRIX || tp == WWT_PANEL || tp == WWT_FRAME || tp == WWT_INSET || tp == NWID_SELECTION)) { NWidgetBase *sub_ptr = sub_widget; - num_used = MakeWidgetTree(nwid_begin, nwid_end, &sub_ptr, biggest_index); - nwid_begin += num_used; - total_used += num_used; + nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, &sub_ptr, biggest_index); } /* Add sub_widget to parent container if available, otherwise return the widget to the caller. */ @@ -3240,15 +3232,15 @@ static int MakeWidgetTree(const NWidgetPart *nwid_begin, const NWidgetPart *nwid if (nwid_parent != nullptr) nwid_parent->Add(sub_widget); if (nwid_cont == nullptr && nwid_parent == nullptr) { *parent = sub_widget; - return total_used; + return nwid_begin; } } - if (nwid_begin == nwid_end) return total_used; // Reached the end of the array of parts? + if (nwid_begin == nwid_end) return nwid_begin; // Reached the end of the array of parts? assert(nwid_begin < nwid_end); assert(nwid_begin->type == WPT_ENDCONTAINER); - return total_used + 1; // *nwid_begin is also 'used' + return nwid_begin + 1; // *nwid_begin is also 'used' } /** @@ -3290,9 +3282,8 @@ NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *nwid_begin, const NWi /* Read the first widget recursively from the array. */ NWidgetBase *nwid = nullptr; - int num_used = MakeWidgetTree(nwid_begin, nwid_end, &nwid, biggest_index); + nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, &nwid, biggest_index); assert(nwid != nullptr); - nwid_begin += num_used; NWidgetContainer *root = new NWidgetVertical; root->Add(nwid); From 337b7b0c63cf273aee38517baa5f01a486eba92b Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Mon, 4 Sep 2023 13:18:47 +0200 Subject: [PATCH 14/72] Fix 8c9ecde9: actually remove autosave_interval from setting window (#11260) --- src/settings_gui.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 140b3765e7..e2aeeec19e 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1814,7 +1814,6 @@ static SettingsContainer &GetSettingsTree() } interface->Add(new SettingEntry("gui.fast_forward_speed_limit")); - interface->Add(new SettingEntry("gui.autosave_interval")); interface->Add(new SettingEntry("gui.toolbar_pos")); interface->Add(new SettingEntry("gui.statusbar_pos")); interface->Add(new SettingEntry("gui.prefer_teamchat")); From 9d2920e9c5bcaaef8a61b184ef5b959f9c9aaa33 Mon Sep 17 00:00:00 2001 From: translators Date: Mon, 4 Sep 2023 18:38:09 +0000 Subject: [PATCH 15/72] Update: Translations from eints french: 2 changes by ottdfevr --- src/lang/french.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lang/french.txt b/src/lang/french.txt index f8390d63f8..fe755b991a 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -1427,6 +1427,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Aucun* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Réduit STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Autoriser les passages à niveau sur les routes ou rails possédés par les concurrents{NBSP}: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Autoriser la construction de passages à niveau sur les routes ou rails possédés par les concurrents STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Autoriser les arrêts de bus sur les routes appartenant aux municipalités{NBSP}: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Autoriser la construction des arrêts de bus sur les routes appartenant aux municipalités From 6e8d7964edef0c348edfe9ce5d5dc698ee5f3031 Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 5 Sep 2023 18:38:17 +0000 Subject: [PATCH 16/72] Update: Translations from eints english (us): 4 changes by 2TallTyler --- src/lang/english_US.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 1539b620c5..a948e11e91 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -1426,6 +1426,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :None* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduced STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Allow grade crossings with roads or rails owned by competitors: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Allow construction of grade crossings on roads or rails owned by competitors STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Allow drive-through road stops on roads owned by towns: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Allow construction of drive-through road stops on roads owned by towns @@ -2651,6 +2653,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Toggle t STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Toggle transparency for bridges. Ctrl+Click to lock STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Toggle transparency for structures like lighthouses and antennas. Ctrl+Click to lock STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Toggle transparency for catenary. Ctrl+Click to lock +STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK}Toggle transparency for loading and cost/income text. Ctrl+Click to lock STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Set objects invisible instead of transparent # Linkgraph legend window @@ -4964,7 +4967,7 @@ STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}No suita STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Must remove railroad track first STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Road is one way or blocked STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Grade crossings not allowed for this rail type -STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Level crossings not allowed for this road type +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Grade crossings not allowed for this road type STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Can't build signals here... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Can't build railroad track here... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Can't remove railroad track from here... From 5f9b8aaa955f1a354ea317f8463785f7d08575b6 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 6 Sep 2023 13:14:12 +0200 Subject: [PATCH 17/72] Codechange: [Script] use nlohmann for Squirrel <-> JSON conversion (#11251) --- src/network/core/config.h | 2 +- src/network/network_admin.cpp | 5 - src/script/api/script_admin.cpp | 72 ++++------ src/script/api/script_admin.hpp | 10 +- src/script/api/script_event_types.cpp | 194 ++++++-------------------- src/script/api/script_event_types.hpp | 22 +-- src/tests/test_script_admin.cpp | 76 +++++----- 7 files changed, 123 insertions(+), 258 deletions(-) diff --git a/src/network/core/config.h b/src/network/core/config.h index 7657a88d06..e6b4882e2b 100644 --- a/src/network/core/config.h +++ b/src/network/core/config.h @@ -60,7 +60,7 @@ static const uint NETWORK_REVISION_LENGTH = 33; ///< The m static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH) static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0' static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0' -static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = COMPAT_MTU - 3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes) +static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = 9000; ///< The maximum length of a receiving gamescript json string, in bytes including '\0'. static const uint NETWORK_CHAT_LENGTH = 900; ///< The maximum length of a chat message, in bytes including '\0' static const uint NETWORK_CONTENT_FILENAME_LENGTH = 48; ///< The maximum length of a content's filename, in bytes including '\0'. static const uint NETWORK_CONTENT_NAME_LENGTH = 32; ///< The maximum length of a content's name, in bytes including '\0'. diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index ae42156d29..40679352d6 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -557,11 +557,6 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const std::string */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const std::string_view json) { - /* At the moment we cannot transmit anything larger than MTU. So we limit - * the maximum amount of json data that can be sent. Account also for - * the trailing \0 of the string */ - if (json.size() + 1 >= NETWORK_GAMESCRIPT_JSON_LENGTH) return NETWORK_RECV_STATUS_OKAY; - Packet *p = new Packet(ADMIN_PACKET_SERVER_GAMESCRIPT); p->Send_string(json); diff --git a/src/script/api/script_admin.cpp b/src/script/api/script_admin.cpp index 9f55e1b958..2c30434792 100644 --- a/src/script/api/script_admin.cpp +++ b/src/script/api/script_admin.cpp @@ -16,9 +16,9 @@ #include "../../safeguards.h" -/* static */ bool ScriptAdmin::MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data) +/* static */ bool ScriptAdmin::MakeJSON(nlohmann::json &json, HSQUIRRELVM vm, SQInteger index, int depth) { - if (max_depth == 0) { + if (depth == SQUIRREL_MAX_DEPTH) { ScriptLog::Error("Send parameters can only be nested to 25 deep. No data sent."); // SQUIRREL_MAX_DEPTH = 25 return false; } @@ -28,7 +28,7 @@ SQInteger res; sq_getinteger(vm, index, &res); - data = fmt::format("{}", res); + json = res; return true; } @@ -36,63 +36,52 @@ const SQChar *buf; sq_getstring(vm, index, &buf); - size_t len = strlen(buf) + 1; - if (len >= 255) { - ScriptLog::Error("Maximum string length is 254 chars. No data sent."); - return false; - } - - data = fmt::format("\"{}\"", buf); + json = std::string(buf); return true; } case OT_ARRAY: { - data = "[ "; + json = nlohmann::json::array(); - bool first = true; sq_pushnull(vm); while (SQ_SUCCEEDED(sq_next(vm, index - 1))) { - if (!first) data += ", "; - if (first) first = false; + nlohmann::json tmp; - std::string tmp; - - bool res = MakeJSON(vm, -1, max_depth - 1, tmp); + bool res = MakeJSON(tmp, vm, -1, depth + 1); sq_pop(vm, 2); if (!res) { sq_pop(vm, 1); return false; } - data += tmp; + + json.push_back(tmp); } sq_pop(vm, 1); - data += " ]"; return true; } case OT_TABLE: { - data = "{ "; + json = nlohmann::json::object(); - bool first = true; sq_pushnull(vm); while (SQ_SUCCEEDED(sq_next(vm, index - 1))) { - if (!first) data += ", "; - if (first) first = false; - - std::string key; - std::string value; - - /* Store the key + value */ - bool res = MakeJSON(vm, -2, max_depth - 1, key) && MakeJSON(vm, -1, max_depth - 1, value); + /* Squirrel ensure the key is a string. */ + assert(sq_gettype(vm, -2) == OT_STRING); + const SQChar *buf; + sq_getstring(vm, -2, &buf); + std::string key = std::string(buf); + + nlohmann::json value; + bool res = MakeJSON(value, vm, -1, depth + 1); sq_pop(vm, 2); if (!res) { sq_pop(vm, 1); return false; } - data += key + ": " + value; + + json[key] = value; } sq_pop(vm, 1); - data += " }"; return true; } @@ -100,17 +89,12 @@ SQBool res; sq_getbool(vm, index, &res); - if (res) { - data = "true"; - return true; - } - - data = "false"; + json = res ? true : false; return true; } case OT_NULL: { - data = "null"; + json = nullptr; return true; } @@ -128,19 +112,13 @@ return sq_throwerror(vm, "ScriptAdmin::Send requires a table as first parameter. No data sent."); } - std::string json; - if (!ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json)) { - sq_pushinteger(vm, 0); - return 1; - } - - if (json.length() > NETWORK_GAMESCRIPT_JSON_LENGTH) { - ScriptLog::Error("You are trying to send a table that is too large to the AdminPort. No data sent."); + nlohmann::json json; + if (!ScriptAdmin::MakeJSON(json, vm, -1)) { sq_pushinteger(vm, 0); return 1; } - NetworkAdminGameScript(json); + NetworkAdminGameScript(json.dump()); sq_pushinteger(vm, 1); return 1; diff --git a/src/script/api/script_admin.hpp b/src/script/api/script_admin.hpp index 03723784c5..5dea0b0510 100644 --- a/src/script/api/script_admin.hpp +++ b/src/script/api/script_admin.hpp @@ -11,6 +11,7 @@ #define SCRIPT_ADMIN_HPP #include "script_object.hpp" +#include /** * Class that handles communication with the AdminPort. @@ -38,13 +39,14 @@ public: protected: /** - * Convert a Squirrel structure into a JSON string. + * Convert a Squirrel structure into a JSON object. + * @param json The resulting JSON object. * @param vm The VM to operate on. * @param index The index we are currently working for. - * @param max_depth The maximal depth to follow the squirrel struct. - * @param data The resulting json string. + * @param depth The current depth in the squirrel struct. + * @return True iff the conversion was successful. */ - static bool MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data); + static bool MakeJSON(nlohmann::json &data, HSQUIRRELVM vm, SQInteger index, int depth = 0); }; #endif /* SCRIPT_ADMIN_HPP */ diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp index cea70f8e61..7b7ebcb9b7 100644 --- a/src/script/api/script_event_types.cpp +++ b/src/script/api/script_event_types.cpp @@ -128,192 +128,84 @@ ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) : { } -#define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++; -#define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return nullptr; } - SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm) { - const char *p = this->json.c_str(); + auto json = nlohmann::json::parse(this->json, nullptr, false); + + if (!json.is_object()) { + ScriptLog::Error("The root element in the JSON data from AdminPort has to be an object."); - if (this->ReadTable(vm, p) == nullptr) { sq_pushnull(vm); return 1; } - return 1; -} + auto top = sq_gettop(vm); + if (!this->ReadValue(vm, json)) { + /* Rewind the stack, removing anything that might be left on top. */ + sq_settop(vm, top); -const char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, const char *p) -{ - const char *value = p; - - bool escape = false; - for (;;) { - if (*p == '\\') { - escape = true; - p++; - continue; - } - if (*p == '"' && escape) { - escape = false; - p++; - continue; - } - escape = false; - - if (*p == '"') break; - if (*p == '\0') RETURN_ERROR(0); - - p++; - } - - size_t len = p - value; - sq_pushstring(vm, value, len); - p++; // Step past the end-of-string marker (") - - return p; -} + ScriptLog::Error("Received invalid JSON data from AdminPort."); -const char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, const char *p) -{ - sq_newtable(vm); - - SKIP_EMPTY(p); - if (*p++ != '{') RETURN_ERROR(1); - - for (;;) { - SKIP_EMPTY(p); - if (*p++ != '"') RETURN_ERROR(1); - - p = ReadString(vm, p); - if (p == nullptr) { - sq_pop(vm, 1); - return nullptr; - } - - SKIP_EMPTY(p); - if (*p++ != ':') RETURN_ERROR(2); - - p = this->ReadValue(vm, p); - if (p == nullptr) { - sq_pop(vm, 2); - return nullptr; - } - - sq_rawset(vm, -3); - /* The key (-2) and value (-1) are popped from the stack by squirrel. */ - - SKIP_EMPTY(p); - if (*p == ',') { - p++; - continue; - } - break; + sq_pushnull(vm); + return 1; } - SKIP_EMPTY(p); - if (*p++ != '}') RETURN_ERROR(1); - - return p; + return 1; } -const char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, const char *p) +bool ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, nlohmann::json &json) { - SKIP_EMPTY(p); - - if (strncmp(p, "false", 5) == 0) { - sq_pushbool(vm, 0); - return p + 5; - } - if (strncmp(p, "true", 4) == 0) { - sq_pushbool(vm, 1); - return p + 4; - } - if (strncmp(p, "null", 4) == 0) { - sq_pushnull(vm); - return p + 4; - } + switch (json.type()) { + case nlohmann::json::value_t::null: + sq_pushnull(vm); + break; - switch (*p) { - case '"': { - /* String */ - p = ReadString(vm, ++p); - if (p == nullptr) return nullptr; + case nlohmann::json::value_t::boolean: + sq_pushbool(vm, json.get() ? 1 : 0); + break; + case nlohmann::json::value_t::string: { + auto value = json.get(); + sq_pushstring(vm, value.data(), value.size()); break; } - case '{': { - /* Table */ - p = this->ReadTable(vm, p); - if (p == nullptr) return nullptr; - + case nlohmann::json::value_t::number_integer: + case nlohmann::json::value_t::number_unsigned: + sq_pushinteger(vm, json.get()); break; - } - case '[': { - /* Array */ - sq_newarray(vm, 0); + case nlohmann::json::value_t::object: + sq_newtable(vm); - /* Empty array? */ - const char *p2 = p + 1; - SKIP_EMPTY(p2); - if (*p2 == ']') { - p = p2 + 1; - break; - } + for (auto &[key, value] : json.items()) { + sq_pushstring(vm, key.data(), key.size()); - while (*p++ != ']') { - p = this->ReadValue(vm, p); - if (p == nullptr) { - sq_pop(vm, 1); - return nullptr; + if (!this->ReadValue(vm, value)) { + return false; } - sq_arrayappend(vm, -2); - SKIP_EMPTY(p); - if (*p == ',') continue; - if (*p == ']') break; - RETURN_ERROR(1); + sq_rawset(vm, -3); } - - p++; - break; - } - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '0': - case '-': { - /* Integer */ - const char *value = p++; - for (;;) { - switch (*p++) { - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '0': - continue; + case nlohmann::json::value_t::array: + sq_newarray(vm, 0); - default: - break; + for (auto &value : json) { + if (!this->ReadValue(vm, value)) { + return false; } - p--; - break; + sq_arrayappend(vm, -2); } - - int res = atoi(value); - sq_pushinteger(vm, (SQInteger)res); - break; - } + /* These types are not supported by Squirrel. */ + case nlohmann::json::value_t::number_float: default: - RETURN_ERROR(0); + return false; } - return p; + return true; } - -#undef SKIP_EMPTY -#undef RETURN_ERROR diff --git a/src/script/api/script_event_types.hpp b/src/script/api/script_event_types.hpp index 79902d2668..8ff883ac28 100644 --- a/src/script/api/script_event_types.hpp +++ b/src/script/api/script_event_types.hpp @@ -14,6 +14,8 @@ #include "script_goal.hpp" #include "script_window.hpp" +#include + /** * Event Vehicle Crash, indicating a vehicle of yours is crashed. * It contains the crash site, the crashed vehicle and the reason for the crash. @@ -912,25 +914,11 @@ private: std::string json; ///< The JSON string. /** - * Read a table from a JSON string. - * @param vm The VM used. - * @param p The (part of the) JSON string reading. - */ - const char *ReadTable(HSQUIRRELVM vm, const char *p); - - /** - * Read a value from a JSON string. - * @param vm The VM used. - * @param p The (part of the) JSON string reading. - */ - const char *ReadValue(HSQUIRRELVM vm, const char *p); - - /** - * Read a string from a JSON string. + * Convert a JSON part fo Squirrel. * @param vm The VM used. - * @param p The (part of the) JSON string reading. + * @param json The JSON part to convert to Squirrel. */ - const char *ReadString(HSQUIRRELVM vm, const char *p); + bool ReadValue(HSQUIRRELVM vm, nlohmann::json &json); }; /** diff --git a/src/tests/test_script_admin.cpp b/src/tests/test_script_admin.cpp index b679498921..95e00a3c47 100644 --- a/src/tests/test_script_admin.cpp +++ b/src/tests/test_script_admin.cpp @@ -72,14 +72,14 @@ public: REQUIRE(sq_gettype(vm, -1) == OT_TABLE); /* Feed the snippet into the MakeJSON function. */ - std::string json; - if (!ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json)) { + nlohmann::json json; + if (!ScriptAdmin::MakeJSON(json, vm, -1)) { sq_close(vm); return std::nullopt; } sq_close(vm); - return json; + return json.dump(); } /** @@ -111,11 +111,11 @@ public: } REQUIRE(sq_gettype(vm, -1) == OT_TABLE); - std::string squirrel_json; - REQUIRE(ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, squirrel_json) == true); + nlohmann::json squirrel_json; + REQUIRE(ScriptAdmin::MakeJSON(squirrel_json, vm, -1) == true); sq_close(vm); - return squirrel_json; + return squirrel_json.dump(); } }; @@ -124,18 +124,18 @@ TEST_CASE("Squirrel -> JSON conversion") { TestScriptController controller; - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = null })sq") == R"json({ "test": null })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = 1 })sq") == R"json({ "test": 1 })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = -1 })sq") == R"json({ "test": -1 })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = true })sq") == R"json({ "test": true })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = "a" })sq") == R"json({ "test": "a" })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ ] })sq") == R"json({ "test": [ ] })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ 1 ] })sq") == R"json({ "test": [ 1 ] })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ 1, "a", true, { test = 1 }, [], null ] })sq") == R"json({ "test": [ 1, "a", true, { "test": 1 }, [ ], null ] })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { } })sq") == R"json({ "test": { } })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1 } })sq") == R"json({ "test": { "test": 1 } })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1, test = 2 } })sq") == R"json({ "test": { "test": 2 } })json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1, test2 = [ 2 ] } })sq") == R"json({ "test": { "test": 1, "test2": [ 2 ] } })json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = null })sq") == R"json({"test":null})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = 1 })sq") == R"json({"test":1})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = -1 })sq") == R"json({"test":-1})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = true })sq") == R"json({"test":true})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = "a" })sq") == R"json({"test":"a"})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ ] })sq") == R"json({"test":[]})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ 1 ] })sq") == R"json({"test":[1]})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ 1, "a", true, { test = 1 }, [], null ] })sq") == R"json({"test":[1,"a",true,{"test":1},[],null]})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { } })sq") == R"json({"test":{}})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1 } })sq") == R"json({"test":{"test":1}})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1, test = 2 } })sq") == R"json({"test":{"test":2}})json"); + CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1, test2 = [ 2 ] } })sq") == R"json({"test":{"test":1,"test2":[2]}})json"); /* Cases that should fail, as we cannot convert a class to JSON. */ CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = DummyClass })sq") == std::nullopt); @@ -147,23 +147,33 @@ TEST_CASE("JSON -> Squirrel conversion") { TestScriptController controller; - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": null })json") == R"json({ "test": null })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": 1 })json") == R"json({ "test": 1 })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": -1 })json") == R"json({ "test": -1 })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": true })json") == R"json({ "test": true })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": "a" })json") == R"json({ "test": "a" })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [] })json") == R"json({ "test": [ ] })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [ 1 ] })json") == R"json({ "test": [ 1 ] })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [ 1, "a", true, { "test": 1 }, [], null ] })json") == R"json({ "test": [ 1, "a", true, { "test": 1 }, [ ], null ] })json"); - // BUG -- This should work, but doesn't. - // CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": {} })json") == R"json({ "test": { } })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": { "test": 1 } })json") == R"json({ "test": { "test": 1 } })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": { "test": 2 } })json") == R"json({ "test": { "test": 2 } })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": { "test": 1, "test2": [ 2 ] } })json") == R"json({ "test": { "test": 1, "test2": [ 2 ] } })json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": null })json") == R"json({"test":null})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": 1 })json") == R"json({"test":1})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": -1 })json") == R"json({"test":-1})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": true })json") == R"json({"test":true})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": "a" })json") == R"json({"test":"a"})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [] })json") == R"json({"test":[]})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [ 1 ] })json") == R"json({"test":[1]})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [ 1, "a", true, { "test": 1 }, [], null ] })json") == R"json({"test":[1,"a",true,{"test":1},[],null]})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": {} })json") == R"json({"test":{}})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": { "test": 1 } })json") == R"json({"test":{"test":1}})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": { "test": 2 } })json") == R"json({"test":{"test":2}})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": { "test": 1, "test2": [ 2 ] } })json") == R"json({"test":{"test":1,"test2":[2]}})json"); /* Check if spaces are properly ignored. */ - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({"test":1})json") == R"json({ "test": 1 })json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({"test": 1})json") == R"json({ "test": 1 })json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({"test":1})json") == R"json({"test":1})json"); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({"test": 1})json") == R"json({"test":1})json"); + + /* Valid JSON but invalid Squirrel (read: floats). */ + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": 1.1 })json") == std::nullopt); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [ 1, 3, 1.1 ] })json") == std::nullopt); + + /* Root element has to be an object. */ + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( 1 )json") == std::nullopt); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( "a" )json") == std::nullopt); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( [ 1 ] )json") == std::nullopt); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( null )json") == std::nullopt); + CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( true )json") == std::nullopt); /* Cases that should fail, as it is invalid JSON. */ CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({"test":test})json") == std::nullopt); From 21bd5fb991cd39827533576e1f73c0fe3a5484cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Wed, 6 Sep 2023 18:29:34 +0200 Subject: [PATCH 18/72] Fix: [CI] preview flow can't install latest version of npm (#11265) --- .github/workflows/preview-build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview-build.yml b/.github/workflows/preview-build.yml index a968899edf..e4e289972d 100644 --- a/.github/workflows/preview-build.yml +++ b/.github/workflows/preview-build.yml @@ -91,7 +91,8 @@ jobs: # Ensure we use the latest version of npm; the one we get with current # emscripten doesn't allow running "npx wrangler" as root. - npm install -g npm + # Current emscripten can't install npm>=10.0.0 because node is too old. + npm install -g npm@9 - name: Publish preview uses: cloudflare/pages-action@v1 From 0316940fe83023b7603ce4db7001bf855f0ff8c2 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 6 Sep 2023 20:36:26 +0100 Subject: [PATCH 19/72] Fix: Inaccurate waiting cargo total in station window when using cargodist (#11213) For stations with many flows and/or small cargo packets, due to accumulated inaccuracies in DivideApprox. The displayed total should match GoodsEntry::TotalCount(). --- src/station_gui.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/station_gui.cpp b/src/station_gui.cpp index fcff2b1e25..1411f9a60e 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -1603,9 +1603,23 @@ struct StationViewWindow : public Window { continue; } - for (CargoDataSet::iterator dest_it = via_entry->Begin(); dest_it != via_entry->End(); ++dest_it) { + uint remaining = cp->Count(); + for (CargoDataSet::iterator dest_it = via_entry->Begin(); dest_it != via_entry->End();) { CargoDataEntry *dest_entry = *dest_it; - uint val = DivideApprox(cp->Count() * dest_entry->GetCount(), via_entry->GetCount()); + + /* Advance iterator here instead of in the for statement to test whether this is the last entry */ + ++dest_it; + + uint val; + if (dest_it == via_entry->End()) { + /* Allocate all remaining waiting cargo to the last destination to avoid + * waiting cargo being "lost", and the displayed total waiting cargo + * not matching GoodsEntry::TotalCount() */ + val = remaining; + } else { + val = std::min(remaining, DivideApprox(cp->Count() * dest_entry->GetCount(), via_entry->GetCount())); + remaining -= val; + } this->ShowCargo(cargo, i, cp->SourceStation(), next, dest_entry->GetStation(), val); } } From 8c742b456f96fbbd0adc69da49e3cfc3812df001 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 1 Jul 2023 22:05:07 +0200 Subject: [PATCH 20/72] Codechange: use Textbuf directly, instead via several virtual functions in Window --- src/console_gui.cpp | 17 ++--------------- src/querystring_gui.h | 31 ------------------------------- src/textbuf.cpp | 9 +++++++++ src/textbuf_type.h | 2 ++ src/video/cocoa/cocoa_wnd.mm | 34 +++++++++++++++++++--------------- src/window.cpp | 35 ++++------------------------------- src/window_gui.h | 4 +--- 7 files changed, 37 insertions(+), 95 deletions(-) diff --git a/src/console_gui.cpp b/src/console_gui.cpp index 3fc5e68288..71d88420f5 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -280,22 +280,9 @@ struct IConsoleWindow : Window } } - const char *GetFocusedText() const override + Textbuf *GetFocusedTextbuf() const override { - return _iconsole_cmdline.buf; - } - - const char *GetCaret() const override - { - return _iconsole_cmdline.buf + _iconsole_cmdline.caretpos; - } - - const char *GetMarkedText(size_t *length) const override - { - if (_iconsole_cmdline.markend == 0) return nullptr; - - *length = _iconsole_cmdline.markend - _iconsole_cmdline.markpos; - return _iconsole_cmdline.buf + _iconsole_cmdline.markpos; + return &_iconsole_cmdline; } Point GetCaretPosition() const override diff --git a/src/querystring_gui.h b/src/querystring_gui.h index 6903e23f6b..fd440a3449 100644 --- a/src/querystring_gui.h +++ b/src/querystring_gui.h @@ -47,37 +47,6 @@ public: Point GetCaretPosition(const Window *w, int wid) const; Rect GetBoundingRect(const Window *w, int wid, const char *from, const char *to) const; ptrdiff_t GetCharAtPosition(const Window *w, int wid, const Point &pt) const; - - /** - * Get the current text. - * @return Current text. - */ - const char *GetText() const - { - return this->text.buf; - } - - /** - * Get the position of the caret in the text buffer. - * @return Pointer to the caret in the text buffer. - */ - const char *GetCaret() const - { - return this->text.buf + this->text.caretpos; - } - - /** - * Get the currently marked text. - * @param[out] length Length of the marked text. - * @return Beginning of the marked area or nullptr if no text is marked. - */ - const char *GetMarkedText(size_t *length) const - { - if (this->text.markend == 0) return nullptr; - - *length = this->text.markend - this->text.markpos; - return this->text.buf + this->text.markpos; - } }; void ShowOnScreenKeyboard(Window *parent, int button); diff --git a/src/textbuf.cpp b/src/textbuf.cpp index be8cc68432..388e480211 100644 --- a/src/textbuf.cpp +++ b/src/textbuf.cpp @@ -275,6 +275,15 @@ void Textbuf::DiscardMarkedText(bool update) this->markpos = this->markend = this->markxoffs = this->marklength = 0; } +/** + * Get the current text. + * @return Current text. + */ +const char *Textbuf::GetText() const +{ + return this->buf; +} + /** Update the character iter after the text has changed. */ void Textbuf::UpdateStringIter() { diff --git a/src/textbuf_type.h b/src/textbuf_type.h index 16f0fd86ae..78c58adb53 100644 --- a/src/textbuf_type.h +++ b/src/textbuf_type.h @@ -65,6 +65,8 @@ struct Textbuf { void DiscardMarkedText(bool update = true); + const char *GetText() const; + private: std::unique_ptr char_iter; diff --git a/src/video/cocoa/cocoa_wnd.mm b/src/video/cocoa/cocoa_wnd.mm index 83048ed98a..52823a7a6c 100644 --- a/src/video/cocoa/cocoa_wnd.mm +++ b/src/video/cocoa/cocoa_wnd.mm @@ -32,6 +32,7 @@ #include "../../window_func.h" #include "../../window_gui.h" #include "../../spritecache.h" +#include "../../textbuf_type.h" #include "../../toolbar_gui.h" #include "table/sprites.h" @@ -932,7 +933,7 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel const char *replace_range = NULL; if (replacementRange.location != NSNotFound) { /* Calculate the part to be replaced. */ - insert_point = Utf8AdvanceByUtf16Units(_focused_window->GetFocusedText(), replacementRange.location); + insert_point = Utf8AdvanceByUtf16Units(_focused_window->GetFocusedTextbuf()->GetText(), replacementRange.location); replace_range = Utf8AdvanceByUtf16Units(insert_point, replacementRange.length); } @@ -960,7 +961,7 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel if (replacementRange.location != NSNotFound) { /* Calculate the part to be replaced. */ NSRange marked = [ self markedRange ]; - insert_point = Utf8AdvanceByUtf16Units(_focused_window->GetFocusedText(), replacementRange.location + (marked.location != NSNotFound ? marked.location : 0u)); + insert_point = Utf8AdvanceByUtf16Units(_focused_window->GetFocusedTextbuf()->GetText(), replacementRange.location + (marked.location != NSNotFound ? marked.location : 0u)); replace_range = Utf8AdvanceByUtf16Units(insert_point, replacementRange.length); } @@ -988,7 +989,9 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel { if (!EditBoxInGlobalFocus()) return NSMakeRange(NSNotFound, 0); - NSUInteger start = CountUtf16Units(_focused_window->GetFocusedText(), _focused_window->GetCaret()); + const Textbuf *text_buf = _focused_window->GetFocusedTextbuf(); + const char *text = text_buf->GetText(); + NSUInteger start = CountUtf16Units(text, text + text_buf->caretpos); return NSMakeRange(start, 0); } @@ -997,11 +1000,12 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel { if (!EditBoxInGlobalFocus()) return NSMakeRange(NSNotFound, 0); - size_t mark_len; - const char *mark = _focused_window->GetMarkedText(&mark_len); - if (mark != nullptr) { - NSUInteger start = CountUtf16Units(_focused_window->GetFocusedText(), mark); - NSUInteger len = CountUtf16Units(mark, mark + mark_len); + const Textbuf *text_buf = _focused_window->GetFocusedTextbuf(); + if (text_buf->markend != 0) { + const char *text = text_buf->GetText(); + const char *mark = text + text_buf->markpos; + NSUInteger start = CountUtf16Units(text, mark); + NSUInteger len = CountUtf16Units(mark, text + text_buf->markend); return NSMakeRange(start, len); } @@ -1014,8 +1018,7 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel { if (!EditBoxInGlobalFocus()) return NO; - size_t len; - return _focused_window->GetMarkedText(&len) != nullptr; + return _focused_window->GetFocusedTextbuf()->markend != 0; } /** Get a string corresponding to the given range. */ @@ -1023,7 +1026,7 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel { if (!EditBoxInGlobalFocus()) return nil; - NSString *s = [ NSString stringWithUTF8String:_focused_window->GetFocusedText() ]; + NSString *s = [ NSString stringWithUTF8String:_focused_window->GetFocusedTextbuf()->GetText() ]; NSRange valid_range = NSIntersectionRange(NSMakeRange(0, [ s length ]), theRange); if (actualRange != nullptr) *actualRange = valid_range; @@ -1043,7 +1046,7 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel { if (!EditBoxInGlobalFocus()) return [ [ [ NSAttributedString alloc ] initWithString:@"" ] autorelease ]; - return [ [ [ NSAttributedString alloc ] initWithString:[ NSString stringWithUTF8String:_focused_window->GetFocusedText() ] ] autorelease ]; + return [ [ [ NSAttributedString alloc ] initWithString:[ NSString stringWithUTF8String:_focused_window->GetFocusedTextbuf()->GetText() ] ] autorelease ]; } /** Get the character that is rendered at the given point. */ @@ -1058,7 +1061,7 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel auto index = _focused_window->GetTextCharacterAtPosition(pt); if (index == -1) return NSNotFound; - auto text = _focused_window->GetFocusedText(); + auto text = _focused_window->GetFocusedTextbuf()->GetText(); return CountUtf16Units(text, text + index); } @@ -1067,9 +1070,10 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel { if (!EditBoxInGlobalFocus()) return NSMakeRect(0, 0, 0, 0); + const char *focused_text = _focused_window->GetFocusedTextbuf()->GetText(); /* Convert range to UTF-8 string pointers. */ - const char *start = Utf8AdvanceByUtf16Units(_focused_window->GetFocusedText(), aRange.location); - const char *end = aRange.length != 0 ? Utf8AdvanceByUtf16Units(_focused_window->GetFocusedText(), aRange.location + aRange.length) : start; + const char *start = Utf8AdvanceByUtf16Units(focused_text, aRange.location); + const char *end = aRange.length != 0 ? Utf8AdvanceByUtf16Units(focused_text, aRange.location + aRange.length) : start; /* Get the bounding rect for the text range.*/ Rect r = _focused_window->GetTextBoundingRect(start, end); diff --git a/src/window.cpp b/src/window.cpp index 839ccbb469..37de6e85ca 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -365,40 +365,13 @@ void Window::UpdateQueryStringSize() } /** - * Get the current input text if an edit box has the focus. - * @return The currently focused input text or nullptr if no input focused. + * Get the current input text buffer. + * @return The currently focused input text buffer or nullptr if no input focused. */ -/* virtual */ const char *Window::GetFocusedText() const +/* virtual */ const Textbuf *Window::GetFocusedTextbuf() const { if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) { - return this->GetQueryString(this->nested_focus->index)->GetText(); - } - - return nullptr; -} - -/** - * Get the string at the caret if an edit box has the focus. - * @return The text at the caret or nullptr if no edit box is focused. - */ -/* virtual */ const char *Window::GetCaret() const -{ - if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) { - return this->GetQueryString(this->nested_focus->index)->GetCaret(); - } - - return nullptr; -} - -/** - * Get the range of the currently marked input text. - * @param[out] length Length of the marked text. - * @return Pointer to the start of the marked text or nullptr if no text is marked. - */ -/* virtual */ const char *Window::GetMarkedText(size_t *length) const -{ - if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) { - return this->GetQueryString(this->nested_focus->index)->GetMarkedText(length); + return &this->GetQueryString(this->nested_focus->index)->text; } return nullptr; diff --git a/src/window_gui.h b/src/window_gui.h index 77f6d20429..e5e438f91d 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -273,9 +273,7 @@ public: QueryString *GetQueryString(uint widnum); void UpdateQueryStringSize(); - virtual const char *GetFocusedText() const; - virtual const char *GetCaret() const; - virtual const char *GetMarkedText(size_t *length) const; + virtual const struct Textbuf *GetFocusedTextbuf() const; virtual Point GetCaretPosition() const; virtual Rect GetTextBoundingRect(const char *from, const char *to) const; virtual ptrdiff_t GetTextCharacterAtPosition(const Point &pt) const; From d725fa14a22b0871fe5a90bcf922d0ac88a4b5b0 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Fri, 8 Sep 2023 12:11:37 +0200 Subject: [PATCH 21/72] Fix: asserts unintentially being partially disabled in release-builds (#11268) The nlohmann-json header file includes assert.h, which rudely resets the assert macro to what that header thinks is right. As we set the assert macro to be active with release builds when WITH_ASSERT is active, this means that every file including nlohmann-json has their asserts disabled (for release-builds) but files that don't do no. Let's avoid this issue, by telling nlohmann to not include assert.h. --- src/stdafx.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/stdafx.h b/src/stdafx.h index 6e19bb6393..9d952c106f 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -394,6 +394,10 @@ void NORETURN AssertFailedError(int line, const char *file, const char *expressi # define assert(expression) if (unlikely(!(expression))) AssertFailedError(__LINE__, __FILE__, #expression); #endif +/* Define JSON_ASSERT, which is used by nlohmann-json. Otherwise the header-file + * will re-include assert.h, and reset the assert macro. */ +#define JSON_ASSERT(x) assert(x) + #if defined(MAX_PATH) /* It's already defined, no need to override */ #elif defined(PATH_MAX) && PATH_MAX > 0 From 00f13282a9075f93f968e0042012c75c81a2d6b0 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Fri, 8 Sep 2023 19:03:10 +0200 Subject: [PATCH 22/72] Codechange: keep how we convert string <-> JSON private (#11269) --- src/script/api/script_admin.cpp | 21 ++- src/script/api/script_admin.hpp | 12 -- src/script/api/script_event_types.cpp | 64 ++++---- src/script/api/script_event_types.hpp | 9 -- src/tests/test_script_admin.cpp | 220 +++++++++++++------------- 5 files changed, 160 insertions(+), 166 deletions(-) diff --git a/src/script/api/script_admin.cpp b/src/script/api/script_admin.cpp index 2c30434792..97a25bbf47 100644 --- a/src/script/api/script_admin.cpp +++ b/src/script/api/script_admin.cpp @@ -14,9 +14,22 @@ #include "../script_instance.hpp" #include "../../string_func.h" +#include + #include "../../safeguards.h" -/* static */ bool ScriptAdmin::MakeJSON(nlohmann::json &json, HSQUIRRELVM vm, SQInteger index, int depth) +/** + * Convert a Squirrel structure into a JSON object. + * + * This function is not "static", so it can be tested in unittests. + * + * @param json The resulting JSON object. + * @param vm The VM to operate on. + * @param index The index we are currently working for. + * @param depth The current depth in the squirrel struct. + * @return True iff the conversion was successful. + */ +bool ScriptAdminMakeJSON(nlohmann::json &json, HSQUIRRELVM vm, SQInteger index, int depth = 0) { if (depth == SQUIRREL_MAX_DEPTH) { ScriptLog::Error("Send parameters can only be nested to 25 deep. No data sent."); // SQUIRREL_MAX_DEPTH = 25 @@ -47,7 +60,7 @@ while (SQ_SUCCEEDED(sq_next(vm, index - 1))) { nlohmann::json tmp; - bool res = MakeJSON(tmp, vm, -1, depth + 1); + bool res = ScriptAdminMakeJSON(tmp, vm, -1, depth + 1); sq_pop(vm, 2); if (!res) { sq_pop(vm, 1); @@ -72,7 +85,7 @@ std::string key = std::string(buf); nlohmann::json value; - bool res = MakeJSON(value, vm, -1, depth + 1); + bool res = ScriptAdminMakeJSON(value, vm, -1, depth + 1); sq_pop(vm, 2); if (!res) { sq_pop(vm, 1); @@ -113,7 +126,7 @@ } nlohmann::json json; - if (!ScriptAdmin::MakeJSON(json, vm, -1)) { + if (!ScriptAdminMakeJSON(json, vm, -1)) { sq_pushinteger(vm, 0); return 1; } diff --git a/src/script/api/script_admin.hpp b/src/script/api/script_admin.hpp index 5dea0b0510..877506e98d 100644 --- a/src/script/api/script_admin.hpp +++ b/src/script/api/script_admin.hpp @@ -11,7 +11,6 @@ #define SCRIPT_ADMIN_HPP #include "script_object.hpp" -#include /** * Class that handles communication with the AdminPort. @@ -36,17 +35,6 @@ public: */ static bool Send(void *table); #endif /* DOXYGEN_API */ - -protected: - /** - * Convert a Squirrel structure into a JSON object. - * @param json The resulting JSON object. - * @param vm The VM to operate on. - * @param index The index we are currently working for. - * @param depth The current depth in the squirrel struct. - * @return True iff the conversion was successful. - */ - static bool MakeJSON(nlohmann::json &data, HSQUIRRELVM vm, SQInteger index, int depth = 0); }; #endif /* SCRIPT_ADMIN_HPP */ diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp index 7b7ebcb9b7..7c4409b6bd 100644 --- a/src/script/api/script_event_types.cpp +++ b/src/script/api/script_event_types.cpp @@ -20,6 +20,8 @@ #include "../../engine_cmd.h" #include "table/strings.h" +#include + #include "../../safeguards.h" bool ScriptEventEnginePreview::IsEngineValid() const @@ -127,33 +129,12 @@ ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) : json(json) { } - -SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm) -{ - auto json = nlohmann::json::parse(this->json, nullptr, false); - - if (!json.is_object()) { - ScriptLog::Error("The root element in the JSON data from AdminPort has to be an object."); - - sq_pushnull(vm); - return 1; - } - - auto top = sq_gettop(vm); - if (!this->ReadValue(vm, json)) { - /* Rewind the stack, removing anything that might be left on top. */ - sq_settop(vm, top); - - ScriptLog::Error("Received invalid JSON data from AdminPort."); - - sq_pushnull(vm); - return 1; - } - - return 1; -} - -bool ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, nlohmann::json &json) +/** + * Convert a JSON part fo Squirrel. + * @param vm The VM used. + * @param json The JSON part to convert to Squirrel. + */ +static bool ScriptEventAdminPortReadValue(HSQUIRRELVM vm, nlohmann::json &json) { switch (json.type()) { case nlohmann::json::value_t::null: @@ -181,7 +162,7 @@ bool ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, nlohmann::json &json) for (auto &[key, value] : json.items()) { sq_pushstring(vm, key.data(), key.size()); - if (!this->ReadValue(vm, value)) { + if (!ScriptEventAdminPortReadValue(vm, value)) { return false; } @@ -193,7 +174,7 @@ bool ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, nlohmann::json &json) sq_newarray(vm, 0); for (auto &value : json) { - if (!this->ReadValue(vm, value)) { + if (!ScriptEventAdminPortReadValue(vm, value)) { return false; } @@ -209,3 +190,28 @@ bool ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, nlohmann::json &json) return true; } + +SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm) +{ + auto json = nlohmann::json::parse(this->json, nullptr, false); + + if (!json.is_object()) { + ScriptLog::Error("The root element in the JSON data from AdminPort has to be an object."); + + sq_pushnull(vm); + return 1; + } + + auto top = sq_gettop(vm); + if (!ScriptEventAdminPortReadValue(vm, json)) { + /* Rewind the stack, removing anything that might be left on top. */ + sq_settop(vm, top); + + ScriptLog::Error("Received invalid JSON data from AdminPort."); + + sq_pushnull(vm); + return 1; + } + + return 1; +} diff --git a/src/script/api/script_event_types.hpp b/src/script/api/script_event_types.hpp index 8ff883ac28..4496b3a310 100644 --- a/src/script/api/script_event_types.hpp +++ b/src/script/api/script_event_types.hpp @@ -14,8 +14,6 @@ #include "script_goal.hpp" #include "script_window.hpp" -#include - /** * Event Vehicle Crash, indicating a vehicle of yours is crashed. * It contains the crash site, the crashed vehicle and the reason for the crash. @@ -912,13 +910,6 @@ public: private: std::string json; ///< The JSON string. - - /** - * Convert a JSON part fo Squirrel. - * @param vm The VM used. - * @param json The JSON part to convert to Squirrel. - */ - bool ReadValue(HSQUIRRELVM vm, nlohmann::json &json); }; /** diff --git a/src/tests/test_script_admin.cpp b/src/tests/test_script_admin.cpp index 95e00a3c47..120dfc1d7d 100644 --- a/src/tests/test_script_admin.cpp +++ b/src/tests/test_script_admin.cpp @@ -20,6 +20,7 @@ #include "../3rdparty/fmt/format.h" #include +#include /** * A controller to start enough so we can use Squirrel for testing. @@ -40,146 +41,141 @@ public: ScriptAllocatorScope scope{&engine}; }; +extern bool ScriptAdminMakeJSON(nlohmann::json &json, HSQUIRRELVM vm, SQInteger index, int depth = 0); + /** - * Small wrapper around ScriptAdmin. - * - * MakeJSON is protected; so for tests, we make a public function with - * which we call into the protected one. This prevents accidental use - * by the rest of the code, while still being able to test it. + * Small wrapper around ScriptAdmin's MakeJSON that prepares the Squirrel + * engine if it was called from actual scripting.. */ -class TestScriptAdmin : public ScriptAdmin { -public: - static std::optional MakeJSON(std::string_view squirrel) - { - auto vm = sq_open(1024); - /* sq_compile creates a closure with our snipper, which is a table. - * Add "return " to get the table on the stack. */ - std::string buffer = fmt::format("return {}", squirrel); - - /* Insert an (empty) class for testing. */ - sq_pushroottable(vm); - sq_pushstring(vm, "DummyClass", -1); - sq_newclass(vm, SQFalse); - sq_newslot(vm, -3, SQFalse); - sq_pop(vm, 1); - - /* Compile the snippet. */ - REQUIRE(sq_compilebuffer(vm, buffer.c_str(), buffer.size(), "test", SQTrue) == SQ_OK); - /* Execute the snippet, capturing the return value. */ - sq_pushroottable(vm); - REQUIRE(sq_call(vm, 1, SQTrue, SQTrue) == SQ_OK); - /* Ensure the snippet pushed a table on the stack. */ - REQUIRE(sq_gettype(vm, -1) == OT_TABLE); - - /* Feed the snippet into the MakeJSON function. */ - nlohmann::json json; - if (!ScriptAdmin::MakeJSON(json, vm, -1)) { - sq_close(vm); - return std::nullopt; - } - +static std::optional TestScriptAdminMakeJSON(std::string_view squirrel) +{ + auto vm = sq_open(1024); + /* sq_compile creates a closure with our snipper, which is a table. + * Add "return " to get the table on the stack. */ + std::string buffer = fmt::format("return {}", squirrel); + + /* Insert an (empty) class for testing. */ + sq_pushroottable(vm); + sq_pushstring(vm, "DummyClass", -1); + sq_newclass(vm, SQFalse); + sq_newslot(vm, -3, SQFalse); + sq_pop(vm, 1); + + /* Compile the snippet. */ + REQUIRE(sq_compilebuffer(vm, buffer.c_str(), buffer.size(), "test", SQTrue) == SQ_OK); + /* Execute the snippet, capturing the return value. */ + sq_pushroottable(vm); + REQUIRE(sq_call(vm, 1, SQTrue, SQTrue) == SQ_OK); + /* Ensure the snippet pushed a table on the stack. */ + REQUIRE(sq_gettype(vm, -1) == OT_TABLE); + + /* Feed the snippet into the MakeJSON function. */ + nlohmann::json json; + if (!ScriptAdminMakeJSON(json, vm, -1)) { sq_close(vm); - return json.dump(); + return std::nullopt; } - /** - * Validate ScriptEventAdminPort can convert JSON to Squirrel. - * - * This function is not actually part of ScriptAdmin, but we will use MakeJSON, - * and as such need to be inside this class. - * - * The easiest way to do validate, is to first use ScriptEventAdminPort (the function - * we are testing) to convert the JSON to a Squirrel table. Then to use MakeJSON - * to convert it back to JSON. - * - * Sadly, Squirrel has no way to easily compare if two tables are identical, so we - * use the JSON -> Squirrel -> JSON method to validate the conversion. But mind you, - * a failure in the final JSON might also mean a bug in MakeJSON. - * - * @param json The JSON-string to convert to Squirrel - * @return The Squirrel table converted to a JSON-string. - */ - static std::optional TestScriptEventAdminPort(const std::string &json) - { - auto vm = sq_open(1024); - - /* Run the conversion JSON -> Squirrel (this will now be on top of the stack). */ - ScriptEventAdminPort(json).GetObject(vm); - if (sq_gettype(vm, -1) == OT_NULL) { - sq_close(vm); - return std::nullopt; - } - REQUIRE(sq_gettype(vm, -1) == OT_TABLE); - - nlohmann::json squirrel_json; - REQUIRE(ScriptAdmin::MakeJSON(squirrel_json, vm, -1) == true); + sq_close(vm); + return json.dump(); +} +/** + * Validate ScriptEventAdminPort can convert JSON to Squirrel. + * + * This function is not actually part of ScriptAdmin, but we will use MakeJSON, + * and as such need to be inside this class. + * + * The easiest way to do validate, is to first use ScriptEventAdminPort (the function + * we are testing) to convert the JSON to a Squirrel table. Then to use MakeJSON + * to convert it back to JSON. + * + * Sadly, Squirrel has no way to easily compare if two tables are identical, so we + * use the JSON -> Squirrel -> JSON method to validate the conversion. But mind you, + * a failure in the final JSON might also mean a bug in MakeJSON. + * + * @param json The JSON-string to convert to Squirrel + * @return The Squirrel table converted to a JSON-string. + */ +static std::optional TestScriptEventAdminPort(const std::string &json) +{ + auto vm = sq_open(1024); + + /* Run the conversion JSON -> Squirrel (this will now be on top of the stack). */ + ScriptEventAdminPort(json).GetObject(vm); + if (sq_gettype(vm, -1) == OT_NULL) { sq_close(vm); - return squirrel_json.dump(); + return std::nullopt; } + REQUIRE(sq_gettype(vm, -1) == OT_TABLE); -}; + nlohmann::json squirrel_json; + REQUIRE(ScriptAdminMakeJSON(squirrel_json, vm, -1) == true); + + sq_close(vm); + return squirrel_json.dump(); +} TEST_CASE("Squirrel -> JSON conversion") { TestScriptController controller; - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = null })sq") == R"json({"test":null})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = 1 })sq") == R"json({"test":1})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = -1 })sq") == R"json({"test":-1})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = true })sq") == R"json({"test":true})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = "a" })sq") == R"json({"test":"a"})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ ] })sq") == R"json({"test":[]})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ 1 ] })sq") == R"json({"test":[1]})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ 1, "a", true, { test = 1 }, [], null ] })sq") == R"json({"test":[1,"a",true,{"test":1},[],null]})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { } })sq") == R"json({"test":{}})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1 } })sq") == R"json({"test":{"test":1}})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1, test = 2 } })sq") == R"json({"test":{"test":2}})json"); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1, test2 = [ 2 ] } })sq") == R"json({"test":{"test":1,"test2":[2]}})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = null })sq") == R"json({"test":null})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = 1 })sq") == R"json({"test":1})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = -1 })sq") == R"json({"test":-1})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = true })sq") == R"json({"test":true})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = "a" })sq") == R"json({"test":"a"})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = [ ] })sq") == R"json({"test":[]})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = [ 1 ] })sq") == R"json({"test":[1]})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = [ 1, "a", true, { test = 1 }, [], null ] })sq") == R"json({"test":[1,"a",true,{"test":1},[],null]})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = { } })sq") == R"json({"test":{}})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = { test = 1 } })sq") == R"json({"test":{"test":1}})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = { test = 1, test = 2 } })sq") == R"json({"test":{"test":2}})json"); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = { test = 1, test2 = [ 2 ] } })sq") == R"json({"test":{"test":1,"test2":[2]}})json"); /* Cases that should fail, as we cannot convert a class to JSON. */ - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = DummyClass })sq") == std::nullopt); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = [ 1, DummyClass ] })sq") == std::nullopt); - CHECK(TestScriptAdmin::MakeJSON(R"sq({ test = { test = 1, test2 = DummyClass } })sq") == std::nullopt); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = DummyClass })sq") == std::nullopt); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = [ 1, DummyClass ] })sq") == std::nullopt); + CHECK(TestScriptAdminMakeJSON(R"sq({ test = { test = 1, test2 = DummyClass } })sq") == std::nullopt); } TEST_CASE("JSON -> Squirrel conversion") { TestScriptController controller; - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": null })json") == R"json({"test":null})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": 1 })json") == R"json({"test":1})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": -1 })json") == R"json({"test":-1})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": true })json") == R"json({"test":true})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": "a" })json") == R"json({"test":"a"})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [] })json") == R"json({"test":[]})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [ 1 ] })json") == R"json({"test":[1]})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [ 1, "a", true, { "test": 1 }, [], null ] })json") == R"json({"test":[1,"a",true,{"test":1},[],null]})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": {} })json") == R"json({"test":{}})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": { "test": 1 } })json") == R"json({"test":{"test":1}})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": { "test": 2 } })json") == R"json({"test":{"test":2}})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": { "test": 1, "test2": [ 2 ] } })json") == R"json({"test":{"test":1,"test2":[2]}})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": null })json") == R"json({"test":null})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": 1 })json") == R"json({"test":1})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": -1 })json") == R"json({"test":-1})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": true })json") == R"json({"test":true})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": "a" })json") == R"json({"test":"a"})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": [] })json") == R"json({"test":[]})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": [ 1 ] })json") == R"json({"test":[1]})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": [ 1, "a", true, { "test": 1 }, [], null ] })json") == R"json({"test":[1,"a",true,{"test":1},[],null]})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": {} })json") == R"json({"test":{}})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": { "test": 1 } })json") == R"json({"test":{"test":1}})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": { "test": 2 } })json") == R"json({"test":{"test":2}})json"); + CHECK(TestScriptEventAdminPort(R"json({ "test": { "test": 1, "test2": [ 2 ] } })json") == R"json({"test":{"test":1,"test2":[2]}})json"); /* Check if spaces are properly ignored. */ - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({"test":1})json") == R"json({"test":1})json"); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({"test": 1})json") == R"json({"test":1})json"); + CHECK(TestScriptEventAdminPort(R"json({"test":1})json") == R"json({"test":1})json"); + CHECK(TestScriptEventAdminPort(R"json({"test": 1})json") == R"json({"test":1})json"); /* Valid JSON but invalid Squirrel (read: floats). */ - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": 1.1 })json") == std::nullopt); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [ 1, 3, 1.1 ] })json") == std::nullopt); + CHECK(TestScriptEventAdminPort(R"json({ "test": 1.1 })json") == std::nullopt); + CHECK(TestScriptEventAdminPort(R"json({ "test": [ 1, 3, 1.1 ] })json") == std::nullopt); /* Root element has to be an object. */ - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( 1 )json") == std::nullopt); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( "a" )json") == std::nullopt); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( [ 1 ] )json") == std::nullopt); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( null )json") == std::nullopt); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( true )json") == std::nullopt); + CHECK(TestScriptEventAdminPort(R"json( 1 )json") == std::nullopt); + CHECK(TestScriptEventAdminPort(R"json( "a" )json") == std::nullopt); + CHECK(TestScriptEventAdminPort(R"json( [ 1 ] )json") == std::nullopt); + CHECK(TestScriptEventAdminPort(R"json( null )json") == std::nullopt); + CHECK(TestScriptEventAdminPort(R"json( true )json") == std::nullopt); /* Cases that should fail, as it is invalid JSON. */ - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({"test":test})json") == std::nullopt); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": 1 )json") == std::nullopt); // Missing closing } - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json( "test": 1})json") == std::nullopt); // Missing opening { - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test" = 1})json") == std::nullopt); - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": [ 1 })json") == std::nullopt); // Missing closing ] - CHECK(TestScriptAdmin::TestScriptEventAdminPort(R"json({ "test": 1 ] })json") == std::nullopt); // Missing opening [ + CHECK(TestScriptEventAdminPort(R"json({"test":test})json") == std::nullopt); + CHECK(TestScriptEventAdminPort(R"json({ "test": 1 )json") == std::nullopt); // Missing closing } + CHECK(TestScriptEventAdminPort(R"json( "test": 1})json") == std::nullopt); // Missing opening { + CHECK(TestScriptEventAdminPort(R"json({ "test" = 1})json") == std::nullopt); + CHECK(TestScriptEventAdminPort(R"json({ "test": [ 1 })json") == std::nullopt); // Missing closing ] + CHECK(TestScriptEventAdminPort(R"json({ "test": 1 ] })json") == std::nullopt); // Missing opening [ } From afc1ea8135d9a082f6051db6e5b1bacd4d8c85f2 Mon Sep 17 00:00:00 2001 From: PeterN Date: Sat, 9 Sep 2023 14:15:53 +0100 Subject: [PATCH 23/72] Codechange: Using alias and std::array for company expense storage. (#11273) This simplifies passing yearly expenses to functions and use of std algorithms. --- src/company_base.h | 2 +- src/company_cmd.cpp | 5 +++-- src/company_gui.cpp | 4 ++-- src/economy_type.h | 5 +++++ src/network/network_admin.cpp | 5 +---- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/company_base.h b/src/company_base.h index 53949fa500..eea9974089 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -92,7 +92,7 @@ struct CompanyProperties { */ bool is_ai; - Money yearly_expenses[3][EXPENSES_END]; ///< Expenses of the company for the last three years, in every #ExpensesType category. + std::array yearly_expenses{}; ///< Expenses of the company for the last three years. CompanyEconomyEntry cur_economy; ///< Economic data of the company of this quarter. CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]; ///< Economic data of the company of the last #MAX_HISTORY_QUARTERS quarters. byte num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy. diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 2647b334f4..901fdbc063 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -750,8 +750,9 @@ static IntervalTimer _companies_yearly({TimerGameCalendar::YE { /* Copy statistics */ for (Company *c : Company::Iterate()) { - memmove(&c->yearly_expenses[1], &c->yearly_expenses[0], sizeof(c->yearly_expenses) - sizeof(c->yearly_expenses[0])); - memset(&c->yearly_expenses[0], 0, sizeof(c->yearly_expenses[0])); + /* Move expenses to previous years. */ + std::rotate(std::rbegin(c->yearly_expenses), std::rbegin(c->yearly_expenses) + 1, std::rend(c->yearly_expenses)); + c->yearly_expenses[0] = {}; SetWindowDirty(WC_FINANCES, c->index); } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 45ca97f8e3..960ae8d37c 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -229,7 +229,7 @@ static void DrawPrice(Money amount, int left, int right, int top, TextColour col * Draw a category of expenses/revenues in the year column. * @return The income sum of the category. */ -static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, const Money(&tbl)[EXPENSES_END]) +static Money DrawYearCategory(const Rect &r, int start_y, ExpensesList list, const Expenses &tbl) { int y = start_y; ExpensesType et; @@ -260,7 +260,7 @@ static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, co * @param tbl Reference to table of amounts for \a year. * @note The environment must provide padding at the left and right of \a r. */ -static void DrawYearColumn(const Rect &r, TimerGameCalendar::Year year, const Money (&tbl)[EXPENSES_END]) +static void DrawYearColumn(const Rect &r, TimerGameCalendar::Year year, const Expenses &tbl) { int y = r.top; Money sum; diff --git a/src/economy_type.h b/src/economy_type.h index 1c754476b1..763634ac3b 100644 --- a/src/economy_type.h +++ b/src/economy_type.h @@ -172,6 +172,11 @@ enum ExpensesType : byte { INVALID_EXPENSES = 0xFF, ///< Invalid expense type. }; +/** + * Data type for storage of Money for each #ExpensesType category. + */ +using Expenses = std::array; + /** * Categories of a price bases. */ diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 40679352d6..8a33b97c54 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -383,10 +383,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyEconomy() { for (const Company *company : Company::Iterate()) { /* Get the income. */ - Money income = 0; - for (uint i = 0; i < lengthof(company->yearly_expenses[0]); i++) { - income -= company->yearly_expenses[0][i]; - } + Money income = -std::reduce(std::begin(company->yearly_expenses[0]), std::end(company->yearly_expenses[0])); Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_ECONOMY); From c3918838f68f5112fadf3f3a2cc75bb0a3310393 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sat, 9 Sep 2023 16:06:00 +0200 Subject: [PATCH 24/72] Fix: crash when opening a damaged base-graphics (#11275) --- src/random_access_file.cpp | 5 +++-- src/random_access_file_type.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/random_access_file.cpp b/src/random_access_file.cpp index 60df8cdc00..37f51530df 100644 --- a/src/random_access_file.cpp +++ b/src/random_access_file.cpp @@ -146,9 +146,10 @@ void RandomAccessFile::ReadBlock(void *ptr, size_t size) * Skip \a n bytes ahead in the file. * @param n Number of bytes to skip reading. */ -void RandomAccessFile::SkipBytes(int n) +void RandomAccessFile::SkipBytes(size_t n) { - int remaining = this->buffer_end - this->buffer; + assert(this->buffer_end >= this->buffer); + size_t remaining = this->buffer_end - this->buffer; if (n <= remaining) { this->buffer += n; } else { diff --git a/src/random_access_file_type.h b/src/random_access_file_type.h index 1573855274..caf58a9ba8 100644 --- a/src/random_access_file_type.h +++ b/src/random_access_file_type.h @@ -51,7 +51,7 @@ public: uint32_t ReadDword(); void ReadBlock(void *ptr, size_t size); - void SkipBytes(int n); + void SkipBytes(size_t n); }; #endif /* RANDOM_ACCESS_FILE_TYPE_H */ From 9040d7813d25926e98163647846105d5fe3fa535 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 8 Sep 2023 20:34:20 +0100 Subject: [PATCH 25/72] Codechange: Use std::array and std::unique_ptr for PersistentStorageArrays. This (mostly) avoids the need for manual memory management and copying. --- src/newgrf_storage.h | 36 +++++++++--------------------------- src/saveload/industry_sl.cpp | 2 +- src/saveload/station_sl.cpp | 2 +- 3 files changed, 11 insertions(+), 29 deletions(-) diff --git a/src/newgrf_storage.h b/src/newgrf_storage.h index 1461581fd2..7ea531443b 100644 --- a/src/newgrf_storage.h +++ b/src/newgrf_storage.h @@ -65,26 +65,10 @@ private: */ template struct PersistentStorageArray : BasePersistentStorageArray { - TYPE storage[SIZE]; ///< Memory to for the storage array - TYPE *prev_storage; ///< Memory to store "old" states so we can revert them on the performance of test cases for commands etc. - - /** Simply construct the array */ - PersistentStorageArray() : prev_storage(nullptr) - { - memset(this->storage, 0, sizeof(this->storage)); - } + using StorageType = std::array; - /** And free all data related to it */ - ~PersistentStorageArray() - { - free(this->prev_storage); - } - - /** Resets all values to zero. */ - void ResetToZero() - { - memset(this->storage, 0, sizeof(this->storage)); - } + StorageType storage{}; ///< Memory for the storage array + std::unique_ptr prev_storage{}; ///< Temporary memory to store previous state so it can be reverted, e.g. for command tests. /** * Stores some value at a given position. @@ -104,10 +88,9 @@ struct PersistentStorageArray : BasePersistentStorageArray { /* We do not have made a backup; lets do so */ if (AreChangesPersistent()) { - assert(this->prev_storage == nullptr); - } else if (this->prev_storage == nullptr) { - this->prev_storage = MallocT(SIZE); - memcpy(this->prev_storage, this->storage, sizeof(this->storage)); + assert(!this->prev_storage); + } else if (!this->prev_storage) { + this->prev_storage = std::make_unique(this->storage); /* We only need to register ourselves when we made the backup * as that is the only time something will have changed */ @@ -132,10 +115,9 @@ struct PersistentStorageArray : BasePersistentStorageArray { void ClearChanges() { - if (this->prev_storage != nullptr) { - memcpy(this->storage, this->prev_storage, sizeof(this->storage)); - free(this->prev_storage); - this->prev_storage = nullptr; + if (this->prev_storage) { + this->storage = *this->prev_storage; + this->prev_storage.reset(); } } }; diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 017ab89bec..1c0b79f5b3 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -246,7 +246,7 @@ struct INDYChunkHandler : ChunkHandler { /* Store the old persistent storage. The GRFID will be added later. */ assert(PersistentStorage::CanAllocateItem()); i->psa = new PersistentStorage(0, 0, 0); - memcpy(i->psa->storage, _old_ind_persistent_storage.storage, sizeof(_old_ind_persistent_storage.storage)); + std::copy(std::begin(_old_ind_persistent_storage.storage), std::end(_old_ind_persistent_storage.storage), std::begin(i->psa->storage)); } if (IsSavegameVersionBefore(SLV_INDUSTRY_CARGO_REORGANISE)) LoadMoveAcceptsProduced(i); Industry::IncIndustryTypeCount(i->type); diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 76ef03dee4..3ae0dabc5f 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -426,7 +426,7 @@ public: /* Store the old persistent storage. The GRFID will be added later. */ assert(PersistentStorage::CanAllocateItem()); st->airport.psa = new PersistentStorage(0, 0, 0); - memcpy(st->airport.psa->storage, _old_st_persistent_storage.storage, sizeof(_old_st_persistent_storage.storage)); + std::copy(std::begin(_old_st_persistent_storage.storage), std::end(_old_st_persistent_storage.storage), std::begin(st->airport.psa->storage)); } size_t num_cargo = this->GetNumCargo(); From 7bd019df906f436c737d36cdaa04e9ba414853fe Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 8 Sep 2023 20:41:46 +0100 Subject: [PATCH 26/72] Codechange: Use std::array for TemporaryStorageArray. This removes the need for initialisation with memset(). --- src/newgrf_storage.h | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/newgrf_storage.h b/src/newgrf_storage.h index 7ea531443b..95ad50cec4 100644 --- a/src/newgrf_storage.h +++ b/src/newgrf_storage.h @@ -131,17 +131,12 @@ struct PersistentStorageArray : BasePersistentStorageArray { */ template struct TemporaryStorageArray { - TYPE storage[SIZE]; ///< Memory to for the storage array - uint16_t init[SIZE]; ///< Storage has been assigned, if this equals 'init_key'. - uint16_t init_key; ///< Magic key to 'init'. + using StorageType = std::array; + using StorageInitType = std::array; - /** Simply construct the array */ - TemporaryStorageArray() - { - memset(this->storage, 0, sizeof(this->storage)); // not exactly needed, but makes code analysers happy - memset(this->init, 0, sizeof(this->init)); - this->init_key = 1; - } + StorageType storage{}; ///< Memory for the storage array + StorageInitType init{}; ///< Storage has been assigned, if this equals 'init_key'. + uint16_t init_key{1}; ///< Magic key to 'init'. /** * Stores some value at a given position. @@ -181,7 +176,7 @@ struct TemporaryStorageArray { this->init_key++; if (this->init_key == 0) { /* When init_key wraps around, we need to reset everything */ - memset(this->init, 0, sizeof(this->init)); + this->init = {}; this->init_key = 1; } } From 7519f7ad79f9b7a2ee3776fa82b0ef1c1357ac80 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 9 Sep 2023 16:36:07 +0100 Subject: [PATCH 27/72] Codechange: Use std::find_if to find or assign a text effect slot. This replaces an index-based loop. --- src/texteff.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/texteff.cpp b/src/texteff.cpp index 2b15d68209..a7cd3cdf04 100644 --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -42,13 +42,10 @@ TextEffectID AddTextEffect(StringID msg, int center, int y, uint8_t duration, Te { if (_game_mode == GM_MENU) return INVALID_TE_ID; - TextEffectID i; - for (i = 0; i < _text_effects.size(); i++) { - if (_text_effects[i].string_id == INVALID_STRING_ID) break; - } - if (i == _text_effects.size()) _text_effects.emplace_back(); + auto it = std::find_if(std::begin(_text_effects), std::end(_text_effects), [](const TextEffect &te) { return te.string_id == INVALID_STRING_ID; }); + if (it == std::end(_text_effects)) it = _text_effects.emplace(std::end(_text_effects)); - TextEffect &te = _text_effects[i]; + TextEffect &te = *it; /* Start defining this object */ te.string_id = msg; @@ -60,7 +57,7 @@ TextEffectID AddTextEffect(StringID msg, int center, int y, uint8_t duration, Te te.width_normal = 0; te.UpdatePosition(center, y, msg); - return i; + return static_cast(it - std::begin(_text_effects)); } void UpdateTextEffect(TextEffectID te_id, StringID msg) From 78b841d14e35e06b071d2fc16550b4b4cd010549 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 9 Sep 2023 16:36:46 +0100 Subject: [PATCH 28/72] Codechange: Take reference to text effect instead of pointer when updating. --- src/texteff.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/texteff.cpp b/src/texteff.cpp index a7cd3cdf04..98a7e85794 100644 --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -63,12 +63,12 @@ TextEffectID AddTextEffect(StringID msg, int center, int y, uint8_t duration, Te void UpdateTextEffect(TextEffectID te_id, StringID msg) { /* Update details */ - TextEffect *te = _text_effects.data() + te_id; - if (msg == te->string_id && !HaveDParamChanged(te->params)) return; - te->string_id = msg; - CopyOutDParam(te->params, 2); + TextEffect &te = _text_effects[te_id]; + if (msg == te.string_id && !HaveDParamChanged(te.params)) return; + te.string_id = msg; + CopyOutDParam(te.params, 2); - te->UpdatePosition(te->center, te->top, te->string_id, te->string_id - 1); + te.UpdatePosition(te.center, te.top, te.string_id, te.string_id - 1); } void UpdateAllTextEffectVirtCoords() From 3c61c642a9ca69ce52cb209965a5707018841f57 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 9 Sep 2023 16:38:12 +0100 Subject: [PATCH 29/72] Codechange: Don't allocate a text effect with INVALID_TE_ID. Previously, despite INVALID_TE_ID existing, it was not checked during allocation and there was no limit to the number of text effects. --- src/texteff.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/texteff.cpp b/src/texteff.cpp index 98a7e85794..01dca6087c 100644 --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -43,7 +43,11 @@ TextEffectID AddTextEffect(StringID msg, int center, int y, uint8_t duration, Te if (_game_mode == GM_MENU) return INVALID_TE_ID; auto it = std::find_if(std::begin(_text_effects), std::end(_text_effects), [](const TextEffect &te) { return te.string_id == INVALID_STRING_ID; }); - if (it == std::end(_text_effects)) it = _text_effects.emplace(std::end(_text_effects)); + if (it == std::end(_text_effects)) { + /* _text_effects.size() is the maximum ID + 1 that has been allocated. We should not allocate INVALID_TE_ID or beyond. */ + if (_text_effects.size() >= INVALID_TE_ID) return INVALID_TE_ID; + it = _text_effects.emplace(std::end(_text_effects)); + } TextEffect &te = *it; From f6939d6c4dbebf1fe0f28a38e6d8cb454f5e674a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 9 Sep 2023 16:38:59 +0100 Subject: [PATCH 30/72] Codechange: Make INVALID_TE_ID a TextEffectID instead of a TextEffectMode. Type-correctness? --- src/texteff.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/texteff.hpp b/src/texteff.hpp index f5b0e3aa10..5f5010c55c 100644 --- a/src/texteff.hpp +++ b/src/texteff.hpp @@ -20,12 +20,12 @@ enum TextEffectMode { TE_RISING, ///< Make the text effect slowly go upwards TE_STATIC, ///< Keep the text effect static - - INVALID_TE_ID = 0xFFFF, }; typedef size_t TextEffectID; +static const TextEffectID INVALID_TE_ID = UINT16_MAX; + TextEffectID AddTextEffect(StringID msg, int x, int y, uint8_t duration, TextEffectMode mode); void InitTextEffects(); void DrawTextEffects(DrawPixelInfo *dpi); From f3b4f9d640cbd8795b481d71bb9aafa0070db464 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 9 Sep 2023 16:40:59 +0100 Subject: [PATCH 31/72] Codechange: Reduce size of TextEffectMode and TextEffectID. TextEffectID was promoted to size_t in #9235, when it was used in loops. However since then the relevant code uses range-for or iterators instead. --- src/texteff.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/texteff.hpp b/src/texteff.hpp index 5f5010c55c..dad9b5888d 100644 --- a/src/texteff.hpp +++ b/src/texteff.hpp @@ -17,12 +17,12 @@ /** * Text effect modes. */ -enum TextEffectMode { +enum TextEffectMode : uint8_t { TE_RISING, ///< Make the text effect slowly go upwards TE_STATIC, ///< Keep the text effect static }; -typedef size_t TextEffectID; +using TextEffectID = uint16_t; static const TextEffectID INVALID_TE_ID = UINT16_MAX; From b0e73277d61fb291425cf1a85a631210993ab2e8 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sat, 9 Sep 2023 21:24:46 +0200 Subject: [PATCH 32/72] Codechange: remove loaded_at_xy from CargoPacket as it was unused (#11276) --- src/cargoaction.cpp | 2 -- src/cargoaction.h | 10 +++--- src/cargopacket.cpp | 34 ++++-------------- src/cargopacket.h | 38 +++------------------ src/economy.cpp | 6 ++-- src/saveload/cargopacket_sl.cpp | 3 -- src/saveload/compat/cargopacket_sl_compat.h | 2 +- src/saveload/compat/vehicle_sl_compat.h | 2 +- src/saveload/oldloader_sl.cpp | 2 +- src/saveload/saveload.h | 1 + src/saveload/station_sl.cpp | 2 +- src/saveload/vehicle_sl.cpp | 4 +-- src/vehicle.cpp | 1 - 13 files changed, 24 insertions(+), 83 deletions(-) diff --git a/src/cargoaction.cpp b/src/cargoaction.cpp index 5853b87da9..a1263a3014 100644 --- a/src/cargoaction.cpp +++ b/src/cargoaction.cpp @@ -120,7 +120,6 @@ bool CargoLoad::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); if (cp_new == nullptr) return false; - cp_new->SetLoadPlace(this->load_place); this->source->RemoveFromCache(cp_new, cp_new->Count()); this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP); return cp_new == cp; @@ -135,7 +134,6 @@ bool CargoReservation::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); if (cp_new == nullptr) return false; - cp_new->SetLoadPlace(this->load_place); this->source->reserved_count += cp_new->Count(); this->source->RemoveFromCache(cp_new, cp_new->Count()); this->destination->Append(cp_new, VehicleCargoList::MTA_LOAD); diff --git a/src/cargoaction.h b/src/cargoaction.h index 58c866ef65..72df5f5789 100644 --- a/src/cargoaction.h +++ b/src/cargoaction.h @@ -77,19 +77,17 @@ public: /** Action of loading cargo from a station onto a vehicle. */ class CargoLoad : public CargoMovement { -protected: - TileIndex load_place; ///< TileIndex to be saved in the packets' loaded_at_xy. public: - CargoLoad(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex load_place) : - CargoMovement(source, destination, max_move), load_place(load_place) {} + CargoLoad(StationCargoList *source, VehicleCargoList *destination, uint max_move) : + CargoMovement(source, destination, max_move) {} bool operator()(CargoPacket *cp); }; /** Action of reserving cargo from a station to be loaded onto a vehicle. */ class CargoReservation : public CargoLoad { public: - CargoReservation(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex load_place) : - CargoLoad(source, destination, max_move, load_place) {} + CargoReservation(StationCargoList *source, VehicleCargoList *destination, uint max_move) : + CargoLoad(source, destination, max_move) {} bool operator()(CargoPacket *cp); }; diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 1bec3b99f3..5718ac86a5 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -46,7 +46,6 @@ CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16_t count, periods_in_transit(0), feeder_share(0), source_xy(source_xy), - loaded_at_xy(0), source_id(source_id), source(source), source_type(source_type) @@ -61,19 +60,17 @@ CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16_t count, * @param periods_in_transit Number of cargo aging periods the cargo has been in transit. * @param source Station the cargo was initially loaded. * @param source_xy Station location the cargo was initially loaded. - * @param loaded_at_xy Location the cargo was loaded last. * @param feeder_share Feeder share the packet has already accumulated. * @param source_type 'Type' of source the packet comes from (for subsidies). * @param source_id Actual source of the packet (for subsidies). * @note We have to zero memory ourselves here because we are using a 'new' * that, in contrary to all other pools, does not memset to 0. */ -CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share, SourceType source_type, SourceID source_id) : +CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : count(count), periods_in_transit(periods_in_transit), feeder_share(feeder_share), source_xy(source_xy), - loaded_at_xy(loaded_at_xy), source_id(source_id), source(source), source_type(source_type) @@ -91,7 +88,7 @@ CargoPacket *CargoPacket::Split(uint new_size) if (!CargoPacket::CanAllocateItem()) return nullptr; Money fs = this->FeederShare(new_size); - CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->source, this->source_xy, this->loaded_at_xy, fs, this->source_type, this->source_id); + CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->source, this->source_xy, fs, this->source_type, this->source_id); this->feeder_share -= fs; this->count -= new_size; return cp_new; @@ -389,23 +386,6 @@ void VehicleCargoList::AgeCargo() } } -/** - * Sets loaded_at_xy to the current station for all cargo to be transferred. - * This is done when stopping or skipping while the vehicle is unloading. In - * that case the vehicle will get part of its transfer credits early and it may - * get more transfer credits than it's entitled to. - * @param xy New loaded_at_xy for the cargo. - */ -void VehicleCargoList::SetTransferLoadPlace(TileIndex xy) -{ - uint sum = 0; - for (Iterator it = this->packets.begin(); sum < this->action_counts[MTA_TRANSFER]; ++it) { - CargoPacket *cp = *it; - cp->loaded_at_xy = xy; - sum += cp->count; - } -} - /** * Choose action to be performed with the given cargo packet. * @param cp The packet. @@ -815,13 +795,12 @@ uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_ * Reserves cargo for loading onto the vehicle. * @param max_move Maximum amount of cargo to reserve. * @param dest VehicleCargoList to reserve for. - * @param load_place Tile index of the current station. * @param next_station Next station(s) the loading vehicle will visit. * @return Amount of cargo actually reserved. */ -uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next_station) +uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, StationIDStack next_station) { - return this->ShiftCargo(CargoReservation(this, dest, max_move, load_place), next_station, true); + return this->ShiftCargo(CargoReservation(this, dest, max_move), next_station, true); } /** @@ -829,14 +808,13 @@ uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, TileIndex * Otherwise load cargo from the station. * @param max_move Amount of cargo to load. * @param dest Vehicle cargo list where the cargo resides. - * @param load_place The new loaded_at_xy to be assigned to packets being moved. * @param next_station Next station(s) the loading vehicle will visit. * @return Amount of cargo actually loaded. * @note Vehicles may or may not reserve, depending on their orders. The two * modes of loading are exclusive, though. If cargo is reserved we don't * need to load unreserved cargo. */ -uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next_station) +uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, StationIDStack next_station) { uint move = std::min(dest->ActionCount(VehicleCargoList::MTA_LOAD), max_move); if (move > 0) { @@ -844,7 +822,7 @@ uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, TileIndex loa dest->Reassign(move); return move; } else { - return this->ShiftCargo(CargoLoad(this, dest, max_move, load_place), next_station, true); + return this->ShiftCargo(CargoLoad(this, dest, max_move), next_station, true); } } diff --git a/src/cargopacket.h b/src/cargopacket.h index 093f2fbda9..3cc46a9446 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -34,13 +34,6 @@ template class CargoList; class StationCargoList; // forward-declare, so we can use it in VehicleCargoList. extern SaveLoadTable GetCargoPacketDesc(); -/** - * To make alignment in the union in CargoPacket a bit easier, create a new type - * that is a StationID, but stored as 32bit. - */ -typedef uint32_t StationID_32bit; -static_assert(sizeof(TileIndex) == sizeof(StationID_32bit)); - /** * Container for cargo from the same location and time. */ @@ -50,10 +43,7 @@ private: uint16_t periods_in_transit; ///< Amount of cargo aging periods this packet has been in transit. Money feeder_share; ///< Value of feeder pickup to be paid for on delivery of cargo. TileIndex source_xy; ///< The origin of the cargo (first station in feeder chain). - union { - TileIndex loaded_at_xy; ///< Location where this cargo has been loaded into the vehicle. - StationID_32bit next_station; ///< Station where the cargo wants to go next. - }; + StationID next_station; ///< Station where the cargo wants to go next. SourceID source_id; ///< Index of source, INVALID_SOURCE if unknown/invalid. StationID source; ///< The station where the cargo came from first. SourceType source_type; ///< Type of \c source_id. @@ -70,7 +60,7 @@ public: CargoPacket(); CargoPacket(StationID source, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id); - CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share = 0, SourceType source_type = SourceType::Industry, SourceID source_id = INVALID_SOURCE); + CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_xy, Money feeder_share = 0, SourceType source_type = SourceType::Industry, SourceID source_id = INVALID_SOURCE); /** Destroy the packet. */ ~CargoPacket() { } @@ -79,12 +69,6 @@ public: void Merge(CargoPacket *cp); void Reduce(uint count); - /** - * Sets the tile where the packet was loaded last. - * @param load_place Tile where the packet was loaded last. - */ - void SetLoadPlace(TileIndex load_place) { this->loaded_at_xy = load_place; } - /** * Sets the station where the packet is supposed to go next. * @param next_station Next station the packet should go to. @@ -175,15 +159,6 @@ public: return this->source_xy; } - /** - * Gets the coordinates of the cargo's last loading station. - * @return Last loading station's coordinates. - */ - inline TileIndex LoadedAtXY() const - { - return this->loaded_at_xy; - } - /** * Gets the ID of station the cargo wants to go next. * @return Next station for this packets. @@ -401,8 +376,6 @@ public: void InvalidateCache(); - void SetTransferLoadPlace(TileIndex xy); - bool Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8_t order_flags, const GoodsEntry *ge, CargoPayment *payment); /** @@ -440,8 +413,7 @@ public: return cp1->source_xy == cp2->source_xy && cp1->periods_in_transit == cp2->periods_in_transit && cp1->source_type == cp2->source_type && - cp1->source_id == cp2->source_id && - cp1->loaded_at_xy == cp2->loaded_at_xy; + cp1->source_id == cp2->source_id; } }; @@ -538,8 +510,8 @@ public: * amount of cargo to be moved. Second parameter is destination (if * applicable), return value is amount of cargo actually moved. */ - uint Reserve(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next); - uint Load(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next); + uint Reserve(uint max_move, VehicleCargoList *dest, StationIDStack next); + uint Load(uint max_move, VehicleCargoList *dest, StationIDStack next); uint Truncate(uint max_move = UINT_MAX, StationCargoAmountMap *cargo_per_source = nullptr); uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge); diff --git a/src/economy.cpp b/src/economy.cpp index 5af92821c7..b2bad75ceb 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1469,7 +1469,7 @@ struct FinalizeRefitAction { if (this->do_reserve) { this->st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(), - &v->cargo, st->xy, this->next_station); + &v->cargo, this->next_station); } this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount(); return true; @@ -1560,7 +1560,7 @@ struct ReserveCargoAction { { if (v->cargo_cap > v->cargo.RemainingCount() && MayLoadUnderExclusiveRights(st, v)) { st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(), - &v->cargo, st->xy, *next_station); + &v->cargo, *next_station); } return true; @@ -1791,7 +1791,7 @@ static void LoadUnloadVehicle(Vehicle *front) if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO); if (_settings_game.order.gradual_loading) cap_left = std::min(cap_left, GetLoadAmount(v)); - uint loaded = ge->cargo.Load(cap_left, &v->cargo, st->xy, next_station); + uint loaded = ge->cargo.Load(cap_left, &v->cargo, next_station); if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) { /* Remember if there are reservations left so that we don't stop * loading before they're loaded. */ diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index 069162867f..40fb25fe68 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -34,7 +34,6 @@ for (VehicleCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) { CargoPacket *cp = *it; cp->source_xy = Station::IsValidID(cp->source) ? Station::Get(cp->source)->xy : v->tile; - cp->loaded_at_xy = cp->source_xy; } } @@ -51,7 +50,6 @@ for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) { CargoPacket *cp = *it; cp->source_xy = Station::IsValidID(cp->source) ? Station::Get(cp->source)->xy : st->xy; - cp->loaded_at_xy = cp->source_xy; } } } @@ -90,7 +88,6 @@ SaveLoadTable GetCargoPacketDesc() static const SaveLoad _cargopacket_desc[] = { SLE_VAR(CargoPacket, source, SLE_UINT16), SLE_VAR(CargoPacket, source_xy, SLE_UINT32), - SLE_VAR(CargoPacket, loaded_at_xy, SLE_UINT32), SLE_VAR(CargoPacket, count, SLE_UINT16), SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_MORE_CARGO_AGE), SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_UINT16, SLV_MORE_CARGO_AGE, SLV_PERIODS_IN_TRANSIT_RENAME), diff --git a/src/saveload/compat/cargopacket_sl_compat.h b/src/saveload/compat/cargopacket_sl_compat.h index eee308bcb0..2622d6e692 100644 --- a/src/saveload/compat/cargopacket_sl_compat.h +++ b/src/saveload/compat/cargopacket_sl_compat.h @@ -16,7 +16,7 @@ const SaveLoadCompat _cargopacket_sl_compat[] = { SLC_VAR("source"), SLC_VAR("source_xy"), - SLC_VAR("loaded_at_xy"), + SLC_NULL(4, SL_MIN_VERSION, SLV_REMOVE_LOADED_AT_XY), SLC_VAR("count"), SLC_VAR("days_in_transit"), SLC_VAR("feeder_share"), diff --git a/src/saveload/compat/vehicle_sl_compat.h b/src/saveload/compat/vehicle_sl_compat.h index 524ff1a3ba..4587dd2824 100644 --- a/src/saveload/compat/vehicle_sl_compat.h +++ b/src/saveload/compat/vehicle_sl_compat.h @@ -82,7 +82,7 @@ const SaveLoadCompat _vehicle_common_sl_compat[] = { SLC_VAR("profit_this_year"), SLC_VAR("profit_last_year"), SLC_VAR("cargo_feeder_share"), - SLC_VAR("cargo_loaded_at_xy"), + SLC_NULL(4, SLV_51, SLV_68), SLC_VAR("value"), SLC_VAR("random_bits"), SLC_VAR("waiting_triggers"), diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index d1349c99a6..12e9b71e96 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -1353,7 +1353,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) { StationID source = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source; TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : (TileIndex)0; - v->cargo.Append(new CargoPacket(_cargo_count, _cargo_periods, source, source_xy, source_xy)); + v->cargo.Append(new CargoPacket(_cargo_count, _cargo_periods, source, source_xy)); } } diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 8c7c283774..71e86aecea 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -359,6 +359,7 @@ enum SaveLoadVersion : uint16_t { SLV_INDUSTRY_CARGO_REORGANISE, ///< 315 PR#10853 Industry accepts/produced data reorganised. SLV_PERIODS_IN_TRANSIT_RENAME, ///< 316 PR#11112 Rename days in transit to (cargo) periods in transit. SLV_NEWGRF_LAST_SERVICE, ///< 317 PR#11124 Added stable date_of_last_service to avoid NewGRF trouble. + SLV_REMOVE_LOADED_AT_XY, ///< 318 PR#11276 Remove loaded_at_xy variable from CargoPacket. SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 3ae0dabc5f..f3b7af25a3 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -449,7 +449,7 @@ public: assert(CargoPacket::CanAllocateItem()); /* Don't construct the packet with station here, because that'll fail with old savegames */ - CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, source, _cargo_source_xy, _cargo_source_xy, _cargo_feeder_share); + CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, source, _cargo_source_xy, _cargo_feeder_share); ge->cargo.Append(cp, INVALID_STATION); SB(ge->status, GoodsEntry::GES_RATING, 1, 1); } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index c4840bdf9a..4ef24cf228 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -577,7 +577,6 @@ static uint32_t _cargo_source_xy; static uint16_t _cargo_count; static uint16_t _cargo_paid_for; static Money _cargo_feeder_share; -static uint32_t _cargo_loaded_at_xy; class SlVehicleCommon : public DefaultSaveLoadHandler { public: @@ -699,7 +698,6 @@ public: SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, SLV_65, SL_MAX_VERSION), SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, SLV_51, SLV_65), SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_INT64, SLV_65, SLV_68), - SLEG_CONDVAR("cargo_loaded_at_xy", _cargo_loaded_at_xy, SLE_UINT32, SLV_51, SLV_68), SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), SLE_CONDVAR(Vehicle, value, SLE_INT64, SLV_65, SL_MAX_VERSION), @@ -1043,7 +1041,7 @@ struct VEHSChunkHandler : ChunkHandler { if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v) && CargoPacket::CanAllocateItem()) { /* Don't construct the packet with station here, because that'll fail with old savegames */ - CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_periods, _cargo_source, _cargo_source_xy, _cargo_loaded_at_xy, _cargo_feeder_share); + CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_periods, _cargo_source, _cargo_source_xy, _cargo_feeder_share); v->cargo.Append(cp); } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index ac42a1a38a..cd47fc9bdb 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2242,7 +2242,6 @@ void Vehicle::CancelReservation(StationID next, Station *st) if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) { Debug(misc, 1, "cancelling cargo reservation"); cargo.Return(UINT_MAX, &st->goods[v->cargo_type].cargo, next); - cargo.SetTransferLoadPlace(st->xy); } cargo.KeepAll(); } From 30172fc03784cd6251602d81d4e0a85b0198ef5c Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sat, 9 Sep 2023 23:21:21 +0200 Subject: [PATCH 33/72] Codechange: cleanup CargoPacket in terms of variable/function names (#11278) Over the years, things got reused and changed, making the current names somewhat unclear in what they actually mean and do. --- src/aircraft_gui.cpp | 4 +- src/cargoaction.cpp | 8 +-- src/cargopacket.cpp | 70 +++++++++++++------------- src/cargopacket.h | 71 +++++++++++++++------------ src/economy.cpp | 10 ++-- src/newgrf_engine.cpp | 2 +- src/newgrf_station.cpp | 2 +- src/roadveh_gui.cpp | 8 +-- src/saveload/cargopacket_sl.cpp | 8 +-- src/script/api/script_station.cpp | 2 +- src/script/api/script_stationlist.cpp | 4 +- src/ship_gui.cpp | 4 +- src/station_gui.cpp | 8 +-- src/train_gui.cpp | 4 +- 14 files changed, 106 insertions(+), 99 deletions(-) diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp index 4192fd2473..1e7c8e62c1 100644 --- a/src/aircraft_gui.cpp +++ b/src/aircraft_gui.cpp @@ -56,10 +56,10 @@ void DrawAircraftDetails(const Aircraft *v, const Rect &r) /* Cargo names (fix pluralness) */ SetDParam(0, u->cargo_type); SetDParam(1, cargo_count); - SetDParam(2, u->cargo.Source()); + SetDParam(2, u->cargo.GetFirstStation()); DrawString(r.left, r.right, y, STR_VEHICLE_DETAILS_CARGO_FROM); y += FONT_HEIGHT_NORMAL; - feeder_share += u->cargo.FeederShare(); + feeder_share += u->cargo.GetFeederShare(); } } } diff --git a/src/cargoaction.cpp b/src/cargoaction.cpp index a1263a3014..8601ba81c8 100644 --- a/src/cargoaction.cpp +++ b/src/cargoaction.cpp @@ -167,7 +167,7 @@ bool CargoTransfer::operator()(CargoPacket *cp) if (cp_new == nullptr) return false; this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count()); /* No transfer credits here as they were already granted during Stage(). */ - this->destination->Append(cp_new, cp_new->NextStation()); + this->destination->Append(cp_new, cp_new->GetNextStation()); return cp_new == cp; } @@ -194,7 +194,7 @@ bool StationCargoReroute::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); if (cp_new == nullptr) cp_new = cp; - StationID next = this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2); + StationID next = this->ge->GetVia(cp_new->GetFirstStation(), this->avoid, this->avoid2); assert(next != this->avoid && next != this->avoid2); if (this->source != this->destination) { this->source->RemoveFromCache(cp_new, cp_new->Count()); @@ -217,8 +217,8 @@ bool VehicleCargoReroute::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); if (cp_new == nullptr) cp_new = cp; - if (cp_new->NextStation() == this->avoid || cp_new->NextStation() == this->avoid2) { - cp->SetNextStation(this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2)); + if (cp_new->GetNextStation() == this->avoid || cp_new->GetNextStation() == this->avoid2) { + cp->SetNextStation(this->ge->GetVia(cp_new->GetFirstStation(), this->avoid, this->avoid2)); } if (this->source != this->destination) { this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count()); diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 5718ac86a5..592940d25b 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -32,23 +32,21 @@ CargoPacket::CargoPacket() /** * Creates a new cargo packet. - * @param source Source station of the packet. - * @param source_xy Source location of the packet. - * @param count Number of cargo entities to put in this packet. - * @param source_type 'Type' of source the packet comes from (for subsidies). - * @param source_id Actual source of the packet (for subsidies). + * @param first_station Source station of the packet. + * @param source_xy Source location of the packet. + * @param count Number of cargo entities to put in this packet. + * @param source_type 'Type' of source the packet comes from (for subsidies). + * @param source_id Actual source of the packet (for subsidies). * @pre count != 0 * @note We have to zero memory ourselves here because we are using a 'new' * that, in contrary to all other pools, does not memset to 0. */ -CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id) : +CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id) : count(count), - periods_in_transit(0), - feeder_share(0), source_xy(source_xy), source_id(source_id), - source(source), - source_type(source_type) + source_type(source_type), + first_station(first_station) { assert(count != 0); } @@ -56,24 +54,24 @@ CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16_t count, /** * Creates a new cargo packet. Initializes the fields that cannot be changed later. * Used when loading or splitting packets. - * @param count Number of cargo entities to put in this packet. + * @param count Number of cargo entities to put in this packet. * @param periods_in_transit Number of cargo aging periods the cargo has been in transit. - * @param source Station the cargo was initially loaded. - * @param source_xy Station location the cargo was initially loaded. - * @param feeder_share Feeder share the packet has already accumulated. - * @param source_type 'Type' of source the packet comes from (for subsidies). - * @param source_id Actual source of the packet (for subsidies). + * @param first_station Station the cargo was initially loaded. + * @param source_xy Station location the cargo was initially loaded. + * @param feeder_share Feeder share the packet has already accumulated. + * @param source_type 'Type' of source the packet comes from (for subsidies). + * @param source_id Actual source of the packet (for subsidies). * @note We have to zero memory ourselves here because we are using a 'new' * that, in contrary to all other pools, does not memset to 0. */ -CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : +CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : count(count), periods_in_transit(periods_in_transit), feeder_share(feeder_share), source_xy(source_xy), source_id(source_id), - source(source), - source_type(source_type) + source_type(source_type), + first_station(first_station) { assert(count != 0); } @@ -87,8 +85,8 @@ CargoPacket *CargoPacket::Split(uint new_size) { if (!CargoPacket::CanAllocateItem()) return nullptr; - Money fs = this->FeederShare(new_size); - CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->source, this->source_xy, fs, this->source_type, this->source_id); + Money fs = this->GetFeederShare(new_size); + CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->source_xy, fs, this->source_type, this->source_id); this->feeder_share -= fs; this->count -= new_size; return cp_new; @@ -112,7 +110,7 @@ void CargoPacket::Merge(CargoPacket *cp) void CargoPacket::Reduce(uint count) { assert(count < this->count); - this->feeder_share -= this->FeederShare(count); + this->feeder_share -= this->GetFeederShare(count); this->count -= count; } @@ -135,7 +133,7 @@ void CargoPacket::Reduce(uint count) /* static */ void CargoPacket::InvalidateAllFrom(StationID sid) { for (CargoPacket *cp : CargoPacket::Iterate()) { - if (cp->source == sid) cp->source = INVALID_STATION; + if (cp->first_station == sid) cp->first_station = INVALID_STATION; } } @@ -176,7 +174,7 @@ template void CargoList::RemoveFromCache(const CargoPacket *cp, uint count) { assert(count <= cp->count); - this->count -= count; + this->count -= count; this->cargo_periods_in_transit -= static_cast(cp->periods_in_transit) * count; } @@ -188,7 +186,7 @@ void CargoList::RemoveFromCache(const CargoPacket *cp, uint count) template void CargoList::AddToCache(const CargoPacket *cp) { - this->count += cp->count; + this->count += cp->count; this->cargo_periods_in_transit += static_cast(cp->periods_in_transit) * cp->count; } @@ -329,7 +327,7 @@ void VehicleCargoList::PopCargo(Taction action) */ void VehicleCargoList::RemoveFromCache(const CargoPacket *cp, uint count) { - this->feeder_share -= cp->FeederShare(count); + this->feeder_share -= cp->GetFeederShare(count); this->Parent::RemoveFromCache(cp, count); } @@ -399,7 +397,7 @@ void VehicleCargoList::AgeCargo() StationID current_station, bool accepted, StationIDStack next_station) { if (cargo_next == INVALID_STATION) { - return (accepted && cp->source != current_station) ? MTA_DELIVER : MTA_KEEP; + return (accepted && cp->first_station != current_station) ? MTA_DELIVER : MTA_KEEP; } else if (cargo_next == current_station) { return MTA_DELIVER; } else if (next_station.Contains(cargo_next)) { @@ -443,13 +441,13 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID MoveToAction action = MTA_LOAD; if (force_keep) { action = MTA_KEEP; - } else if (force_unload && accepted && cp->source != current_station) { + } else if (force_unload && accepted && cp->first_station != current_station) { action = MTA_DELIVER; } else if (force_transfer) { action = MTA_TRANSFER; /* We cannot send the cargo to any of the possible next hops and * also not to the current station. */ - FlowStatMap::const_iterator flow_it(ge->flows.find(cp->source)); + FlowStatMap::const_iterator flow_it(ge->flows.find(cp->first_station)); if (flow_it == ge->flows.end()) { cargo_next = INVALID_STATION; } else { @@ -468,11 +466,11 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID } else { /* Rewrite an invalid source station to some random other one to * avoid keeping the cargo in the vehicle forever. */ - if (cp->source == INVALID_STATION && !ge->flows.empty()) { - cp->source = ge->flows.begin()->first; + if (cp->first_station == INVALID_STATION && !ge->flows.empty()) { + cp->first_station = ge->flows.begin()->first; } bool restricted = false; - FlowStatMap::const_iterator flow_it(ge->flows.find(cp->source)); + FlowStatMap::const_iterator flow_it(ge->flows.find(cp->first_station)); if (flow_it == ge->flows.end()) { cargo_next = INVALID_STATION; } else { @@ -757,7 +755,7 @@ uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_ CargoPacket *cp = *it; if (prev_count > max_move && RandomRange(prev_count) < prev_count - max_move) { if (do_count && loop == 0) { - (*cargo_per_source)[cp->source] += cp->count; + (*cargo_per_source)[cp->first_station] += cp->count; } ++it; continue; @@ -770,16 +768,16 @@ uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_ moved += diff; } if (loop > 0) { - if (do_count) (*cargo_per_source)[cp->source] -= diff; + if (do_count) (*cargo_per_source)[cp->first_station] -= diff; return moved; } else { - if (do_count) (*cargo_per_source)[cp->source] += cp->count; + if (do_count) (*cargo_per_source)[cp->first_station] += cp->count; ++it; } } else { it = this->packets.erase(it); if (do_count && loop > 0) { - (*cargo_per_source)[cp->source] -= cp->count; + (*cargo_per_source)[cp->first_station] -= cp->count; } moved += cp->count; this->RemoveFromCache(cp, cp->count); diff --git a/src/cargopacket.h b/src/cargopacket.h index 3cc46a9446..12b8babbe9 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -39,14 +39,17 @@ extern SaveLoadTable GetCargoPacketDesc(); */ struct CargoPacket : CargoPacketPool::PoolItem<&_cargopacket_pool> { private: - uint16_t count; ///< The amount of cargo in this packet. - uint16_t periods_in_transit; ///< Amount of cargo aging periods this packet has been in transit. - Money feeder_share; ///< Value of feeder pickup to be paid for on delivery of cargo. - TileIndex source_xy; ///< The origin of the cargo (first station in feeder chain). - StationID next_station; ///< Station where the cargo wants to go next. - SourceID source_id; ///< Index of source, INVALID_SOURCE if unknown/invalid. - StationID source; ///< The station where the cargo came from first. - SourceType source_type; ///< Type of \c source_id. + uint16_t count{0}; ///< The amount of cargo in this packet. + uint16_t periods_in_transit{0}; ///< Amount of cargo aging periods this packet has been in transit. + + Money feeder_share{0}; ///< Value of feeder pickup to be paid for on delivery of cargo. + + TileIndex source_xy{0}; ///< The origin of the cargo. + SourceID source_id{INVALID_SOURCE}; ///< Index of industry/town/HQ, INVALID_SOURCE if unknown/invalid. + SourceType source_type{SourceType::Industry}; ///< Type of \c source_id. + + StationID first_station{INVALID_STATION}; ///< The station where the cargo came from first. + StationID next_station{INVALID_STATION}; ///< Station where the cargo wants to go next. /** The CargoList caches, thus needs to know about it. */ template friend class CargoList; @@ -59,7 +62,7 @@ public: static const uint16_t MAX_COUNT = UINT16_MAX; CargoPacket(); - CargoPacket(StationID source, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id); + CargoPacket(StationID first_station, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id); CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_xy, Money feeder_share = 0, SourceType source_type = SourceType::Industry, SourceID source_id = INVALID_SOURCE); /** Destroy the packet. */ @@ -73,13 +76,19 @@ public: * Sets the station where the packet is supposed to go next. * @param next_station Next station the packet should go to. */ - void SetNextStation(StationID next_station) { this->next_station = next_station; } + void SetNextStation(StationID next_station) + { + this->next_station = next_station; + } /** * Adds some feeder share to the packet. * @param new_share Feeder share to be added. */ - void AddFeederShare(Money new_share) { this->feeder_share += new_share; } + void AddFeederShare(Money new_share) + { + this->feeder_share += new_share; + } /** * Gets the number of 'items' in this packet. @@ -95,7 +104,7 @@ public: * the feeder chain. * @return Feeder share. */ - inline Money FeederShare() const + inline Money GetFeederShare() const { return this->feeder_share; } @@ -106,7 +115,7 @@ public: * @param part Amount of cargo to get the share for. * @return Feeder share for the given amount of cargo. */ - inline Money FeederShare(uint part) const + inline Money GetFeederShare(uint part) const { return this->feeder_share * part / static_cast(this->count); } @@ -118,7 +127,7 @@ public: * value is capped at UINT16_MAX. * @return Length this cargo has been in transit. */ - inline uint16_t PeriodsInTransit() const + inline uint16_t GetPeriodsInTransit() const { return this->periods_in_transit; } @@ -127,7 +136,7 @@ public: * Gets the type of the cargo's source. industry, town or head quarter. * @return Source type. */ - inline SourceType SourceSubsidyType() const + inline SourceType GetSourceType() const { return this->source_type; } @@ -136,7 +145,7 @@ public: * Gets the ID of the cargo's source. An IndustryID, TownID or CompanyID. * @return Source ID. */ - inline SourceID SourceSubsidyID() const + inline SourceID GetSourceID() const { return this->source_id; } @@ -145,16 +154,16 @@ public: * Gets the ID of the station where the cargo was loaded for the first time. * @return StationID. */ - inline StationID SourceStation() const + inline StationID GetFirstStation() const { - return this->source; + return this->first_station; } /** - * Gets the coordinates of the cargo's source station. - * @return Source station's coordinates. + * Gets the coordinates of the cargo's source. + * @return Source coordinates of cargo. */ - inline TileIndex SourceStationXY() const + inline TileIndex GetSourceXY() const { return this->source_xy; } @@ -163,7 +172,7 @@ public: * Gets the ID of station the cargo wants to go next. * @return Next station for this packets. */ - inline StationID NextStation() const + inline StationID GetNextStation() const { return this->next_station; } @@ -297,19 +306,19 @@ public: friend class VehicleCargoReroute; /** - * Returns source of the first cargo packet in this list. - * @return The before mentioned source. + * Returns the first station of the first cargo packet in this list. + * @return The before mentioned station. */ - inline StationID Source() const + inline StationID GetFirstStation() const { - return this->count == 0 ? INVALID_STATION : this->packets.front()->source; + return this->count == 0 ? INVALID_STATION : this->packets.front()->first_station; } /** * Returns total sum of the feeder share for all packets. * @return The before mentioned number. */ - inline Money FeederShare() const + inline Money GetFeederShare() const { return this->feeder_share; } @@ -469,12 +478,12 @@ public: } /** - * Returns source of the first cargo packet in this list. - * @return The before mentioned source. + * Returns first station of the first cargo packet in this list. + * @return The before mentioned station. */ - inline StationID Source() const + inline StationID GetFirstStation() const { - return this->count == 0 ? INVALID_STATION : this->packets.begin()->second.front()->source; + return this->count == 0 ? INVALID_STATION : this->packets.begin()->second.front()->first_station; } /** diff --git a/src/economy.cpp b/src/economy.cpp index b2bad75ceb..1dce13e603 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1233,11 +1233,11 @@ void CargoPayment::PayFinalDelivery(const CargoPacket *cp, uint count) } /* Handle end of route payment */ - Money profit = DeliverGoods(count, this->ct, this->current_station, cp->SourceStationXY(), cp->PeriodsInTransit(), this->owner, cp->SourceSubsidyType(), cp->SourceSubsidyID()); + Money profit = DeliverGoods(count, this->ct, this->current_station, cp->GetSourceXY(), cp->GetPeriodsInTransit(), this->owner, cp->GetSourceType(), cp->GetSourceID()); this->route_profit += profit; /* The vehicle's profit is whatever route profit there is minus feeder shares. */ - this->visual_profit += profit - cp->FeederShare(count); + this->visual_profit += profit - cp->GetFeederShare(count); } /** @@ -1248,12 +1248,12 @@ void CargoPayment::PayFinalDelivery(const CargoPacket *cp, uint count) */ Money CargoPayment::PayTransfer(const CargoPacket *cp, uint count) { - Money profit = -cp->FeederShare(count) + GetTransportedGoodsIncome( + Money profit = -cp->GetFeederShare(count) + GetTransportedGoodsIncome( count, /* pay transfer vehicle the difference between the payment for the journey from * the source to the current point, and the sum of the previous transfer payments */ - DistanceManhattan(cp->SourceStationXY(), Station::Get(this->current_station)->xy), - cp->PeriodsInTransit(), + DistanceManhattan(cp->GetSourceXY(), Station::Get(this->current_station)->xy), + cp->GetPeriodsInTransit(), this->ct); profit = profit * _settings_game.economy.feeder_payment_share / 100; diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index d0e9685df9..15464e5262 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -823,7 +823,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec case 0x3B: return GB(v->cargo_cap, 8, 8); case 0x3C: return ClampTo(v->cargo.StoredCount()); case 0x3D: return GB(ClampTo(v->cargo.StoredCount()), 8, 8); - case 0x3E: return v->cargo.Source(); + case 0x3E: return v->cargo.GetFirstStation(); case 0x3F: return ClampTo(v->cargo.PeriodsInTransit()); case 0x40: return ClampTo(v->age); case 0x41: return GB(ClampTo(v->age), 8, 8); diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 560bd29f93..cf9ddd9817 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -445,7 +445,7 @@ uint32_t Station::GetNewGRFVariable(const ResolverObject &object, byte variable, case 1: return GB(std::min(g->cargo.TotalCount(), 4095u), 0, 4) | (GB(g->status, GoodsEntry::GES_ACCEPTANCE, 1) << 7); case 2: return g->time_since_pickup; case 3: return g->rating; - case 4: return g->cargo.Source(); + case 4: return g->cargo.GetFirstStation(); case 5: return g->cargo.PeriodsInTransit(); case 6: return g->last_speed; case 7: return g->last_age; diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index 7c5cdb76b3..301b0c90a7 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -81,9 +81,9 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r) if (u->cargo.StoredCount() > 0) { SetDParam(0, u->cargo_type); SetDParam(1, u->cargo.StoredCount()); - SetDParam(2, u->cargo.Source()); + SetDParam(2, u->cargo.GetFirstStation()); str = STR_VEHICLE_DETAILS_CARGO_FROM; - feeder_share += u->cargo.FeederShare(); + feeder_share += u->cargo.GetFeederShare(); } DrawString(r.left, r.right, y, str); y += FONT_HEIGHT_NORMAL; @@ -100,9 +100,9 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r) if (v->cargo.StoredCount() > 0) { SetDParam(0, v->cargo_type); SetDParam(1, v->cargo.StoredCount()); - SetDParam(2, v->cargo.Source()); + SetDParam(2, v->cargo.GetFirstStation()); str = STR_VEHICLE_DETAILS_CARGO_FROM; - feeder_share += v->cargo.FeederShare(); + feeder_share += v->cargo.GetFeederShare(); } DrawString(r.left, r.right, y, str); y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index 40fb25fe68..0332b8a4b9 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -33,7 +33,7 @@ const CargoPacketList *packets = v->cargo.Packets(); for (VehicleCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) { CargoPacket *cp = *it; - cp->source_xy = Station::IsValidID(cp->source) ? Station::Get(cp->source)->xy : v->tile; + cp->source_xy = Station::IsValidID(cp->first_station) ? Station::Get(cp->first_station)->xy : v->tile; } } @@ -49,7 +49,7 @@ const StationCargoPacketMap *packets = ge->cargo.Packets(); for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) { CargoPacket *cp = *it; - cp->source_xy = Station::IsValidID(cp->source) ? Station::Get(cp->source)->xy : st->xy; + cp->source_xy = Station::IsValidID(cp->first_station) ? Station::Get(cp->first_station)->xy : st->xy; } } } @@ -58,7 +58,7 @@ if (IsSavegameVersionBefore(SLV_120)) { /* CargoPacket's source should be either INVALID_STATION or a valid station */ for (CargoPacket *cp : CargoPacket::Iterate()) { - if (!Station::IsValidID(cp->source)) cp->source = INVALID_STATION; + if (!Station::IsValidID(cp->first_station)) cp->first_station = INVALID_STATION; } } @@ -86,7 +86,7 @@ SaveLoadTable GetCargoPacketDesc() { static const SaveLoad _cargopacket_desc[] = { - SLE_VAR(CargoPacket, source, SLE_UINT16), + SLE_VARNAME(CargoPacket, first_station, "source", SLE_UINT16), SLE_VAR(CargoPacket, source_xy, SLE_UINT32), SLE_VAR(CargoPacket, count, SLE_UINT16), SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_MORE_CARGO_AGE), diff --git a/src/script/api/script_station.cpp b/src/script/api/script_station.cpp index ed153a4605..83bfde2958 100644 --- a/src/script/api/script_station.cpp +++ b/src/script/api/script_station.cpp @@ -69,7 +69,7 @@ template StationCargoList::ConstIterator(cargo_list.Packets()->end())); for (StationCargoList::ConstIterator it = range.first; it != range.second; it++) { const CargoPacket *cp = *it; - if (!Tfrom || cp->SourceStation() == from_station_id) cargo_count += cp->Count(); + if (!Tfrom || cp->GetFirstStation() == from_station_id) cargo_count += cp->Count(); } return cargo_count; diff --git a/src/script/api/script_stationlist.cpp b/src/script/api/script_stationlist.cpp index 5ccb6a0609..dd254f19cb 100644 --- a/src/script/api/script_stationlist.cpp +++ b/src/script/api/script_stationlist.cpp @@ -179,7 +179,7 @@ void ScriptStationList_CargoWaiting::Add(StationID station_id, CargoID cargo, St StationCargoList::ConstIterator iter = collector.GE()->cargo.Packets()->begin(); StationCargoList::ConstIterator end = collector.GE()->cargo.Packets()->end(); for (; iter != end; ++iter) { - collector.Update((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count()); + collector.Update((*iter)->GetFirstStation(), iter.GetKey(), (*iter)->Count()); } } @@ -218,7 +218,7 @@ ScriptStationList_CargoWaitingViaByFrom::ScriptStationList_CargoWaitingViaByFrom std::pair range = collector.GE()->cargo.Packets()->equal_range(via); for (StationCargoList::ConstIterator iter = range.first; iter != range.second; ++iter) { - collector.Update((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count()); + collector.Update((*iter)->GetFirstStation(), iter.GetKey(), (*iter)->Count()); } } diff --git a/src/ship_gui.cpp b/src/ship_gui.cpp index d5991c9b93..7ff8ac20c8 100644 --- a/src/ship_gui.cpp +++ b/src/ship_gui.cpp @@ -79,13 +79,13 @@ void DrawShipDetails(const Vehicle *v, const Rect &r) if (v->cargo.StoredCount() > 0) { SetDParam(0, v->cargo_type); SetDParam(1, v->cargo.StoredCount()); - SetDParam(2, v->cargo.Source()); + SetDParam(2, v->cargo.GetFirstStation()); str = STR_VEHICLE_DETAILS_CARGO_FROM; } DrawString(r.left, r.right, y, str); y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; /* Draw Transfer credits text */ - SetDParam(0, v->cargo.FeederShare()); + SetDParam(0, v->cargo.GetFeederShare()); DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 1411f9a60e..87f64167f5 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -1591,15 +1591,15 @@ struct StationViewWindow : public Window { const CargoPacket *cp = *it; StationID next = it.GetKey(); - const CargoDataEntry *source_entry = source_dest->Retrieve(cp->SourceStation()); + const CargoDataEntry *source_entry = source_dest->Retrieve(cp->GetFirstStation()); if (source_entry == nullptr) { - this->ShowCargo(cargo, i, cp->SourceStation(), next, INVALID_STATION, cp->Count()); + this->ShowCargo(cargo, i, cp->GetFirstStation(), next, INVALID_STATION, cp->Count()); continue; } const CargoDataEntry *via_entry = source_entry->Retrieve(next); if (via_entry == nullptr) { - this->ShowCargo(cargo, i, cp->SourceStation(), next, INVALID_STATION, cp->Count()); + this->ShowCargo(cargo, i, cp->GetFirstStation(), next, INVALID_STATION, cp->Count()); continue; } @@ -1620,7 +1620,7 @@ struct StationViewWindow : public Window { val = std::min(remaining, DivideApprox(cp->Count() * dest_entry->GetCount(), via_entry->GetCount())); remaining -= val; } - this->ShowCargo(cargo, i, cp->SourceStation(), next, dest_entry->GetStation(), val); + this->ShowCargo(cargo, i, cp->GetFirstStation(), next, dest_entry->GetStation(), val); } } this->ShowCargo(cargo, i, NEW_STATION, NEW_STATION, NEW_STATION, packets.ReservedCount()); diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 00d2703e55..fc2a8b1583 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -291,7 +291,7 @@ static void GetCargoSummaryOfArticulatedVehicle(const Train *v, CargoSummary *su item->capacity += v->cargo_cap; item->amount += v->cargo.StoredCount(); - if (item->source == INVALID_STATION) item->source = v->cargo.Source(); + if (item->source == INVALID_STATION) item->source = v->cargo.GetFirstStation(); } while ((v = v->Next()) != nullptr && v->IsArticulatedPart()); } @@ -440,7 +440,7 @@ void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t v for (const Vehicle *u = v; u != nullptr; u = u->Next()) { act_cargo[u->cargo_type] += u->cargo.StoredCount(); max_cargo[u->cargo_type] += u->cargo_cap; - feeder_share += u->cargo.FeederShare(); + feeder_share += u->cargo.GetFeederShare(); } /* draw total cargo tab */ From fca2b377261ce7fb105e2eadb3869c9bbeb0e1b8 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Wed, 16 Aug 2023 09:01:24 -0400 Subject: [PATCH 34/72] Codechange: Move Ticks into their own class --- src/aircraft_cmd.cpp | 2 +- src/company_cmd.cpp | 6 ++--- src/date_type.h | 20 --------------- src/engine.cpp | 3 ++- src/graph_gui.cpp | 3 ++- src/industry_cmd.cpp | 4 +-- src/linkgraph/linkgraph_gui.cpp | 3 ++- src/linkgraph/mcf.cpp | 3 ++- src/linkgraph/refresh.cpp | 2 +- src/misc_gui.cpp | 6 ++--- src/network/network.cpp | 5 ++-- src/network/network_client.cpp | 3 ++- src/network/network_server.cpp | 4 +-- src/newgrf_town.cpp | 5 ++-- src/order_base.h | 19 +++++++------- src/order_cmd.cpp | 4 +-- src/roadveh_cmd.cpp | 2 +- src/saveload/afterload.cpp | 4 +-- src/script/api/script_town.cpp | 6 ++--- src/ship_cmd.cpp | 2 +- src/sortlist_type.h | 3 ++- src/station_cmd.cpp | 8 +++--- src/table/engines.h | 12 ++++----- src/timer/timer_game_calendar.cpp | 4 +-- src/timer/timer_game_tick.h | 29 +++++++++++++++++++--- src/timetable.h | 3 ++- src/timetable_cmd.cpp | 15 +++++------ src/timetable_gui.cpp | 41 ++++++++++++++++--------------- src/town.h | 3 ++- src/town_cmd.cpp | 6 ++--- src/town_gui.cpp | 2 +- src/train_cmd.cpp | 10 ++++---- src/vehicle.cpp | 4 +-- src/vehicle_gui.cpp | 2 +- 34 files changed, 132 insertions(+), 116 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index f8e8bae342..7ec0d2e4b3 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -453,7 +453,7 @@ void Aircraft::OnNewDay() if (this->running_ticks == 0) return; - CommandCost cost(EXPENSES_AIRCRAFT_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS)); + CommandCost cost(EXPENSES_AIRCRAFT_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS)); this->profit_this_year -= cost.GetCost(); this->running_ticks = 0; diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 901fdbc063..3be9d48efb 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -659,7 +659,7 @@ static void HandleBankruptcyTakeover(Company *c) * number of companies. The minimum number of days in a quarter * is 90: 31 in January, 28 in February and 31 in March. * Note that the company going bankrupt can't buy itself. */ - static const int TAKE_OVER_TIMEOUT = 3 * 30 * DAY_TICKS / (MAX_COMPANIES - 1); + static const int TAKE_OVER_TIMEOUT = 3 * 30 * Ticks::DAY_TICKS / (MAX_COMPANIES - 1); assert(c->bankrupt_asked != 0); @@ -717,7 +717,7 @@ void OnTick_Companies() } if (_new_competitor_timeout.HasFired() && _game_mode != GM_MENU && AI::CanStartNew()) { - int32_t timeout = _settings_game.difficulty.competitors_interval * 60 * TICKS_PER_SECOND; + int32_t timeout = _settings_game.difficulty.competitors_interval * 60 * Ticks::TICKS_PER_SECOND; /* If the interval is zero, start as many competitors as needed then check every ~10 minutes if a company went bankrupt and needs replacing. */ if (timeout == 0) { /* count number of competitors */ @@ -731,7 +731,7 @@ void OnTick_Companies() if (n++ >= _settings_game.difficulty.max_no_competitors) break; Command::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID); } - timeout = 10 * 60 * TICKS_PER_SECOND; + timeout = 10 * 60 * Ticks::TICKS_PER_SECOND; } /* Randomize a bit when the AI is actually going to start; ranges from 87.5% .. 112.5% of indicated value. */ timeout += ScriptObject::GetRandomizer(OWNER_NONE).Next(timeout / 4) - timeout / 8; diff --git a/src/date_type.h b/src/date_type.h index 412fcd275e..c76b43258c 100644 --- a/src/date_type.h +++ b/src/date_type.h @@ -12,31 +12,12 @@ #include "timer/timer_game_calendar.h" -typedef int32_t Ticks; ///< The type to store ticks in - - -/** - * 1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885. On - * an overflow the new day begun and 65535 / 885 = 74. - * 1 tick is approximately 27 ms. - * 1 day is thus about 2 seconds (74 * 27 = 1998) on a machine that can run OpenTTD normally - */ -static const int DAY_TICKS = 74; ///< ticks per day static const int DAYS_IN_YEAR = 365; ///< days per year static const int DAYS_IN_LEAP_YEAR = 366; ///< sometimes, you need one day more... static const int MONTHS_IN_YEAR = 12; ///< months per year static const int SECONDS_PER_DAY = 2; ///< approximate seconds per day, not for precise calculations -static const int STATION_RATING_TICKS = 185; ///< cycle duration for updating station rating -static const int STATION_ACCEPTANCE_TICKS = 250; ///< cycle duration for updating station acceptance -static const int STATION_LINKGRAPH_TICKS = 504; ///< cycle duration for cleaning dead links -static const int CARGO_AGING_TICKS = 185; ///< cycle duration for aging cargo -static const int INDUSTRY_PRODUCE_TICKS = 256; ///< cycle duration for industry production -static const int TOWN_GROWTH_TICKS = 70; ///< cycle duration for towns trying to grow. (this originates from the size of the town array in TTD -static const int INDUSTRY_CUT_TREE_TICKS = INDUSTRY_PRODUCE_TICKS * 2; ///< cycle duration for lumber mill's extra action - - /* * ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are * primarily used for loading newgrf and savegame data and returning some @@ -98,6 +79,5 @@ static constexpr TimerGameCalendar::Date MAX_DATE = DateAtStartOfYear(MAX_YEAR + static constexpr TimerGameCalendar::Year INVALID_YEAR = -1; ///< Representation of an invalid year static constexpr TimerGameCalendar::Date INVALID_DATE = -1; ///< Representation of an invalid date -static constexpr Ticks INVALID_TICKS = -1; ///< Representation of an invalid number of ticks #endif /* DATE_TYPE_H */ diff --git a/src/engine.cpp b/src/engine.cpp index a66bc501da..612e046c5c 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -30,6 +30,7 @@ #include "error.h" #include "engine_base.h" #include "timer/timer.h" +#include "timer/timer_game_tick.h" #include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -94,7 +95,7 @@ Engine::Engine(VehicleType type, EngineID base) default: break; // The aircraft, disasters and especially visual effects have no NewGRF configured visual effects } /* Set cargo aging period to the default value. */ - this->info.cargo_age_period = CARGO_AGING_TICKS; + this->info.cargo_age_period = Ticks::CARGO_AGING_TICKS; /* Not a variant */ this->info.variant_id = INVALID_ENGINE; return; diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 91179e8286..e6aeeb22ff 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -22,6 +22,7 @@ #include "currency.h" #include "timer/timer.h" #include "timer/timer_window.h" +#include "timer/timer_game_tick.h" #include "timer/timer_game_calendar.h" #include "zoom_func.h" @@ -1130,7 +1131,7 @@ struct PerformanceRatingDetailWindow : Window { UpdateCompanyRatingAndValue(c, false); } - this->timeout = DAY_TICKS * 5; + this->timeout = Ticks::DAY_TICKS * 5; } uint score_info_left; diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index a45b3f581b..5fbbdb2131 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1155,7 +1155,7 @@ static void ProduceIndustryGoods(Industry *i) i->counter--; /* produce some cargo */ - if ((i->counter % INDUSTRY_PRODUCE_TICKS) == 0) { + if ((i->counter % Ticks::INDUSTRY_PRODUCE_TICKS) == 0) { if (HasBit(indsp->callback_mask, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1); IndustryBehaviour indbehav = indsp->behaviour; @@ -1188,7 +1188,7 @@ static void ProduceIndustryGoods(Industry *i) if (cb_res != CALLBACK_FAILED) { cut = ConvertBooleanCallback(indsp->grf_prop.grffile, CBID_INDUSTRY_SPECIAL_EFFECT, cb_res); } else { - cut = ((i->counter % INDUSTRY_CUT_TREE_TICKS) == 0); + cut = ((i->counter % Ticks::INDUSTRY_CUT_TREE_TICKS) == 0); } if (cut) ChopLumberMillTrees(i); diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index abe892d81c..bcd3325075 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -12,6 +12,7 @@ #include "../window_func.h" #include "../company_base.h" #include "../company_gui.h" +#include "../timer/timer_game_tick.h" #include "../timer/timer_game_calendar.h" #include "../viewport_func.h" #include "../zoom_func.h" @@ -221,7 +222,7 @@ void LinkGraphOverlay::AddLinks(const Station *from, const Station *to) ConstEdge &edge = lg[ge.node][to->goods[c].node]; this->AddStats(c, lg.Monthly(edge.capacity), lg.Monthly(edge.usage), ge.flows.GetFlowVia(to->index), - edge.TravelTime() / DAY_TICKS, + edge.TravelTime() / Ticks::DAY_TICKS, from->owner == OWNER_NONE || to->owner == OWNER_NONE, this->cached_links[from->index][to->index]); } diff --git a/src/linkgraph/mcf.cpp b/src/linkgraph/mcf.cpp index 21db2464e9..051d50924e 100644 --- a/src/linkgraph/mcf.cpp +++ b/src/linkgraph/mcf.cpp @@ -2,6 +2,7 @@ #include "../stdafx.h" #include "../core/math_func.hpp" +#include "../timer/timer_game_tick.h" #include "mcf.h" #include "../safeguards.h" @@ -290,7 +291,7 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths) IsCargoInClass(this->job.Cargo(), CC_EXPRESS); uint distance = DistanceMaxPlusManhattan(this->job[from].base.xy, this->job[to].base.xy) + 1; /* Compute a default travel time from the distance and an average speed of 1 tile/day. */ - uint time = (edge.base.TravelTime() != 0) ? edge.base.TravelTime() + DAY_TICKS : distance * DAY_TICKS; + uint time = (edge.base.TravelTime() != 0) ? edge.base.TravelTime() + Ticks::DAY_TICKS : distance * Ticks::DAY_TICKS; uint distance_anno = express ? time : distance; Tannotation *dest = static_cast(paths[to]); diff --git a/src/linkgraph/refresh.cpp b/src/linkgraph/refresh.cpp index 8a9551a82a..26f9ee8339 100644 --- a/src/linkgraph/refresh.cpp +++ b/src/linkgraph/refresh.cpp @@ -234,7 +234,7 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next) if (this->is_full_loading && this->vehicle->orders != nullptr && st->index == vehicle->last_station_visited && this->vehicle->orders->GetTotalDuration() > - (Ticks)this->vehicle->current_order_time) { + (TimerGameTick::Ticks)this->vehicle->current_order_time) { uint effective_capacity = cargo_quantity * this->vehicle->load_unload_ticks; if (effective_capacity > (uint)this->vehicle->orders->GetTotalDuration()) { IncreaseStats(st, c, next_station, effective_capacity / diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 4a58104490..7fc8498991 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -573,7 +573,7 @@ void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost) msg = STR_INCOME_FLOAT_INCOME; } SetDParam(0, cost); - AddTextEffect(msg, pt.x, pt.y, DAY_TICKS, TE_RISING); + AddTextEffect(msg, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING); } /** @@ -590,7 +590,7 @@ void ShowFeederIncomeAnimation(int x, int y, int z, Money transfer, Money income SetDParam(0, transfer); if (income == 0) { - AddTextEffect(STR_FEEDER, pt.x, pt.y, DAY_TICKS, TE_RISING); + AddTextEffect(STR_FEEDER, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING); } else { StringID msg = STR_FEEDER_COST; if (income < 0) { @@ -598,7 +598,7 @@ void ShowFeederIncomeAnimation(int x, int y, int z, Money transfer, Money income msg = STR_FEEDER_INCOME; } SetDParam(1, income); - AddTextEffect(msg, pt.x, pt.y, DAY_TICKS, TE_RISING); + AddTextEffect(msg, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING); } } diff --git a/src/network/network.cpp b/src/network/network.cpp index bad43bc0d5..12db048c18 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -11,6 +11,7 @@ #include "../strings_func.h" #include "../command_func.h" +#include "../timer/timer_game_tick.h" #include "../timer/timer_game_calendar.h" #include "network_admin.h" #include "network_client.h" @@ -274,8 +275,8 @@ uint NetworkCalculateLag(const NetworkClientSocket *cs) /* This client has missed their ACK packet after 1 DAY_TICKS.. * so we increase their lag for every frame that passes! * The packet can be out by a max of _net_frame_freq */ - if (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq < _frame_counter) { - lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq); + if (cs->last_frame_server + Ticks::DAY_TICKS + _settings_client.network.frame_freq < _frame_counter) { + lag += _frame_counter - (cs->last_frame_server + Ticks::DAY_TICKS + _settings_client.network.frame_freq); } return lag; } diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 41d0f9376f..1407217237 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -20,6 +20,7 @@ #include "../company_gui.h" #include "../company_cmd.h" #include "../core/random_func.hpp" +#include "../timer/timer_game_tick.h" #include "../timer/timer_game_calendar.h" #include "../gfx_func.h" #include "../error.h" @@ -876,7 +877,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FRAME(Packet *p /* Let the server know that we received this frame correctly * We do this only once per day, to save some bandwidth ;) */ if (!_network_first_time && last_ack_frame < _frame_counter) { - last_ack_frame = _frame_counter + DAY_TICKS; + last_ack_frame = _frame_counter + Ticks::DAY_TICKS; Debug(net, 7, "Sent ACK at {}", _frame_counter); SendAck(); } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index a81fe597c5..d702321013 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1141,7 +1141,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p) /* The client is trying to catch up with the server */ if (this->status == STATUS_PRE_ACTIVE) { /* The client is not yet caught up? */ - if (frame + DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY; + if (frame + Ticks::DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY; /* Now it is! Unpause the game */ this->status = STATUS_ACTIVE; @@ -1724,7 +1724,7 @@ void NetworkServer_Tick(bool send_frame) * did not receive a packet, then the client is not just * slow, but the connection is likely severed. Mentioning * frame_freq is not useful in this case. */ - if (lag > (uint)DAY_TICKS && cs->lag_test == 0 && cs->last_packet + std::chrono::seconds(2) > std::chrono::steady_clock::now()) { + if (lag > (uint)Ticks::DAY_TICKS && cs->lag_test == 0 && cs->last_packet + std::chrono::seconds(2) > std::chrono::steady_clock::now()) { IConsolePrint(CC_WARNING, "[{}] Client #{} is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id); cs->lag_test = 1; } diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp index 127b64fa5e..6250690c42 100644 --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -11,6 +11,7 @@ #include "debug.h" #include "town.h" #include "newgrf_town.h" +#include "timer/timer_game_tick.h" #include "safeguards.h" @@ -47,7 +48,7 @@ case 0x81: return GB(static_cast(this->t->xy), 8, 8); case 0x82: return ClampTo(this->t->cache.population); case 0x83: return GB(ClampTo(this->t->cache.population), 8, 8); - case 0x8A: return this->t->grow_counter / TOWN_GROWTH_TICKS; + case 0x8A: return this->t->grow_counter / Ticks::TOWN_GROWTH_TICKS; case 0x92: return this->t->flags; // In original game, 0x92 and 0x93 are really one word. Since flags is a byte, this is to adjust case 0x93: return 0; case 0x94: return ClampTo(this->t->cache.squared_town_zone_radius[0]); @@ -79,7 +80,7 @@ case 0xAE: return this->t->have_ratings; case 0xB2: return this->t->statues; case 0xB6: return ClampTo(this->t->cache.num_houses); - case 0xB9: return this->t->growth_rate / TOWN_GROWTH_TICKS; + case 0xB9: return this->t->growth_rate / Ticks::TOWN_GROWTH_TICKS; case 0xBA: return ClampTo(this->t->supplied[CT_PASSENGERS].new_max); case 0xBB: return GB(ClampTo(this->t->supplied[CT_PASSENGERS].new_max), 8, 8); case 0xBC: return ClampTo(this->t->supplied[CT_MAIL].new_max); diff --git a/src/order_base.h b/src/order_base.h index 9cbd2c2995..06e91aaf55 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -17,6 +17,7 @@ #include "depot_type.h" #include "station_type.h" #include "vehicle_type.h" +#include "timer/timer_game_tick.h" #include "date_type.h" #include "saveload/saveload.h" @@ -268,8 +269,8 @@ private: uint num_vehicles; ///< NOSAVE: Number of vehicles that share this order list. Vehicle *first_shared; ///< NOSAVE: pointer to the first vehicle in the shared order chain. - Ticks timetable_duration; ///< NOSAVE: Total timetabled duration of the order list. - Ticks total_duration; ///< NOSAVE: Total (timetabled or not) duration of the order list. + TimerGameTick::Ticks timetable_duration; ///< NOSAVE: Total timetabled duration of the order list. + TimerGameTick::Ticks total_duration; ///< NOSAVE: Total (timetabled or not) duration of the order list. public: /** Default constructor producing an invalid order list. */ @@ -366,34 +367,34 @@ public: bool IsCompleteTimetable() const; /** - * Gets the total duration of the vehicles timetable or INVALID_TICKS is the timetable is not complete. - * @return total timetable duration or INVALID_TICKS for incomplete timetables + * Gets the total duration of the vehicles timetable or Tick::INVALID_TICKS is the timetable is not complete. + * @return total timetable duration or Tick::INVALID_TICKS for incomplete timetables */ - inline Ticks GetTimetableTotalDuration() const { return this->IsCompleteTimetable() ? this->timetable_duration : INVALID_TICKS; } + inline TimerGameTick::Ticks GetTimetableTotalDuration() const { return this->IsCompleteTimetable() ? this->timetable_duration : Ticks::INVALID_TICKS; } /** * Gets the known duration of the vehicles timetable even if the timetable is not complete. * @return known timetable duration */ - inline Ticks GetTimetableDurationIncomplete() const { return this->timetable_duration; } + inline TimerGameTick::Ticks GetTimetableDurationIncomplete() const { return this->timetable_duration; } /** * Gets the known duration of the vehicles orders, timetabled or not. * @return known order duration. */ - inline Ticks GetTotalDuration() const { return this->total_duration; } + inline TimerGameTick::Ticks GetTotalDuration() const { return this->total_duration; } /** * Must be called if an order's timetable is changed to update internal book keeping. * @param delta By how many ticks has the timetable duration changed */ - void UpdateTimetableDuration(Ticks delta) { this->timetable_duration += delta; } + void UpdateTimetableDuration(TimerGameTick::Ticks delta) { this->timetable_duration += delta; } /** * Must be called if an order's timetable is changed to update internal book keeping. * @param delta By how many ticks has the total duration changed */ - void UpdateTotalDuration(Ticks delta) { this->total_duration += delta; } + void UpdateTotalDuration(TimerGameTick::Ticks delta) { this->total_duration += delta; } void FreeChain(bool keep_orderlist = false); diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index b6bf5c5bc0..b7039045e2 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -619,8 +619,8 @@ void OrderList::DebugCheckSanity() const VehicleOrderID check_num_orders = 0; VehicleOrderID check_num_manual_orders = 0; uint check_num_vehicles = 0; - Ticks check_timetable_duration = 0; - Ticks check_total_duration = 0; + TimerGameTick::Ticks check_timetable_duration = 0; + TimerGameTick::Ticks check_total_duration = 0; Debug(misc, 6, "Checking OrderList {} for sanity...", this->index); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 7f1ef4f116..8fe5cc4780 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1720,7 +1720,7 @@ void RoadVehicle::OnNewDay() if (this->running_ticks == 0) return; - CommandCost cost(EXPENSES_ROADVEH_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS)); + CommandCost cost(EXPENSES_ROADVEH_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS)); this->profit_this_year -= cost.GetCost(); this->running_ticks = 0; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index b03ad503d4..66ffd850a6 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -727,7 +727,7 @@ bool AfterLoadGame() } /* The value of TimerGameCalendar::date_fract got divided, so make sure that old games are converted correctly. */ - if (IsSavegameVersionBefore(SLV_11, 1) || (IsSavegameVersionBefore(SLV_147) && TimerGameCalendar::date_fract > DAY_TICKS)) TimerGameCalendar::date_fract /= 885; + if (IsSavegameVersionBefore(SLV_11, 1) || (IsSavegameVersionBefore(SLV_147) && TimerGameCalendar::date_fract > Ticks::DAY_TICKS)) TimerGameCalendar::date_fract /= 885; /* Update current year * must be done before loading sprites as some newgrfs check it */ @@ -2999,7 +2999,7 @@ bool AfterLoadGame() t->growth_rate = TownTicksToGameTicks(t->growth_rate & ~0x8000); } /* Add t->index % TOWN_GROWTH_TICKS to spread growth across ticks. */ - t->grow_counter = TownTicksToGameTicks(t->grow_counter) + t->index % TOWN_GROWTH_TICKS; + t->grow_counter = TownTicksToGameTicks(t->grow_counter) + t->index % Ticks::TOWN_GROWTH_TICKS; } } diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp index 3e023b92dc..b884374b6c 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -171,9 +171,9 @@ break; default: - EnforcePrecondition(false, (days_between_town_growth * DAY_TICKS / TOWN_GROWTH_TICKS) <= MAX_TOWN_GROWTH_TICKS); + EnforcePrecondition(false, (days_between_town_growth * ::Ticks::DAY_TICKS / ::Ticks::TOWN_GROWTH_TICKS) <= MAX_TOWN_GROWTH_TICKS); /* Don't use growth_rate 0 as it means GROWTH_NORMAL */ - growth_rate = std::max(days_between_town_growth * DAY_TICKS, 2u) - 1; + growth_rate = std::max(days_between_town_growth * ::Ticks::DAY_TICKS, 2u) - 1; break; } @@ -188,7 +188,7 @@ if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return TOWN_GROWTH_NONE; - return RoundDivSU(t->growth_rate + 1, DAY_TICKS); + return RoundDivSU(t->growth_rate + 1, ::Ticks::DAY_TICKS); } /* static */ SQInteger ScriptTown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile) diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 48620a2502..78a66cc930 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -236,7 +236,7 @@ void Ship::OnNewDay() if (this->running_ticks == 0) return; - CommandCost cost(EXPENSES_SHIP_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS)); + CommandCost cost(EXPENSES_SHIP_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS)); this->profit_this_year -= cost.GetCost(); this->running_ticks = 0; diff --git a/src/sortlist_type.h b/src/sortlist_type.h index ce60ea6930..4c2056d2d8 100644 --- a/src/sortlist_type.h +++ b/src/sortlist_type.h @@ -14,6 +14,7 @@ #include "core/bitmath_func.hpp" #include "core/mem_func.hpp" #include "date_type.h" +#include "timer/timer_game_tick.h" /** Flags of the sort list. */ enum SortListFlags { @@ -72,7 +73,7 @@ protected: void ResetResortTimer() { /* Resort every 10 days */ - this->resort_timer = DAY_TICKS * 10; + this->resort_timer = Ticks::DAY_TICKS * 10; } public: diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 1d5a64d756..84ce14d39f 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3964,7 +3964,7 @@ static void StationHandleSmallTick(BaseStation *st) if ((st->facilities & FACIL_WAYPOINT) != 0 || !st->IsInUse()) return; byte b = st->delete_ctr + 1; - if (b >= STATION_RATING_TICKS) b = 0; + if (b >= Ticks::STATION_RATING_TICKS) b = 0; st->delete_ctr = b; if (b == 0) UpdateStationRating(Station::From(st)); @@ -3978,18 +3978,18 @@ void OnTick_Station() StationHandleSmallTick(st); /* Clean up the link graph about once a week. */ - if (Station::IsExpected(st) && (TimerGameTick::counter + st->index) % STATION_LINKGRAPH_TICKS == 0) { + if (Station::IsExpected(st) && (TimerGameTick::counter + st->index) % Ticks::STATION_LINKGRAPH_TICKS == 0) { DeleteStaleLinks(Station::From(st)); }; /* Spread out big-tick over STATION_ACCEPTANCE_TICKS ticks. */ - if ((TimerGameTick::counter + st->index) % STATION_ACCEPTANCE_TICKS == 0) { + if ((TimerGameTick::counter + st->index) % Ticks::STATION_ACCEPTANCE_TICKS == 0) { /* Stop processing this station if it was deleted */ if (!StationHandleBigTick(st)) continue; } /* Spread out station animation over STATION_ACCEPTANCE_TICKS ticks. */ - if ((TimerGameTick::counter + st->index) % STATION_ACCEPTANCE_TICKS == 0) { + if ((TimerGameTick::counter + st->index) % Ticks::STATION_ACCEPTANCE_TICKS == 0) { TriggerStationAnimation(st, st->xy, SAT_250_TICKS); TriggerRoadStopAnimation(st, st->xy, SAT_250_TICKS); if (Station::IsExpected(st)) AirportAnimationTrigger(Station::From(st), AAT_STATION_250_TICKS); diff --git a/src/table/engines.h b/src/table/engines.h index 830ab93ced..acc7b8f824 100644 --- a/src/table/engines.h +++ b/src/table/engines.h @@ -24,7 +24,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MT(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MT(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Ticks::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a multiple-unit train into the EngineInfo struct. @@ -37,7 +37,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MM(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MM(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a train carriage into the EngineInfo struct. @@ -50,7 +50,7 @@ * @see MT * @note the 5 between b and f is the load amount */ -#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a road vehicle into the EngineInfo struct. @@ -63,7 +63,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MR(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MR(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a ship into the EngineInfo struct. @@ -75,7 +75,7 @@ * @param f Bitmask of the climates * @note the 10 between b and f is the load amount */ -#define MS(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MS(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of an aeroplane into the EngineInfo struct. @@ -86,7 +86,7 @@ * @param e Bitmask of the climates * @note the 20 between b and e is the load amount */ -#define MA(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, CT_INVALID, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MA(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, CT_INVALID, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /* Climates * T = Temperate diff --git a/src/timer/timer_game_calendar.cpp b/src/timer/timer_game_calendar.cpp index 8cf18c91b2..60cb8ea454 100644 --- a/src/timer/timer_game_calendar.cpp +++ b/src/timer/timer_game_calendar.cpp @@ -151,7 +151,7 @@ static const uint16_t _accum_days_for_month[] = { */ /* static */ void TimerGameCalendar::SetDate(TimerGameCalendar::Date date, TimerGameCalendar::DateFract fract) { - assert(fract < DAY_TICKS); + assert(fract < Ticks::DAY_TICKS); YearMonthDay ymd; @@ -189,7 +189,7 @@ void TimerManager::Elapsed(TimerGameCalendar::TElapsed delta) if (_game_mode == GM_MENU) return; TimerGameCalendar::date_fract++; - if (TimerGameCalendar::date_fract < DAY_TICKS) return; + if (TimerGameCalendar::date_fract < Ticks::DAY_TICKS) return; TimerGameCalendar::date_fract = 0; /* increase day counter */ diff --git a/src/timer/timer_game_tick.h b/src/timer/timer_game_tick.h index f6f5638217..96e1da2481 100644 --- a/src/timer/timer_game_tick.h +++ b/src/timer/timer_game_tick.h @@ -14,9 +14,6 @@ #include -/** Estimation of how many ticks fit in a single second. */ -static const uint TICKS_PER_SECOND = 1000 / MILLISECONDS_PER_TICK; - /** * Timer that represents the game-ticks. It will pause when the game is paused. * @@ -24,6 +21,8 @@ static const uint TICKS_PER_SECOND = 1000 / MILLISECONDS_PER_TICK; */ class TimerGameTick { public: + using Ticks = int32_t; ///< The type to store ticks in + using TPeriod = uint; using TElapsed = uint; struct TStorage { @@ -33,4 +32,28 @@ public: static uint64_t counter; ///< Monotonic counter, in ticks, since start of game. }; +/** + * Storage class for Ticks constants. + */ +class Ticks { +public: + static constexpr TimerGameTick::Ticks INVALID_TICKS = -1; ///< Representation of an invalid number of ticks. + + /** + * 1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885. On an overflow the new day begun and 65535 / 885 = 74. + * 1 tick is approximately 27 ms. + * 1 day is thus about 2 seconds (74 * 27 = 1998) on a machine that can run OpenTTD normally + */ + static constexpr TimerGameTick::Ticks DAY_TICKS = 74; ///< ticks per day + static constexpr TimerGameTick::Ticks TICKS_PER_SECOND = 1000 / MILLISECONDS_PER_TICK; ///< Estimation of how many ticks fit in a single second. + + static constexpr TimerGameTick::Ticks STATION_RATING_TICKS = 185; ///< Cycle duration for updating station rating. + static constexpr TimerGameTick::Ticks STATION_ACCEPTANCE_TICKS = 250; ///< Cycle duration for updating station acceptance. + static constexpr TimerGameTick::Ticks STATION_LINKGRAPH_TICKS = 504; ///< Cycle duration for cleaning dead links. + static constexpr TimerGameTick::Ticks CARGO_AGING_TICKS = 185; ///< Cycle duration for aging cargo. + static constexpr TimerGameTick::Ticks INDUSTRY_PRODUCE_TICKS = 256; ///< Cycle duration for industry production. + static constexpr TimerGameTick::Ticks TOWN_GROWTH_TICKS = 70; ///< Cycle duration for towns trying to grow (this originates from the size of the town array in TTD). + static constexpr TimerGameTick::Ticks INDUSTRY_CUT_TREE_TICKS = INDUSTRY_PRODUCE_TICKS * 2; ///< Cycle duration for lumber mill's extra action. +}; + #endif /* TIMER_GAME_TICK_H */ diff --git a/src/timetable.h b/src/timetable.h index efa38599e3..cbc482a825 100644 --- a/src/timetable.h +++ b/src/timetable.h @@ -10,6 +10,7 @@ #ifndef TIMETABLE_H #define TIMETABLE_H +#include "timer/timer_game_tick.h" #include "date_type.h" #include "timer/timer_game_calendar.h" #include "vehicle_type.h" @@ -18,6 +19,6 @@ static const TimerGameCalendar::Year MAX_TIMETABLE_START_YEARS = 15; ///< The ma void ShowTimetableWindow(const Vehicle *v); void UpdateVehicleTimetable(Vehicle *v, bool travelling); -void SetTimetableParams(int param1, int param2, Ticks ticks); +void SetTimetableParams(int param1, int param2, TimerGameTick::Ticks ticks); #endif /* TIMETABLE_H */ diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index 459f257dba..ee317458e9 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -10,6 +10,7 @@ #include "stdafx.h" #include "command_func.h" #include "company_func.h" +#include "timer/timer_game_tick.h" #include "timer/timer_game_calendar.h" #include "window_func.h" #include "vehicle_base.h" @@ -307,7 +308,7 @@ CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool tim if (start_date - TimerGameCalendar::date > DateAtStartOfYear(MAX_TIMETABLE_START_YEARS)) return CMD_ERROR; if (TimerGameCalendar::date - start_date > DAYS_IN_LEAP_YEAR) return CMD_ERROR; if (timetable_all && !v->orders->IsCompleteTimetable()) return CommandCost(STR_ERROR_TIMETABLE_INCOMPLETE); - if (timetable_all && start_date + total_duration / DAY_TICKS > MAX_DATE) return CMD_ERROR; + if (timetable_all && start_date + total_duration / Ticks::DAY_TICKS > MAX_DATE) return CMD_ERROR; if (flags & DC_EXEC) { std::vector vehs; @@ -333,7 +334,7 @@ CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool tim w->lateness_counter = 0; ClrBit(w->vehicle_flags, VF_TIMETABLE_STARTED); /* Do multiplication, then division to reduce rounding errors. */ - w->timetable_start = start_date + idx * total_duration / num_vehs / DAY_TICKS; + w->timetable_start = start_date + idx * total_duration / num_vehs / Ticks::DAY_TICKS; SetWindowDirty(WC_VEHICLE_TIMETABLE, w->index); ++idx; } @@ -426,7 +427,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) just_started = !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED); if (v->timetable_start != 0) { - v->lateness_counter = static_cast(TimerGameCalendar::date - v->timetable_start) * DAY_TICKS + TimerGameCalendar::date_fract; + v->lateness_counter = static_cast(TimerGameCalendar::date - v->timetable_start) * Ticks::DAY_TICKS + TimerGameCalendar::date_fract; v->timetable_start = 0; } @@ -460,7 +461,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) * the timetable entry like is done for road vehicles/ships. * Thus always make sure at least one tick is used between the * processing of different orders when filling the timetable. */ - uint time_to_set = CeilDiv(std::max(time_taken, 1U), DAY_TICKS) * DAY_TICKS; + uint time_to_set = CeilDiv(std::max(time_taken, 1U), Ticks::DAY_TICKS) * Ticks::DAY_TICKS; if (travelling && (autofilling || !real_current_order->IsTravelTimetabled())) { ChangeTimetable(v, v->cur_real_order_index, time_to_set, MTF_TRAVEL_TIME, autofilling); @@ -493,10 +494,10 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) * check how many ticks the (fully filled) timetable has. If a timetable cycle is * shorter than the amount of ticks we are late we reduce the lateness by the * length of a full cycle till lateness is less than the length of a timetable - * cycle. When the timetable isn't fully filled the cycle will be INVALID_TICKS. */ + * cycle. When the timetable isn't fully filled the cycle will be Tick::INVALID_TICKS. */ if (v->lateness_counter > (int)timetabled) { - Ticks cycle = v->orders->GetTimetableTotalDuration(); - if (cycle != INVALID_TICKS && v->lateness_counter > cycle) { + TimerGameTick::Ticks cycle = v->orders->GetTimetableTotalDuration(); + if (cycle != Ticks::INVALID_TICKS && v->lateness_counter > cycle) { v->lateness_counter %= cycle; } } diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index e58375d64d..8bd4db9a95 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -18,6 +18,7 @@ #include "string_func.h" #include "gfx_func.h" #include "company_func.h" +#include "timer/timer_game_tick.h" #include "timer/timer_game_calendar.h" #include "date_gui.h" #include "vehicle_gui.h" @@ -34,8 +35,8 @@ /** Container for the arrival/departure dates of a vehicle */ struct TimetableArrivalDeparture { - Ticks arrival; ///< The arrival time - Ticks departure; ///< The departure time + TimerGameTick::Ticks arrival; ///< The arrival time + TimerGameTick::Ticks departure; ///< The departure time }; /** @@ -44,14 +45,14 @@ struct TimetableArrivalDeparture { * @param param2 the second DParam to fill * @param ticks the number of ticks to 'draw' */ -void SetTimetableParams(int param1, int param2, Ticks ticks) +void SetTimetableParams(int param1, int param2, TimerGameTick::Ticks ticks) { if (_settings_client.gui.timetable_in_ticks) { SetDParam(param1, STR_TIMETABLE_TICKS); SetDParam(param2, ticks); } else { SetDParam(param1, STR_TIMETABLE_DAYS); - SetDParam(param2, ticks / DAY_TICKS); + SetDParam(param2, ticks / Ticks::DAY_TICKS); } } @@ -85,7 +86,7 @@ static bool CanDetermineTimeTaken(const Order *order, bool travelling) * @param table Fill in arrival and departures including intermediate orders * @param offset Add this value to result and all arrivals and departures */ -static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, std::vector &table, Ticks offset) +static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, std::vector &table, TimerGameTick::Ticks offset) { assert(!table.empty()); assert(v->GetNumOrders() >= 2); @@ -93,10 +94,10 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID /* Pre-initialize with unknown time */ for (int i = 0; i < v->GetNumOrders(); ++i) { - table[i].arrival = table[i].departure = INVALID_TICKS; + table[i].arrival = table[i].departure = Ticks::INVALID_TICKS; } - Ticks sum = offset; + TimerGameTick::Ticks sum = offset; VehicleOrderID i = start; const Order *order = v->GetOrder(i); @@ -182,7 +183,7 @@ struct TimetableWindow : Window { assert(HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)); bool travelling = (!v->current_order.IsType(OT_LOADING) || v->current_order.GetNonStopType() == ONSF_STOP_EVERYWHERE); - Ticks start_time = TimerGameCalendar::date_fract - v->current_order_time; + TimerGameTick::Ticks start_time = TimerGameCalendar::date_fract - v->current_order_time; FillTimetableArrivalDepartureTable(v, v->cur_real_order_index % v->GetNumOrders(), travelling, table, start_time); @@ -425,7 +426,7 @@ struct TimetableWindow : Window { /* Arrival and departure times are handled in an all-or-nothing approach, * i.e. are only shown if we can calculate all times. * Excluding order lists with only one order makes some things easier. */ - Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0; + TimerGameTick::Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0; if (total_time <= 0 || v->GetNumOrders() <= 1 || !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) return; std::vector arr_dep(v->GetNumOrders()); @@ -435,8 +436,8 @@ struct TimetableWindow : Window { int selected = this->sel_index; Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); - bool show_late = this->show_expected && v->lateness_counter > DAY_TICKS; - Ticks offset = show_late ? 0 : -v->lateness_counter; + bool show_late = this->show_expected && v->lateness_counter > Ticks::DAY_TICKS; + TimerGameTick::Ticks offset = show_late ? 0 : -v->lateness_counter; for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop /* Don't draw anything if it extends past the end of the window. */ @@ -446,9 +447,9 @@ struct TimetableWindow : Window { SetDParam(0, show_late ? TC_RED : TC_INVALID); if (i % 2 == 0) { /* Draw an arrival time. */ - if (arr_dep[i / 2].arrival != INVALID_TICKS) { + if (arr_dep[i / 2].arrival != Ticks::INVALID_TICKS) { /* First set the offset and text colour based on the expected/scheduled mode and some other things. */ - Ticks this_offset; + TimerGameTick::Ticks this_offset; if (this->show_expected && i / 2 == earlyID) { /* Show expected arrival. */ this_offset = 0; @@ -459,13 +460,13 @@ struct TimetableWindow : Window { } /* Now actually draw the arrival time. */ - SetDParam(1, TimerGameCalendar::date + (arr_dep[i / 2].arrival + this_offset) / DAY_TICKS); + SetDParam(1, TimerGameCalendar::date + (arr_dep[i / 2].arrival + this_offset) / Ticks::DAY_TICKS); DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_ARRIVAL, i == selected ? TC_WHITE : TC_BLACK); } } else { /* Draw a departure time. */ - if (arr_dep[i / 2].departure != INVALID_TICKS) { - SetDParam(1, TimerGameCalendar::date + (arr_dep[i / 2].departure + offset) / DAY_TICKS); + if (arr_dep[i / 2].departure != Ticks::INVALID_TICKS) { + SetDParam(1, TimerGameCalendar::date + (arr_dep[i / 2].departure + offset) / Ticks::DAY_TICKS); DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_DEPARTURE, i == selected ? TC_WHITE : TC_BLACK); } } @@ -482,7 +483,7 @@ struct TimetableWindow : Window { const Vehicle *v = this->vehicle; Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); - Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0; + TimerGameTick::Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0; if (total_time != 0) { SetTimetableParams(0, 1, total_time); DrawString(tr, v->orders->IsCompleteTimetable() ? STR_TIMETABLE_TOTAL_TIME : STR_TIMETABLE_TOTAL_TIME_INCOMPLETE); @@ -499,7 +500,7 @@ struct TimetableWindow : Window { /* We aren't running on a timetable yet, so how can we be "on time" * when we aren't even "on service"/"on duty"? */ DrawString(tr, STR_TIMETABLE_STATUS_NOT_STARTED); - } else if (v->lateness_counter == 0 || (!_settings_client.gui.timetable_in_ticks && v->lateness_counter / DAY_TICKS == 0)) { + } else if (v->lateness_counter == 0 || (!_settings_client.gui.timetable_in_ticks && v->lateness_counter / Ticks::DAY_TICKS == 0)) { DrawString(tr, STR_TIMETABLE_STATUS_ON_TIME); } else { SetTimetableParams(0, 1, abs(v->lateness_counter)); @@ -570,7 +571,7 @@ struct TimetableWindow : Window { if (order != nullptr) { uint time = (selected % 2 != 0) ? order->GetTravelTime() : order->GetWaitTime(); - if (!_settings_client.gui.timetable_in_ticks) time /= DAY_TICKS; + if (!_settings_client.gui.timetable_in_ticks) time /= Ticks::DAY_TICKS; if (time != 0) { SetDParam(0, time); @@ -666,7 +667,7 @@ struct TimetableWindow : Window { } case WID_VT_CHANGE_TIME: - if (!_settings_client.gui.timetable_in_ticks) val *= DAY_TICKS; + if (!_settings_client.gui.timetable_in_ticks) val *= Ticks::DAY_TICKS; if (this->change_timetable_all) { Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, ClampTo(val)); diff --git a/src/town.h b/src/town.h index c33a05a6a1..b20e3cc30d 100644 --- a/src/town.h +++ b/src/town.h @@ -12,6 +12,7 @@ #include "viewport_type.h" #include "date_type.h" +#include "timer/timer_game_tick.h" #include "town_map.h" #include "subsidy_type.h" #include "newgrf_storage.h" @@ -305,7 +306,7 @@ void MakeDefaultName(T *obj) * tick 0 is a valid tick so actual amount is one more than the counter value. */ static inline uint16_t TownTicksToGameTicks(uint16_t ticks) { - return (std::min(ticks, MAX_TOWN_GROWTH_TICKS) + 1) * TOWN_GROWTH_TICKS - 1; + return (std::min(ticks, MAX_TOWN_GROWTH_TICKS) + 1) * Ticks::TOWN_GROWTH_TICKS - 1; } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 6b7e827ddd..16e5338ba6 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -822,7 +822,7 @@ static void TownTickHandler(Town *t) i = t->growth_rate; } else { /* If growth failed wait a bit before retrying */ - i = std::min(t->growth_rate, TOWN_GROWTH_TICKS - 1); + i = std::min(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1); } } t->grow_counter = i; @@ -1868,7 +1868,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSi t->cache.population = 0; /* Spread growth across ticks so even if there are many * similar towns they're unlikely to grow all in one tick */ - t->grow_counter = t->index % TOWN_GROWTH_TICKS; + t->grow_counter = t->index % Ticks::TOWN_GROWTH_TICKS; t->growth_rate = TownTicksToGameTicks(250); t->show_zone = false; @@ -3236,7 +3236,7 @@ static CommandCost TownActionFundBuildings(Town *t, DoCommandFlag flags) * tick-perfect and gives player some time window where they can * spam funding with the exact same efficiency. */ - t->grow_counter = std::min(t->grow_counter, 2 * TOWN_GROWTH_TICKS - (t->growth_rate - t->grow_counter) % TOWN_GROWTH_TICKS); + t->grow_counter = std::min(t->grow_counter, 2 * Ticks::TOWN_GROWTH_TICKS - (t->growth_rate - t->grow_counter) % Ticks::TOWN_GROWTH_TICKS); SetWindowDirty(WC_TOWN_VIEW, t->index); } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 8b2a820f57..48e84dc3a6 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -453,7 +453,7 @@ public: } if (HasBit(this->town->flags, TOWN_IS_GROWING)) { - SetDParam(0, RoundDivSU(this->town->growth_rate + 1, DAY_TICKS)); + SetDParam(0, RoundDivSU(this->town->growth_rate + 1, Ticks::DAY_TICKS)); DrawString(tr, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED); tr.top += FONT_HEIGHT_NORMAL; } else { diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index dde3b329a8..7b7961bf2c 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3353,12 +3353,12 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) v->cur_speed = 0; v->subspeed = 0; v->progress = 255; // make sure that every bit of acceleration will hit the signal again, so speed stays 0. - if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_oneway_signal * DAY_TICKS * 2) return false; + if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_oneway_signal * Ticks::DAY_TICKS * 2) return false; } else if (HasSignalOnTrackdir(gp.new_tile, i)) { v->cur_speed = 0; v->subspeed = 0; v->progress = 255; // make sure that every bit of acceleration will hit the signal again, so speed stays 0. - if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_twoway_signal * DAY_TICKS * 2) { + if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_twoway_signal * Ticks::DAY_TICKS * 2) { DiagDirection exitdir = TrackdirToExitdir(i); TileIndex o_tile = TileAddByDiagDir(gp.new_tile, exitdir); @@ -3978,14 +3978,14 @@ static bool TrainLocoHandler(Train *v, bool mode) ++v->wait_counter; /* Should we try reversing this tick if still stuck? */ - bool turn_around = v->wait_counter % (_settings_game.pf.wait_for_pbs_path * DAY_TICKS) == 0 && _settings_game.pf.reverse_at_signals; + bool turn_around = v->wait_counter % (_settings_game.pf.wait_for_pbs_path * Ticks::DAY_TICKS) == 0 && _settings_game.pf.reverse_at_signals; if (!turn_around && v->wait_counter % _settings_game.pf.path_backoff_interval != 0 && v->force_proceed == TFP_NONE) return true; if (!TryPathReserve(v)) { /* Still stuck. */ if (turn_around) ReverseTrainDirection(v); - if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * DAY_TICKS) { + if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * Ticks::DAY_TICKS) { /* Show message to player. */ if (_settings_client.gui.lost_vehicle_warn && v->owner == _local_company) { SetDParam(0, v->index); @@ -4179,7 +4179,7 @@ void Train::OnNewDay() if (this->running_ticks != 0) { /* running costs */ - CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS)); + CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS)); this->profit_this_year -= cost.GetCost(); this->running_ticks = 0; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index cd47fc9bdb..c07f4431f3 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -918,7 +918,7 @@ static void RunVehicleDayProc() if (_game_mode != GM_NORMAL) return; /* Run the day_proc for every DAY_TICKS vehicle starting at TimerGameCalendar::date_fract. */ - for (size_t i = TimerGameCalendar::date_fract; i < Vehicle::GetPoolSize(); i += DAY_TICKS) { + for (size_t i = TimerGameCalendar::date_fract; i < Vehicle::GetPoolSize(); i += Ticks::DAY_TICKS) { Vehicle *v = Vehicle::Get(i); if (v == nullptr) continue; @@ -2108,7 +2108,7 @@ void Vehicle::BeginLoading() { assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP); - Ticks travel_time = TimerGameTick::counter - this->last_loading_tick; + TimerGameTick::Ticks travel_time = TimerGameTick::counter - this->last_loading_tick; if (this->current_order.IsType(OT_GOTO_STATION) && this->current_order.GetDestination() == this->last_station_visited) { this->DeleteUnreachedImplicitOrders(); diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 71250a5d1e..173338b21f 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2809,7 +2809,7 @@ void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_i StringID msg = (v->vehstatus & VS_STOPPED) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED; Point pt = RemapCoords(v->x_pos, v->y_pos, v->z_pos); - AddTextEffect(msg, pt.x, pt.y, DAY_TICKS, TE_RISING); + AddTextEffect(msg, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING); } /** From 77173a6a103723eaf0a60b96393801067c152e4e Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Wed, 16 Aug 2023 09:43:31 -0400 Subject: [PATCH 35/72] Codechange: Move date consts and functions to CalendarTime and TimerGameCalendar classes --- src/aircraft_cmd.cpp | 2 +- src/build_vehicle_gui.cpp | 2 +- src/cheat_gui.cpp | 4 +- src/company_gui.cpp | 4 +- src/date_gui.cpp | 4 +- src/date_type.h | 67 -------- src/depot_gui.cpp | 2 +- src/economy.cpp | 4 +- src/engine.cpp | 6 +- src/genworld_gui.cpp | 22 +-- src/linkgraph/flowmapper.cpp | 2 +- src/linkgraph/linkgraph.cpp | 12 +- src/linkgraph/linkgraph.h | 4 +- src/linkgraph/linkgraphjob.cpp | 6 +- src/linkgraph/linkgraphjob.h | 2 +- src/linkgraph/linkgraphschedule.cpp | 6 +- src/misc_gui.cpp | 4 +- src/network/core/network_game_info.cpp | 10 +- src/newgrf.cpp | 20 +-- src/newgrf_airport.cpp | 2 +- src/newgrf_engine.cpp | 12 +- src/newgrf_industries.cpp | 6 +- src/newgrf_roadstop.cpp | 2 +- src/newgrf_station.cpp | 4 +- src/newgrf_text.cpp | 3 +- src/news_gui.cpp | 2 +- src/openttd.cpp | 4 +- src/order_base.h | 4 +- src/order_cmd.cpp | 4 +- src/rail.cpp | 6 +- src/road.cpp | 10 +- src/road_cmd.cpp | 2 +- src/roadveh_cmd.cpp | 2 +- src/saveload/afterload.cpp | 28 ++-- src/saveload/misc_sl.cpp | 2 +- src/saveload/oldloader_sl.cpp | 10 +- src/script/api/script_date.cpp | 2 +- src/script/api/script_date.hpp | 3 +- src/settings.cpp | 4 +- src/settings_gui.cpp | 8 +- src/ship_cmd.cpp | 2 +- src/station.cpp | 2 +- src/station_cmd.cpp | 4 +- src/statusbar_gui.cpp | 2 +- src/story_gui.cpp | 2 +- src/subsidy.cpp | 2 +- src/table/airport_defaults.h | 20 +-- src/table/engines.h | 12 +- src/table/object_land.h | 2 +- src/table/railtypes.h | 8 +- src/table/roadtypes.h | 4 +- src/table/settings/currency_settings.ini | 4 +- src/table/settings/gui_settings.ini | 8 +- src/table/settings/network_settings.ini | 4 +- src/table/settings/world_settings.ini | 12 +- src/table/town_land.h | 198 +++++++++++------------ src/timer/timer_game_calendar.cpp | 34 ++-- src/timer/timer_game_calendar.h | 122 +++++++++++--- src/timetable_cmd.cpp | 10 +- src/timetable_gui.cpp | 2 +- src/toolbar_gui.cpp | 10 +- src/town_cmd.cpp | 2 +- src/train_cmd.cpp | 2 +- src/vehicle.cpp | 10 +- src/vehicle_func.h | 2 +- src/vehicle_gui.cpp | 10 +- 66 files changed, 400 insertions(+), 393 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 7ec0d2e4b3..ea7dad6d2e 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -453,7 +453,7 @@ void Aircraft::OnNewDay() if (this->running_ticks == 0) return; - CommandCost cost(EXPENSES_AIRCRAFT_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS)); + CommandCost cost(EXPENSES_AIRCRAFT_RUN, this->GetRunningCost() * this->running_ticks / (CalendarTime::DAYS_IN_YEAR * Ticks::DAY_TICKS)); this->profit_this_year -= cost.GetCost(); this->running_ticks = 0; diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 7c5a259933..733434cb0c 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -967,7 +967,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) { /* Design date - Life length */ SetDParam(0, ymd.year); - SetDParam(1, DateToYear(e->GetLifeLengthInDays())); + SetDParam(1, TimerGameCalendar::DateToYear(e->GetLifeLengthInDays())); DrawString(left, right, y, STR_PURCHASE_INFO_DESIGNED_LIFE); y += FONT_HEIGHT_NORMAL; diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index e058a27cf7..37239d1339 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -104,7 +104,7 @@ extern void EnginesMonthlyLoop(); static int32_t ClickChangeDateCheat(int32_t new_value, int32_t change_direction) { /* Don't allow changing to an invalid year, or the current year. */ - auto new_year = Clamp(TimerGameCalendar::Year(new_value), MIN_YEAR, MAX_YEAR); + auto new_year = Clamp(TimerGameCalendar::Year(new_value), CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR); if (new_year == TimerGameCalendar::year) return static_cast(TimerGameCalendar::year); TimerGameCalendar::YearMonthDay ymd; @@ -320,7 +320,7 @@ struct CheatWindow : Window { switch (ce->str) { /* Display date for change date cheat */ case STR_CHEAT_CHANGE_DATE: - SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 11, 31)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(CalendarTime::MAX_YEAR, 11, 31)); width = std::max(width, GetStringBoundingBox(ce->str).width); break; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 960ae8d37c..71689a087e 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1861,7 +1861,7 @@ struct CompanyInfrastructureWindow : Window } /* Get the date introduced railtypes as well. */ - this->railtypes = AddDateIntroducedRailTypes(this->railtypes, MAX_DATE); + this->railtypes = AddDateIntroducedRailTypes(this->railtypes, CalendarTime::MAX_DATE); /* Find the used roadtypes. */ for (const Engine *e : Engine::IterateType(VEH_ROAD)) { @@ -1871,7 +1871,7 @@ struct CompanyInfrastructureWindow : Window } /* Get the date introduced roadtypes as well. */ - this->roadtypes = AddDateIntroducedRoadTypes(this->roadtypes, MAX_DATE); + this->roadtypes = AddDateIntroducedRoadTypes(this->roadtypes, CalendarTime::MAX_DATE); this->roadtypes &= ~_roadtypes_hidden_mask; } diff --git a/src/date_gui.cpp b/src/date_gui.cpp index cc012f545b..2e3a43c356 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -44,8 +44,8 @@ struct SetDateWindow : Window { Window(desc), callback(callback), callback_data(callback_data), - min_year(std::max(MIN_YEAR, min_year)), - max_year(std::min(MAX_YEAR, max_year)) + min_year(std::max(CalendarTime::MIN_YEAR, min_year)), + max_year(std::min(CalendarTime::MAX_YEAR, max_year)) { assert(this->min_year <= this->max_year); this->parent = parent; diff --git a/src/date_type.h b/src/date_type.h index c76b43258c..5688159c84 100644 --- a/src/date_type.h +++ b/src/date_type.h @@ -12,72 +12,5 @@ #include "timer/timer_game_calendar.h" -static const int DAYS_IN_YEAR = 365; ///< days per year -static const int DAYS_IN_LEAP_YEAR = 366; ///< sometimes, you need one day more... -static const int MONTHS_IN_YEAR = 12; ///< months per year - -static const int SECONDS_PER_DAY = 2; ///< approximate seconds per day, not for precise calculations - -/* - * ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are - * primarily used for loading newgrf and savegame data and returning some - * newgrf (callback) functions that were in the original (TTD) inherited - * format, where 'TimerGameCalendar::date == 0' meant that it was 1920-01-01. - */ - -/** The minimum starting year/base year of the original TTD */ -static constexpr TimerGameCalendar::Year ORIGINAL_BASE_YEAR = 1920; -/** The original ending year */ -static constexpr TimerGameCalendar::Year ORIGINAL_END_YEAR = 2051; -/** The maximum year of the original TTD */ -static constexpr TimerGameCalendar::Year ORIGINAL_MAX_YEAR = 2090; - -/** - * Calculate the date of the first day of a given year. - * @param year the year to get the first day of. - * @return the date. - */ -static constexpr TimerGameCalendar::Date DateAtStartOfYear(TimerGameCalendar::Year year) -{ - int32_t year_as_int = static_cast(year); - uint number_of_leap_years = (year == 0) ? 0 : ((year_as_int - 1) / 4 - (year_as_int - 1) / 100 + (year_as_int - 1) / 400 + 1); - - return (DAYS_IN_YEAR * year_as_int) + number_of_leap_years; -} - -/** - * Calculate the year of a given date. - * @param date The date to consider. - * @return the year. - */ -static inline TimerGameCalendar::Year DateToYear(TimerGameCalendar::Date date) -{ - return static_cast(date) / DAYS_IN_LEAP_YEAR; -} - -/** - * The date of the first day of the original base year. - */ -static constexpr TimerGameCalendar::Date DAYS_TILL_ORIGINAL_BASE_YEAR = DateAtStartOfYear(ORIGINAL_BASE_YEAR); - -/** The absolute minimum & maximum years in OTTD */ -static constexpr TimerGameCalendar::Year MIN_YEAR = 0; - -/** The default starting year */ -static constexpr TimerGameCalendar::Year DEF_START_YEAR = 1950; -/** The default scoring end year */ -static constexpr TimerGameCalendar::Year DEF_END_YEAR = ORIGINAL_END_YEAR - 1; - -/** - * MAX_YEAR, nicely rounded value of the number of years that can - * be encoded in a single 32 bits date, about 2^31 / 366 years. - */ -static constexpr TimerGameCalendar::Year MAX_YEAR = 5000000; - -/** The date of the last day of the max year. */ -static constexpr TimerGameCalendar::Date MAX_DATE = DateAtStartOfYear(MAX_YEAR + 1) - 1; - -static constexpr TimerGameCalendar::Year INVALID_YEAR = -1; ///< Representation of an invalid year -static constexpr TimerGameCalendar::Date INVALID_DATE = -1; ///< Representation of an invalid date #endif /* DATE_TYPE_H */ diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 4a7ada72fb..0acc15a02d 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -360,7 +360,7 @@ struct DepotWindow : Window { DrawSpriteIgnorePadding((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, false, SA_CENTER); SetDParam(0, v->unitnumber); - DrawString(text, STR_JUST_COMMA, (v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? TC_BLACK : TC_RED); + DrawString(text, STR_JUST_COMMA, (v->max_age - CalendarTime::DAYS_IN_LEAP_YEAR) >= v->age ? TC_BLACK : TC_RED); } } diff --git a/src/economy.cpp b/src/economy.cpp index 1dce13e603..4bf3335e88 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -735,7 +735,7 @@ bool AddInflation(bool check_year) * inflation doesn't add anything after that either; it even makes playing * it impossible due to the diverging cost and income rates. */ - if (check_year && (TimerGameCalendar::year < ORIGINAL_BASE_YEAR || TimerGameCalendar::year >= ORIGINAL_MAX_YEAR)) return true; + if (check_year && (TimerGameCalendar::year < CalendarTime::ORIGINAL_BASE_YEAR || TimerGameCalendar::year >= CalendarTime::ORIGINAL_MAX_YEAR)) return true; if (_economy.inflation_prices == MAX_INFLATION || _economy.inflation_payment == MAX_INFLATION) return true; @@ -928,7 +928,7 @@ void StartupEconomy() if (_settings_game.economy.inflation) { /* Apply inflation that happened before our game start year. */ - int months = static_cast(std::min(TimerGameCalendar::year, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR) * 12; + int months = static_cast(std::min(TimerGameCalendar::year, CalendarTime::ORIGINAL_MAX_YEAR) - CalendarTime::ORIGINAL_BASE_YEAR) * 12; for (int i = 0; i < months; i++) { AddInflation(false); } diff --git a/src/engine.cpp b/src/engine.cpp index 612e046c5c..66c9880868 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -438,7 +438,7 @@ uint Engine::GetDisplayMaxTractiveEffort() const */ TimerGameCalendar::Date Engine::GetLifeLengthInDays() const { - return DateAtStartOfYear(this->info.lifelength + _settings_game.vehicle.extend_vehicle_life); + return TimerGameCalendar::DateAtStartOfYear(this->info.lifelength + _settings_game.vehicle.extend_vehicle_life); } /** @@ -663,7 +663,7 @@ void SetYearEngineAgingStops() /* Base year ending date on half the model life */ TimerGameCalendar::YearMonthDay ymd; - TimerGameCalendar::ConvertDateToYMD(ei->base_intro + static_cast(DateAtStartOfYear(ei->lifelength)) / 2, &ymd); + TimerGameCalendar::ConvertDateToYMD(ei->base_intro + static_cast(TimerGameCalendar::DateAtStartOfYear(ei->lifelength)) / 2, &ymd); _year_engine_aging_stops = std::max(_year_engine_aging_stops, ymd.year); } @@ -1103,7 +1103,7 @@ void EnginesMonthlyLoop() /* Do not introduce invalid engines */ if (!e->IsEnabled()) continue; - if (!(e->flags & ENGINE_AVAILABLE) && TimerGameCalendar::date >= (e->intro_date + DAYS_IN_YEAR)) { + if (!(e->flags & ENGINE_AVAILABLE) && TimerGameCalendar::date >= (e->intro_date + CalendarTime::DAYS_IN_YEAR)) { /* Introduce it to all companies */ NewVehicleAvailable(e); } else if (!(e->flags & (ENGINE_AVAILABLE | ENGINE_EXCLUSIVE_PREVIEW)) && TimerGameCalendar::date >= e->intro_date) { diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 294b60c55e..ab4a332b53 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -569,8 +569,8 @@ struct GenerateLandscapeWindow : public Window { this->SetWidgetDisabledState(WID_GL_HEIGHTMAP_HEIGHT_DOWN, _settings_newgame.game_creation.heightmap_height <= MIN_HEIGHTMAP_HEIGHT); this->SetWidgetDisabledState(WID_GL_HEIGHTMAP_HEIGHT_UP, _settings_newgame.game_creation.heightmap_height >= GetMapHeightLimit()); } - this->SetWidgetDisabledState(WID_GL_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= MIN_YEAR); - this->SetWidgetDisabledState(WID_GL_START_DATE_UP, _settings_newgame.game_creation.starting_year >= MAX_YEAR); + this->SetWidgetDisabledState(WID_GL_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= CalendarTime::MIN_YEAR); + this->SetWidgetDisabledState(WID_GL_START_DATE_UP, _settings_newgame.game_creation.starting_year >= CalendarTime::MAX_YEAR); this->SetWidgetDisabledState(WID_GL_SNOW_COVERAGE_DOWN, _settings_newgame.game_creation.snow_coverage <= 0 || _settings_newgame.game_creation.landscape != LT_ARCTIC); this->SetWidgetDisabledState(WID_GL_SNOW_COVERAGE_UP, _settings_newgame.game_creation.snow_coverage >= 100 || _settings_newgame.game_creation.landscape != LT_ARCTIC); this->SetWidgetDisabledState(WID_GL_DESERT_COVERAGE_DOWN, _settings_newgame.game_creation.desert_coverage <= 0 || _settings_newgame.game_creation.landscape != LT_TROPIC); @@ -599,7 +599,7 @@ struct GenerateLandscapeWindow : public Window { break; case WID_GL_START_DATE_TEXT: - SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 0, 1)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(CalendarTime::MAX_YEAR, 0, 1)); d = GetStringBoundingBox(STR_JUST_DATE_LONG); break; @@ -763,7 +763,7 @@ struct GenerateLandscapeWindow : public Window { if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) { this->HandleButtonClick(widget); - _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_GL_START_DATE_TEXT, MIN_YEAR, MAX_YEAR); + _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_GL_START_DATE_TEXT, CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR); this->InvalidateData(); } _left_button_clicked = false; @@ -968,7 +968,7 @@ struct GenerateLandscapeWindow : public Window { /* An empty string means revert to the default */ switch (this->widget_id) { case WID_GL_HEIGHTMAP_HEIGHT_TEXT: value = MAP_HEIGHT_LIMIT_AUTO_MINIMUM; break; - case WID_GL_START_DATE_TEXT: value = static_cast(DEF_START_YEAR); break; + case WID_GL_START_DATE_TEXT: value = static_cast(CalendarTime::DEF_START_YEAR); break; case WID_GL_SNOW_COVERAGE_TEXT: value = DEF_SNOW_COVERAGE; break; case WID_GL_DESERT_COVERAGE_TEXT: value = DEF_DESERT_COVERAGE; break; case WID_GL_TOWN_PULLDOWN: value = 1; break; @@ -987,7 +987,7 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_START_DATE_TEXT: this->SetWidgetDirty(WID_GL_START_DATE_TEXT); - _settings_newgame.game_creation.starting_year = Clamp(TimerGameCalendar::Year(value), MIN_YEAR, MAX_YEAR); + _settings_newgame.game_creation.starting_year = Clamp(TimerGameCalendar::Year(value), CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR); break; case WID_GL_SNOW_COVERAGE_TEXT: @@ -1125,8 +1125,8 @@ struct CreateScenarioWindow : public Window void OnPaint() override { - this->SetWidgetDisabledState(WID_CS_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= MIN_YEAR); - this->SetWidgetDisabledState(WID_CS_START_DATE_UP, _settings_newgame.game_creation.starting_year >= MAX_YEAR); + this->SetWidgetDisabledState(WID_CS_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= CalendarTime::MIN_YEAR); + this->SetWidgetDisabledState(WID_CS_START_DATE_UP, _settings_newgame.game_creation.starting_year >= CalendarTime::MAX_YEAR); this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_DOWN, _settings_newgame.game_creation.se_flat_world_height <= 0); this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_UP, _settings_newgame.game_creation.se_flat_world_height >= GetMapHeightLimit()); @@ -1143,7 +1143,7 @@ struct CreateScenarioWindow : public Window StringID str = STR_JUST_INT; switch (widget) { case WID_CS_START_DATE_TEXT: - SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 0, 1)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(CalendarTime::MAX_YEAR, 0, 1)); str = STR_JUST_DATE_LONG; break; @@ -1199,7 +1199,7 @@ struct CreateScenarioWindow : public Window this->HandleButtonClick(widget); this->SetDirty(); - _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_CS_START_DATE_TEXT, MIN_YEAR, MAX_YEAR); + _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_CS_START_DATE_TEXT, CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR); } _left_button_clicked = false; break; @@ -1258,7 +1258,7 @@ struct CreateScenarioWindow : public Window switch (this->widget_id) { case WID_CS_START_DATE_TEXT: this->SetWidgetDirty(WID_CS_START_DATE_TEXT); - _settings_newgame.game_creation.starting_year = Clamp(TimerGameCalendar::Year(value), MIN_YEAR, MAX_YEAR); + _settings_newgame.game_creation.starting_year = Clamp(TimerGameCalendar::Year(value), CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR); break; case WID_CS_FLAT_LAND_HEIGHT_TEXT: diff --git a/src/linkgraph/flowmapper.cpp b/src/linkgraph/flowmapper.cpp index b27719dc52..dfbce810a1 100644 --- a/src/linkgraph/flowmapper.cpp +++ b/src/linkgraph/flowmapper.cpp @@ -50,7 +50,7 @@ void FlowMapper::Run(LinkGraphJob &job) const /* Scale by time the graph has been running without being compressed. Add 1 to avoid * division by 0 if spawn date == last compression date. This matches * LinkGraph::Monthly(). */ - auto runtime = job.JoinDate() - job.Settings().recalc_time / SECONDS_PER_DAY - job.LastCompression() + 1; + auto runtime = job.JoinDate() - job.Settings().recalc_time / CalendarTime::SECONDS_PER_DAY - job.LastCompression() + 1; for (auto &it : flows) { it.second.ScaleToMonthly(static_cast(runtime)); } diff --git a/src/linkgraph/linkgraph.cpp b/src/linkgraph/linkgraph.cpp index 33d2adbad6..b573df0913 100644 --- a/src/linkgraph/linkgraph.cpp +++ b/src/linkgraph/linkgraph.cpp @@ -29,7 +29,7 @@ LinkGraph::BaseNode::BaseNode(TileIndex xy, StationID st, uint demand) this->supply = 0; this->demand = demand; this->station = st; - this->last_update = INVALID_DATE; + this->last_update = CalendarTime::INVALID_DATE; } /** @@ -40,8 +40,8 @@ LinkGraph::BaseEdge::BaseEdge(NodeID dest_node) this->capacity = 0; this->usage = 0; this->travel_time_sum = 0; - this->last_unrestricted_update = INVALID_DATE; - this->last_restricted_update = INVALID_DATE; + this->last_unrestricted_update = CalendarTime::INVALID_DATE; + this->last_restricted_update = CalendarTime::INVALID_DATE; this->dest_node = dest_node; } @@ -55,10 +55,10 @@ void LinkGraph::ShiftDates(TimerGameCalendar::Date interval) this->last_compression += interval; for (NodeID node1 = 0; node1 < this->Size(); ++node1) { BaseNode &source = this->nodes[node1]; - if (source.last_update != INVALID_DATE) source.last_update += interval; + if (source.last_update != CalendarTime::INVALID_DATE) source.last_update += interval; for (BaseEdge &edge : this->nodes[node1].edges) { - if (edge.last_unrestricted_update != INVALID_DATE) edge.last_unrestricted_update += interval; - if (edge.last_restricted_update != INVALID_DATE) edge.last_restricted_update += interval; + if (edge.last_unrestricted_update != CalendarTime::INVALID_DATE) edge.last_unrestricted_update += interval; + if (edge.last_restricted_update != CalendarTime::INVALID_DATE) edge.last_restricted_update += interval; } } } diff --git a/src/linkgraph/linkgraph.h b/src/linkgraph/linkgraph.h index 6ca1a04b29..7f9e1e352d 100644 --- a/src/linkgraph/linkgraph.h +++ b/src/linkgraph/linkgraph.h @@ -63,8 +63,8 @@ public: TimerGameCalendar::Date LastUpdate() const { return std::max(this->last_unrestricted_update, this->last_restricted_update); } void Update(uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode); - void Restrict() { this->last_unrestricted_update = INVALID_DATE; } - void Release() { this->last_restricted_update = INVALID_DATE; } + void Restrict() { this->last_unrestricted_update = CalendarTime::INVALID_DATE; } + void Release() { this->last_restricted_update = CalendarTime::INVALID_DATE; } /** Comparison operator based on \c dest_node. */ bool operator <(const BaseEdge &rhs) const diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp index 98e329ea79..64494ffddb 100644 --- a/src/linkgraph/linkgraphjob.cpp +++ b/src/linkgraph/linkgraphjob.cpp @@ -37,7 +37,7 @@ LinkGraphJob::LinkGraphJob(const LinkGraph &orig) : * This is on purpose. */ link_graph(orig), settings(_settings_game.linkgraph), - join_date(TimerGameCalendar::date + (_settings_game.linkgraph.recalc_time / SECONDS_PER_DAY)), + join_date(TimerGameCalendar::date + (_settings_game.linkgraph.recalc_time / CalendarTime::SECONDS_PER_DAY)), job_completed(false), job_aborted(false) { @@ -131,14 +131,14 @@ LinkGraphJob::~LinkGraphJob() if (st2 == nullptr || st2->goods[this->Cargo()].link_graph != this->link_graph.index || st2->goods[this->Cargo()].node != dest_id || !(*lg)[node_id].HasEdgeTo(dest_id) || - (*lg)[node_id][dest_id].LastUpdate() == INVALID_DATE) { + (*lg)[node_id][dest_id].LastUpdate() == CalendarTime::INVALID_DATE) { /* Edge has been removed. Delete flows. */ StationIDStack erased = flows.DeleteFlows(to); /* Delete old flows for source stations which have been deleted * from the new flows. This avoids flow cycles between old and * new flows. */ while (!erased.IsEmpty()) ge.flows.erase(erased.Pop()); - } else if ((*lg)[node_id][dest_id].last_restricted_update == INVALID_DATE) { + } else if ((*lg)[node_id][dest_id].last_restricted_update == CalendarTime::INVALID_DATE) { /* Edge is fully restricted. */ flows.RestrictFlows(to); } diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h index 6ea6c70307..90e477e161 100644 --- a/src/linkgraph/linkgraphjob.h +++ b/src/linkgraph/linkgraphjob.h @@ -178,7 +178,7 @@ public: * settings have to be brutally const-casted in order to populate them. */ LinkGraphJob() : settings(_settings_game.linkgraph), - join_date(INVALID_DATE), job_completed(false), job_aborted(false) {} + join_date(CalendarTime::INVALID_DATE), job_completed(false), job_aborted(false) {} LinkGraphJob(const LinkGraph &orig); ~LinkGraphJob(); diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index 4a2af43d02..3f3fed8168 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -178,7 +178,7 @@ void StateGameLoop_LinkGraphPauseControl() } } else if (_pause_mode == PM_UNPAUSED && TimerGameCalendar::date_fract == LinkGraphSchedule::SPAWN_JOIN_TICK - 2 && - static_cast(TimerGameCalendar::date) % (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) == (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) / 2 && + static_cast(TimerGameCalendar::date) % (_settings_game.linkgraph.recalc_interval / CalendarTime::SECONDS_PER_DAY) == (_settings_game.linkgraph.recalc_interval / CalendarTime::SECONDS_PER_DAY) / 2 && LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { /* Perform check two TimerGameCalendar::date_fract ticks before we would join, to make * sure it also works in multiplayer. */ @@ -205,10 +205,10 @@ void AfterLoad_LinkGraphPauseControl() void OnTick_LinkGraph() { if (TimerGameCalendar::date_fract != LinkGraphSchedule::SPAWN_JOIN_TICK) return; - TimerGameCalendar::Date offset = static_cast(TimerGameCalendar::date) % (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY); + TimerGameCalendar::Date offset = static_cast(TimerGameCalendar::date) % (_settings_game.linkgraph.recalc_interval / CalendarTime::SECONDS_PER_DAY); if (offset == 0) { LinkGraphSchedule::instance.SpawnNext(); - } else if (offset == (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) / 2) { + } else if (offset == (_settings_game.linkgraph.recalc_interval / CalendarTime::SECONDS_PER_DAY) / 2) { if (!_networking || _network_server) { PerformanceMeasurer::SetInactive(PFE_GL_LINKGRAPH); LinkGraphSchedule::instance.JoinNext(); diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 7fc8498991..658a2ec625 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -138,7 +138,7 @@ public: /* Because build_date is not set yet in every TileDesc, we make sure it is empty */ TileDesc td; - td.build_date = INVALID_DATE; + td.build_date = CalendarTime::INVALID_DATE; /* Most tiles have only one owner, but * - drivethrough roadstops can be build on town owned roads (up to 2 owners) and @@ -224,7 +224,7 @@ public: this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY)); /* Build date */ - if (td.build_date != INVALID_DATE) { + if (td.build_date != CalendarTime::INVALID_DATE) { SetDParam(0, td.build_date); this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_BUILD_DATE)); } diff --git a/src/network/core/network_game_info.cpp b/src/network/core/network_game_info.cpp index 0993e1ad15..817eb518b8 100644 --- a/src/network/core/network_game_info.cpp +++ b/src/network/core/network_game_info.cpp @@ -255,8 +255,6 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool */ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table) { - static const TimerGameCalendar::Date MAX_DATE = TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11 - byte game_info_version = p->Recv_uint8(); NewGRFSerializationType newgrf_serialisation = NST_GRFID_MD5; @@ -323,8 +321,8 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfo } case 3: - info->game_date = Clamp(p->Recv_uint32(), 0, static_cast(MAX_DATE)); - info->start_date = Clamp(p->Recv_uint32(), 0, static_cast(MAX_DATE)); + info->game_date = Clamp(p->Recv_uint32(), 0, static_cast(CalendarTime::MAX_DATE)); + info->start_date = Clamp(p->Recv_uint32(), 0, static_cast(CalendarTime::MAX_DATE)); FALLTHROUGH; case 2: @@ -342,8 +340,8 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfo info->clients_on = p->Recv_uint8 (); info->spectators_on = p->Recv_uint8 (); if (game_info_version < 3) { // 16 bits dates got scrapped and are read earlier - info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR; - info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR; + info->game_date = p->Recv_uint16() + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; + info->start_date = p->Recv_uint16() + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; } if (game_info_version < 6) while (p->Recv_uint8() != 0) {} // Used to contain the map-name. info->map_width = p->Recv_uint16(); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index a94b003763..5904decbdb 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -996,7 +996,7 @@ static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteRe { switch (prop) { case 0x00: // Introduction date - ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR; + ei->base_intro = buf->ReadWord() + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; break; case 0x02: // Decay speed @@ -2197,7 +2197,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteR case 0x08: { // Year of availability /* We treat '0' as always available */ byte year = buf->ReadByte(); - bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0); + bridge->avail_year = (year > 0 ? CalendarTime::ORIGINAL_BASE_YEAR + year : 0); break; } @@ -2257,7 +2257,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteR break; case 0x0F: // Long format year of availability (year since year 0) - bridge->avail_year = Clamp(TimerGameCalendar::Year(buf->ReadDWord()), MIN_YEAR, MAX_YEAR); + bridge->avail_year = Clamp(TimerGameCalendar::Year(buf->ReadDWord()), CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR); break; case 0x10: { // purchase string @@ -2430,8 +2430,8 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt case 0x0A: { // Availability years uint16_t years = buf->ReadWord(); - housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8); - housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8); + housespec->min_year = GB(years, 0, 8) > 150 ? CalendarTime::MAX_YEAR : CalendarTime::ORIGINAL_BASE_YEAR + GB(years, 0, 8); + housespec->max_year = GB(years, 8, 8) > 150 ? CalendarTime::MAX_YEAR : CalendarTime::ORIGINAL_BASE_YEAR + GB(years, 8, 8); break; } @@ -3991,7 +3991,7 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B case 0x0C: as->min_year = buf->ReadWord(); as->max_year = buf->ReadWord(); - if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR; + if (as->max_year == 0xFFFF) as->max_year = CalendarTime::MAX_YEAR; break; case 0x0D: @@ -6512,11 +6512,11 @@ bool GetGlobalVariable(byte param, uint32_t *value, const GRFFile *grffile) { switch (param) { case 0x00: // current date - *value = static_cast(std::max(TimerGameCalendar::date - DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::Date(0))); + *value = static_cast(std::max(TimerGameCalendar::date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::Date(0))); return true; case 0x01: // current year - *value = static_cast(Clamp(TimerGameCalendar::year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR); + *value = static_cast(Clamp(TimerGameCalendar::year, CalendarTime::ORIGINAL_BASE_YEAR, CalendarTime::ORIGINAL_MAX_YEAR) - CalendarTime::ORIGINAL_BASE_YEAR); return true; case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24) @@ -7228,7 +7228,7 @@ static uint32_t GetPatchVariable(uint8_t param) { switch (param) { /* start year - 1920 */ - case 0x0B: return static_cast(std::max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR); + case 0x0B: return static_cast(std::max(_settings_game.game_creation.starting_year, CalendarTime::ORIGINAL_BASE_YEAR) - CalendarTime::ORIGINAL_BASE_YEAR); /* freight trains weight factor */ case 0x0E: return _settings_game.vehicle.freight_trains; @@ -9237,7 +9237,7 @@ static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseS */ static void EnsureEarlyHouse(HouseZones bitmask) { - TimerGameCalendar::Year min_year = MAX_YEAR; + TimerGameCalendar::Year min_year = CalendarTime::MAX_YEAR; for (int i = 0; i < NUM_HOUSES; i++) { HouseSpec *hs = HouseSpec::Get(i); diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index 81801739a9..4dffc76cde 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -212,7 +212,7 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) case 0x7C: return (this->st->airport.psa != nullptr) ? this->st->airport.psa->GetValue(parameter) : 0; case 0xF0: return this->st->facilities; - case 0xFA: return ClampTo(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR); + case 0xFA: return ClampTo(this->st->build_date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); } return this->st->GetNewGRFVariable(this->ro, variable, parameter, available); diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 15464e5262..11a6ff7d29 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -767,8 +767,8 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec } return (variable - 0x80) == 0x10 ? ticks : GB(ticks, 8, 8); } - case 0x12: return ClampTo(v->date_of_last_service_newgrf - DAYS_TILL_ORIGINAL_BASE_YEAR); - case 0x13: return GB(ClampTo(v->date_of_last_service_newgrf - DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8); + case 0x12: return ClampTo(v->date_of_last_service_newgrf - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); + case 0x13: return GB(ClampTo(v->date_of_last_service_newgrf - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8); case 0x14: return v->GetServiceInterval(); case 0x15: return GB(v->GetServiceInterval(), 8, 8); case 0x16: return v->last_station_visited; @@ -829,7 +829,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec case 0x41: return GB(ClampTo(v->age), 8, 8); case 0x42: return ClampTo(v->max_age); case 0x43: return GB(ClampTo(v->max_age), 8, 8); - case 0x44: return static_cast(Clamp(v->build_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR); + case 0x44: return static_cast(Clamp(v->build_year, CalendarTime::ORIGINAL_BASE_YEAR, CalendarTime::ORIGINAL_MAX_YEAR) - CalendarTime::ORIGINAL_BASE_YEAR); case 0x45: return v->unitnumber; case 0x46: return v->GetEngine()->grf_prop.local_id; case 0x47: return GB(v->GetEngine()->grf_prop.local_id, 8, 8); @@ -974,9 +974,9 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec case 0x48: return Engine::Get(this->self_type)->flags; // Vehicle Type Info case 0x49: return static_cast(TimerGameCalendar::year); // 'Long' format build year case 0x4B: return static_cast(TimerGameCalendar::date); // Long date of last service - case 0x92: return ClampTo(TimerGameCalendar::date - DAYS_TILL_ORIGINAL_BASE_YEAR); // Date of last service - case 0x93: return GB(ClampTo(TimerGameCalendar::date - DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8); - case 0xC4: return static_cast(Clamp(TimerGameCalendar::year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR); // Build year + case 0x92: return ClampTo(TimerGameCalendar::date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // Date of last service + case 0x93: return GB(ClampTo(TimerGameCalendar::date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8); + case 0xC4: return static_cast(Clamp(TimerGameCalendar::year, CalendarTime::ORIGINAL_BASE_YEAR, CalendarTime::ORIGINAL_MAX_YEAR) - CalendarTime::ORIGINAL_BASE_YEAR); // Build year case 0xC6: return Engine::Get(this->self_type)->grf_prop.local_id; case 0xC7: return GB(Engine::Get(this->self_type)->grf_prop.local_id, 8, 8); case 0xDA: return INVALID_VEHICLE; // Next vehicle diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 672d2034be..e0ce836108 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -396,16 +396,16 @@ static uint32_t GetCountAndDistanceOfClosestInstance(byte param_setID, byte layo case 0xA6: return indspec->grf_prop.local_id; case 0xA7: return this->industry->founder; case 0xA8: return this->industry->random_colour; - case 0xA9: return ClampTo(this->industry->last_prod_year - ORIGINAL_BASE_YEAR); + case 0xA9: return ClampTo(this->industry->last_prod_year - CalendarTime::ORIGINAL_BASE_YEAR); case 0xAA: return this->industry->counter; case 0xAB: return GB(this->industry->counter, 8, 8); case 0xAC: return this->industry->was_cargo_delivered; - case 0xB0: return ClampTo(this->industry->construction_date - DAYS_TILL_ORIGINAL_BASE_YEAR); // Date when built since 1920 (in days) + case 0xB0: return ClampTo(this->industry->construction_date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // Date when built since 1920 (in days) case 0xB3: return this->industry->construction_type; // Construction type case 0xB4: { auto it = std::max_element(std::begin(this->industry->accepted), std::end(this->industry->accepted), [](const auto &a, const auto &b) { return a.last_accepted < b.last_accepted; }); - return ClampTo(it->last_accepted - DAYS_TILL_ORIGINAL_BASE_YEAR); // Date last cargo accepted since 1920 (in days) + return ClampTo(it->last_accepted - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // Date last cargo accepted since 1920 (in days) } } diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index 5b0eb6f735..bce9b5f21a 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -173,7 +173,7 @@ uint32_t RoadStopScopeResolver::GetVariable(byte variable, uint32_t parameter, b case 0xF0: return this->st == nullptr ? 0 : this->st->facilities; // facilities - case 0xFA: return ClampTo((this->st == nullptr ? TimerGameCalendar::date : this->st->build_date) - DAYS_TILL_ORIGINAL_BASE_YEAR); // build date + case 0xFA: return ClampTo((this->st == nullptr ? TimerGameCalendar::date : this->st->build_date) - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // build date } if (this->st != nullptr) return this->st->GetNewGRFVariable(this->ro, variable, parameter, available); diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index cf9ddd9817..3dbf10538c 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -291,7 +291,7 @@ TownScopeResolver *StationResolverObject::GetTown() } break; - case 0xFA: return ClampTo(TimerGameCalendar::date - DAYS_TILL_ORIGINAL_BASE_YEAR); // Build date, clamped to a 16 bit value + case 0xFA: return ClampTo(TimerGameCalendar::date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // Build date, clamped to a 16 bit value } *available = false; @@ -381,7 +381,7 @@ TownScopeResolver *StationResolverObject::GetTown() case 0x84: return this->st->string_id; case 0x86: return 0; case 0xF0: return this->st->facilities; - case 0xFA: return ClampTo(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR); + case 0xFA: return ClampTo(this->st->build_date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); } return this->st->GetNewGRFVariable(this->ro, variable, parameter, available); diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 506e80a965..d979573dbb 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -23,6 +23,7 @@ #include "newgrf_text.h" #include "newgrf_cargo.h" #include "string_func.h" +#include "timer/timer_game_calendar.h" #include "date_type.h" #include "debug.h" #include "core/alloc_type.hpp" @@ -912,7 +913,7 @@ uint RemapNewGRFStringControlCode(uint scc, const char **str, StringParameters & /* Dates from NewGRFs have 1920-01-01 as their zero point, convert it to OpenTTD's epoch. */ case SCC_NEWGRF_PRINT_WORD_DATE_LONG: - case SCC_NEWGRF_PRINT_WORD_DATE_SHORT: parameters.SetParam(0, _newgrf_textrefstack.PopUnsignedWord() + DAYS_TILL_ORIGINAL_BASE_YEAR); break; + case SCC_NEWGRF_PRINT_WORD_DATE_SHORT: parameters.SetParam(0, _newgrf_textrefstack.PopUnsignedWord() + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); break; case SCC_NEWGRF_DISCARD_WORD: _newgrf_textrefstack.PopUnsignedWord(); break; diff --git a/src/news_gui.cpp b/src/news_gui.cpp index a3cc39b778..383dbc082a 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -1134,7 +1134,7 @@ struct MessageHistoryWindow : Window { /* Months are off-by-one, so it's actually 8. Not using * month 12 because the 1 is usually less wide. */ - SetDParam(0, TimerGameCalendar::ConvertYMDToDate(ORIGINAL_MAX_YEAR, 7, 30)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(CalendarTime::ORIGINAL_MAX_YEAR, 7, 30)); this->date_width = GetStringBoundingBox(STR_JUST_DATE_TINY).width + WidgetDimensions::scaled.hsep_wide; size->height = 4 * resize->height + WidgetDimensions::scaled.framerect.Vertical(); // At least 4 lines are visible. diff --git a/src/openttd.cpp b/src/openttd.cpp index 6fb3b4a34f..418f49abac 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -380,7 +380,7 @@ void OpenBrowser(const char *url) /** Callback structure of statements to be executed after the NewGRF scan. */ struct AfterNewGRFScan : NewGRFScanCallback { - TimerGameCalendar::Year startyear = INVALID_YEAR; ///< The start year. + TimerGameCalendar::Year startyear = CalendarTime::INVALID_YEAR; ///< The start year. uint32_t generation_seed = GENERATE_NEW_SEED; ///< Seed for the new game. std::string dedicated_host; ///< Hostname for the dedicated server. uint16_t dedicated_port = 0; ///< Port for the dedicated server. @@ -429,7 +429,7 @@ struct AfterNewGRFScan : NewGRFScanCallback { MusicDriver::GetInstance()->SetVolume(_settings_client.music.music_vol); SetEffectVolume(_settings_client.music.effect_vol); - if (startyear != INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", static_cast(startyear)); + if (startyear != CalendarTime::INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", static_cast(startyear)); if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed; if (!dedicated_host.empty()) { diff --git a/src/order_base.h b/src/order_base.h index 06e91aaf55..9671b96cac 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -367,8 +367,8 @@ public: bool IsCompleteTimetable() const; /** - * Gets the total duration of the vehicles timetable or Tick::INVALID_TICKS is the timetable is not complete. - * @return total timetable duration or Tick::INVALID_TICKS for incomplete timetables + * Gets the total duration of the vehicles timetable or Ticks::INVALID_TICKS is the timetable is not complete. + * @return total timetable duration or Ticks::INVALID_TICKS for incomplete timetables */ inline TimerGameTick::Ticks GetTimetableTotalDuration() const { return this->IsCompleteTimetable() ? this->timetable_duration : Ticks::INVALID_TICKS; } diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index b7039045e2..e20eac5056 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1947,10 +1947,10 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v) case OCV_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->reliability), value); break; case OCV_MAX_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->GetEngine()->reliability), value); break; case OCV_MAX_SPEED: skip_order = OrderConditionCompare(occ, v->GetDisplayMaxSpeed() * 10 / 16, value); break; - case OCV_AGE: skip_order = OrderConditionCompare(occ, DateToYear(v->age), value); break; + case OCV_AGE: skip_order = OrderConditionCompare(occ, TimerGameCalendar::DateToYear(v->age), value); break; case OCV_REQUIRES_SERVICE: skip_order = OrderConditionCompare(occ, v->NeedsServicing(), value); break; case OCV_UNCONDITIONALLY: skip_order = true; break; - case OCV_REMAINING_LIFETIME: skip_order = OrderConditionCompare(occ, std::max(DateToYear(v->max_age - v->age + DAYS_IN_LEAP_YEAR - 1), TimerGameCalendar::Year(0)), value); break; + case OCV_REMAINING_LIFETIME: skip_order = OrderConditionCompare(occ, std::max(TimerGameCalendar::DateToYear(v->max_age - v->age + CalendarTime::DAYS_IN_LEAP_YEAR - 1), TimerGameCalendar::Year(0)), value); break; default: NOT_REACHED(); } diff --git a/src/rail.cpp b/src/rail.cpp index d8991f0a4b..d07c641b55 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -225,7 +225,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date if (rti->label == 0) continue; /* Not date introduced. */ - if (!IsInsideMM(rti->introduction_date, 0, static_cast(MAX_DATE))) continue; + if (!IsInsideMM(rti->introduction_date, 0, static_cast(CalendarTime::MAX_DATE))) continue; /* Not yet introduced at this date. */ if (rti->introduction_date > date) continue; @@ -256,7 +256,7 @@ RailTypes GetCompanyRailtypes(CompanyID company, bool introduces) const EngineInfo *ei = &e->info; if (HasBit(ei->climates, _settings_game.game_creation.landscape) && - (HasBit(e->company_avail, company) || TimerGameCalendar::date >= e->intro_date + DAYS_IN_YEAR)) { + (HasBit(e->company_avail, company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) { const RailVehicleInfo *rvi = &e->u.rail; if (rvi->railveh_type != RAILVEH_WAGON) { @@ -298,7 +298,7 @@ RailTypes GetRailTypes(bool introduces) } } - if (introduces) return AddDateIntroducedRailTypes(rts, MAX_DATE); + if (introduces) return AddDateIntroducedRailTypes(rts, CalendarTime::MAX_DATE); return rts; } diff --git a/src/road.cpp b/src/road.cpp index de16bdf947..d2b4144fdd 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -115,7 +115,7 @@ bool HasRoadTypeAvail(const CompanyID company, RoadType roadtype) if (rti->label == 0) return false; /* Not yet introduced at this date. */ - if (IsInsideMM(rti->introduction_date, 0, static_cast(MAX_DATE)) && rti->introduction_date > TimerGameCalendar::date) return false; + if (IsInsideMM(rti->introduction_date, 0, static_cast(CalendarTime::MAX_DATE)) && rti->introduction_date > TimerGameCalendar::date) return false; /* * Do not allow building hidden road types, except when a town may build it. @@ -173,7 +173,7 @@ RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date if (rti->label == 0) continue; /* Not date introduced. */ - if (!IsInsideMM(rti->introduction_date, 0, static_cast(MAX_DATE))) continue; + if (!IsInsideMM(rti->introduction_date, 0, static_cast(CalendarTime::MAX_DATE))) continue; /* Not yet introduced at this date. */ if (rti->introduction_date > date) continue; @@ -204,7 +204,7 @@ RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces) const EngineInfo *ei = &e->info; if (HasBit(ei->climates, _settings_game.game_creation.landscape) && - (HasBit(e->company_avail, company) || TimerGameCalendar::date >= e->intro_date + DAYS_IN_YEAR)) { + (HasBit(e->company_avail, company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) { const RoadVehicleInfo *rvi = &e->u.road; assert(rvi->roadtype < ROADTYPE_END); if (introduces) { @@ -241,7 +241,7 @@ RoadTypes GetRoadTypes(bool introduces) } } - if (introduces) return AddDateIntroducedRoadTypes(rts, MAX_DATE); + if (introduces) return AddDateIntroducedRoadTypes(rts, CalendarTime::MAX_DATE); return rts; } @@ -302,7 +302,7 @@ RoadTypes ExistingRoadTypes(CompanyID c) } /* Get the date introduced roadtypes as well. */ - known_roadtypes = AddDateIntroducedRoadTypes(known_roadtypes, MAX_DATE); + known_roadtypes = AddDateIntroducedRoadTypes(known_roadtypes, CalendarTime::MAX_DATE); return known_roadtypes; } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 7bfbce0970..1d325f042a 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -150,7 +150,7 @@ RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt) rti->label = label; rti->alternate_labels.clear(); rti->flags = ROTFB_NONE; - rti->introduction_date = INVALID_DATE; + rti->introduction_date = CalendarTime::INVALID_DATE; /* Make us compatible with ourself. */ rti->powered_roadtypes = (RoadTypes)(1ULL << rt); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 8fe5cc4780..4917a05b50 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1720,7 +1720,7 @@ void RoadVehicle::OnNewDay() if (this->running_ticks == 0) return; - CommandCost cost(EXPENSES_ROADVEH_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS)); + CommandCost cost(EXPENSES_ROADVEH_RUN, this->GetRunningCost() * this->running_ticks / (CalendarTime::DAYS_IN_YEAR * Ticks::DAY_TICKS)); this->profit_this_year -= cost.GetCost(); this->running_ticks = 0; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 66ffd850a6..815bc252d0 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -259,7 +259,7 @@ static void InitializeWindowsAndCaches() /* For each company, verify (while loading a scenario) that the inauguration date is the current year and set it * accordingly if it is not the case. No need to set it on companies that are not been used already, * thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */ - if (_file_to_saveload.abstract_ftype == FT_SCENARIO && c->inaugurated_year != MIN_YEAR) { + if (_file_to_saveload.abstract_ftype == FT_SCENARIO && c->inaugurated_year != CalendarTime::MIN_YEAR) { c->inaugurated_year = TimerGameCalendar::year; } } @@ -776,13 +776,13 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_ENDING_YEAR)) { - _settings_game.game_creation.ending_year = DEF_END_YEAR; + _settings_game.game_creation.ending_year = CalendarTime::DEF_END_YEAR; } /* Convert linkgraph update settings from days to seconds. */ if (IsSavegameVersionBefore(SLV_LINKGRAPH_SECONDS)) { - _settings_game.linkgraph.recalc_interval *= SECONDS_PER_DAY; - _settings_game.linkgraph.recalc_time *= SECONDS_PER_DAY; + _settings_game.linkgraph.recalc_interval *= CalendarTime::SECONDS_PER_DAY; + _settings_game.linkgraph.recalc_time *= CalendarTime::SECONDS_PER_DAY; } /* Load the sprites */ @@ -1422,18 +1422,18 @@ bool AfterLoadGame() /* Time starts at 0 instead of 1920. * Account for this in older games by adding an offset */ if (IsSavegameVersionBefore(SLV_31)) { - TimerGameCalendar::date += DAYS_TILL_ORIGINAL_BASE_YEAR; - TimerGameCalendar::year += ORIGINAL_BASE_YEAR; + TimerGameCalendar::date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; + TimerGameCalendar::year += CalendarTime::ORIGINAL_BASE_YEAR; - for (Station *st : Station::Iterate()) st->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR; - for (Waypoint *wp : Waypoint::Iterate()) wp->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR; - for (Engine *e : Engine::Iterate()) e->intro_date += DAYS_TILL_ORIGINAL_BASE_YEAR; - for (Company *c : Company::Iterate()) c->inaugurated_year += ORIGINAL_BASE_YEAR; - for (Industry *i : Industry::Iterate()) i->last_prod_year += ORIGINAL_BASE_YEAR; + for (Station *st : Station::Iterate()) st->build_date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; + for (Waypoint *wp : Waypoint::Iterate()) wp->build_date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; + for (Engine *e : Engine::Iterate()) e->intro_date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; + for (Company *c : Company::Iterate()) c->inaugurated_year += CalendarTime::ORIGINAL_BASE_YEAR; + for (Industry *i : Industry::Iterate()) i->last_prod_year += CalendarTime::ORIGINAL_BASE_YEAR; for (Vehicle *v : Vehicle::Iterate()) { - v->date_of_last_service += DAYS_TILL_ORIGINAL_BASE_YEAR; - v->build_year += ORIGINAL_BASE_YEAR; + v->date_of_last_service += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; + v->build_year += CalendarTime::ORIGINAL_BASE_YEAR; } } @@ -1925,7 +1925,7 @@ bool AfterLoadGame() /* Replace "house construction year" with "house age" */ if (IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)) { - t.m5() = ClampTo(TimerGameCalendar::year - (t.m5() + ORIGINAL_BASE_YEAR)); + t.m5() = ClampTo(TimerGameCalendar::year - (t.m5() + CalendarTime::ORIGINAL_BASE_YEAR)); } } } diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index f9d9e4188d..af20e34e83 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -135,7 +135,7 @@ struct DATEChunkHandler : ChunkHandler { this->LoadCommon(_date_check_desc, _date_check_sl_compat); if (IsSavegameVersionBefore(SLV_31)) { - _load_check_data.current_date += DAYS_TILL_ORIGINAL_BASE_YEAR; + _load_check_data.current_date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; } } }; diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 12e9b71e96..5543013ed2 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -398,7 +398,7 @@ static bool FixTTOEngines() for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i); } - TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::ConvertYMDToDate(2050, 0, 1)); + TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::ConvertYMDToDate(2050, 0, 1)); for (EngineID i = 0; i < 256; i++) { int oi = ttd_to_tto[i]; @@ -406,11 +406,11 @@ static bool FixTTOEngines() if (oi == 255) { /* Default engine is used */ - TimerGameCalendar::date += DAYS_TILL_ORIGINAL_BASE_YEAR; + TimerGameCalendar::date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; StartupOneEngine(e, aging_date, 0); CalcEngineReliability(e, false); - e->intro_date -= DAYS_TILL_ORIGINAL_BASE_YEAR; - TimerGameCalendar::date -= DAYS_TILL_ORIGINAL_BASE_YEAR; + e->intro_date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; + TimerGameCalendar::date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; /* Make sure for example monorail and maglev are available when they should be */ if (TimerGameCalendar::date >= e->intro_date && HasBit(e->info.climates, 0)) { @@ -1020,7 +1020,7 @@ static bool LoadOldCompany(LoadgameState *ls, int num) } _company_colours[num] = (Colours)c->colour; - c->inaugurated_year -= ORIGINAL_BASE_YEAR; + c->inaugurated_year -= CalendarTime::ORIGINAL_BASE_YEAR; return true; } diff --git a/src/script/api/script_date.cpp b/src/script/api/script_date.cpp index 1fbf80999e..886bef830f 100644 --- a/src/script/api/script_date.cpp +++ b/src/script/api/script_date.cpp @@ -56,7 +56,7 @@ { if (month < 1 || month > 12) return DATE_INVALID; if (day_of_month < 1 || day_of_month > 31) return DATE_INVALID; - if (year < 0 || year > MAX_YEAR) return DATE_INVALID; + if (year < 0 || year > CalendarTime::MAX_YEAR) return DATE_INVALID; return (ScriptDate::Date)(int32_t)::TimerGameCalendar::ConvertYMDToDate(year, month - 1, day_of_month); } diff --git a/src/script/api/script_date.hpp b/src/script/api/script_date.hpp index 6fa2053cc4..01ef5d3dc2 100644 --- a/src/script/api/script_date.hpp +++ b/src/script/api/script_date.hpp @@ -11,6 +11,7 @@ #define SCRIPT_DATE_HPP #include "script_object.hpp" +#include "timer/timer_game_calendar.h" #include "../../date_type.h" /** @@ -31,7 +32,7 @@ public: * compose valid date values for a known year, month and day. */ enum Date { - DATE_INVALID = (int32_t)::INVALID_DATE, ///< A value representing an invalid date. + DATE_INVALID = (int32_t)::CalendarTime::INVALID_DATE, ///< A value representing an invalid date. }; /** diff --git a/src/settings.cpp b/src/settings.cpp index 4d8134f267..3c18f4ec32 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1283,8 +1283,8 @@ void LoadFromConfig(bool startup) /* Load basic settings only during bootstrap, load other settings not during bootstrap */ if (!startup) { if (generic_version < IFV_LINKGRAPH_SECONDS) { - _settings_newgame.linkgraph.recalc_interval *= SECONDS_PER_DAY; - _settings_newgame.linkgraph.recalc_time *= SECONDS_PER_DAY; + _settings_newgame.linkgraph.recalc_interval *= CalendarTime::SECONDS_PER_DAY; + _settings_newgame.linkgraph.recalc_time *= CalendarTime::SECONDS_PER_DAY; } /* Move no_http_content_downloads and use_relay_service from generic_ini to private_ini. */ diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index e2aeeec19e..28a466b927 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2751,7 +2751,7 @@ struct CustomCurrencyWindow : Window { this->SetWidgetDisabledState(WID_CC_RATE_DOWN, _custom_currency.rate == 1); this->SetWidgetDisabledState(WID_CC_RATE_UP, _custom_currency.rate == UINT16_MAX); this->SetWidgetDisabledState(WID_CC_YEAR_DOWN, _custom_currency.to_euro == CF_NOEURO); - this->SetWidgetDisabledState(WID_CC_YEAR_UP, _custom_currency.to_euro == MAX_YEAR); + this->SetWidgetDisabledState(WID_CC_YEAR_UP, _custom_currency.to_euro == CalendarTime::MAX_YEAR); } void SetStringParameters(int widget) const override @@ -2850,8 +2850,8 @@ struct CustomCurrencyWindow : Window { break; case WID_CC_YEAR_UP: - _custom_currency.to_euro = Clamp(_custom_currency.to_euro + 1, MIN_EURO_YEAR, MAX_YEAR); - if (_custom_currency.to_euro == MAX_YEAR) this->DisableWidget(WID_CC_YEAR_UP); + _custom_currency.to_euro = Clamp(_custom_currency.to_euro + 1, MIN_EURO_YEAR, CalendarTime::MAX_YEAR); + if (_custom_currency.to_euro == CalendarTime::MAX_YEAR) this->DisableWidget(WID_CC_YEAR_UP); this->EnableWidget(WID_CC_YEAR_DOWN); break; @@ -2897,7 +2897,7 @@ struct CustomCurrencyWindow : Window { case WID_CC_YEAR: { // Year to switch to euro TimerGameCalendar::Year val = atoi(str); - _custom_currency.to_euro = (val < MIN_EURO_YEAR ? CF_NOEURO : std::min(val, MAX_YEAR)); + _custom_currency.to_euro = (val < MIN_EURO_YEAR ? CF_NOEURO : std::min(val, CalendarTime::MAX_YEAR)); break; } } diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 78a66cc930..7f07233a61 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -236,7 +236,7 @@ void Ship::OnNewDay() if (this->running_ticks == 0) return; - CommandCost cost(EXPENSES_SHIP_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS)); + CommandCost cost(EXPENSES_SHIP_RUN, this->GetRunningCost() * this->running_ticks / (CalendarTime::DAYS_IN_YEAR * Ticks::DAY_TICKS)); this->profit_this_year -= cost.GetCost(); this->running_ticks = 0; diff --git a/src/station.cpp b/src/station.cpp index 590abc976e..85bbc09f1a 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -105,7 +105,7 @@ Station::~Station() for (NodeID node = 0; node < lg->Size(); ++node) { Station *st = Station::Get((*lg)[node].station); st->goods[c].flows.erase(this->index); - if ((*lg)[node].HasEdgeTo(this->goods[c].node) && (*lg)[node][this->goods[c].node].LastUpdate() != INVALID_DATE) { + if ((*lg)[node].HasEdgeTo(this->goods[c].node) && (*lg)[node][this->goods[c].node].LastUpdate() != CalendarTime::INVALID_DATE) { st->goods[c].flows.DeleteFlows(this->index); RerouteCargo(st, c, this->index, st->index); } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 84ce14d39f..da47d6dfbd 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3863,11 +3863,11 @@ void DeleteStaleLinks(Station *from) ge.flows.DeleteFlows(to->index); RerouteCargo(from, c, to->index, from->index); } - } else if (edge.last_unrestricted_update != INVALID_DATE && TimerGameCalendar::date - edge.last_unrestricted_update > timeout) { + } else if (edge.last_unrestricted_update != CalendarTime::INVALID_DATE && TimerGameCalendar::date - edge.last_unrestricted_update > timeout) { edge.Restrict(); ge.flows.RestrictFlows(to->index); RerouteCargo(from, c, to->index, from->index); - } else if (edge.last_restricted_update != INVALID_DATE && TimerGameCalendar::date - edge.last_restricted_update > timeout) { + } else if (edge.last_restricted_update != CalendarTime::INVALID_DATE && TimerGameCalendar::date - edge.last_restricted_update > timeout) { edge.Release(); } } diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index be49e19854..782d998b89 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -89,7 +89,7 @@ struct StatusBarWindow : Window { Dimension d; switch (widget) { case WID_S_LEFT: - SetDParamMaxValue(0, DateAtStartOfYear(MAX_YEAR)); + SetDParamMaxValue(0, TimerGameCalendar::DateAtStartOfYear(CalendarTime::MAX_YEAR)); d = GetStringBoundingBox(STR_JUST_DATE_LONG); break; diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 9f3db43d1b..b9c6a29b5c 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -699,7 +699,7 @@ public: int y_offset = -scrollpos; /* Date */ - if (page->date != INVALID_DATE) { + if (page->date != CalendarTime::INVALID_DATE) { SetDParam(0, page->date); DrawString(0, fr.right, y_offset, STR_JUST_DATE_LONG, TC_BLACK); } diff --git a/src/subsidy.cpp b/src/subsidy.cpp index 6821a35d44..620a5c30be 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -45,7 +45,7 @@ void Subsidy::AwardTo(CompanyID company) assert(!this->IsAwarded()); this->awarded = company; - this->remaining = _settings_game.difficulty.subsidy_duration * MONTHS_IN_YEAR; + this->remaining = _settings_game.difficulty.subsidy_duration * CalendarTime::MONTHS_IN_YEAR; SetDParam(0, company); NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME)); diff --git a/src/table/airport_defaults.h b/src/table/airport_defaults.h index c4734f151d..7305779412 100644 --- a/src/table/airport_defaults.h +++ b/src/table/airport_defaults.h @@ -10,7 +10,7 @@ #ifndef AIRPORT_DEFAULTS_H #define AIRPORT_DEFAULTS_H -#include "date_type.h" +#include "timer/timer_game_calendar.h" /** * Definition of an airport tiles layout. @@ -397,20 +397,20 @@ static const Direction _default_airports_rotation[] = { /* The helidepot and helistation have ATP_TTDP_SMALL because they are at ground level */ extern const AirportSpec _origin_airport_specs[] = { AS(country, 4, 3, 0, 1959, 4, 3, 7, ATP_TTDP_SMALL, APC_SMALL, STR_AIRPORT_SMALL, SPR_AIRPORT_PREVIEW_SMALL), - AS(city, 6, 6, 1955, MAX_YEAR, 5, 5, 24, ATP_TTDP_LARGE, APC_LARGE, STR_AIRPORT_CITY, SPR_AIRPORT_PREVIEW_LARGE), - AS_ND(heliport, 1, 1, 1963, MAX_YEAR, 4, 1, 4, ATP_TTDP_HELIPORT, APC_HELIPORT, STR_AIRPORT_HELIPORT, SPR_AIRPORT_PREVIEW_HELIPORT), - AS(metropolitan, 6, 6, 1980, MAX_YEAR, 6, 8, 28, ATP_TTDP_LARGE, APC_LARGE, STR_AIRPORT_METRO, SPR_AIRPORT_PREVIEW_METROPOLITAN), - AS(international, 7, 7, 1990, MAX_YEAR, 8, 17, 42, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERNATIONAL, SPR_AIRPORT_PREVIEW_INTERNATIONAL), - AS(commuter, 5, 4, 1983, MAX_YEAR, 4, 4, 20, ATP_TTDP_SMALL, APC_SMALL, STR_AIRPORT_COMMUTER, SPR_AIRPORT_PREVIEW_COMMUTER), - AS(helidepot, 2, 2, 1976, MAX_YEAR, 4, 2, 7, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELIDEPOT, SPR_AIRPORT_PREVIEW_HELIDEPOT), - AS(intercontinental, 9, 11, 2002, MAX_YEAR, 10, 25, 72, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERCONTINENTAL, SPR_AIRPORT_PREVIEW_INTERCONTINENTAL), - AS(helistation, 4, 2, 1980, MAX_YEAR, 4, 3, 14, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELISTATION, SPR_AIRPORT_PREVIEW_HELISTATION), + AS(city, 6, 6, 1955, CalendarTime::MAX_YEAR, 5, 5, 24, ATP_TTDP_LARGE, APC_LARGE, STR_AIRPORT_CITY, SPR_AIRPORT_PREVIEW_LARGE), + AS_ND(heliport, 1, 1, 1963, CalendarTime::MAX_YEAR, 4, 1, 4, ATP_TTDP_HELIPORT, APC_HELIPORT, STR_AIRPORT_HELIPORT, SPR_AIRPORT_PREVIEW_HELIPORT), + AS(metropolitan, 6, 6, 1980, CalendarTime::MAX_YEAR, 6, 8, 28, ATP_TTDP_LARGE, APC_LARGE, STR_AIRPORT_METRO, SPR_AIRPORT_PREVIEW_METROPOLITAN), + AS(international, 7, 7, 1990, CalendarTime::MAX_YEAR, 8, 17, 42, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERNATIONAL, SPR_AIRPORT_PREVIEW_INTERNATIONAL), + AS(commuter, 5, 4, 1983, CalendarTime::MAX_YEAR, 4, 4, 20, ATP_TTDP_SMALL, APC_SMALL, STR_AIRPORT_COMMUTER, SPR_AIRPORT_PREVIEW_COMMUTER), + AS(helidepot, 2, 2, 1976, CalendarTime::MAX_YEAR, 4, 2, 7, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELIDEPOT, SPR_AIRPORT_PREVIEW_HELIDEPOT), + AS(intercontinental, 9, 11, 2002, CalendarTime::MAX_YEAR, 10, 25, 72, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERCONTINENTAL, SPR_AIRPORT_PREVIEW_INTERCONTINENTAL), + AS(helistation, 4, 2, 1980, CalendarTime::MAX_YEAR, 4, 3, 14, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELISTATION, SPR_AIRPORT_PREVIEW_HELISTATION), AS_GENERIC(&_airportfta_oilrig, nullptr, _default_airports_rotation, 0, nullptr, 0, 1, 1, 0, 4, 0, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, 0, false), }; static_assert(NEW_AIRPORT_OFFSET == lengthof(_origin_airport_specs)); -const AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, nullptr, _default_airports_rotation, 0, nullptr, 0, 0, 0, 0, 0, MIN_YEAR, MIN_YEAR, 0, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false); +const AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, nullptr, _default_airports_rotation, 0, nullptr, 0, 0, 0, 0, 0, CalendarTime::MIN_YEAR, CalendarTime::MIN_YEAR, 0, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false); #undef AS #undef AS_ND diff --git a/src/table/engines.h b/src/table/engines.h index acc7b8f824..9fc31efb02 100644 --- a/src/table/engines.h +++ b/src/table/engines.h @@ -24,7 +24,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MT(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Ticks::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MT(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Ticks::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a multiple-unit train into the EngineInfo struct. @@ -37,7 +37,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MM(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MM(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, Ticks::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a train carriage into the EngineInfo struct. @@ -50,7 +50,7 @@ * @see MT * @note the 5 between b and f is the load amount */ -#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MW(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Ticks::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a road vehicle into the EngineInfo struct. @@ -63,7 +63,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MR(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MR(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Ticks::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a ship into the EngineInfo struct. @@ -75,7 +75,7 @@ * @param f Bitmask of the climates * @note the 10 between b and f is the load amount */ -#define MS(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MS(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Ticks::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of an aeroplane into the EngineInfo struct. @@ -86,7 +86,7 @@ * @param e Bitmask of the climates * @note the 20 between b and e is the load amount */ -#define MA(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, CT_INVALID, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } +#define MA(a, b, c, d, e) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, CT_INVALID, 0, 8, 0, 0, 0, STR_EMPTY, Ticks::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /* Climates * T = Temperate diff --git a/src/table/object_land.h b/src/table/object_land.h index b6ab0e3b79..ac1653c97b 100644 --- a/src/table/object_land.h +++ b/src/table/object_land.h @@ -121,7 +121,7 @@ static const DrawTileSprites _object_hq[] = { #undef TILE_SPRITE_LINE -#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) { GRFFilePropsBase<2>(), {0, 0, 0, 0}, INVALID_OBJECT_CLASS, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, MAX_DATE + 1, flags, 0, height, 1, gen_amount } +#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) { GRFFilePropsBase<2>(), {0, 0, 0, 0}, INVALID_OBJECT_CLASS, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, CalendarTime::MAX_DATE + 1, flags, 0, height, 1, gen_amount } /* Climates * T = Temperate diff --git a/src/table/railtypes.h b/src/table/railtypes.h index 95285de5f0..b70b4f8c8f 100644 --- a/src/table/railtypes.h +++ b/src/table/railtypes.h @@ -99,7 +99,7 @@ static const RailtypeInfo _original_railtypes[] = { 0x0A, /* introduction date */ - INVALID_DATE, + CalendarTime::INVALID_DATE, /* railtypes required for this to be introduced */ RAILTYPES_NONE, @@ -200,7 +200,7 @@ static const RailtypeInfo _original_railtypes[] = { 0x0A, /* introduction date */ - INVALID_DATE, + CalendarTime::INVALID_DATE, /* railtypes required for this to be introduced */ RAILTYPES_NONE, @@ -297,7 +297,7 @@ static const RailtypeInfo _original_railtypes[] = { 0x0A, /* introduction date */ - INVALID_DATE, + CalendarTime::INVALID_DATE, /* railtypes required for this to be introduced */ RAILTYPES_NONE, @@ -394,7 +394,7 @@ static const RailtypeInfo _original_railtypes[] = { 0x0A, /* introduction date */ - INVALID_DATE, + CalendarTime::INVALID_DATE, /* railtypes required for this to be introduced */ RAILTYPES_NONE, diff --git a/src/table/roadtypes.h b/src/table/roadtypes.h index c59965d53c..f4148cf85f 100644 --- a/src/table/roadtypes.h +++ b/src/table/roadtypes.h @@ -82,7 +82,7 @@ static const RoadTypeInfo _original_roadtypes[] = { 0x01, /* introduction date */ - static_cast(MIN_YEAR), + static_cast(CalendarTime::MIN_YEAR), /* roadtypes required for this to be introduced */ ROADTYPES_NONE, @@ -162,7 +162,7 @@ static const RoadTypeInfo _original_roadtypes[] = { 0x01, /* introduction date */ - INVALID_DATE, + CalendarTime::INVALID_DATE, /* roadtypes required for this to be introduced */ ROADTYPES_NONE, diff --git a/src/table/settings/currency_settings.ini b/src/table/settings/currency_settings.ini index 4a0e733387..0f19952ccf 100644 --- a/src/table/settings/currency_settings.ini +++ b/src/table/settings/currency_settings.ini @@ -50,8 +50,8 @@ cat = SC_BASIC var = to_euro type = SLE_INT32 def = 0 -min = MIN_YEAR -max = MAX_YEAR +min = CalendarTime::MIN_YEAR +max = CalendarTime::MAX_YEAR [SDT_SSTR] var = prefix diff --git a/src/table/settings/gui_settings.ini b/src/table/settings/gui_settings.ini index 62ad58d1dc..ab6fdc4bb2 100644 --- a/src/table/settings/gui_settings.ini +++ b/src/table/settings/gui_settings.ini @@ -496,8 +496,8 @@ var = gui.coloured_news_year type = SLE_INT32 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC def = 2000 -min = MIN_YEAR -max = MAX_YEAR +min = CalendarTime::MIN_YEAR +max = CalendarTime::MAX_YEAR interval = 1 str = STR_CONFIG_SETTING_COLOURED_NEWS_YEAR strhelp = STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT @@ -543,8 +543,8 @@ var = gui.semaphore_build_before type = SLE_INT32 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC def = 1950 -min = MIN_YEAR -max = MAX_YEAR +min = CalendarTime::MIN_YEAR +max = CalendarTime::MAX_YEAR interval = 1 str = STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE strhelp = STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT diff --git a/src/table/settings/network_settings.ini b/src/table/settings/network_settings.ini index 3ec38ac8e7..ae31973433 100644 --- a/src/table/settings/network_settings.ini +++ b/src/table/settings/network_settings.ini @@ -237,8 +237,8 @@ var = network.restart_game_year type = SLE_INT32 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY def = 0 -min = MIN_YEAR -max = MAX_YEAR +min = CalendarTime::MIN_YEAR +max = CalendarTime::MAX_YEAR interval = 1 [SDTC_VAR] diff --git a/src/table/settings/world_settings.ini b/src/table/settings/world_settings.ini index ba698ba756..1d6143a925 100644 --- a/src/table/settings/world_settings.ini +++ b/src/table/settings/world_settings.ini @@ -122,9 +122,9 @@ cat = SC_BASIC [SDT_VAR] var = game_creation.starting_year type = SLE_INT32 -def = DEF_START_YEAR -min = MIN_YEAR -max = MAX_YEAR +def = CalendarTime::DEF_START_YEAR +min = CalendarTime::MIN_YEAR +max = CalendarTime::MAX_YEAR interval = 1 str = STR_CONFIG_SETTING_STARTING_YEAR strval = STR_JUST_INT @@ -135,9 +135,9 @@ var = game_creation.ending_year type = SLE_INT32 from = SLV_ENDING_YEAR flags = SF_GUI_0_IS_SPECIAL -def = DEF_END_YEAR -min = MIN_YEAR -max = MAX_YEAR - 1 +def = CalendarTime::DEF_END_YEAR +min = CalendarTime::MIN_YEAR +max = CalendarTime::MAX_YEAR - 1 interval = 1 str = STR_CONFIG_SETTING_ENDING_YEAR strhelp = STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT diff --git a/src/table/town_land.h b/src/table/town_land.h index 92292f6203..83b663add1 100644 --- a/src/table/town_land.h +++ b/src/table/town_land.h @@ -1821,7 +1821,7 @@ static const HouseSpec _original_house_specs[] = { * remove_rating_decrease * | mail_generation * min_year | | 1st CargoID acceptance - * | max_year | | | 2nd CargoID acceptance + * | CalendarTime::MAX_YEAR | | | 2nd CargoID acceptance * | | population | | | | 3th CargoID acceptance * | | | removal_cost | | | | | * | | | | building_name | | | | | @@ -1832,59 +1832,59 @@ static const HouseSpec _original_house_specs[] = { * +-cargoID accepted | | | | | | | | * | | | | | | | | | | | */ - MS(1963, MAX_YEAR, 187, 150, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 70, 8, 3, 4, + MS(1963, CalendarTime::MAX_YEAR, 187, 150, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 70, 8, 3, 4, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 00 - MS(1957, MAX_YEAR, 85, 140, STR_TOWN_BUILDING_NAME_OFFICE_BLOCK_1, 130, 55, 8, 3, 4, + MS(1957, CalendarTime::MAX_YEAR, 85, 140, STR_TOWN_BUILDING_NAME_OFFICE_BLOCK_1, 130, 55, 8, 3, 4, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 01 - MS(1968, MAX_YEAR, 40, 100, STR_TOWN_BUILDING_NAME_SMALL_BLOCK_OF_FLATS_1, 90, 20, 8, 3, 1, + MS(1968, CalendarTime::MAX_YEAR, 40, 100, STR_TOWN_BUILDING_NAME_SMALL_BLOCK_OF_FLATS_1, 90, 20, 8, 3, 1, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON4 | HZ_ZON3 | HZ_ZON2, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 02 - MS( 0, MAX_YEAR, 5, 90, STR_TOWN_BUILDING_NAME_CHURCH_1, 230, 2, 2, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 5, 90, STR_TOWN_BUILDING_NAME_CHURCH_1, 230, 2, 2, 0, 0, BUILDING_IS_CHURCH | TILE_SIZE_1x1, HZ_TEMP | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 03 - MS(1975, MAX_YEAR, 220, 160, STR_TOWN_BUILDING_NAME_LARGE_OFFICE_BLOCK_1, 160, 85, 10, 4, 6, + MS(1975, CalendarTime::MAX_YEAR, 220, 160, STR_TOWN_BUILDING_NAME_LARGE_OFFICE_BLOCK_1, 160, 85, 10, 4, 6, BUILDING_IS_ANIMATED | TILE_SIZE_1x1, HZ_TEMP | HZ_SUBARTC_BELOW | HZ_SUBTROPIC | HZ_ZON5, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 04 - MS(1975, MAX_YEAR, 220, 160, STR_TOWN_BUILDING_NAME_LARGE_OFFICE_BLOCK_1, 160, 85, 10, 4, 6, + MS(1975, CalendarTime::MAX_YEAR, 220, 160, STR_TOWN_BUILDING_NAME_LARGE_OFFICE_BLOCK_1, 160, 85, 10, 4, 6, BUILDING_IS_ANIMATED | TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON5, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 05 - MS( 0, MAX_YEAR, 30, 80, STR_TOWN_BUILDING_NAME_TOWN_HOUSES_1, 80, 12, 4, 1, 0, + MS( 0, CalendarTime::MAX_YEAR, 30, 80, STR_TOWN_BUILDING_NAME_TOWN_HOUSES_1, 80, 12, 4, 1, 0, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 06 - MS(1959, MAX_YEAR, 140, 180, STR_TOWN_BUILDING_NAME_HOTEL_1, 150, 22, 6, 1, 2, + MS(1959, CalendarTime::MAX_YEAR, 140, 180, STR_TOWN_BUILDING_NAME_HOTEL_1, 150, 22, 6, 1, 2, TILE_SIZE_1x2, HZ_TEMP | HZ_ZON5 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 07 - MS(1959, MAX_YEAR, 0, 180, STR_TOWN_BUILDING_NAME_HOTEL_1, 150, 22, 6, 1, 2, + MS(1959, CalendarTime::MAX_YEAR, 0, 180, STR_TOWN_BUILDING_NAME_HOTEL_1, 150, 22, 6, 1, 2, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 08 - MS(1945, MAX_YEAR, 0, 65, STR_TOWN_BUILDING_NAME_STATUE_1, 40, 0, 2, 0, 0, + MS(1945, CalendarTime::MAX_YEAR, 0, 65, STR_TOWN_BUILDING_NAME_STATUE_1, 40, 0, 2, 0, 0, TILE_SIZE_1x1, HZ_TEMP | HZ_SUBARTC_BELOW | HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 09 - MS(1945, MAX_YEAR, 0, 65, STR_TOWN_BUILDING_NAME_FOUNTAIN_1, 40, 0, 2, 0, 0, + MS(1945, CalendarTime::MAX_YEAR, 0, 65, STR_TOWN_BUILDING_NAME_FOUNTAIN_1, 40, 0, 2, 0, 0, TILE_SIZE_1x1, HZ_TEMP | HZ_SUBARTC_BELOW | HZ_SUBTROPIC | HZ_ZON5, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 0A - MS( 0, MAX_YEAR, 0, 60, STR_TOWN_BUILDING_NAME_PARK_1, 75, 0, 2, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 0, 60, STR_TOWN_BUILDING_NAME_PARK_1, 75, 0, 2, 0, 0, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 0B - MS(1935, MAX_YEAR, 0, 60, STR_TOWN_BUILDING_NAME_PARK_1, 75, 0, 2, 0, 0, + MS(1935, CalendarTime::MAX_YEAR, 0, 60, STR_TOWN_BUILDING_NAME_PARK_1, 75, 0, 2, 0, 0, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 0C - MS(1951, MAX_YEAR, 150, 130, STR_TOWN_BUILDING_NAME_OFFICE_BLOCK_2, 110, 65, 8, 2, 4, + MS(1951, CalendarTime::MAX_YEAR, 150, 130, STR_TOWN_BUILDING_NAME_OFFICE_BLOCK_2, 110, 65, 8, 2, 4, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 0D @@ -1900,31 +1900,31 @@ static const HouseSpec _original_house_specs[] = { TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 10 - MS(1977, MAX_YEAR, 130, 200, STR_TOWN_BUILDING_NAME_MODERN_OFFICE_BUILDING_1, 150, 50, 10, 3, 6, + MS(1977, CalendarTime::MAX_YEAR, 130, 200, STR_TOWN_BUILDING_NAME_MODERN_OFFICE_BUILDING_1, 150, 50, 10, 3, 6, TILE_SIZE_1x1, HZ_TEMP | HZ_SUBARTC_BELOW | HZ_SUBTROPIC | HZ_ZON5, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 11 - MS(1983, MAX_YEAR, 6, 145, STR_TOWN_BUILDING_NAME_WAREHOUSE_1, 110, 10, 6, 3, 8, + MS(1983, CalendarTime::MAX_YEAR, 6, 145, STR_TOWN_BUILDING_NAME_WAREHOUSE_1, 110, 10, 6, 3, 8, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 12 - MS(1985, MAX_YEAR, 110, 155, STR_TOWN_BUILDING_NAME_OFFICE_BLOCK_3, 110, 55, 6, 2, 6, + MS(1985, CalendarTime::MAX_YEAR, 110, 155, STR_TOWN_BUILDING_NAME_OFFICE_BLOCK_3, 110, 55, 6, 2, 6, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 13 - MS( 0, MAX_YEAR, 65, 250, STR_TOWN_BUILDING_NAME_STADIUM_1, 300, 5, 4, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 65, 250, STR_TOWN_BUILDING_NAME_STADIUM_1, 300, 5, 4, 0, 0, BUILDING_IS_STADIUM | TILE_SIZE_2x2, HZ_TEMP | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 14 - MS( 0, MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_1, 300, 5, 4, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_1, 300, 5, 4, 0, 0, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 15 - MS( 0, MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_1, 300, 5, 4, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_1, 300, 5, 4, 0, 0, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 16 - MS( 0, MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_1, 300, 5, 4, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_1, 300, 5, 4, 0, 0, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 17 @@ -1936,15 +1936,15 @@ static const HouseSpec _original_house_specs[] = { TILE_SIZE_1x1, HZ_TEMP | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 19 - MS(1931, MAX_YEAR, 13, 71, STR_TOWN_BUILDING_NAME_HOUSES_1, 75, 8, 3, 1, 0, + MS(1931, CalendarTime::MAX_YEAR, 13, 71, STR_TOWN_BUILDING_NAME_HOUSES_1, 75, 8, 3, 1, 0, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 1A - MS(1935, MAX_YEAR, 100, 135, STR_TOWN_BUILDING_NAME_FLATS_1, 100, 35, 7, 2, 2, + MS(1935, CalendarTime::MAX_YEAR, 100, 135, STR_TOWN_BUILDING_NAME_FLATS_1, 100, 35, 7, 2, 2, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 1B - MS(1963, MAX_YEAR, 170, 145, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_2, 170, 50, 8, 3, 3, + MS(1963, CalendarTime::MAX_YEAR, 170, 145, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_2, 170, 50, 8, 3, 3, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 1C @@ -1952,31 +1952,31 @@ static const HouseSpec _original_house_specs[] = { TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 1D - MS(1973, MAX_YEAR, 180, 155, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_3, 180, 64, 8, 3, 3, + MS(1973, CalendarTime::MAX_YEAR, 180, 155, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_3, 180, 64, 8, 3, 3, TILE_SIZE_1x1, HZ_TEMP | HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 1E - MS( 0, MAX_YEAR, 35, 220, STR_TOWN_BUILDING_NAME_THEATER_1, 230, 23, 8, 2, 2, + MS( 0, CalendarTime::MAX_YEAR, 35, 220, STR_TOWN_BUILDING_NAME_THEATER_1, 230, 23, 8, 2, 2, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 1F - MS(1958, MAX_YEAR, 65, 250, STR_TOWN_BUILDING_NAME_STADIUM_2, 300, 5, 4, 0, 0, + MS(1958, CalendarTime::MAX_YEAR, 65, 250, STR_TOWN_BUILDING_NAME_STADIUM_2, 300, 5, 4, 0, 0, BUILDING_IS_STADIUM | TILE_SIZE_2x2, HZ_TEMP | HZ_SUBARTC_BELOW | HZ_SUBTROPIC | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 20 - MS(1958, MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_2, 300, 5, 4, 0, 0, + MS(1958, CalendarTime::MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_2, 300, 5, 4, 0, 0, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 21 - MS(1958, MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_2, 300, 5, 4, 0, 0, + MS(1958, CalendarTime::MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_2, 300, 5, 4, 0, 0, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 22 - MS(1958, MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_2, 300, 5, 4, 0, 0, + MS(1958, CalendarTime::MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_STADIUM_2, 300, 5, 4, 0, 0, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 23 - MS(2000, MAX_YEAR, 140, 170, STR_TOWN_BUILDING_NAME_OFFICES_1, 250, 65, 8, 3, 2, + MS(2000, CalendarTime::MAX_YEAR, 140, 170, STR_TOWN_BUILDING_NAME_OFFICES_1, 250, 65, 8, 3, 2, TILE_SIZE_1x1, HZ_TEMP | HZ_SUBARTC_BELOW | HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 24 @@ -1988,39 +1988,39 @@ static const HouseSpec _original_house_specs[] = { TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 26 - MS(1945, MAX_YEAR, 35, 210, STR_TOWN_BUILDING_NAME_CINEMA_1, 230, 23, 8, 2, 2, + MS(1945, CalendarTime::MAX_YEAR, 35, 210, STR_TOWN_BUILDING_NAME_CINEMA_1, 230, 23, 8, 2, 2, TILE_SIZE_1x1, HZ_TEMP | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 27 - MS(1983, MAX_YEAR, 180, 250, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1, 300, 5, 8, 2, 3, + MS(1983, CalendarTime::MAX_YEAR, 180, 250, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1, 300, 5, 8, 2, 3, TILE_SIZE_2x2, HZ_TEMP | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 |HZ_ZON2, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 28 - MS(1983, MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1, 300, 5, 8, 2, 3, + MS(1983, CalendarTime::MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1, 300, 5, 8, 2, 3, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 29 - MS(1983, MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1, 300, 5, 8, 2, 3, + MS(1983, CalendarTime::MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1, 300, 5, 8, 2, 3, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 2A - MS(1983, MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1, 300, 5, 8, 2, 3, + MS(1983, CalendarTime::MAX_YEAR, 0, 250, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1, 300, 5, 8, 2, 3, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 2B - MS( 0, MAX_YEAR, 80, 100, STR_TOWN_BUILDING_NAME_FLATS_1, 90, 20, 5, 2, 2, + MS( 0, CalendarTime::MAX_YEAR, 80, 100, STR_TOWN_BUILDING_NAME_FLATS_1, 90, 20, 5, 2, 2, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 2C - MS( 0, MAX_YEAR, 80, 100, STR_TOWN_BUILDING_NAME_FLATS_1, 90, 20, 5, 2, 2, + MS( 0, CalendarTime::MAX_YEAR, 80, 100, STR_TOWN_BUILDING_NAME_FLATS_1, 90, 20, 5, 2, 2, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 2D - MS( 0, MAX_YEAR, 16, 70, STR_TOWN_BUILDING_NAME_HOUSES_2, 70, 6, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 16, 70, STR_TOWN_BUILDING_NAME_HOUSES_2, 70, 6, 3, 1, 2, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 2E - MS( 0, MAX_YEAR, 16, 70, STR_TOWN_BUILDING_NAME_HOUSES_2, 70, 6, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 16, 70, STR_TOWN_BUILDING_NAME_HOUSES_2, 70, 6, 3, 1, 2, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 2F @@ -2032,59 +2032,59 @@ static const HouseSpec _original_house_specs[] = { TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 31 - MS(1966, MAX_YEAR, 135, 150, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 120, 60, 8, 3, 4, + MS(1966, CalendarTime::MAX_YEAR, 135, 150, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 120, 60, 8, 3, 4, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 32 - MS(1966, MAX_YEAR, 135, 150, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 120, 60, 8, 3, 4, + MS(1966, CalendarTime::MAX_YEAR, 135, 150, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 120, 60, 8, 3, 4, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 33 - MS(1970, MAX_YEAR, 170, 170, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 70, 9, 3, 4, + MS(1970, CalendarTime::MAX_YEAR, 170, 170, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 70, 9, 3, 4, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 34 - MS(1970, MAX_YEAR, 170, 170, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 70, 9, 3, 4, + MS(1970, CalendarTime::MAX_YEAR, 170, 170, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 70, 9, 3, 4, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 35 - MS(1974, MAX_YEAR, 210, 200, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 80, 10, 3, 5, + MS(1974, CalendarTime::MAX_YEAR, 210, 200, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 80, 10, 3, 5, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 36 - MS(1974, MAX_YEAR, 210, 200, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 80, 10, 3, 5, + MS(1974, CalendarTime::MAX_YEAR, 210, 200, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 80, 10, 3, 5, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 37 - MS( 0, MAX_YEAR, 10, 60, STR_TOWN_BUILDING_NAME_HOUSES_2, 60, 5, 2, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 10, 60, STR_TOWN_BUILDING_NAME_HOUSES_2, 60, 5, 2, 1, 1, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 38 - MS( 0, MAX_YEAR, 10, 60, STR_TOWN_BUILDING_NAME_HOUSES_2, 60, 5, 2, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 10, 60, STR_TOWN_BUILDING_NAME_HOUSES_2, 60, 5, 2, 1, 1, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 39 - MS( 0, MAX_YEAR, 25, 100, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 80, 20, 3, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 25, 100, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 80, 20, 3, 1, 1, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 3A - MS( 0, MAX_YEAR, 25, 100, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 80, 20, 3, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 25, 100, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 80, 20, 3, 1, 1, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 3B - MS( 0, MAX_YEAR, 6, 85, STR_TOWN_BUILDING_NAME_CHURCH_1, 230, 2, 2, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 6, 85, STR_TOWN_BUILDING_NAME_CHURCH_1, 230, 2, 2, 0, 0, BUILDING_IS_CHURCH | TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 3C - MS( 0, MAX_YEAR, 6, 85, STR_TOWN_BUILDING_NAME_CHURCH_1, 230, 2, 2, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 6, 85, STR_TOWN_BUILDING_NAME_CHURCH_1, 230, 2, 2, 0, 0, BUILDING_IS_CHURCH | TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 3D - MS( 0, MAX_YEAR, 17, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 7, 3, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 17, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 7, 3, 1, 1, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 3E - MS( 0, MAX_YEAR, 17, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 7, 3, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 17, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 7, 3, 1, 1, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 3F @@ -2096,179 +2096,179 @@ static const HouseSpec _original_house_specs[] = { TILE_SIZE_1x1, HZ_SUBARTC_ABOVE| HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 41 - MS(1972, MAX_YEAR, 140, 160, STR_TOWN_BUILDING_NAME_HOTEL_1, 160, 25, 6, 1, 3, + MS(1972, CalendarTime::MAX_YEAR, 140, 160, STR_TOWN_BUILDING_NAME_HOTEL_1, 160, 25, 6, 1, 3, TILE_SIZE_1x2, HZ_SUBARTC_BELOW| HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 42 - MS(1972, MAX_YEAR, 0, 160, STR_TOWN_BUILDING_NAME_HOTEL_1, 160, 25, 6, 1, 2, + MS(1972, CalendarTime::MAX_YEAR, 0, 160, STR_TOWN_BUILDING_NAME_HOTEL_1, 160, 25, 6, 1, 2, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 43 - MS(1972, MAX_YEAR, 140, 160, STR_TOWN_BUILDING_NAME_HOTEL_1, 160, 25, 6, 1, 3, + MS(1972, CalendarTime::MAX_YEAR, 140, 160, STR_TOWN_BUILDING_NAME_HOTEL_1, 160, 25, 6, 1, 3, TILE_SIZE_1x2, HZ_SUBARTC_ABOVE| HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 44 - MS(1972, MAX_YEAR, 0, 160, STR_TOWN_BUILDING_NAME_HOTEL_1, 160, 25, 6, 1, 2, + MS(1972, CalendarTime::MAX_YEAR, 0, 160, STR_TOWN_BUILDING_NAME_HOTEL_1, 160, 25, 6, 1, 2, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 45 - MS(1963, MAX_YEAR, 105, 130, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 105, 50, 7, 2, 3, + MS(1963, CalendarTime::MAX_YEAR, 105, 130, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 105, 50, 7, 2, 3, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 46 - MS(1963, MAX_YEAR, 105, 130, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 105, 50, 7, 2, 3, + MS(1963, CalendarTime::MAX_YEAR, 105, 130, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 105, 50, 7, 2, 3, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE| HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 47 - MS(1978, MAX_YEAR, 190, 190, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 135, 75, 9, 3, 4, + MS(1978, CalendarTime::MAX_YEAR, 190, 190, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 135, 75, 9, 3, 4, TILE_SIZE_1x1, HZ_SUBARTC_BELOW | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 48 - MS(1978, MAX_YEAR, 190, 190, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 135, 75, 9, 3, 4, + MS(1978, CalendarTime::MAX_YEAR, 190, 190, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 135, 75, 9, 3, 4, TILE_SIZE_1x1, HZ_SUBARTC_ABOVE | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 49 - MS(1967, MAX_YEAR, 250, 140, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 200, 60, 7, 2, 2, + MS(1967, CalendarTime::MAX_YEAR, 250, 140, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 200, 60, 7, 2, 2, TILE_SIZE_2x1, HZ_SUBARTC_BELOW| HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 4A - MS(1967, MAX_YEAR, 0, 140, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 200, 60, 7, 2, 2, + MS(1967, CalendarTime::MAX_YEAR, 0, 140, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 200, 60, 7, 2, 2, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 4B - MS(1967, MAX_YEAR, 250, 140, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 200, 60, 7, 2, 2, + MS(1967, CalendarTime::MAX_YEAR, 250, 140, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 200, 60, 7, 2, 2, TILE_SIZE_2x1, HZ_SUBARTC_ABOVE | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 4C - MS(1967, MAX_YEAR, 0, 140, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 200, 60, 7, 2, 2, + MS(1967, CalendarTime::MAX_YEAR, 0, 140, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 200, 60, 7, 2, 2, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 4D - MS( 0, MAX_YEAR, 16, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 6, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 16, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 6, 3, 1, 2, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 4E - MS( 0, MAX_YEAR, 16, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 6, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 16, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 6, 3, 1, 2, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 4F - MS( 0, MAX_YEAR, 16, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 5, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 16, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 5, 3, 1, 2, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 50 - MS( 0, MAX_YEAR, 7, 30, STR_TOWN_BUILDING_NAME_HOUSES_2, 30, 4, 3, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 7, 30, STR_TOWN_BUILDING_NAME_HOUSES_2, 30, 4, 3, 1, 1, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 51 - MS( 0, MAX_YEAR, 45, 130, STR_TOWN_BUILDING_NAME_FLATS_1, 95, 15, 6, 2, 1, + MS( 0, CalendarTime::MAX_YEAR, 45, 130, STR_TOWN_BUILDING_NAME_FLATS_1, 95, 15, 6, 2, 1, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 52 - MS( 0, MAX_YEAR, 8, 90, STR_TOWN_BUILDING_NAME_CHURCH_1, 200, 3, 2, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 8, 90, STR_TOWN_BUILDING_NAME_CHURCH_1, 200, 3, 2, 0, 0, BUILDING_IS_CHURCH | TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON4 | HZ_ZON3 | HZ_ZON2, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 53 - MS( 0, MAX_YEAR, 18, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 7, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 18, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 7, 3, 1, 2, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2, CT_PASSENGERS, CT_MAIL, CT_FOOD), // 54 - MS(1973, MAX_YEAR, 90, 110, STR_TOWN_BUILDING_NAME_FLATS_1, 95, 24, 6, 2, 1, + MS(1973, CalendarTime::MAX_YEAR, 90, 110, STR_TOWN_BUILDING_NAME_FLATS_1, 95, 24, 6, 2, 1, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 55 - MS(1962, MAX_YEAR, 120, 120, STR_TOWN_BUILDING_NAME_FLATS_1, 95, 25, 6, 2, 1, + MS(1962, CalendarTime::MAX_YEAR, 120, 120, STR_TOWN_BUILDING_NAME_FLATS_1, 95, 25, 6, 2, 1, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 56 - MS(1984, MAX_YEAR, 250, 190, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 80, 8, 3, 4, + MS(1984, CalendarTime::MAX_YEAR, 250, 190, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 80, 8, 3, 4, TILE_SIZE_2x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 57 - MS(1984, MAX_YEAR, 0, 190, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 80, 8, 3, 4, + MS(1984, CalendarTime::MAX_YEAR, 0, 190, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 140, 80, 8, 3, 4, TILE_NO_FLAG, HZ_SUBTROPIC, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 58 - MS( 0, MAX_YEAR, 80, 110, STR_TOWN_BUILDING_NAME_FLATS_1, 95, 23, 6, 2, 1, + MS( 0, CalendarTime::MAX_YEAR, 80, 110, STR_TOWN_BUILDING_NAME_FLATS_1, 95, 23, 6, 2, 1, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 59 - MS(1993, MAX_YEAR, 180, 180, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 150, 90, 8, 3, 4, + MS(1993, CalendarTime::MAX_YEAR, 180, 180, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 150, 90, 8, 3, 4, TILE_SIZE_1x1, HZ_SUBTROPIC | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_GOODS), // 5A - MS( 0, MAX_YEAR, 8, 90, STR_TOWN_BUILDING_NAME_CHURCH_1, 200, 3, 2, 0, 0, + MS( 0, CalendarTime::MAX_YEAR, 8, 90, STR_TOWN_BUILDING_NAME_CHURCH_1, 200, 3, 2, 0, 0, BUILDING_IS_CHURCH | TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 5B - MS( 0, MAX_YEAR, 18, 90, STR_TOWN_BUILDING_NAME_HOUSES_2, 90, 5, 6, 2, 2, + MS( 0, CalendarTime::MAX_YEAR, 18, 90, STR_TOWN_BUILDING_NAME_HOUSES_2, 90, 5, 6, 2, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 5C - MS( 0, MAX_YEAR, 7, 70, STR_TOWN_BUILDING_NAME_HOUSES_2, 50, 3, 3, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 7, 70, STR_TOWN_BUILDING_NAME_HOUSES_2, 50, 3, 3, 1, 1, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 5D - MS( 0, MAX_YEAR, 15, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 75, 6, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 15, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 75, 6, 3, 1, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 5E - MS( 0, MAX_YEAR, 17, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 75, 6, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 17, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 75, 6, 3, 1, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 5F - MS( 0, MAX_YEAR, 19, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 75, 6, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 19, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 75, 6, 3, 1, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 60 - MS( 0, MAX_YEAR, 21, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 75, 6, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 21, 80, STR_TOWN_BUILDING_NAME_HOUSES_2, 75, 6, 3, 1, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 61 - MS( 0, MAX_YEAR, 75, 160, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 20, 8, 4, 2, + MS( 0, CalendarTime::MAX_YEAR, 75, 160, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 20, 8, 4, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 62 - MS( 0, MAX_YEAR, 35, 90, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 9, 4, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 35, 90, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 9, 4, 1, 2, TILE_SIZE_1x2, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 63 - MS( 0, MAX_YEAR, 0, 90, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 0, 4, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 0, 90, STR_TOWN_BUILDING_NAME_HOUSES_2, 80, 0, 4, 1, 2, TILE_NO_FLAG, HZ_NOZNS, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 64 - MS( 0, MAX_YEAR, 85, 150, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 18, 8, 4, 2, + MS( 0, CalendarTime::MAX_YEAR, 85, 150, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 18, 8, 4, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 65 - MS( 0, MAX_YEAR, 11, 60, STR_TOWN_BUILDING_NAME_IGLOO_1, 45, 3, 3, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 11, 60, STR_TOWN_BUILDING_NAME_IGLOO_1, 45, 3, 3, 1, 1, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 66 - MS( 0, MAX_YEAR, 10, 60, STR_TOWN_BUILDING_NAME_TEPEES_1, 45, 3, 3, 1, 1, + MS( 0, CalendarTime::MAX_YEAR, 10, 60, STR_TOWN_BUILDING_NAME_TEPEES_1, 45, 3, 3, 1, 1, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 67 - MS( 0, MAX_YEAR, 67, 140, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 130, 22, 8, 4, 4, + MS( 0, CalendarTime::MAX_YEAR, 67, 140, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 130, 22, 8, 4, 4, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_FIZZY_DRINKS), // 68 - MS( 0, MAX_YEAR, 86, 145, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 130, 23, 8, 4, 4, + MS( 0, CalendarTime::MAX_YEAR, 86, 145, STR_TOWN_BUILDING_NAME_SHOPS_AND_OFFICES_1, 130, 23, 8, 4, 4, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_FIZZY_DRINKS), // 69 - MS( 0, MAX_YEAR, 95, 165, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 28, 8, 4, 2, + MS( 0, CalendarTime::MAX_YEAR, 95, 165, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, 130, 28, 8, 4, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 6A - MS( 0, MAX_YEAR, 30, 90, STR_TOWN_BUILDING_NAME_STATUE_1, 70, 10, 4, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 30, 90, STR_TOWN_BUILDING_NAME_STATUE_1, 70, 10, 4, 1, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 6B - MS( 0, MAX_YEAR, 25, 75, STR_TOWN_BUILDING_NAME_TEAPOT_HOUSE_1, 65, 8, 3, 1, 2, + MS( 0, CalendarTime::MAX_YEAR, 25, 75, STR_TOWN_BUILDING_NAME_TEAPOT_HOUSE_1, 65, 8, 3, 1, 2, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_CANDY), // 6C - MS( 0, MAX_YEAR, 18, 85, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1, 95, 7, 3, 2, 4, + MS( 0, CalendarTime::MAX_YEAR, 18, 85, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1, 95, 7, 3, 2, 4, TILE_SIZE_1x1, HZ_TOYLND | HZ_ZON5 | HZ_ZON4 | HZ_ZON3 | HZ_ZON2 | HZ_ZON1, CT_PASSENGERS, CT_MAIL, CT_FIZZY_DRINKS), // 6D diff --git a/src/timer/timer_game_calendar.cpp b/src/timer/timer_game_calendar.cpp index 60cb8ea454..7e3a47e0c4 100644 --- a/src/timer/timer_game_calendar.cpp +++ b/src/timer/timer_game_calendar.cpp @@ -68,42 +68,42 @@ static const uint16_t _accum_days_for_month[] = { * @param date the date to convert from * @param ymd the year, month and day to write to */ -/* static */ void TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::Date date, YearMonthDay *ymd) +/* static */ void TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::Date date, TimerGameCalendar::YearMonthDay *ymd) { /* Year determination in multiple steps to account for leap * years. First do the large steps, then the smaller ones. */ /* There are 97 leap years in 400 years */ - TimerGameCalendar::Year yr = 400 * (static_cast(date) / (DAYS_IN_YEAR * 400 + 97)); - int rem = static_cast(date) % (DAYS_IN_YEAR * 400 + 97); + TimerGameCalendar::Year yr = 400 * (static_cast(date) / (CalendarTime::DAYS_IN_YEAR * 400 + 97)); + int rem = static_cast(date) % (CalendarTime::DAYS_IN_YEAR * 400 + 97); uint16_t x; - if (rem >= DAYS_IN_YEAR * 100 + 25) { + if (rem >= CalendarTime::DAYS_IN_YEAR * 100 + 25) { /* There are 25 leap years in the first 100 years after * every 400th year, as every 400th year is a leap year */ yr += 100; - rem -= DAYS_IN_YEAR * 100 + 25; + rem -= CalendarTime::DAYS_IN_YEAR * 100 + 25; /* There are 24 leap years in the next couple of 100 years */ - yr += 100 * (rem / (DAYS_IN_YEAR * 100 + 24)); - rem = (rem % (DAYS_IN_YEAR * 100 + 24)); + yr += 100 * (rem / (CalendarTime::DAYS_IN_YEAR * 100 + 24)); + rem = (rem % (CalendarTime::DAYS_IN_YEAR * 100 + 24)); } - if (!TimerGameCalendar::IsLeapYear(yr) && rem >= DAYS_IN_YEAR * 4) { + if (!TimerGameCalendar::IsLeapYear(yr) && rem >= CalendarTime::DAYS_IN_YEAR * 4) { /* The first 4 year of the century are not always a leap year */ yr += 4; - rem -= DAYS_IN_YEAR * 4; + rem -= CalendarTime::DAYS_IN_YEAR * 4; } /* There is 1 leap year every 4 years */ - yr += 4 * (rem / (DAYS_IN_YEAR * 4 + 1)); - rem = rem % (DAYS_IN_YEAR * 4 + 1); + yr += 4 * (rem / (CalendarTime::DAYS_IN_YEAR * 4 + 1)); + rem = rem % (CalendarTime::DAYS_IN_YEAR * 4 + 1); /* The last (max 3) years to account for; the first one * can be, but is not necessarily a leap year */ - while (rem >= (TimerGameCalendar::IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR)) { - rem -= TimerGameCalendar::IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; + while (rem >= (TimerGameCalendar::IsLeapYear(yr) ? CalendarTime::DAYS_IN_LEAP_YEAR : CalendarTime::DAYS_IN_YEAR)) { + rem -= TimerGameCalendar::IsLeapYear(yr) ? CalendarTime::DAYS_IN_LEAP_YEAR : CalendarTime::DAYS_IN_YEAR; yr++; } @@ -131,7 +131,7 @@ static const uint16_t _accum_days_for_month[] = { /* Account for the missing of the 29th of February in non-leap years */ if (!TimerGameCalendar::IsLeapYear(year) && days >= ACCUM_MAR) days--; - return DateAtStartOfYear(year) + days; + return TimerGameCalendar::DateAtStartOfYear(year) + days; } /** @@ -153,7 +153,7 @@ static const uint16_t _accum_days_for_month[] = { { assert(fract < Ticks::DAY_TICKS); - YearMonthDay ymd; + TimerGameCalendar::YearMonthDay ymd; TimerGameCalendar::date = date; TimerGameCalendar::date_fract = fract; @@ -240,11 +240,11 @@ void TimerManager::Elapsed(TimerGameCalendar::TElapsed delta) } /* check if we reached the maximum year, decrement dates by a year */ - if (TimerGameCalendar::year == MAX_YEAR + 1) { + if (TimerGameCalendar::year == CalendarTime::MAX_YEAR + 1) { int days_this_year; TimerGameCalendar::year--; - days_this_year = TimerGameCalendar::IsLeapYear(TimerGameCalendar::year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; + days_this_year = TimerGameCalendar::IsLeapYear(TimerGameCalendar::year) ? CalendarTime::DAYS_IN_LEAP_YEAR : CalendarTime::DAYS_IN_YEAR; TimerGameCalendar::date -= days_this_year; for (Vehicle *v : Vehicle::Iterate()) v->ShiftDates(-days_this_year); for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year); diff --git a/src/timer/timer_game_calendar.h b/src/timer/timer_game_calendar.h index de8c78a8ec..d28190d356 100644 --- a/src/timer/timer_game_calendar.h +++ b/src/timer/timer_game_calendar.h @@ -33,6 +33,29 @@ */ class TimerGameCalendar { public: + /** The type to store our dates in. */ + using Date = StrongType::Typedef; + + /** The fraction of a date we're in, i.e. the number of ticks since the last date changeover. */ + using DateFract = uint16_t; + + /** Type for the year, note: 0 based, i.e. starts at the year 0. */ + using Year = StrongType::Typedef; + /** Type for the month, note: 0 based, i.e. 0 = January, 11 = December. */ + using Month = uint8_t; + /** Type for the day of the month, note: 1 based, first day of a month is 1. */ + using Day = uint8_t; + + /** + * Data structure to convert between Date and triplet (year, month, and day). + * @see TimerGameCalendar::ConvertDateToYMD(), TimerGameCalendar::ConvertYMDToDate() + */ + struct YearMonthDay { + Year year; ///< Year (0...) + Month month; ///< Month (0..11) + Day day; ///< Day (1..31) + }; + enum Trigger { DAY, WEEK, @@ -77,33 +100,35 @@ public: struct TStorage { }; - /** The type to store our dates in. */ - using Date = StrongType::Typedef; - - /** The fraction of a date we're in, i.e. the number of ticks since the last date changeover. */ - using DateFract = uint16_t; - - /** Type for the year, note: 0 based, i.e. starts at the year 0. */ - using Year = StrongType::Typedef; - /** Type for the month, note: 0 based, i.e. 0 = January, 11 = December. */ - using Month = uint8_t; - /** Type for the day of the month, note: 1 based, first day of a month is 1. */ - using Day = uint8_t; + static bool IsLeapYear(Year yr); + static void ConvertDateToYMD(Date date, YearMonthDay * ymd); + static Date ConvertYMDToDate(Year year, Month month, Day day); + static void SetDate(Date date, DateFract fract); /** - * Data structure to convert between Date and triplet (year, month, and day). - * @see TimerGameCalendar::ConvertDateToYMD(), TimerGameCalendar::ConvertYMDToDate() - */ - struct YearMonthDay { - Year year; ///< Year (0...) - Month month; ///< Month (0..11) - Day day; ///< Day (1..31) - }; + * Calculate the year of a given date. + * @param date The date to consider. + * @return the year. + */ + static constexpr Year DateToYear(Date date) + { + /* Hardcode the number of days in a year because we can't access CalendarTime from here. */ + return static_cast(date) / 366; + } - static bool IsLeapYear(TimerGameCalendar::Year yr); - static void ConvertDateToYMD(TimerGameCalendar::Date date, YearMonthDay *ymd); - static TimerGameCalendar::Date ConvertYMDToDate(TimerGameCalendar::Year year, TimerGameCalendar::Month month, TimerGameCalendar::Day day); - static void SetDate(TimerGameCalendar::Date date, TimerGameCalendar::DateFract fract); + /** + * Calculate the date of the first day of a given year. + * @param year the year to get the first day of. + * @return the date. + */ + static constexpr Date DateAtStartOfYear(Year year) + { + int32_t year_as_int = static_cast(year); + uint number_of_leap_years = (year == 0) ? 0 : ((year_as_int - 1) / 4 - (year_as_int - 1) / 100 + (year_as_int - 1) / 400 + 1); + + /* Hardcode the number of days in a year because we can't access CalendarTime from here. */ + return (365 * year_as_int) + number_of_leap_years; + } static Year year; ///< Current year, starting at 0. static Month month; ///< Current month (0..11). @@ -111,4 +136,53 @@ public: static DateFract date_fract; ///< Fractional part of the day. }; +/** + * Storage class for Calendar time constants. + */ +class CalendarTime { +public: + static constexpr int DAYS_IN_YEAR = 365; ///< days per year + static constexpr int DAYS_IN_LEAP_YEAR = 366; ///< sometimes, you need one day more... + static constexpr int MONTHS_IN_YEAR = 12; ///< months per year + + static constexpr int SECONDS_PER_DAY = 2; ///< approximate seconds per day, not for precise calculations + + /* + * ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are + * primarily used for loading newgrf and savegame data and returning some + * newgrf (callback) functions that were in the original (TTD) inherited + * format, where 'TimerGameCalendar::date == 0' meant that it was 1920-01-01. + */ + + /** The minimum starting year/base year of the original TTD */ + static constexpr TimerGameCalendar::Year ORIGINAL_BASE_YEAR = 1920; + /** The original ending year */ + static constexpr TimerGameCalendar::Year ORIGINAL_END_YEAR = 2051; + /** The maximum year of the original TTD */ + static constexpr TimerGameCalendar::Year ORIGINAL_MAX_YEAR = 2090; + + /** The absolute minimum & maximum years in OTTD */ + static constexpr TimerGameCalendar::Year MIN_YEAR = 0; + + /** The default starting year */ + static constexpr TimerGameCalendar::Year DEF_START_YEAR = 1950; + /** The default scoring end year */ + static constexpr TimerGameCalendar::Year DEF_END_YEAR = ORIGINAL_END_YEAR - 1; + + /** + * MAX_YEAR, nicely rounded value of the number of years that can + * be encoded in a single 32 bits date, about 2^31 / 366 years. + */ + static constexpr TimerGameCalendar::Year MAX_YEAR = 5000000; + + /** The date of the first day of the original base year. */ + static constexpr TimerGameCalendar::Date DAYS_TILL_ORIGINAL_BASE_YEAR = TimerGameCalendar::DateAtStartOfYear(ORIGINAL_BASE_YEAR); + + /** The date of the last day of the max year. */ + static constexpr TimerGameCalendar::Date MAX_DATE = TimerGameCalendar::DateAtStartOfYear(CalendarTime::MAX_YEAR + 1) - 1; + + static constexpr TimerGameCalendar::Year INVALID_YEAR = -1; ///< Representation of an invalid year + static constexpr TimerGameCalendar::Date INVALID_DATE = -1; ///< Representation of an invalid date +}; + #endif /* TIMER_GAME_CALENDAR_H */ diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index ee317458e9..8fe617ed70 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -304,11 +304,11 @@ CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool tim int total_duration = v->orders->GetTimetableTotalDuration(); /* Don't let a timetable start more than 15 years into the future or 1 year in the past. */ - if (start_date < 0 || start_date > MAX_DATE) return CMD_ERROR; - if (start_date - TimerGameCalendar::date > DateAtStartOfYear(MAX_TIMETABLE_START_YEARS)) return CMD_ERROR; - if (TimerGameCalendar::date - start_date > DAYS_IN_LEAP_YEAR) return CMD_ERROR; + if (start_date < 0 || start_date > CalendarTime::MAX_DATE) return CMD_ERROR; + if (start_date - TimerGameCalendar::date > TimerGameCalendar::DateAtStartOfYear(MAX_TIMETABLE_START_YEARS)) return CMD_ERROR; + if (TimerGameCalendar::date - start_date > CalendarTime::DAYS_IN_LEAP_YEAR) return CMD_ERROR; if (timetable_all && !v->orders->IsCompleteTimetable()) return CommandCost(STR_ERROR_TIMETABLE_INCOMPLETE); - if (timetable_all && start_date + total_duration / Ticks::DAY_TICKS > MAX_DATE) return CMD_ERROR; + if (timetable_all && start_date + total_duration / Ticks::DAY_TICKS > CalendarTime::MAX_DATE) return CMD_ERROR; if (flags & DC_EXEC) { std::vector vehs; @@ -494,7 +494,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) * check how many ticks the (fully filled) timetable has. If a timetable cycle is * shorter than the amount of ticks we are late we reduce the lateness by the * length of a full cycle till lateness is less than the length of a timetable - * cycle. When the timetable isn't fully filled the cycle will be Tick::INVALID_TICKS. */ + * cycle. When the timetable isn't fully filled the cycle will be Ticks::INVALID_TICKS. */ if (v->lateness_counter > (int)timetabled) { TimerGameTick::Ticks cycle = v->orders->GetTimetableTotalDuration(); if (cycle != Ticks::INVALID_TICKS && v->lateness_counter > cycle) { diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 8bd4db9a95..36d8bcb693 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -194,7 +194,7 @@ struct TimetableWindow : Window { { switch (widget) { case WID_VT_ARRIVAL_DEPARTURE_PANEL: - SetDParamMaxValue(1, DateAtStartOfYear(MAX_YEAR), 0, FS_SMALL); + SetDParamMaxValue(1, TimerGameCalendar::DateAtStartOfYear(CalendarTime::MAX_YEAR), 0, FS_SMALL); size->width = std::max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE).width) + WidgetDimensions::scaled.hsep_wide + padding.width; FALLTHROUGH; diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 91c2def043..0ec27b6d15 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -1148,7 +1148,7 @@ void ToggleDirtyBlocks() */ void SetStartingYear(TimerGameCalendar::Year year) { - _settings_game.game_creation.starting_year = Clamp(year, MIN_YEAR, MAX_YEAR); + _settings_game.game_creation.starting_year = Clamp(year, CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR); TimerGameCalendar::Date new_date = TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); /* If you open a savegame as scenario there may already be link graphs.*/ LinkGraphSchedule::instance.ShiftDates(new_date - TimerGameCalendar::date); @@ -2357,8 +2357,8 @@ struct ScenarioEditorToolbarWindow : Window { void OnPaint() override { - this->SetWidgetDisabledState(WID_TE_DATE_BACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR); - this->SetWidgetDisabledState(WID_TE_DATE_FORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR); + this->SetWidgetDisabledState(WID_TE_DATE_BACKWARD, _settings_game.game_creation.starting_year <= CalendarTime::MIN_YEAR); + this->SetWidgetDisabledState(WID_TE_DATE_FORWARD, _settings_game.game_creation.starting_year >= CalendarTime::MAX_YEAR); this->SetWidgetDisabledState(WID_TE_ROADS, (GetRoadTypes(true) & ~_roadtypes_type) == ROADTYPES_NONE); this->SetWidgetDisabledState(WID_TE_TRAMS, (GetRoadTypes(true) & _roadtypes_type) == ROADTYPES_NONE); @@ -2398,7 +2398,7 @@ struct ScenarioEditorToolbarWindow : Window { break; case WID_TE_DATE: - SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 0, 1)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(CalendarTime::MAX_YEAR, 0, 1)); *size = GetStringBoundingBox(STR_JUST_DATE_LONG); break; } @@ -2512,7 +2512,7 @@ struct ScenarioEditorToolbarWindow : Window { value = atoi(str); } else { /* An empty string means revert to the default */ - value = static_cast(DEF_START_YEAR); + value = static_cast(CalendarTime::DEF_START_YEAR); } SetStartingYear(value); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 16e5338ba6..01b4f46652 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -871,7 +871,7 @@ RoadType GetTownRoadType(const Town *t) if (!HasBit(rti->flags, ROTF_TOWN_BUILD)) continue; /* Not yet introduced at this date. */ - if (IsInsideMM(rti->introduction_date, 0, static_cast(MAX_DATE)) && rti->introduction_date > TimerGameCalendar::date) continue; + if (IsInsideMM(rti->introduction_date, 0, static_cast(CalendarTime::MAX_DATE)) && rti->introduction_date > TimerGameCalendar::date) continue; if (best != nullptr) { if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 7b7961bf2c..472f462938 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -4179,7 +4179,7 @@ void Train::OnNewDay() if (this->running_ticks != 0) { /* running costs */ - CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS)); + CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (CalendarTime::DAYS_IN_YEAR * Ticks::DAY_TICKS)); this->profit_this_year -= cost.GetCost(); this->running_ticks = 0; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index c07f4431f3..270d3c655b 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1369,7 +1369,7 @@ bool Vehicle::HandleBreakdown() */ void AgeVehicle(Vehicle *v) { - if (v->age < MAX_DATE) { + if (v->age < CalendarTime::MAX_DATE) { v->age++; if (v->IsPrimaryVehicle() && v->age == VEHICLE_PROFIT_MIN_AGE + 1) GroupStatistics::VehicleReachedMinAge(v); } @@ -1378,7 +1378,7 @@ void AgeVehicle(Vehicle *v) auto age = v->age - v->max_age; for (int32_t i = 0; i <= 4; i++) { - if (age == DateAtStartOfYear(i)) { + if (age == TimerGameCalendar::DateAtStartOfYear(i)) { v->reliability_spd_dec <<= 1; break; } @@ -1396,11 +1396,11 @@ void AgeVehicle(Vehicle *v) if (EngineHasReplacementForCompany(c, v->engine_type, v->group_id)) return; StringID str; - if (age == DateAtStartOfYear(-1)) { + if (age == TimerGameCalendar::DateAtStartOfYear(-1)) { str = STR_NEWS_VEHICLE_IS_GETTING_OLD; - } else if (age == DateAtStartOfYear(0)) { + } else if (age == TimerGameCalendar::DateAtStartOfYear(0)) { str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD; - } else if (age > DateAtStartOfYear(0) && (static_cast(age) % DAYS_IN_LEAP_YEAR) == 0) { + } else if (age > TimerGameCalendar::DateAtStartOfYear(0) && (static_cast(age) % CalendarTime::DAYS_IN_LEAP_YEAR) == 0) { str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND; } else { return; diff --git a/src/vehicle_func.h b/src/vehicle_func.h index e0c7b37956..da225d844b 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -25,7 +25,7 @@ #define IS_CUSTOM_FIRSTHEAD_SPRITE(x) (x == 0xFD) #define IS_CUSTOM_SECONDHEAD_SPRITE(x) (x == 0xFE) -static const int VEHICLE_PROFIT_MIN_AGE = DAYS_IN_YEAR * 2; ///< Only vehicles older than this have a meaningful profit. +static const int VEHICLE_PROFIT_MIN_AGE = CalendarTime::DAYS_IN_YEAR * 2; ///< Only vehicles older than this have a meaningful profit. static const Money VEHICLE_PROFIT_THRESHOLD = 10000; ///< Threshold for a vehicle to be considered making good profit. /** diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 173338b21f..bc54b53a9f 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1733,7 +1733,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int if (v->IsChainInDepot()) { tc = TC_BLUE; } else { - tc = (v->age > v->max_age - DAYS_IN_LEAP_YEAR) ? TC_RED : TC_BLACK; + tc = (v->age > v->max_age - CalendarTime::DAYS_IN_LEAP_YEAR) ? TC_RED : TC_BLACK; } SetDParam(0, v->unitnumber); @@ -2438,7 +2438,7 @@ struct VehicleDetailsWindow : Window { case WID_VD_SERVICING_INTERVAL: SetDParamMaxValue(0, MAX_SERVINT_DAYS); // Roughly the maximum interval - SetDParamMaxValue(1, DateAtStartOfYear(MAX_YEAR)); // Roughly the maximum year + SetDParamMaxValue(1, TimerGameCalendar::DateAtStartOfYear(CalendarTime::MAX_YEAR)); // Roughly the maximum year size->width = std::max( GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT).width, GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS).width @@ -2495,9 +2495,9 @@ struct VehicleDetailsWindow : Window { Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); /* Draw running cost */ - SetDParam(1, DateToYear(v->age)); - SetDParam(0, (v->age + DAYS_IN_YEAR < v->max_age) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED); - SetDParam(2, DateToYear(v->max_age)); + SetDParam(1, TimerGameCalendar::DateToYear(v->age)); + SetDParam(0, (v->age + CalendarTime::DAYS_IN_YEAR < v->max_age) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED); + SetDParam(2, TimerGameCalendar::DateToYear(v->max_age)); SetDParam(3, v->GetDisplayRunningCost()); DrawString(tr, STR_VEHICLE_INFO_AGE_RUNNING_COST_YR); tr.top += FONT_HEIGHT_NORMAL; From 701a61c9af199e5f2760585b1b9d924249903262 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Wed, 16 Aug 2023 10:10:50 -0400 Subject: [PATCH 36/72] Codechange: Delete date_type.h --- src/CMakeLists.txt | 1 - src/date_gui.cpp | 1 - src/date_type.h | 16 ---------------- src/graph_gui.cpp | 1 - src/linkgraph/linkgraph.h | 1 - src/network/network_base.h | 1 - src/newgrf_airport.h | 1 - src/newgrf_profiling.h | 1 - src/newgrf_text.cpp | 1 - src/order_base.h | 1 - src/rail.h | 1 - src/saveload/misc_sl.cpp | 1 - src/script/api/script_date.hpp | 1 - src/settings.cpp | 1 - src/sortlist_type.h | 1 - src/statusbar_gui.cpp | 1 - src/story_cmd.h | 1 - src/timetable.h | 1 - src/town.h | 1 - src/vehicle_func.h | 1 - 20 files changed, 35 deletions(-) delete mode 100644 src/date_type.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ef4fa3fdf..0add42130c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -117,7 +117,6 @@ add_files( currency.h date_gui.cpp date_gui.h - date_type.h debug.cpp debug.h dedicated.cpp diff --git a/src/date_gui.cpp b/src/date_gui.cpp index 2e3a43c356..9d94e154da 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -13,7 +13,6 @@ #include "window_func.h" #include "window_gui.h" #include "date_gui.h" -#include "date_type.h" #include "core/geometry_func.hpp" #include "widgets/dropdown_type.h" diff --git a/src/date_type.h b/src/date_type.h deleted file mode 100644 index 5688159c84..0000000000 --- a/src/date_type.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file date_type.h Types related to the dates in OpenTTD. */ - -#ifndef DATE_TYPE_H -#define DATE_TYPE_H - -#include "timer/timer_game_calendar.h" - - -#endif /* DATE_TYPE_H */ diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index e6aeeb22ff..57f1e80949 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -16,7 +16,6 @@ #include "cargotype.h" #include "strings_func.h" #include "window_func.h" -#include "date_type.h" #include "gfx_func.h" #include "core/geometry_func.hpp" #include "currency.h" diff --git a/src/linkgraph/linkgraph.h b/src/linkgraph/linkgraph.h index 7f9e1e352d..57fe6a3fb3 100644 --- a/src/linkgraph/linkgraph.h +++ b/src/linkgraph/linkgraph.h @@ -13,7 +13,6 @@ #include "../core/pool_type.hpp" #include "../station_base.h" #include "../cargotype.h" -#include "../date_type.h" #include "../timer/timer_game_calendar.h" #include "../saveload/saveload.h" #include "linkgraph_type.h" diff --git a/src/network/network_base.h b/src/network/network_base.h index 44ad10af1b..3557cb45e4 100644 --- a/src/network/network_base.h +++ b/src/network/network_base.h @@ -14,7 +14,6 @@ #include "core/address.h" #include "../core/pool_type.hpp" #include "../company_type.h" -#include "../date_type.h" #include "../timer/timer_game_calendar.h" /** Type for the pool with client information. */ diff --git a/src/newgrf_airport.h b/src/newgrf_airport.h index 944c9cf19c..e09d16e046 100644 --- a/src/newgrf_airport.h +++ b/src/newgrf_airport.h @@ -11,7 +11,6 @@ #define NEWGRF_AIRPORT_H #include "airport.h" -#include "date_type.h" #include "timer/timer_game_calendar.h" #include "newgrf_class.h" #include "newgrf_commons.h" diff --git a/src/newgrf_profiling.h b/src/newgrf_profiling.h index d67f069377..629a42ea0b 100644 --- a/src/newgrf_profiling.h +++ b/src/newgrf_profiling.h @@ -11,7 +11,6 @@ #define NEWGRF_PROFILING_H #include "stdafx.h" -#include "date_type.h" #include "timer/timer_game_calendar.h" #include "newgrf.h" #include "newgrf_callbacks.h" diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index d979573dbb..a4b984ca88 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -24,7 +24,6 @@ #include "newgrf_cargo.h" #include "string_func.h" #include "timer/timer_game_calendar.h" -#include "date_type.h" #include "debug.h" #include "core/alloc_type.hpp" #include "language.h" diff --git a/src/order_base.h b/src/order_base.h index 9671b96cac..89d00a3d48 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -18,7 +18,6 @@ #include "station_type.h" #include "vehicle_type.h" #include "timer/timer_game_tick.h" -#include "date_type.h" #include "saveload/saveload.h" typedef Pool OrderPool; diff --git a/src/rail.h b/src/rail.h index 6fbcaf3bf1..4c46073ccc 100644 --- a/src/rail.h +++ b/src/rail.h @@ -17,7 +17,6 @@ #include "economy_func.h" #include "slope_type.h" #include "strings_type.h" -#include "date_type.h" #include "timer/timer_game_calendar.h" #include "signal_type.h" #include "settings_type.h" diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index af20e34e83..d0c04daa05 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -20,7 +20,6 @@ #include "../gfx_func.h" #include "../core/random_func.hpp" #include "../fios.h" -#include "../date_type.h" #include "../timer/timer.h" #include "../timer/timer_game_tick.h" diff --git a/src/script/api/script_date.hpp b/src/script/api/script_date.hpp index 01ef5d3dc2..2e108a74c8 100644 --- a/src/script/api/script_date.hpp +++ b/src/script/api/script_date.hpp @@ -12,7 +12,6 @@ #include "script_object.hpp" #include "timer/timer_game_calendar.h" -#include "../../date_type.h" /** * Class that handles all date related (calculation) functions. diff --git a/src/settings.cpp b/src/settings.cpp index 3c18f4ec32..cfd6dedba0 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -45,7 +45,6 @@ #include "fios.h" #include "fileio_func.h" #include "settings_cmd.h" -#include "date_type.h" #include "table/strings.h" diff --git a/src/sortlist_type.h b/src/sortlist_type.h index 4c2056d2d8..feb02dce53 100644 --- a/src/sortlist_type.h +++ b/src/sortlist_type.h @@ -13,7 +13,6 @@ #include "core/enum_type.hpp" #include "core/bitmath_func.hpp" #include "core/mem_func.hpp" -#include "date_type.h" #include "timer/timer_game_tick.h" /** Flags of the sort list. */ diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 782d998b89..2719fef18d 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -25,7 +25,6 @@ #include "toolbar_gui.h" #include "core/geometry_func.hpp" #include "zoom_func.h" -#include "date_type.h" #include "timer/timer.h" #include "timer/timer_game_calendar.h" #include "timer/timer_window.h" diff --git a/src/story_cmd.h b/src/story_cmd.h index d71efa6383..155ffe0031 100644 --- a/src/story_cmd.h +++ b/src/story_cmd.h @@ -12,7 +12,6 @@ #include "command_type.h" #include "company_type.h" -#include "date_type.h" #include "story_type.h" #include "vehicle_type.h" diff --git a/src/timetable.h b/src/timetable.h index cbc482a825..597d391da7 100644 --- a/src/timetable.h +++ b/src/timetable.h @@ -11,7 +11,6 @@ #define TIMETABLE_H #include "timer/timer_game_tick.h" -#include "date_type.h" #include "timer/timer_game_calendar.h" #include "vehicle_type.h" diff --git a/src/town.h b/src/town.h index b20e3cc30d..60ec9deae5 100644 --- a/src/town.h +++ b/src/town.h @@ -11,7 +11,6 @@ #define TOWN_H #include "viewport_type.h" -#include "date_type.h" #include "timer/timer_game_tick.h" #include "town_map.h" #include "subsidy_type.h" diff --git a/src/vehicle_func.h b/src/vehicle_func.h index da225d844b..06268b4abb 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -11,7 +11,6 @@ #define VEHICLE_FUNC_H #include "gfx_type.h" -#include "date_type.h" #include "direction_type.h" #include "command_type.h" #include "vehicle_type.h" From e6c02ebee65ed9465d5be1aacebabde0f4d7c241 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 10 Sep 2023 15:20:58 +0200 Subject: [PATCH 37/72] Fix b0e73277: cargodist information got lost when splitting of cargo (#11280) During b0e73277 we removed loaded_at_xy, but I kinda forgot that it was a union with next_station. Now next_station wasn't copied anymore, or checked in AreMergable. --- src/cargopacket.cpp | 8 +++++--- src/cargopacket.h | 4 +++- src/saveload/oldloader_sl.cpp | 2 +- src/saveload/station_sl.cpp | 2 +- src/saveload/vehicle_sl.cpp | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 592940d25b..5b15eba48c 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -57,6 +57,7 @@ CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t * @param count Number of cargo entities to put in this packet. * @param periods_in_transit Number of cargo aging periods the cargo has been in transit. * @param first_station Station the cargo was initially loaded. + * @param next_station Next station the cargo wants to go. * @param source_xy Station location the cargo was initially loaded. * @param feeder_share Feeder share the packet has already accumulated. * @param source_type 'Type' of source the packet comes from (for subsidies). @@ -64,14 +65,15 @@ CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t * @note We have to zero memory ourselves here because we are using a 'new' * that, in contrary to all other pools, does not memset to 0. */ -CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : +CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, StationID next_station, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : count(count), periods_in_transit(periods_in_transit), feeder_share(feeder_share), source_xy(source_xy), source_id(source_id), source_type(source_type), - first_station(first_station) + first_station(first_station), + next_station(next_station) { assert(count != 0); } @@ -86,7 +88,7 @@ CargoPacket *CargoPacket::Split(uint new_size) if (!CargoPacket::CanAllocateItem()) return nullptr; Money fs = this->GetFeederShare(new_size); - CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->source_xy, fs, this->source_type, this->source_id); + CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->next_station, this->source_xy, fs, this->source_type, this->source_id); this->feeder_share -= fs; this->count -= new_size; return cp_new; diff --git a/src/cargopacket.h b/src/cargopacket.h index 12b8babbe9..cea865c7b7 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -63,7 +63,7 @@ public: CargoPacket(); CargoPacket(StationID first_station, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id); - CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source, TileIndex source_xy, Money feeder_share = 0, SourceType source_type = SourceType::Industry, SourceID source_id = INVALID_SOURCE); + CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, StationID next_station, TileIndex source_xy, Money feeder_share = 0, SourceType source_type = SourceType::Industry, SourceID source_id = INVALID_SOURCE); /** Destroy the packet. */ ~CargoPacket() { } @@ -422,6 +422,7 @@ public: return cp1->source_xy == cp2->source_xy && cp1->periods_in_transit == cp2->periods_in_transit && cp1->source_type == cp2->source_type && + cp1->next_station == cp2->next_station && cp1->source_id == cp2->source_id; } }; @@ -536,6 +537,7 @@ public: return cp1->source_xy == cp2->source_xy && cp1->periods_in_transit == cp2->periods_in_transit && cp1->source_type == cp2->source_type && + cp1->next_station == cp2->next_station && cp1->source_id == cp2->source_id; } }; diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 5543013ed2..feae25f6ec 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -1353,7 +1353,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) { StationID source = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source; TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : (TileIndex)0; - v->cargo.Append(new CargoPacket(_cargo_count, _cargo_periods, source, source_xy)); + v->cargo.Append(new CargoPacket(_cargo_count, _cargo_periods, source, INVALID_STATION, source_xy)); } } diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index f3b7af25a3..3203188bf9 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -449,7 +449,7 @@ public: assert(CargoPacket::CanAllocateItem()); /* Don't construct the packet with station here, because that'll fail with old savegames */ - CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, source, _cargo_source_xy, _cargo_feeder_share); + CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, source, INVALID_STATION, _cargo_source_xy, _cargo_feeder_share); ge->cargo.Append(cp, INVALID_STATION); SB(ge->status, GoodsEntry::GES_RATING, 1, 1); } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 4ef24cf228..92da70d9b7 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -1041,7 +1041,7 @@ struct VEHSChunkHandler : ChunkHandler { if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v) && CargoPacket::CanAllocateItem()) { /* Don't construct the packet with station here, because that'll fail with old savegames */ - CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_periods, _cargo_source, _cargo_source_xy, _cargo_feeder_share); + CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_periods, _cargo_source, INVALID_STATION, _cargo_source_xy, _cargo_feeder_share); v->cargo.Append(cp); } From a6f2f3c042da36731eb291510fb5b5e19e9d3c9a Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 10 Sep 2023 17:09:31 +0200 Subject: [PATCH 38/72] Add: [NewGRF] Inspection window for airports. As as the station window combines all station types, accessing the debug view is via the parent of the airport tile only. --- src/newgrf_airport.cpp | 44 ---------------------------- src/newgrf_airport.h | 46 +++++++++++++++++++++++++++++ src/newgrf_debug_gui.cpp | 1 + src/table/newgrf_debug_data.h | 55 +++++++++++++++++++++++++++++++++-- 4 files changed, 100 insertions(+), 46 deletions(-) diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index 4dffc76cde..93a01f2070 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -17,50 +17,6 @@ #include "safeguards.h" -/** Resolver for the airport scope. */ -struct AirportScopeResolver : public ScopeResolver { - struct Station *st; ///< Station of the airport for which the callback is run, or \c nullptr for build gui. - byte airport_id; ///< Type of airport for which the callback is run. - byte layout; ///< Layout of the airport to build. - TileIndex tile; ///< Tile for the callback, only valid for airporttile callbacks. - - /** - * Constructor of the scope resolver for an airport. - * @param ro Surrounding resolver. - * @param tile %Tile for the callback, only valid for airporttile callbacks. - * @param st %Station of the airport for which the callback is run, or \c nullptr for build gui. - * @param airport_id Type of airport for which the callback is run. - * @param layout Layout of the airport to build. - */ - AirportScopeResolver(ResolverObject &ro, TileIndex tile, Station *st, byte airport_id, byte layout) - : ScopeResolver(ro), st(st), airport_id(airport_id), layout(layout), tile(tile) - { - } - - uint32_t GetRandomBits() const override; - uint32_t GetVariable(byte variable, uint32_t parameter, bool *available) const override; - void StorePSA(uint pos, int32_t value) override; -}; - -/** Resolver object for airports. */ -struct AirportResolverObject : public ResolverObject { - AirportScopeResolver airport_scope; - - AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout, - CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0); - - ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override - { - switch (scope) { - case VSG_SCOPE_SELF: return &this->airport_scope; - default: return ResolverObject::GetScope(scope, relative); - } - } - - GrfSpecFeature GetFeature() const override; - uint32_t GetDebugID() const override; -}; - /** * Reset airport classes to their default state. * This includes initialising the defaults classes with an empty diff --git a/src/newgrf_airport.h b/src/newgrf_airport.h index e09d16e046..8eec8ad1c0 100644 --- a/src/newgrf_airport.h +++ b/src/newgrf_airport.h @@ -14,6 +14,7 @@ #include "timer/timer_game_calendar.h" #include "newgrf_class.h" #include "newgrf_commons.h" +#include "newgrf_spritegroup.h" #include "tilearea_type.h" /** Copy from station_map.h */ @@ -143,6 +144,51 @@ typedef NewGRFClass AirportClass; void BindAirportSpecs(); +/** Resolver for the airport scope. */ +struct AirportScopeResolver : public ScopeResolver { + struct Station *st; ///< Station of the airport for which the callback is run, or \c nullptr for build gui. + byte airport_id; ///< Type of airport for which the callback is run. + byte layout; ///< Layout of the airport to build. + TileIndex tile; ///< Tile for the callback, only valid for airporttile callbacks. + + /** + * Constructor of the scope resolver for an airport. + * @param ro Surrounding resolver. + * @param tile %Tile for the callback, only valid for airporttile callbacks. + * @param st %Station of the airport for which the callback is run, or \c nullptr for build gui. + * @param airport_id Type of airport for which the callback is run. + * @param layout Layout of the airport to build. + */ + AirportScopeResolver(ResolverObject &ro, TileIndex tile, Station *st, byte airport_id, byte layout) + : ScopeResolver(ro), st(st), airport_id(airport_id), layout(layout), tile(tile) + { + } + + uint32_t GetRandomBits() const override; + uint32_t GetVariable(byte variable, uint32_t parameter, bool *available) const override; + void StorePSA(uint pos, int32_t value) override; +}; + + +/** Resolver object for airports. */ +struct AirportResolverObject : public ResolverObject { + AirportScopeResolver airport_scope; + + AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout, + CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0); + + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override + { + switch (scope) { + case VSG_SCOPE_SELF: return &this->airport_scope; + default: return ResolverObject::GetScope(scope, relative); + } + } + + GrfSpecFeature GetFeature() const override; + uint32_t GetDebugID() const override; +}; + StringID GetAirportTextCallback(const AirportSpec *as, byte layout, uint16_t callback); #endif /* NEWGRF_AIRPORT_H */ diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index afef4e9308..d7cd8e7495 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -28,6 +28,7 @@ #include "train.h" #include "roadveh.h" +#include "newgrf_airport.h" #include "newgrf_airporttiles.h" #include "newgrf_debug.h" #include "newgrf_object.h" diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index 2410e68882..7427a5ecc1 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -494,7 +494,7 @@ static const NICallback _nic_airporttiles[] = { class NIHAirportTile : public NIHelper { bool IsInspectable(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile != nullptr; } - uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); } + uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_AIRPORTS, GetStationIndex(index)); } const void *GetInstance(uint index)const override { return nullptr; } const void *GetSpec(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(index)); } void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); } @@ -515,6 +515,57 @@ static const NIFeature _nif_airporttile = { }; +/*** NewGRF airports ***/ + +static const NIVariable _niv_airports[] = { + NIV(0x40, "Layout number"), + NIV(0x48, "bitmask of accepted cargoes"), + NIV(0x60, "amount of cargo waiting"), + NIV(0x61, "time since last cargo pickup"), + NIV(0x62, "rating of cargo"), + NIV(0x63, "time spent on route"), + NIV(0x64, "information about last vehicle picking cargo up"), + NIV(0x65, "amount of cargo acceptance"), + NIV(0x69, "information about cargo accepted in the past"), + NIV(0xF1, "type of the airport"), + NIV(0xF6, "airport block status"), + NIV(0xFA, "built date"), + NIV_END() +}; + +class NIHAiport : public NIHelper { + bool IsInspectable(uint index) const override { return AirportSpec::Get(Station::Get(index)->airport.type)->grf_prop.grffile != nullptr; } + uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::Get(index)->town->index); } + const void *GetInstance(uint index)const override { return Station::Get(index); } + const void *GetSpec(uint index) const override { return AirportSpec::Get(Station::Get(index)->airport.type); } + void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, index, Station::Get(index)->airport.tile); } + uint32_t GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? AirportSpec::Get(Station::Get(index)->airport.type)->grf_prop.grffile->grfid : 0; } + + uint Resolve(uint index, uint var, uint param, bool *avail) const override + { + Station *st = Station::Get(index); + AirportResolverObject ro(st->airport.tile, st, st->airport.type, st->airport.layout); + return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); + } + + uint GetPSASize(uint index, uint32_t grfid) const override { return cpp_lengthof(PersistentStorage, storage); } + + const int32_t *GetPSAFirstPosition(uint index, uint32_t grfid) const override + { + const Station *st = (const Station *)this->GetInstance(index); + if (st->airport.psa == nullptr) return nullptr; + return (int32_t *)(&st->airport.psa->storage); + } +}; + +static const NIFeature _nif_airport = { + nullptr, + nullptr, + _niv_airports, + new NIHAiport(), +}; + + /*** NewGRF towns ***/ static const NIVariable _niv_towns[] = { @@ -680,7 +731,7 @@ static const NIFeature * const _nifeatures[] = { &_nif_industry, // GSF_INDUSTRIES nullptr, // GSF_CARGOES (has no "physical" objects) nullptr, // GSF_SOUNDFX (has no "physical" objects) - nullptr, // GSF_AIRPORTS (feature not implemented) + &_nif_airport, // GSF_AIRPORTS nullptr, // GSF_SIGNALS (feature not implemented) &_nif_object, // GSF_OBJECTS &_nif_railtype, // GSF_RAILTYPES From 1c620b349f3c15aff20eb4d3372cbba16589213e Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 10 Sep 2023 17:28:53 +0200 Subject: [PATCH 39/72] Feature: [NewGRF] Related Act2 objects for airports and airport tiles. Airports are similar two stations and industries, both of which have the town as related object. Airport tiles are similar to industry tiles, which have the industry as related object. This seems a sensible structure, so let's make it Airport Tile -> Airport -> Town. --- src/newgrf_airport.cpp | 21 +++++++++++++++++++++ src/newgrf_airport.h | 10 ++++++++++ src/newgrf_airporttiles.cpp | 4 +++- src/newgrf_airporttiles.h | 2 ++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index 93a01f2070..fe7566a7d4 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -14,6 +14,7 @@ #include "newgrf_text.h" #include "station_base.h" #include "newgrf_class_func.h" +#include "town.h" #include "safeguards.h" @@ -210,6 +211,26 @@ uint32_t AirportResolverObject::GetDebugID() const this->st->airport.psa->StoreValue(pos, value); } +/** + * Get the town scope associated with a station, if it exists. + * On the first call, the town scope is created (if possible). + * @return Town scope, if available. + */ +TownScopeResolver *AirportResolverObject::GetTown() +{ + if (!this->town_scope) { + Town *t = nullptr; + if (this->airport_scope.st != nullptr) { + t = this->airport_scope.st->town; + } else if (this->airport_scope.tile != INVALID_TILE) { + t = ClosestTownFromTile(this->airport_scope.tile, UINT_MAX); + } + if (t == nullptr) return nullptr; + this->town_scope.reset(new TownScopeResolver(*this, t, this->airport_scope.st == nullptr)); + } + return this->town_scope.get(); +} + /** * Constructor of the airport resolver. * @param tile %Tile for the callback, only valid for airporttile callbacks. diff --git a/src/newgrf_airport.h b/src/newgrf_airport.h index 8eec8ad1c0..273b0d60c8 100644 --- a/src/newgrf_airport.h +++ b/src/newgrf_airport.h @@ -15,6 +15,7 @@ #include "newgrf_class.h" #include "newgrf_commons.h" #include "newgrf_spritegroup.h" +#include "newgrf_town.h" #include "tilearea_type.h" /** Copy from station_map.h */ @@ -173,14 +174,23 @@ struct AirportScopeResolver : public ScopeResolver { /** Resolver object for airports. */ struct AirportResolverObject : public ResolverObject { AirportScopeResolver airport_scope; + std::unique_ptr town_scope; ///< The town scope resolver (created on the first call). AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout, CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0); + TownScopeResolver *GetTown(); + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &this->airport_scope; + case VSG_SCOPE_PARENT: + { + TownScopeResolver *tsr = this->GetTown(); + if (tsr != nullptr) return tsr; + FALLTHROUGH; + } default: return ResolverObject::GetScope(scope, relative); } } diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index 0f817d3b07..1abf8b20bc 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -214,7 +214,9 @@ static uint32_t GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint */ AirportTileResolverObject::AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st, CallbackID callback, uint32_t callback_param1, uint32_t callback_param2) - : ResolverObject(ats->grf_prop.grffile, callback, callback_param1, callback_param2), tiles_scope(*this, ats, tile, st) + : ResolverObject(ats->grf_prop.grffile, callback, callback_param1, callback_param2), + tiles_scope(*this, ats, tile, st), + airport_scope(*this, tile, st, st != nullptr ? st->airport.type : (byte)AT_DUMMY, st != nullptr ? st->airport.layout : 0) { this->root_spritegroup = ats->grf_prop.spritegroup[0]; } diff --git a/src/newgrf_airporttiles.h b/src/newgrf_airporttiles.h index 90a1457b0b..c855d64c15 100644 --- a/src/newgrf_airporttiles.h +++ b/src/newgrf_airporttiles.h @@ -44,6 +44,7 @@ struct AirportTileScopeResolver : public ScopeResolver { /** Resolver for tiles of an airport. */ struct AirportTileResolverObject : public ResolverObject { AirportTileScopeResolver tiles_scope; ///< Scope resolver for the tiles. + AirportScopeResolver airport_scope; ///< Scope resolver for the airport owning the tile. AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st, CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0); @@ -52,6 +53,7 @@ struct AirportTileResolverObject : public ResolverObject { { switch (scope) { case VSG_SCOPE_SELF: return &tiles_scope; + case VSG_SCOPE_PARENT: return &airport_scope; default: return ResolverObject::GetScope(scope, relative); } } From 6643c010bddafc8e92aec415c110f52dcd8c50ac Mon Sep 17 00:00:00 2001 From: PeterN Date: Sun, 10 Sep 2023 18:55:37 +0100 Subject: [PATCH 40/72] Fix: NewGRF house class mappings were not reset between games. (#11279) --- src/newgrf_house.cpp | 7 ++++++- src/newgrf_house.h | 1 + src/town_cmd.cpp | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index 7d82cc83b7..ad05665a08 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -25,7 +25,7 @@ #include "safeguards.h" static BuildingCounts _building_counts; -static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX]; +static std::array _class_mapping; HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, NUM_HOUSES, INVALID_HOUSE_ID); @@ -72,6 +72,11 @@ uint32_t HouseResolverObject::GetDebugID() const return HouseSpec::Get(this->house_scope.house_id)->grf_prop.local_id; } +void ResetHouseClassIDs() +{ + _class_mapping = {}; +} + HouseClassID AllocateHouseClassID(byte grf_class_id, uint32_t grfid) { /* Start from 1 because 0 means that no class has been assigned. */ diff --git a/src/newgrf_house.h b/src/newgrf_house.h index e44906d3e8..71e1390eea 100644 --- a/src/newgrf_house.h +++ b/src/newgrf_house.h @@ -87,6 +87,7 @@ struct HouseClassMapping { uint8_t class_id; ///< The class id within the grf file }; +void ResetHouseClassIDs(); HouseClassID AllocateHouseClassID(byte grf_class_id, uint32_t grfid); void InitializeBuildingCounts(); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 01b4f46652..8b17d4482d 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -3842,6 +3842,8 @@ HouseSpec _house_specs[NUM_HOUSES]; void ResetHouses() { + ResetHouseClassIDs(); + auto insert = std::copy(std::begin(_original_house_specs), std::end(_original_house_specs), std::begin(_house_specs)); std::fill(insert, std::end(_house_specs), HouseSpec{}); From a0f6983be4ee62d4b1919dea44f2db0f98148039 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 10 Sep 2023 22:34:02 +0200 Subject: [PATCH 41/72] Codechange: remove parameter from VehicleCargoList::Reassign that is always INVALID_STATION --- src/cargopacket.cpp | 9 ++++----- src/cargopacket.h | 2 +- src/economy.cpp | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 5b15eba48c..1c924ade6e 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -533,7 +533,7 @@ void VehicleCargoList::InvalidateCache() * @return Amount of cargo actually reassigned. */ template -uint VehicleCargoList::Reassign(uint max_move, StationID) +uint VehicleCargoList::Reassign(uint max_move) { static_assert(Tfrom != MTA_TRANSFER && Tto != MTA_TRANSFER); static_assert(Tfrom - Tto == 1 || Tto - Tfrom == 1); @@ -547,11 +547,10 @@ uint VehicleCargoList::Reassign(uint max_move, StationID) * Reassign cargo from MTA_DELIVER to MTA_TRANSFER and take care of the next * station the cargo wants to visit. * @param max_move Maximum amount of cargo to reassign. - * @param next_station Station to record as next hop in the reassigned packets. * @return Amount of cargo actually reassigned. */ template<> -uint VehicleCargoList::Reassign(uint max_move, StationID next_station) +uint VehicleCargoList::Reassign(uint max_move) { max_move = std::min(this->action_counts[MTA_DELIVER], max_move); @@ -565,7 +564,7 @@ uint VehicleCargoList::ReassignCount(); this->packets.insert(it, cp_split); } - cp->next_station = next_station; + cp->next_station = INVALID_STATION; } this->action_counts[MTA_DELIVER] -= max_move; @@ -844,4 +843,4 @@ uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID */ template class CargoList; template class CargoList; -template uint VehicleCargoList::Reassign(uint, StationID); +template uint VehicleCargoList::Reassign(uint); diff --git a/src/cargopacket.h b/src/cargopacket.h index cea865c7b7..650e431ac4 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -403,7 +403,7 @@ public: * applicable), return value is amount of cargo actually moved. */ template - uint Reassign(uint max_move, StationID update = INVALID_STATION); + uint Reassign(uint max_move); uint Return(uint max_move, StationCargoList *dest, StationID next_station); uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment); uint Shift(uint max_move, VehicleCargoList *dest); diff --git a/src/economy.cpp b/src/economy.cpp index 4bf3335e88..fb11504981 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1689,7 +1689,7 @@ static void LoadUnloadVehicle(Vehicle *front) if (front->current_order.GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) { /* Transfer instead of delivering. */ v->cargo.Reassign( - v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER), INVALID_STATION); + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER)); } else { uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER); if (v->cargo_cap < new_remaining) { From 9f8c1ea552e1ca6fe0bffe47cf280d70195e653f Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 10 Sep 2023 22:33:33 +0200 Subject: [PATCH 42/72] Codechange: rename next_station to next_hop to avoid confusing with another next_station --- src/cargoaction.cpp | 6 +++--- src/cargopacket.cpp | 12 ++++++------ src/cargopacket.h | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/cargoaction.cpp b/src/cargoaction.cpp index 8601ba81c8..0b8d203706 100644 --- a/src/cargoaction.cpp +++ b/src/cargoaction.cpp @@ -167,7 +167,7 @@ bool CargoTransfer::operator()(CargoPacket *cp) if (cp_new == nullptr) return false; this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count()); /* No transfer credits here as they were already granted during Stage(). */ - this->destination->Append(cp_new, cp_new->GetNextStation()); + this->destination->Append(cp_new, cp_new->GetNextHop()); return cp_new == cp; } @@ -217,8 +217,8 @@ bool VehicleCargoReroute::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); if (cp_new == nullptr) cp_new = cp; - if (cp_new->GetNextStation() == this->avoid || cp_new->GetNextStation() == this->avoid2) { - cp->SetNextStation(this->ge->GetVia(cp_new->GetFirstStation(), this->avoid, this->avoid2)); + if (cp_new->GetNextHop() == this->avoid || cp_new->GetNextHop() == this->avoid2) { + cp->SetNextHop(this->ge->GetVia(cp_new->GetFirstStation(), this->avoid, this->avoid2)); } if (this->source != this->destination) { this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count()); diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 1c924ade6e..3b9a46fb9f 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -57,7 +57,7 @@ CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t * @param count Number of cargo entities to put in this packet. * @param periods_in_transit Number of cargo aging periods the cargo has been in transit. * @param first_station Station the cargo was initially loaded. - * @param next_station Next station the cargo wants to go. + * @param next_hop Next station the cargo wants to go. * @param source_xy Station location the cargo was initially loaded. * @param feeder_share Feeder share the packet has already accumulated. * @param source_type 'Type' of source the packet comes from (for subsidies). @@ -65,7 +65,7 @@ CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t * @note We have to zero memory ourselves here because we are using a 'new' * that, in contrary to all other pools, does not memset to 0. */ -CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, StationID next_station, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : +CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, StationID next_hop, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : count(count), periods_in_transit(periods_in_transit), feeder_share(feeder_share), @@ -73,7 +73,7 @@ CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID source_id(source_id), source_type(source_type), first_station(first_station), - next_station(next_station) + next_hop(next_hop) { assert(count != 0); } @@ -88,7 +88,7 @@ CargoPacket *CargoPacket::Split(uint new_size) if (!CargoPacket::CanAllocateItem()) return nullptr; Money fs = this->GetFeederShare(new_size); - CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->next_station, this->source_xy, fs, this->source_type, this->source_id); + CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->next_hop, this->source_xy, fs, this->source_type, this->source_id); this->feeder_share -= fs; this->count -= new_size; return cp_new; @@ -501,7 +501,7 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID share = payment->PayTransfer(cp, cp->count); cp->AddFeederShare(share); this->feeder_share += share; - cp->next_station = cargo_next; + cp->next_hop = cargo_next; break; default: NOT_REACHED(); @@ -564,7 +564,7 @@ uint VehicleCargoList::ReassignCount(); this->packets.insert(it, cp_split); } - cp->next_station = INVALID_STATION; + cp->next_hop = INVALID_STATION; } this->action_counts[MTA_DELIVER] -= max_move; diff --git a/src/cargopacket.h b/src/cargopacket.h index 650e431ac4..a575762281 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -49,7 +49,7 @@ private: SourceType source_type{SourceType::Industry}; ///< Type of \c source_id. StationID first_station{INVALID_STATION}; ///< The station where the cargo came from first. - StationID next_station{INVALID_STATION}; ///< Station where the cargo wants to go next. + StationID next_hop{INVALID_STATION}; ///< Station where the cargo wants to go next. /** The CargoList caches, thus needs to know about it. */ template friend class CargoList; @@ -74,11 +74,11 @@ public: /** * Sets the station where the packet is supposed to go next. - * @param next_station Next station the packet should go to. + * @param next_hop Next station the packet should go to. */ - void SetNextStation(StationID next_station) + void SetNextHop(StationID next_hop) { - this->next_station = next_station; + this->next_hop = next_hop; } /** @@ -172,9 +172,9 @@ public: * Gets the ID of station the cargo wants to go next. * @return Next station for this packets. */ - inline StationID GetNextStation() const + inline StationID GetNextHop() const { - return this->next_station; + return this->next_hop; } static void InvalidateAllFrom(SourceType src_type, SourceID src); From 1243c331b633924be1c105a9baf92dce184b1dce Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 10 Sep 2023 22:34:26 +0200 Subject: [PATCH 43/72] Fix: don't compare next_station when trying to merge CargoPackets For vehicle packets they shouldn't be compared, and for station packets they are already in a bucket per next_station. --- src/cargopacket.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cargopacket.h b/src/cargopacket.h index a575762281..85f8e6a42f 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -422,7 +422,6 @@ public: return cp1->source_xy == cp2->source_xy && cp1->periods_in_transit == cp2->periods_in_transit && cp1->source_type == cp2->source_type && - cp1->next_station == cp2->next_station && cp1->source_id == cp2->source_id; } }; @@ -537,7 +536,6 @@ public: return cp1->source_xy == cp2->source_xy && cp1->periods_in_transit == cp2->periods_in_transit && cp1->source_type == cp2->source_type && - cp1->next_station == cp2->next_station && cp1->source_id == cp2->source_id; } }; From 9e3763cfb3375277cc8ed9fa9ab085142a97f6c5 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 10 Sep 2023 22:35:03 +0200 Subject: [PATCH 44/72] Fix b0e73277: save/load next_station for CargoPacket again --- src/saveload/cargopacket_sl.cpp | 2 ++ src/saveload/compat/cargopacket_sl_compat.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index 0332b8a4b9..dd7036c03f 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -88,6 +88,8 @@ SaveLoadTable GetCargoPacketDesc() static const SaveLoad _cargopacket_desc[] = { SLE_VARNAME(CargoPacket, first_station, "source", SLE_UINT16), SLE_VAR(CargoPacket, source_xy, SLE_UINT32), + SLE_CONDVARNAME(CargoPacket, next_hop, "loaded_at_xy", SLE_FILE_U32 | SLE_VAR_U16, SL_MIN_VERSION, SLV_REMOVE_LOADED_AT_XY), + SLE_CONDVARNAME(CargoPacket, next_hop, "loaded_at_xy", SLE_UINT16, SLV_REMOVE_LOADED_AT_XY, SL_MAX_VERSION), SLE_VAR(CargoPacket, count, SLE_UINT16), SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_MORE_CARGO_AGE), SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_UINT16, SLV_MORE_CARGO_AGE, SLV_PERIODS_IN_TRANSIT_RENAME), diff --git a/src/saveload/compat/cargopacket_sl_compat.h b/src/saveload/compat/cargopacket_sl_compat.h index 2622d6e692..eee308bcb0 100644 --- a/src/saveload/compat/cargopacket_sl_compat.h +++ b/src/saveload/compat/cargopacket_sl_compat.h @@ -16,7 +16,7 @@ const SaveLoadCompat _cargopacket_sl_compat[] = { SLC_VAR("source"), SLC_VAR("source_xy"), - SLC_NULL(4, SL_MIN_VERSION, SLV_REMOVE_LOADED_AT_XY), + SLC_VAR("loaded_at_xy"), SLC_VAR("count"), SLC_VAR("days_in_transit"), SLC_VAR("feeder_share"), From 7e3cdbaf6264ce890a53507b0ed4c24667f884cd Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 10 Sep 2023 22:35:24 +0200 Subject: [PATCH 45/72] Fix: mark next_station as INVALID_STATION when loading from older savegames --- src/saveload/oldloader_sl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index feae25f6ec..1936d66b2b 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -710,7 +710,7 @@ static bool LoadOldGood(LoadgameState *ls, int num) SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15)); SB(ge->status, GoodsEntry::GES_RATING, 1, _cargo_source != 0xFF); if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) { - ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, 0, 0), + ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, INVALID_STATION, 0), INVALID_STATION); } From a0b2f28f9c41f794cefbb0ac090732465057a061 Mon Sep 17 00:00:00 2001 From: PeterN Date: Mon, 11 Sep 2023 00:01:08 +0100 Subject: [PATCH 46/72] Codechange: Use std::copy/fill pattern to initialize rail and road specs. (#11285) This avoids use of lengthof and array indices. --- src/rail_cmd.cpp | 14 ++------------ src/road_cmd.cpp | 13 ++----------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 7c0e52dd1f..f4adfefe58 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -66,18 +66,8 @@ void ResetRailTypes() { static_assert(lengthof(_original_railtypes) <= lengthof(_railtypes)); - uint i = 0; - for (; i < lengthof(_original_railtypes); i++) _railtypes[i] = _original_railtypes[i]; - - static const RailtypeInfo empty_railtype = { - {0,0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,{}}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0}, - 0, RAILTYPES_NONE, RAILTYPES_NONE, 0, 0, 0, RTFB_NONE, 0, 0, 0, 0, 0, - RailTypeLabelList(), 0, 0, RAILTYPES_NONE, RAILTYPES_NONE, 0, - {}, {} }; - for (; i < lengthof(_railtypes); i++) _railtypes[i] = empty_railtype; + auto insert = std::copy(std::begin(_original_railtypes), std::end(_original_railtypes), std::begin(_railtypes)); + std::fill(insert, std::end(_railtypes), RailtypeInfo{}); _railtypes_hidden_mask = RAILTYPES_NONE; } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 1d325f042a..edcfefe56f 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -67,17 +67,8 @@ void ResetRoadTypes() { static_assert(lengthof(_original_roadtypes) <= lengthof(_roadtypes)); - uint i = 0; - for (; i < lengthof(_original_roadtypes); i++) _roadtypes[i] = _original_roadtypes[i]; - - static const RoadTypeInfo empty_roadtype = { - { 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, 0, {}, {} }, - ROADTYPES_NONE, ROTFB_NONE, 0, 0, 0, 0, - RoadTypeLabelList(), 0, 0, ROADTYPES_NONE, ROADTYPES_NONE, 0, - {}, {} }; - for (; i < lengthof(_roadtypes); i++) _roadtypes[i] = empty_roadtype; + auto insert = std::copy(std::begin(_original_roadtypes), std::end(_original_roadtypes), std::begin(_roadtypes)); + std::fill(insert, std::end(_roadtypes), RoadTypeInfo{}); _roadtypes_hidden_mask = ROADTYPES_NONE; _roadtypes_type = ROADTYPES_TRAM; From acd7d3c913618ab2e205a33a202b135dfb4b0079 Mon Sep 17 00:00:00 2001 From: PeterN Date: Mon, 11 Sep 2023 09:55:12 +0100 Subject: [PATCH 47/72] Codechange: Rename *Railtype* to *RailType* for consistency. (#11287) --- src/autoreplace_gui.cpp | 2 +- src/build_vehicle_gui.cpp | 2 +- src/company_cmd.cpp | 2 +- src/console_cmds.cpp | 2 +- src/elrail.cpp | 6 ++--- src/engine.cpp | 6 ++--- src/newgrf.cpp | 12 ++++----- src/newgrf_engine.cpp | 2 +- src/newgrf_railtype.cpp | 6 ++--- src/newgrf_railtype.h | 10 ++++---- src/newgrf_station.cpp | 2 +- src/rail.cpp | 16 ++++++------ src/rail.h | 20 +++++++-------- src/rail_cmd.cpp | 34 +++++++++++++------------- src/rail_gui.cpp | 18 +++++++------- src/road_cmd.cpp | 4 +-- src/saveload/afterload.cpp | 2 +- src/saveload/labelmaps_sl.cpp | 2 +- src/script/api/script_rail.cpp | 2 +- src/script/api/script_railtypelist.cpp | 2 +- src/station_cmd.cpp | 8 +++--- src/table/railtypes.h | 2 +- src/train_cmd.cpp | 2 +- src/tunnelbridge_cmd.cpp | 14 +++++------ src/vehicle.cpp | 2 +- 25 files changed, 90 insertions(+), 90 deletions(-) diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 8b342ca712..afe9b65fe6 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -357,7 +357,7 @@ public: switch (this->window_number) { case VEH_TRAIN: for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - const RailtypeInfo *rti = GetRailTypeInfo(rt); + const RailTypeInfo *rti = GetRailTypeInfo(rt); /* Skip rail type if it has no label */ if (rti->label == 0) continue; d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text)); diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 733434cb0c..3ea29e6007 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1698,7 +1698,7 @@ struct BuildVehicleWindow : Window { switch (widget) { case WID_BV_CAPTION: if (this->vehicle_type == VEH_TRAIN && !this->listview_mode) { - const RailtypeInfo *rti = GetRailTypeInfo(this->filter.railtype); + const RailTypeInfo *rti = GetRailTypeInfo(this->filter.railtype); SetDParam(0, rti->strings.build_caption); } else if (this->vehicle_type == VEH_ROAD && !this->listview_mode) { const RoadTypeInfo *rti = GetRoadTypeInfo(this->filter.roadtype); diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 3be9d48efb..02663c301e 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -563,7 +563,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY) /* Scale the initial loan based on the inflation rounded down to the loan interval. The maximum loan has already been inflation adjusted. */ c->money = c->current_loan = std::min((INITIAL_LOAN * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL, _economy.max_loan); - c->avail_railtypes = GetCompanyRailtypes(c->index); + c->avail_railtypes = GetCompanyRailTypes(c->index); c->avail_roadtypes = GetCompanyRoadTypes(c->index); c->inaugurated_year = TimerGameCalendar::year; diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index b3e3607bce..5c773d573f 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -2398,7 +2398,7 @@ static void ConDumpRailTypes() std::map grfs; for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) { - const RailtypeInfo *rti = GetRailTypeInfo(rt); + const RailTypeInfo *rti = GetRailTypeInfo(rt); if (rti->label == 0) continue; uint32_t grfid = 0; const GRFFile *grf = rti->grffile[RTSG_GROUND]; diff --git a/src/elrail.cpp b/src/elrail.cpp index b341516472..72021cb9ed 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -176,7 +176,7 @@ static TrackBits MaskWireBits(TileIndex t, TrackBits tracks) */ static inline SpriteID GetWireBase(TileIndex tile, TileContext context = TCX_NORMAL) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); SpriteID wires = GetCustomRailSprite(rti, tile, RTSG_WIRES, context); return wires == 0 ? SPR_WIRE_BASE : wires; } @@ -186,7 +186,7 @@ static inline SpriteID GetWireBase(TileIndex tile, TileContext context = TCX_NOR */ static inline SpriteID GetPylonBase(TileIndex tile, TileContext context = TCX_NORMAL) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); SpriteID pylons = GetCustomRailSprite(rti, tile, RTSG_PYLONS, context); return pylons == 0 ? SPR_PYLON_BASE : pylons; } @@ -633,7 +633,7 @@ void SettingsDisableElrail(int32_t new_value) } } - for (Company *c : Company::Iterate()) c->avail_railtypes = GetCompanyRailtypes(c->index); + for (Company *c : Company::Iterate()) c->avail_railtypes = GetCompanyRailTypes(c->index); /* This resets the _last_built_railtype, which will be invalid for electric * rails. It may have unintended consequences if that function is ever diff --git a/src/engine.cpp b/src/engine.cpp index 66c9880868..3aa242e375 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -756,7 +756,7 @@ void StartupEngines() /* Update the bitmasks for the vehicle lists */ for (Company *c : Company::Iterate()) { - c->avail_railtypes = GetCompanyRailtypes(c->index); + c->avail_railtypes = GetCompanyRailTypes(c->index); c->avail_roadtypes = GetCompanyRoadTypes(c->index); } @@ -779,7 +779,7 @@ static void EnableEngineForCompany(EngineID eid, CompanyID company) SetBit(e->company_avail, company); if (e->type == VEH_TRAIN) { - c->avail_railtypes = GetCompanyRailtypes(c->index); + c->avail_railtypes = GetCompanyRailTypes(c->index); } else if (e->type == VEH_ROAD) { c->avail_roadtypes = GetCompanyRoadTypes(c->index); } @@ -807,7 +807,7 @@ static void DisableEngineForCompany(EngineID eid, CompanyID company) ClrBit(e->company_avail, company); if (e->type == VEH_TRAIN) { - c->avail_railtypes = GetCompanyRailtypes(c->index); + c->avail_railtypes = GetCompanyRailTypes(c->index); } else if (e->type == VEH_ROAD) { c->avail_roadtypes = GetCompanyRoadTypes(c->index); } diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 5904decbdb..787b0cc386 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -4212,7 +4212,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR { ChangeInfoResult ret = CIR_SUCCESS; - extern RailtypeInfo _railtypes[RAILTYPE_END]; + extern RailTypeInfo _railtypes[RAILTYPE_END]; if (id + numinfo > RAILTYPE_END) { GrfMsg(1, "RailTypeChangeInfo: Rail type {} is invalid, max {}, ignoring", id + numinfo, RAILTYPE_END); @@ -4223,7 +4223,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR RailType rt = _cur.grffile->railtype_map[id + i]; if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID; - RailtypeInfo *rti = &_railtypes[rt]; + RailTypeInfo *rti = &_railtypes[rt]; switch (prop) { case 0x08: // Label of rail type @@ -4342,7 +4342,7 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte { ChangeInfoResult ret = CIR_SUCCESS; - extern RailtypeInfo _railtypes[RAILTYPE_END]; + extern RailTypeInfo _railtypes[RAILTYPE_END]; if (id + numinfo > RAILTYPE_END) { GrfMsg(1, "RailTypeReserveInfo: Rail type {} is invalid, max {}, ignoring", id + numinfo, RAILTYPE_END); @@ -5929,10 +5929,10 @@ static void RailTypeMapSpriteGroup(ByteReader *buf, uint8_t idcount) if (ctype >= RTSG_END) continue; - extern RailtypeInfo _railtypes[RAILTYPE_END]; + extern RailTypeInfo _railtypes[RAILTYPE_END]; for (auto &railtype : railtypes) { if (railtype != INVALID_RAILTYPE) { - RailtypeInfo *rti = &_railtypes[railtype]; + RailTypeInfo *rti = &_railtypes[railtype]; rti->grffile[ctype] = _cur.grffile; rti->group[ctype] = _cur.spritegroups[groupid]; @@ -7595,7 +7595,7 @@ static void ParamSet(ByteReader *buf) break; case 0x8F: { // Rail track type cost factors - extern RailtypeInfo _railtypes[RAILTYPE_END]; + extern RailTypeInfo _railtypes[RAILTYPE_END]; _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8); if (_settings_game.vehicle.disable_elrails) { _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8); diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 11a6ff7d29..8eac2b0d7a 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -578,7 +578,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec switch (v->type) { case VEH_TRAIN: { RailType rt = GetTileRailType(v->tile); - const RailtypeInfo *rti = GetRailTypeInfo(rt); + const RailTypeInfo *rti = GetRailTypeInfo(rt); return ((rti->flags & RTFB_CATENARY) ? 0x200 : 0) | (HasPowerOnRail(Train::From(v)->railtype, rt) ? 0x100 : 0) | GetReverseRailTypeTranslation(rt, object->ro.grffile); diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 6b7bfd763c..a95d686d45 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -78,7 +78,7 @@ uint32_t RailTypeResolverObject::GetDebugID() const * @param param1 Extra parameter (first parameter of the callback, except railtypes do not have callbacks). * @param param2 Extra parameter (second parameter of the callback, except railtypes do not have callbacks). */ -RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32_t param1, uint32_t param2) +RailTypeResolverObject::RailTypeResolverObject(const RailTypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32_t param1, uint32_t param2) : ResolverObject(rti != nullptr ? rti->grffile[rtsg] : nullptr, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, rti, tile, context) { this->root_spritegroup = rti != nullptr ? rti->group[rtsg] : nullptr; @@ -93,7 +93,7 @@ RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileInde * @param[out] num_results If not nullptr, return the number of sprites in the spriteset. * @return The sprite to draw. */ -SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context, uint *num_results) +SpriteID GetCustomRailSprite(const RailTypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context, uint *num_results) { assert(rtsg < RTSG_END); @@ -118,7 +118,7 @@ SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSp * @param gui Is the sprite being used on the map or in the GUI? * @return The sprite to draw. */ -SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui) +SpriteID GetCustomSignalSprite(const RailTypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui) { if (rti->group[RTSG_SIGNALS] == nullptr) return 0; diff --git a/src/newgrf_railtype.h b/src/newgrf_railtype.h index 0d599fc976..af07556aef 100644 --- a/src/newgrf_railtype.h +++ b/src/newgrf_railtype.h @@ -18,7 +18,7 @@ struct RailTypeScopeResolver : public ScopeResolver { TileIndex tile; ///< Tracktile. For track on a bridge this is the southern bridgehead. TileContext context; ///< Are we resolving sprites for the upper halftile, or on a bridge? - const RailtypeInfo *rti; + const RailTypeInfo *rti; /** * Constructor of the railtype scope resolvers. @@ -26,7 +26,7 @@ struct RailTypeScopeResolver : public ScopeResolver { * @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead. * @param context Are we resolving sprites for the upper halftile, or on a bridge? */ - RailTypeScopeResolver(ResolverObject &ro, const RailtypeInfo *rti, TileIndex tile, TileContext context) + RailTypeScopeResolver(ResolverObject &ro, const RailTypeInfo *rti, TileIndex tile, TileContext context) : ScopeResolver(ro), tile(tile), context(context), rti(rti) { } @@ -39,7 +39,7 @@ struct RailTypeScopeResolver : public ScopeResolver { struct RailTypeResolverObject : public ResolverObject { RailTypeScopeResolver railtype_scope; ///< Resolver for the railtype scope. - RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32_t param1 = 0, uint32_t param2 = 0); + RailTypeResolverObject(const RailTypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32_t param1 = 0, uint32_t param2 = 0); ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { @@ -53,8 +53,8 @@ struct RailTypeResolverObject : public ResolverObject { uint32_t GetDebugID() const override; }; -SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context = TCX_NORMAL, uint *num_results = nullptr); -SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui = false); +SpriteID GetCustomRailSprite(const RailTypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context = TCX_NORMAL, uint *num_results = nullptr); +SpriteID GetCustomSignalSprite(const RailTypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui = false); RailType GetRailTypeTranslation(uint8_t railtype, const GRFFile *grffile); uint8_t GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile); diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 3dbf10538c..fa120d3b23 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -768,7 +768,7 @@ void DeallocateSpecFromStation(BaseStation *st, byte specindex) bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station) { const DrawTileSprites *sprites = nullptr; - const RailtypeInfo *rti = GetRailTypeInfo(railtype); + const RailTypeInfo *rti = GetRailTypeInfo(railtype); PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company); uint tile = 2; diff --git a/src/rail.cpp b/src/rail.cpp index d07c641b55..9bd11e391c 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -183,7 +183,7 @@ RailType GetTileRailType(Tile tile) * @param railtype requested RailType * @return true if company has requested RailType available */ -bool HasRailtypeAvail(const CompanyID company, const RailType railtype) +bool HasRailTypeAvail(const CompanyID company, const RailType railtype) { return !HasBit(_railtypes_hidden_mask, railtype) && HasBit(Company::Get(company)->avail_railtypes, railtype); } @@ -193,7 +193,7 @@ bool HasRailtypeAvail(const CompanyID company, const RailType railtype) * @param company the company in question * @return true if company has any RailTypes available */ -bool HasAnyRailtypesAvail(const CompanyID company) +bool HasAnyRailTypesAvail(const CompanyID company) { return (Company::Get(company)->avail_railtypes & ~_railtypes_hidden_mask) != 0; } @@ -203,9 +203,9 @@ bool HasAnyRailtypesAvail(const CompanyID company) * @param rail the railtype to check. * @return true if the current company may build the rail. */ -bool ValParamRailtype(const RailType rail) +bool ValParamRailType(const RailType rail) { - return rail < RAILTYPE_END && HasRailtypeAvail(_current_company, rail); + return rail < RAILTYPE_END && HasRailTypeAvail(_current_company, rail); } /** @@ -220,7 +220,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date RailTypes rts = current; for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - const RailtypeInfo *rti = GetRailTypeInfo(rt); + const RailTypeInfo *rti = GetRailTypeInfo(rt); /* Unused rail type. */ if (rti->label == 0) continue; @@ -248,7 +248,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date * @param introduces If true, include rail types introduced by other rail types * @return the rail types. */ -RailTypes GetCompanyRailtypes(CompanyID company, bool introduces) +RailTypes GetCompanyRailTypes(CompanyID company, bool introduces) { RailTypes rts = RAILTYPES_NONE; @@ -312,14 +312,14 @@ RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels) { /* Loop through each rail type until the label is found */ for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { - const RailtypeInfo *rti = GetRailTypeInfo(r); + const RailTypeInfo *rti = GetRailTypeInfo(r); if (rti->label == label) return r; } if (allow_alternate_labels) { /* Test if any rail type defines the label as an alternate. */ for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { - const RailtypeInfo *rti = GetRailTypeInfo(r); + const RailTypeInfo *rti = GetRailTypeInfo(r); if (std::find(rti->alternate_labels.begin(), rti->alternate_labels.end(), label) != rti->alternate_labels.end()) return r; } } diff --git a/src/rail.h b/src/rail.h index 4c46073ccc..6b52eab661 100644 --- a/src/rail.h +++ b/src/rail.h @@ -121,7 +121,7 @@ typedef std::vector RailTypeLabelList; /** * This struct contains all the info that is needed to draw and construct tracks. */ -class RailtypeInfo { +class RailTypeInfo { public: /** * Struct containing the main sprites. @note not all sprites are listed, but only @@ -299,11 +299,11 @@ public: /** * Returns a pointer to the Railtype information for a given railtype * @param railtype the rail type which the information is requested for - * @return The pointer to the RailtypeInfo + * @return The pointer to the RailTypeInfo */ -static inline const RailtypeInfo *GetRailTypeInfo(RailType railtype) +static inline const RailTypeInfo *GetRailTypeInfo(RailType railtype) { - extern RailtypeInfo _railtypes[RAILTYPE_END]; + extern RailTypeInfo _railtypes[RAILTYPE_END]; assert(railtype < RAILTYPE_END); return &_railtypes[railtype]; } @@ -355,8 +355,8 @@ static inline bool Rail90DegTurnDisallowed(RailType rt1, RailType rt2, bool def { if (rt1 == INVALID_RAILTYPE || rt2 == INVALID_RAILTYPE) return def; - const RailtypeInfo *rti1 = GetRailTypeInfo(rt1); - const RailtypeInfo *rti2 = GetRailTypeInfo(rt2); + const RailTypeInfo *rti1 = GetRailTypeInfo(rt1); + const RailTypeInfo *rti2 = GetRailTypeInfo(rt2); bool rt1_90deg = HasBit(rti1->flags, RTF_DISALLOW_90DEG) || (!HasBit(rti1->flags, RTF_ALLOW_90DEG) && def); bool rt2_90deg = HasBit(rti2->flags, RTF_DISALLOW_90DEG) || (!HasBit(rti2->flags, RTF_ALLOW_90DEG) && def); @@ -446,13 +446,13 @@ int TicksToLeaveDepot(const Train *v); Foundation GetRailFoundation(Slope tileh, TrackBits bits); -bool HasRailtypeAvail(const CompanyID company, const RailType railtype); -bool HasAnyRailtypesAvail(const CompanyID company); -bool ValParamRailtype(const RailType rail); +bool HasRailTypeAvail(const CompanyID company, const RailType railtype); +bool HasAnyRailTypesAvail(const CompanyID company); +bool ValParamRailType(const RailType rail); RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date date); -RailTypes GetCompanyRailtypes(CompanyID company, bool introduces = true); +RailTypes GetCompanyRailTypes(CompanyID company, bool introduces = true); RailTypes GetRailTypes(bool introduces); RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels = true); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index f4adfefe58..762f2bf855 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -43,7 +43,7 @@ /** Helper type for lists/vectors of trains */ typedef std::vector TrainList; -RailtypeInfo _railtypes[RAILTYPE_END]; +RailTypeInfo _railtypes[RAILTYPE_END]; std::vector _sorted_railtypes; RailTypes _railtypes_hidden_mask; @@ -67,12 +67,12 @@ void ResetRailTypes() static_assert(lengthof(_original_railtypes) <= lengthof(_railtypes)); auto insert = std::copy(std::begin(_original_railtypes), std::end(_original_railtypes), std::begin(_railtypes)); - std::fill(insert, std::end(_railtypes), RailtypeInfo{}); + std::fill(insert, std::end(_railtypes), RailTypeInfo{}); _railtypes_hidden_mask = RAILTYPES_NONE; } -void ResolveRailTypeGUISprites(RailtypeInfo *rti) +void ResolveRailTypeGUISprites(RailTypeInfo *rti) { SpriteID cursors_base = GetCustomRailSprite(rti, INVALID_TILE, RTSG_CURSORS); if (cursors_base != 0) { @@ -130,7 +130,7 @@ static bool CompareRailTypes(const RailType &first, const RailType &second) void InitRailTypes() { for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - RailtypeInfo *rti = &_railtypes[rt]; + RailTypeInfo *rti = &_railtypes[rt]; ResolveRailTypeGUISprites(rti); if (HasBit(rti->flags, RTF_HIDDEN)) SetBit(_railtypes_hidden_mask, rt); } @@ -150,7 +150,7 @@ void InitRailTypes() RailType AllocateRailType(RailTypeLabel label) { for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - RailtypeInfo *rti = &_railtypes[rt]; + RailTypeInfo *rti = &_railtypes[rt]; if (rti->label == 0) { /* Set up new rail type */ @@ -428,7 +428,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType rai { CommandCost cost(EXPENSES_CONSTRUCTION); - if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR; + if (!ValParamRailType(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR; Slope tileh = GetTileSlope(tile); TrackBits trackbit = TrackToTrackBits(track); @@ -878,7 +878,7 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, TileI { CommandCost total_cost(EXPENSES_CONSTRUCTION); - if ((!remove && !ValParamRailtype(railtype)) || !ValParamTrackOrientation(track)) return CMD_ERROR; + if ((!remove && !ValParamRailType(railtype)) || !ValParamTrackOrientation(track)) return CMD_ERROR; if (end_tile >= Map::Size() || tile >= Map::Size()) return CMD_ERROR; Trackdir trackdir = TrackToTrackdir(track); @@ -964,7 +964,7 @@ CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex end_tile, Tile CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir) { /* check railtype and valid direction for depot (0 through 3), 4 in total */ - if (!ValParamRailtype(railtype) || !IsValidDiagDirection(dir)) return CMD_ERROR; + if (!ValParamRailType(railtype) || !IsValidDiagDirection(dir)) return CMD_ERROR; Slope tileh = GetTileSlope(tile); @@ -1555,7 +1555,7 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s { TileIndex area_end = tile; - if (!ValParamRailtype(totype)) return CMD_ERROR; + if (!ValParamRailType(totype)) return CMD_ERROR; if (area_start >= Map::Size()) return CMD_ERROR; TrainList affected_trains; @@ -1869,7 +1869,7 @@ static uint GetSaveSlopeZ(uint x, uint y, Track track) return GetSlopePixelZ(x, y); } -static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, SignalState condition, SignalOffsets image, uint pos) +static void DrawSingleSignal(TileIndex tile, const RailTypeInfo *rti, Track track, SignalState condition, SignalOffsets image, uint pos) { bool side; switch (_settings_game.construction.train_signal_side) { @@ -2008,7 +2008,7 @@ static void DrawTrackFence_SW(const TileInfo *ti, SpriteID base_image, uint num_ * @param ti Tile drawing information. * @param rti Rail type information. */ -static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti) +static void DrawTrackDetails(const TileInfo *ti, const RailTypeInfo *rti) { /* Base sprite for track fences. * Note: Halftile slopes only have fences on the upper part. */ @@ -2070,7 +2070,7 @@ static inline void DrawTrackSprite(SpriteID sprite, PaletteID pal, const TileInf DrawGroundSprite(sprite, pal, nullptr, 0, (ti->tileh & s) ? -8 : 0); } -static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeInfo *rti) +static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailTypeInfo *rti) { RailGroundType rgt = GetRailGroundType(ti->tile); Foundation f = GetRailFoundation(ti->tileh, track); @@ -2237,7 +2237,7 @@ static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeIn */ static void DrawTrackBits(TileInfo *ti, TrackBits track) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); if (rti->UsesOverlay()) { DrawTrackBitsOverlay(ti, track, rti); @@ -2386,7 +2386,7 @@ static void DrawTrackBits(TileInfo *ti, TrackBits track) } } -static void DrawSignals(TileIndex tile, TrackBits rails, const RailtypeInfo *rti) +static void DrawSignals(TileIndex tile, TrackBits rails, const RailTypeInfo *rti) { #define MAYBE_DRAW_SIGNAL(x, y, z, t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, rti, t, GetSingleSignalState(tile, x), y, z) @@ -2420,7 +2420,7 @@ static void DrawSignals(TileIndex tile, TrackBits rails, const RailtypeInfo *rti static void DrawTile_Track(TileInfo *ti) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); _drawtile_track_palette = COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile)); @@ -2542,7 +2542,7 @@ static void DrawTile_Track(TileInfo *ti) void DrawTrainDepotSprite(int x, int y, int dir, RailType railtype) { const DrawTileSprites *dts = &_depot_gfx_table[dir]; - const RailtypeInfo *rti = GetRailTypeInfo(railtype); + const RailTypeInfo *rti = GetRailTypeInfo(railtype); SpriteID image = rti->UsesOverlay() ? SPR_FLAT_GRASS_TILE : dts->ground.sprite; uint32_t offset = rti->GetRailtypeSpriteOffset(); @@ -2781,7 +2781,7 @@ static bool ClickTile_Track(TileIndex tile) static void GetTileDesc_Track(TileIndex tile, TileDesc *td) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); td->rail_speed = rti->max_speed; td->railtype = rti->strings.name; td->owner[0] = GetTileOwner(tile); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 95c84b6d8d..cd9270f11c 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -435,7 +435,7 @@ struct BuildRailToolbarWindow : Window { void SetupRailToolbar(RailType railtype) { this->railtype = railtype; - const RailtypeInfo *rti = GetRailTypeInfo(railtype); + const RailTypeInfo *rti = GetRailTypeInfo(railtype); assert(railtype < RAILTYPE_END); this->GetWidget(WID_RAT_BUILD_NS)->widget_data = rti->gui_sprites.build_ns_rail; @@ -491,7 +491,7 @@ struct BuildRailToolbarWindow : Window { void SetStringParameters(int widget) const override { if (widget == WID_RAT_CAPTION) { - const RailtypeInfo *rti = GetRailTypeInfo(this->railtype); + const RailTypeInfo *rti = GetRailTypeInfo(this->railtype); if (rti->max_speed > 0) { SetDParam(0, STR_TOOLBAR_RAILTYPE_VELOCITY); SetDParam(1, rti->strings.toolbar_caption); @@ -857,7 +857,7 @@ static WindowDesc _build_rail_desc( Window *ShowBuildRailToolbar(RailType railtype) { if (!Company::IsValidID(_local_company)) return nullptr; - if (!ValParamRailtype(railtype)) return nullptr; + if (!ValParamRailType(railtype)) return nullptr; CloseWindowByClass(WC_BUILD_TOOLBAR); _cur_railtype = railtype; @@ -1704,7 +1704,7 @@ public: this->sig_sprite_size.width = 0; this->sig_sprite_size.height = 0; this->sig_sprite_bottom_offset = 0; - const RailtypeInfo *rti = GetRailTypeInfo(_cur_railtype); + const RailTypeInfo *rti = GetRailTypeInfo(_cur_railtype); for (uint type = SIGTYPE_NORMAL; type < SIGTYPE_END; type++) { for (uint variant = SIG_ELECTRIC; variant <= SIG_SEMAPHORE; variant++) { for (uint lowered = 0; lowered < 2; lowered++) { @@ -2268,14 +2268,14 @@ static void SetDefaultRailGui() case 0: { /* Use first available type */ std::vector::const_iterator it = std::find_if(_sorted_railtypes.begin(), _sorted_railtypes.end(), - [](RailType r){ return HasRailtypeAvail(_local_company, r); }); + [](RailType r){ return HasRailTypeAvail(_local_company, r); }); rt = it != _sorted_railtypes.end() ? *it : RAILTYPE_BEGIN; break; } case 1: { /* Use last available type */ std::vector::const_reverse_iterator it = std::find_if(_sorted_railtypes.rbegin(), _sorted_railtypes.rend(), - [](RailType r){ return HasRailtypeAvail(_local_company, r); }); + [](RailType r){ return HasRailTypeAvail(_local_company, r); }); rt = it != _sorted_railtypes.rend() ? *it : RAILTYPE_BEGIN; break; } @@ -2342,7 +2342,7 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) /* Find the used railtypes. */ if (for_replacement) { - avail_railtypes = GetCompanyRailtypes(c->index, false); + avail_railtypes = GetCompanyRailTypes(c->index, false); used_railtypes = GetRailTypes(false); } else { avail_railtypes = c->avail_railtypes; @@ -2360,7 +2360,7 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) if (!for_replacement) { for (const auto &rt : _sorted_railtypes) { if (!HasBit(used_railtypes, rt)) continue; - const RailtypeInfo *rti = GetRailTypeInfo(rt); + const RailTypeInfo *rti = GetRailTypeInfo(rt); d = maxdim(d, GetSpriteSize(rti->gui_sprites.build_x_rail)); } } @@ -2369,7 +2369,7 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) /* If it's not used ever, don't show it to the user. */ if (!HasBit(used_railtypes, rt)) continue; - const RailtypeInfo *rti = GetRailTypeInfo(rt); + const RailTypeInfo *rti = GetRailTypeInfo(rt); SetDParam(0, rti->strings.menu_text); SetDParam(1, rti->max_speed); diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index edcfefe56f..2e16f25a92 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1687,7 +1687,7 @@ static void DrawTile_Road(TileInfo *ti) Axis axis = GetCrossingRailAxis(ti->tile); - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); RoadType road_rt = GetRoadTypeRoad(ti->tile); RoadType tram_rt = GetRoadTypeTram(ti->tile); @@ -2174,7 +2174,7 @@ static void GetTileDesc_Road(TileIndex tile, TileDesc *td) td->str = STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING; rail_owner = GetTileOwner(tile); - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); td->railtype = rti->strings.name; td->rail_speed = rti->max_speed; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 815bc252d0..24ed09283b 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1413,7 +1413,7 @@ bool AfterLoadGame() } for (Company *c : Company::Iterate()) { - c->avail_railtypes = GetCompanyRailtypes(c->index); + c->avail_railtypes = GetCompanyRailTypes(c->index); c->avail_roadtypes = GetCompanyRoadTypes(c->index); } diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index b2d05ddbb1..b9e77ad578 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -29,7 +29,7 @@ static bool NeedRailTypeConversion() { for (uint i = 0; i < _railtype_list.size(); i++) { if ((RailType)i < RAILTYPE_END) { - const RailtypeInfo *rti = GetRailTypeInfo((RailType)i); + const RailTypeInfo *rti = GetRailTypeInfo((RailType)i); if (rti->label != _railtype_list[i]) return true; } else { if (_railtype_list[i] != 0) return true; diff --git a/src/script/api/script_rail.cpp b/src/script/api/script_rail.cpp index b703b8ce07..3caf070509 100644 --- a/src/script/api/script_rail.cpp +++ b/src/script/api/script_rail.cpp @@ -72,7 +72,7 @@ EnforceDeityOrCompanyModeValid(false); if ((::RailType)rail_type >= RAILTYPE_END) return false; - return ScriptCompanyMode::IsDeity() || ::HasRailtypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type); + return ScriptCompanyMode::IsDeity() || ::HasRailTypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type); } /* static */ ScriptRail::RailType ScriptRail::GetCurrentRailType() diff --git a/src/script/api/script_railtypelist.cpp b/src/script/api/script_railtypelist.cpp index cfc0b3b550..7bf55dca4b 100644 --- a/src/script/api/script_railtypelist.cpp +++ b/src/script/api/script_railtypelist.cpp @@ -18,6 +18,6 @@ ScriptRailTypeList::ScriptRailTypeList() { EnforceDeityOrCompanyModeValid_Void(); for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - if (ScriptCompanyMode::IsDeity() || ::HasRailtypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt); + if (ScriptCompanyMode::IsDeity() || ::HasRailTypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt); } } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index da47d6dfbd..83f8320b27 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1313,7 +1313,7 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp CommandCost ret = CheckIfAuthorityAllowsNewStation(tile_org, flags); if (ret.Failed()) return ret; - if (!ValParamRailtype(rt) || !IsValidAxis(axis)) return CMD_ERROR; + if (!ValParamRailType(rt) || !IsValidAxis(axis)) return CMD_ERROR; /* Check if the given station class is valid */ if ((uint)spec_class >= StationClass::GetClassCount() || spec_class == STAT_CLASS_WAYP) return CMD_ERROR; @@ -2924,7 +2924,7 @@ static void DrawTile_Station(TileInfo *ti) DrawTileSprites tmp_rail_layout; const DrawTileSprites *t = nullptr; int32_t total_offset; - const RailtypeInfo *rti = nullptr; + const RailTypeInfo *rti = nullptr; uint32_t relocation = 0; uint32_t ground_relocation = 0; BaseStation *st = nullptr; @@ -3213,7 +3213,7 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro int32_t total_offset = 0; PaletteID pal = COMPANY_SPRITE_COLOUR(_local_company); const DrawTileSprites *t = GetStationTileLayout(st, image); - const RailtypeInfo *railtype_info = nullptr; + const RailTypeInfo *railtype_info = nullptr; if (railtype != INVALID_RAILTYPE) { railtype_info = GetRailTypeInfo(railtype); @@ -3321,7 +3321,7 @@ void FillTileDescRailStation(TileIndex tile, TileDesc *td) } } - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); td->rail_speed = rti->max_speed; td->railtype = rti->strings.name; } diff --git a/src/table/railtypes.h b/src/table/railtypes.h index b70b4f8c8f..7346e0470a 100644 --- a/src/table/railtypes.h +++ b/src/table/railtypes.h @@ -16,7 +16,7 @@ /** * Global Railtype definition */ -static const RailtypeInfo _original_railtypes[] = { +static const RailTypeInfo _original_railtypes[] = { /** Railway */ { // Main Sprites { SPR_RAIL_TRACK_Y, SPR_RAIL_TRACK_N_S, SPR_RAIL_TRACK_BASE, SPR_RAIL_SINGLE_X, SPR_RAIL_SINGLE_Y, diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 472f462938..0958fb582c 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -357,7 +357,7 @@ int Train::GetCurveSpeedLimit() const if (max_speed != absolute_max_speed) { /* Apply the current railtype's curve speed advantage */ - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(this->tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(this->tile)); max_speed += (max_speed / 2) * rti->curve_speed; if (this->tcache.cached_tilt) { diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 61adb5936e..f21139fb8d 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -275,7 +275,7 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex ti case TRANSPORT_RAIL: railtype = (RailType)road_rail_type; - if (!ValParamRailtype(railtype)) return CMD_ERROR; + if (!ValParamRailType(railtype)) return CMD_ERROR; break; case TRANSPORT_WATER: @@ -631,7 +631,7 @@ CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportT switch (transport_type) { case TRANSPORT_RAIL: railtype = (RailType)road_rail_type; - if (!ValParamRailtype(railtype)) return CMD_ERROR; + if (!ValParamRailType(railtype)) return CMD_ERROR; break; case TRANSPORT_ROAD: @@ -1285,7 +1285,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) SpriteID image; SpriteID railtype_overlay = 0; if (transport_type == TRANSPORT_RAIL) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); image = rti->base_sprites.tunnel; if (rti->UsesOverlay()) { /* Check if the railtype has custom tunnel portals. */ @@ -1354,7 +1354,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) AddSortableSpriteToDraw(catenary_sprite_base + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR); } } else { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); if (rti->UsesOverlay()) { SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_TUNNEL); if (surface != 0) DrawGroundSprite(surface + tunnelbridge_direction, PAL_NONE); @@ -1459,7 +1459,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) EndSpriteCombine(); } else if (transport_type == TRANSPORT_RAIL) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); if (rti->UsesOverlay()) { SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE); if (surface != 0) { @@ -1617,7 +1617,7 @@ void DrawBridgeMiddle(const TileInfo *ti) /* DrawBridgeRoadBits() calls EndSpriteCombine() and StartSpriteCombine() */ DrawBridgeRoadBits(rampsouth, x, y, bridge_z, axis ^ 1, false); } else if (transport_type == TRANSPORT_RAIL) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(rampsouth)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(rampsouth)); if (rti->UsesOverlay() && !IsInvisibilitySet(TO_BRIDGES)) { SpriteID surface = GetCustomRailSprite(rti, rampsouth, RTSG_BRIDGE, TCX_ON_BRIDGE); if (surface != 0) { @@ -1744,7 +1744,7 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) } if (tt == TRANSPORT_RAIL) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); + const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); td->rail_speed = rti->max_speed; td->railtype = rti->strings.name; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 270d3c655b..56c17b89ef 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1835,7 +1835,7 @@ bool CanBuildVehicleInfrastructure(VehicleType type, byte subtype) UnitID max; switch (type) { case VEH_TRAIN: - if (!HasAnyRailtypesAvail(_local_company)) return false; + if (!HasAnyRailTypesAvail(_local_company)) return false; max = _settings_game.vehicle.max_trains; break; case VEH_ROAD: From 3fd50c29490b08efe1b6a789eddc3578e2452c98 Mon Sep 17 00:00:00 2001 From: translators Date: Mon, 11 Sep 2023 18:38:29 +0000 Subject: [PATCH 48/72] Update: Translations from eints swedish: 2 changes by optiedev vietnamese: 11 changes by KhoiCanDev romanian: 5 changes by bnegrut danish: 2 changes by bscargo dutch: 2 changes by Afoklala portuguese: 2 changes by azulcosta polish: 15 changes by pAter-exe --- src/lang/danish.txt | 2 ++ src/lang/dutch.txt | 2 ++ src/lang/polish.txt | 22 +++++++++++++++------- src/lang/portuguese.txt | 2 ++ src/lang/romanian.txt | 7 +++++-- src/lang/swedish.txt | 2 ++ src/lang/vietnamese.txt | 19 +++++++++++-------- 7 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 41f34ec01d..d259ec7c89 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -1426,6 +1426,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ingen* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :reduceret STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Tillad vejkryds - jernbaneoverskæringer med veje eller skinner ejet af konkurrenter: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Tillad konstruktion af overkørsler på veje eller skinner ejet af konkurrenter STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Tillad gennemkørsels-stop på veje ejet af en by: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Tillad konstruktion af gennemkørsels-stop på by-ejede veje diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 32965faf2c..b3d1cc233f 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -1426,6 +1426,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Geen* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Verminderd STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normaal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Gelijkvloerse kruisingen met wegen of spoorwegen van tegenstanders toestaan: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Bouwen van gelijkvloerse kruisingen met wegen of spoorwegen van tegenstanders toestaan STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Doorrijhaltes op stedelijke wegen toestaan: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Bouwen van doorrijhaltes op stedelijke wegen toestaan diff --git a/src/lang/polish.txt b/src/lang/polish.txt index fcd92b40ae..8236503745 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -538,12 +538,12 @@ STR_ABBREV_ALL :+ # 'Mode' of transport for cargoes STR_PASSENGERS :{COMMA}{NBSP}pasażer{P "" ów ów} STR_BAGS :{COMMA}{NBSP}wor{P ek ki ków} -STR_BAGS.d :{COMMA} worków -STR_BAGS.c :{COMMA} workom -STR_BAGS.b :{COMMA} worki -STR_BAGS.n :{COMMA} workami -STR_BAGS.m :{COMMA} workach -STR_BAGS.w :{COMMA} worki +STR_BAGS.d :{COMMA}{NBSP}worków +STR_BAGS.c :{COMMA}{NBSP}workom +STR_BAGS.b :{COMMA}{NBSP}worki +STR_BAGS.n :{COMMA}{NBSP}workami +STR_BAGS.m :{COMMA}{NBSP}workach +STR_BAGS.w :{COMMA}{NBSP}worki STR_TONS :{COMMA}{NBSP}ton{P a y ""} STR_LITERS :{COMMA}{NBSP}litr{P "" y ów} STR_ITEMS :{COMMA}{NBSP}sztuk{P a i ""} @@ -1806,6 +1806,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Brak* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Zredukowana STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalna +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Pozwól na skrzyżowania dróg z torami kolejowymi należącymi do konkurentów: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Pozwala budować przejazdy kolejowe przez drogi lub tory należące do konkurentów STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Pozwól na budowę przystanków przelotowych na drogach miejskich: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Pozwalaj budować przystanki przelotowe na drogach będących własnością miast @@ -5179,7 +5181,7 @@ STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Należy STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Nie można wyczyścić terenu... STR_ERROR_SITE_UNSUITABLE :{WHITE}... niewłaściwa parcela STR_ERROR_ALREADY_BUILT :{WHITE}... już zbudowano -STR_ERROR_OWNED_BY :{WHITE}... w posiadaniu {STRING} +STR_ERROR_OWNED_BY :{WHITE}... własność {STRING.d} STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... teren jest własnością innej firmy STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}... osiągnięto limit kształtowania terenu STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}... osiągnięto limit czyszczenia pól @@ -6031,6 +6033,12 @@ STR_FORMAT_DEPOT_NAME_AIRCRAFT :Hangar {STATION STR_UNKNOWN_STATION :Nieznana stacja STR_DEFAULT_SIGN_NAME :Napis STR_COMPANY_SOMEONE :ktoś +STR_COMPANY_SOMEONE.d :kogoś +STR_COMPANY_SOMEONE.c :komuś +STR_COMPANY_SOMEONE.b :kogoś +STR_COMPANY_SOMEONE.n :kimś +STR_COMPANY_SOMEONE.m :kimś +STR_COMPANY_SOMEONE.w :ktoś STR_SAVEGAME_NAME_DEFAULT :{COMPANY}, {STRING} STR_SAVEGAME_NAME_SPECTATOR :Obserwator, {1:STRING} diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index bad1d34ef1..52da4c4b62 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -1427,6 +1427,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nenhum* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduzido STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Permitir passagens de nível com estradas ou carris de outras empresas: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Permite a construção de passagens de nível nas estradas ou carris pertencentes a outras empresas STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permite estações de passagem nas estradas pertencentes às localidades: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permite a construção de estações de passagem nas ruas pertencentes a localidades. diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index 6bc056c16b..89b6810e94 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -1425,6 +1425,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :niciunul STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :redus STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :normal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Permite treceri la nivel cu drumuri sau șine deținute de concurenți: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Permite construirea de treceri la nivel pe drumuri sau șine deținute de concurenți STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permite construirea stațiilor pe drumurile deținute de orașe: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permite construirea de stații pe drumurile aflate în proprietatea orașelor @@ -1896,8 +1898,8 @@ STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Permite ca ora STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Orașele au voie să construiască treceri la nivel cu calea ferată: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Dacă este activată, orașele vor putea să construiască treceri la nivel cu calea ferată -STR_CONFIG_SETTING_NOISE_LEVEL :Permite controlarea nivelului de zgomot al aeroportului de către oras: {STRING} -STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Dacă această opțiune este dezactivată, pot exista două aeroporturi în fiecare oraș. Când opțiunea este activată, numărul de aeroporturi este limitat de nivelul de zgomot acceptat de oraș, care depinde de populație, mărimea aeroportului și distanța față de oraș +STR_CONFIG_SETTING_NOISE_LEVEL :Limitează amplasarea aeroportului în funcție de nivelul de zgomot: {STRING} +STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Permiteți orașelor să blocheze construcția aeroportului pe baza nivelului de acceptare a zgomotului, care se bazează pe populația orașului și pe dimensiunea și distanța aeroportului. Dacă această setare este dezactivată, orașele permit doar două aeroporturi, cu excepția cazului în care atitudinea autorităților locale este setată la „Permisiv”. STR_CONFIG_SETTING_TOWN_FOUNDING :Crearea oraşelor în joc: {STRING} STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Dacă este activată, jucătorii pot fonda noi orașe în joc @@ -2650,6 +2652,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Comută STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Comută transparenţa pentru poduri. Ctrl+Click pentru blocare STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Comută transparenţa pentru structuri de tip faruri şi antene. Ctrl+Click pentru blocare STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Comută transparenţa pentru catenar. Ctrl+Click pentru blocare +STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK}Comută transparența textului pentru încărcare și cost/venit. Ctrl+Clic pentru a bloca STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Setează obiectele ca invizibile în loc de transparente # Linkgraph legend window diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index f041518176..69135adb59 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -1426,6 +1426,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Inga* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reducerad STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Tillåt korsningar med vägar och räls ägda av andra företag: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Tillåt genomfartshållplatser på vägar som ägs av städer: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Tillåt konstruktion av genomfartshållplatser på vägar som ägs av städer @@ -2651,6 +2652,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Växla g STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Växla genomskinlighet för broar. Ctrl+klick för att låsa STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Växla genomskinlighet för byggnader såsom fyrar och antenner. Ctrl+klick för att låsa STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Växla genomskinlighet för kontaktledning. Ctrl+klick för att låsa +STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK} Växla genomskinlighet för pålastnings, kostnads och inkomsttext. Ctrl+klick för att låsa STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Gör object osynliga istället för genomskinliga # Linkgraph legend window diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index c7cd7caf17..f764f618dd 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -783,7 +783,7 @@ STR_SMALLMAP_LEGENDA_AIRCRAFT :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES :{TINY_FONT}{BLACK}Tuyến vận tải STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLACK}Rừng STR_SMALLMAP_LEGENDA_RAILROAD_STATION :{TINY_FONT}{BLACK}Ga tàu hỏa -STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Truck Loading Bay +STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Trạm bốc dỡ hàng xe tải STR_SMALLMAP_LEGENDA_BUS_STATION :{TINY_FONT}{BLACK}Bến xe buýt STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT :{TINY_FONT}{BLACK}Sân bay/Bãi đỗ trực thăng STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLACK}Cảng biển @@ -1426,6 +1426,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :không* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :giảm bớt STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :bình thường +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Cho phép đường cắt ngang trên đường trường hoặc đường ray sở hữu bởi công ty khác: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Cho phép xây dựng đường cắt ngang trên đường trường hoặc đường ray sở hữu bởi công ty khác STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Cho phép xây điểm dừng xe buýt trên đường sở hữu bởi thị trấn: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Cho phép xây dựng điểm dừng xe buýt trên đường thuộc sở hữu của địa phương @@ -1897,8 +1899,8 @@ STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Cho phép đô STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Đô thị cho phép xây giao nhau đồng mức: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Bật tùy chọn này cho phép đô thị xây giao nhau đồng mức -STR_CONFIG_SETTING_NOISE_LEVEL :Cho phép chính quyền địa phương kiểm soát độ ồn của sân bay: {STRING} -STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Nếu tắt tùy chọn này, mỗi đô thị chỉ xây được 2 sân bay. Nếu bật tùy chọn này, số lượng sân bay được giới hạn bởi độ ồn cho phép của đô thị, dựa vào dân số, quy mô sân bay và khoảng cách +STR_CONFIG_SETTING_NOISE_LEVEL :Giới hạn vị trí xây sân bay dựa vào độ ồn: {STRING} +STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Cho phép đô thị từ chối việc xây dựng sân bay dựa vào độ ồn cho phép của họ, được tính trên lượng dân số của đô thị và khoảng cách, kích thước của sân bay. Nếu thiết lập này được tắt, đô thị chỉ cho phép hai sân bay trừ khi thái độ của địa phương đang ở trạng thái "Dễ dãi" STR_CONFIG_SETTING_TOWN_FOUNDING :Thành lập đô thị trong ván chơi: {STRING} STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Bật tùy chọn này cho phép người chơi tạo lập đô thị mới trong màn chơi @@ -2645,12 +2647,13 @@ STR_MISSING_GRAPHICS_ERROR_QUIT :{BLACK}Thoát O STR_TRANSPARENCY_CAPTION :{WHITE}Tuỳ Hiệu Ứng Trong Suốt STR_TRANSPARENT_SIGNS_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho đèn tín hiệu. Ctrl+Click để khoá. STR_TRANSPARENT_TREES_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho cây cối. Ctrl+Click để khoá. -STR_TRANSPARENT_HOUSES_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho nhà cửa. Ctrl+Click để khoá. -STR_TRANSPARENT_INDUSTRIES_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho nhà máy. Ctrl+Click để khoá. -STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho các công trình nhà ga, xưởng và điểm mốc. Ctrl+Click để khoá. -STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho cầu. Ctrl+Click để khoá. +STR_TRANSPARENT_HOUSES_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho nhà cửa. Ctrl+Click để khoá +STR_TRANSPARENT_INDUSTRIES_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho nhà máy. Ctrl+Click để khoá +STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho các công trình nhà ga, xưởng và điểm mốc. Ctrl+Click để khoá +STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho cầu. Ctrl+Click để khoá STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho đèn biển, ăn-ten... Ctrl+Click để khoá. -STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho các mắt xích. Ctrl+Click để khoá. +STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho các mắt xích. Ctrl+Click để khoá +STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK}Bật hiệu ứng trong suốt cho thông báo tải và chi phí/thu nhập. Ctrl+Click để khoá STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Đặt các đối ẩn đi thay vì trong suốt # Linkgraph legend window From b389d45d55da17e527bc0d8ee1f4fc364984643e Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Mon, 11 Sep 2023 20:55:23 +0200 Subject: [PATCH 49/72] Doc: Add more hyperlinks within the included documentation (#11288) Co-authored-by: Niels Martin Hansen --- CONTRIBUTING.md | 10 ++++++++++ COPYING.md | 2 +- README.md | 20 ++++++++++++++------ docs/debugging_desyncs.md | 3 +++ docs/multiplayer.md | 3 +++ 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2c76179dee..0f773ff320 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -182,6 +182,16 @@ There is no single source for OpenTTD development docs. It's a complex project w A good entry point is [Development](https://wiki.openttd.org/en/Development/) on the OpenTTD wiki; this provides links to wiki documentation and other sources. The GitHub repo also includes some non-comprehensive documentation in [/docs](./docs). +These include: +- When to [change other languages and when not to](./docs/eints.md). +- The [savegame format](./docs/savegame_format.md). +- The [release process](./docs/releasing_openttd.md). +- Some [notes on the link graph algorithm](./docs/linkgraph.md). +- The [network game coordinator](./docs/game_coordinator.md). +- How to use [the admin port for network games](./docs/admin_network.md), also useful for multiplayer server hosts. +- The [performance metrics and logging features](./docs/logging_and_performance_metrics.md), also useful for add-on developers. +- How [symbol server and analysis works](./docs/symbol_server.md). +- And several miscellaneous files detailing internal data structures and graphics measurements and palettes. You may also want the guide to [compiling OpenTTD](./COMPILING.md). diff --git a/COPYING.md b/COPYING.md index 2c2818d14c..27885642ba 100644 --- a/COPYING.md +++ b/COPYING.md @@ -1,5 +1,5 @@ This is the license which applies to OpenTTD with the exception of some -3rd party modules. See [./README.md](./README.md) for details +3rd party modules. See [our readme](./README.md) for details GNU General Public License ========================== diff --git a/README.md b/README.md index 374df8f7f4..b7b66a1024 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,10 @@ - 1.6) [OpenTTD directories](#16-openttd-directories) - 1.7) [Compiling OpenTTD](#17-compiling-openttd) - 2.0) [Contact and community](#20-contact-and-community) - - 2.1) [Contributing to OpenTTD](#21-contributing-to-openttd) - - 2.2) [Reporting bugs](#22-reporting-bugs) - - 2.3) [Translating](#23-translating) + - 2.1) [Multiplayer games](#21-multiplayer-games) + - 2.2) [Contributing to OpenTTD](#22-contributing-to-openttd) + - 2.3) [Reporting bugs](#23-reporting-bugs) + - 2.4) [Translating](#24-translating) - 3.0) [Licensing](#30-licensing) - 4.0) [Credits](#40-credits) @@ -144,12 +145,19 @@ If you want to compile OpenTTD from source, instructions can be found in [COMPIL - the OpenTTD wiki has a [page listing OpenTTD communities](https://wiki.openttd.org/en/Community/Community) including some in languages other than English -### 2.1) Contributing to OpenTTD +### 2.1) Multiplayer games + +You can play OpenTTD with others, either cooperatively or competitively. + +See the [multiplayer documentation](./docs/multiplayer.md) for more details. + + +### 2.2) Contributing to OpenTTD We welcome contributors to OpenTTD. More information for contributors can be found in [CONTRIBUTING.md](./CONTRIBUTING.md) -### 2.2) Reporting bugs +### 2.3) Reporting bugs Good bug reports are very helpful. We have a [guide to reporting bugs](./CONTRIBUTING.md#bug-reports) to help with this. @@ -157,7 +165,7 @@ Desyncs in multiplayer are complex to debug and report (some software developmen Instructions can be found in [debugging and reporting desyncs](./docs/debugging_desyncs.md). -### 2.3) Translating +### 2.4) Translating OpenTTD is translated into many languages. Translations are added and updated via the [online translation tool](https://translator.openttd.org). diff --git a/docs/debugging_desyncs.md b/docs/debugging_desyncs.md index f5ea06e082..0b6aacde8e 100644 --- a/docs/debugging_desyncs.md +++ b/docs/debugging_desyncs.md @@ -53,4 +53,7 @@ Do NOT remove the dmp_cmds savegames of a desync you have reported until the desync has been fixed; if you, by accident, send us the wrong savegames we will not be able to reproduce the desync and thus will be unable to fix it. +## More information +You can find more theory on the causes and debugging of desyncs in the +[desync documentation](./desync.md). diff --git a/docs/multiplayer.md b/docs/multiplayer.md index 6ef14c4e77..15aaa68e15 100644 --- a/docs/multiplayer.md +++ b/docs/multiplayer.md @@ -193,6 +193,9 @@ If it is, and your server still isn't showing up, start OpenTTD with `-d net=4` as extra argument. This will show debug message related to the network, including communication to/from the Game Coordinator. +See the [Game Coordinator documentation](./game_coordinator.md) for more +technical information about the Game Coordinator service. + ### My server warns a lot about getaddrinfo taking N seconds This could be a transient issue with your (local) DNS server, but if the From a16aa3ef7d5a5789a8e988567adde7685aee3d2b Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 12 Sep 2023 18:38:00 +0000 Subject: [PATCH 50/72] Update: Translations from eints swedish: 1 change by joeax910 --- src/lang/swedish.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 69135adb59..8c33b08ce3 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -1427,6 +1427,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reducerad STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Tillåt korsningar med vägar och räls ägda av andra företag: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Tillåt konstruktion av korsningar på vägar och järnvägar som ägs av motståndare STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Tillåt genomfartshållplatser på vägar som ägs av städer: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Tillåt konstruktion av genomfartshållplatser på vägar som ägs av städer From d1a0ca67be2bf9c403e3ed4572fa34db259efa95 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 13 Sep 2023 15:40:01 +0200 Subject: [PATCH 51/72] Codechange: simplify splitting of CargoPacket (#11286) --- src/cargopacket.cpp | 51 +++++++++++++++++++++-------------- src/cargopacket.h | 3 ++- src/saveload/oldloader_sl.cpp | 4 +-- src/saveload/station_sl.cpp | 2 +- src/saveload/vehicle_sl.cpp | 2 +- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 3b9a46fb9f..cc2929b516 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -32,48 +32,59 @@ CargoPacket::CargoPacket() /** * Creates a new cargo packet. + * * @param first_station Source station of the packet. * @param source_xy Source location of the packet. * @param count Number of cargo entities to put in this packet. * @param source_type 'Type' of source the packet comes from (for subsidies). * @param source_id Actual source of the packet (for subsidies). * @pre count != 0 - * @note We have to zero memory ourselves here because we are using a 'new' - * that, in contrary to all other pools, does not memset to 0. */ CargoPacket::CargoPacket(StationID first_station, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id) : - count(count), - source_xy(source_xy), - source_id(source_id), - source_type(source_type), - first_station(first_station) + count(count), + source_xy(source_xy), + source_id(source_id), + source_type(source_type), + first_station(first_station) { assert(count != 0); } /** - * Creates a new cargo packet. Initializes the fields that cannot be changed later. - * Used when loading or splitting packets. + * Create a new cargo packet. Used for older savegames to load in their partial data. + * * @param count Number of cargo entities to put in this packet. * @param periods_in_transit Number of cargo aging periods the cargo has been in transit. * @param first_station Station the cargo was initially loaded. - * @param next_hop Next station the cargo wants to go. * @param source_xy Station location the cargo was initially loaded. * @param feeder_share Feeder share the packet has already accumulated. - * @param source_type 'Type' of source the packet comes from (for subsidies). - * @param source_id Actual source of the packet (for subsidies). - * @note We have to zero memory ourselves here because we are using a 'new' - * that, in contrary to all other pools, does not memset to 0. */ -CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, StationID next_hop, TileIndex source_xy, Money feeder_share, SourceType source_type, SourceID source_id) : +CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, TileIndex source_xy, Money feeder_share) : count(count), periods_in_transit(periods_in_transit), feeder_share(feeder_share), source_xy(source_xy), - source_id(source_id), - source_type(source_type), - first_station(first_station), - next_hop(next_hop) + first_station(first_station) +{ + assert(count != 0); +} + +/** + * Creates a new cargo packet. Used when loading or splitting packets. + * + * @param count Number of cargo entities to put in this packet. + * @param feeder_share Feeder share the packet has already accumulated. + * @param original The original packet we are splitting. + */ +CargoPacket::CargoPacket(uint16_t count, Money feeder_share, CargoPacket &original) : + count(count), + periods_in_transit(original.periods_in_transit), + feeder_share(feeder_share), + source_xy(original.source_xy), + source_id(original.source_id), + source_type(original.source_type), + first_station(original.first_station), + next_hop(original.next_hop) { assert(count != 0); } @@ -88,7 +99,7 @@ CargoPacket *CargoPacket::Split(uint new_size) if (!CargoPacket::CanAllocateItem()) return nullptr; Money fs = this->GetFeederShare(new_size); - CargoPacket *cp_new = new CargoPacket(new_size, this->periods_in_transit, this->first_station, this->next_hop, this->source_xy, fs, this->source_type, this->source_id); + CargoPacket *cp_new = new CargoPacket(new_size, fs, *this); this->feeder_share -= fs; this->count -= new_size; return cp_new; diff --git a/src/cargopacket.h b/src/cargopacket.h index 85f8e6a42f..c5dfb0cfef 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -63,7 +63,8 @@ public: CargoPacket(); CargoPacket(StationID first_station, TileIndex source_xy, uint16_t count, SourceType source_type, SourceID source_id); - CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, StationID next_station, TileIndex source_xy, Money feeder_share = 0, SourceType source_type = SourceType::Industry, SourceID source_id = INVALID_SOURCE); + CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, TileIndex source_xy, Money feeder_share); + CargoPacket(uint16_t count, Money feeder_share, CargoPacket &original); /** Destroy the packet. */ ~CargoPacket() { } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 1936d66b2b..cb1e261eeb 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -710,7 +710,7 @@ static bool LoadOldGood(LoadgameState *ls, int num) SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15)); SB(ge->status, GoodsEntry::GES_RATING, 1, _cargo_source != 0xFF); if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) { - ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, INVALID_STATION, 0), + ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, INVALID_TILE, 0), INVALID_STATION); } @@ -1353,7 +1353,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) { StationID source = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source; TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : (TileIndex)0; - v->cargo.Append(new CargoPacket(_cargo_count, _cargo_periods, source, INVALID_STATION, source_xy)); + v->cargo.Append(new CargoPacket(_cargo_count, _cargo_periods, source, source_xy, 0)); } } diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 3203188bf9..f3b7af25a3 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -449,7 +449,7 @@ public: assert(CargoPacket::CanAllocateItem()); /* Don't construct the packet with station here, because that'll fail with old savegames */ - CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, source, INVALID_STATION, _cargo_source_xy, _cargo_feeder_share); + CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, source, _cargo_source_xy, _cargo_feeder_share); ge->cargo.Append(cp, INVALID_STATION); SB(ge->status, GoodsEntry::GES_RATING, 1, 1); } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 92da70d9b7..4ef24cf228 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -1041,7 +1041,7 @@ struct VEHSChunkHandler : ChunkHandler { if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v) && CargoPacket::CanAllocateItem()) { /* Don't construct the packet with station here, because that'll fail with old savegames */ - CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_periods, _cargo_source, INVALID_STATION, _cargo_source_xy, _cargo_feeder_share); + CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_periods, _cargo_source, _cargo_source_xy, _cargo_feeder_share); v->cargo.Append(cp); } From 4765d0f8c2a351ad2e2d11b32eb8433582d4c119 Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Sat, 3 Apr 2021 00:49:57 +0200 Subject: [PATCH 52/72] Change: Text Layouter support querying all lines for character at pixel --- src/gfx.cpp | 2 +- src/gfx_layout.cpp | 7 +++++-- src/gfx_layout.h | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gfx.cpp b/src/gfx.cpp index ef2bbc06f3..24329c430e 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -899,7 +899,7 @@ ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize if (x < 0) return -1; Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize); - return layout.GetCharAtPosition(x); + return layout.GetCharAtPosition(x, 0); } /** diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index 6ae31bfd15..2f479247ec 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -270,11 +270,14 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const /** * Get the character that is at a pixel position in the first line of the layouted text. * @param x Position in the string. + * @param line_index Which line of the layout to search * @return String offset of the position (bytes) or -1 if no character is at the position. */ -ptrdiff_t Layouter::GetCharAtPosition(int x) const +ptrdiff_t Layouter::GetCharAtPosition(int x, size_t line_index) const { - const auto &line = this->front(); + if (line_index >= this->size()) return -1; + + const auto &line = this->at(line_index); for (int run_index = 0; run_index < line->CountRuns(); run_index++) { const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index); diff --git a/src/gfx_layout.h b/src/gfx_layout.h index 3a5b48d316..0fe321921b 100644 --- a/src/gfx_layout.h +++ b/src/gfx_layout.h @@ -177,7 +177,7 @@ public: Layouter(std::string_view str, int maxw = INT32_MAX, TextColour colour = TC_FROMSTRING, FontSize fontsize = FS_NORMAL); Dimension GetBounds(); Point GetCharPosition(std::string_view::const_iterator ch) const; - ptrdiff_t GetCharAtPosition(int x) const; + ptrdiff_t GetCharAtPosition(int x, size_t line_index) const; static void ResetFontCache(FontSize size); static void ResetLineCache(); From 2cff43251ebde09ab8fe33e610dd0887206e8aae Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Sat, 3 Apr 2021 12:01:29 +0200 Subject: [PATCH 53/72] Add: Install additional documentation files with the game Also include it in Emscripten packages --- CMakeLists.txt | 15 +++++++++++++++ cmake/InstallAndPackage.cmake | 19 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 400c145e08..9ed01c2101 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -381,6 +381,21 @@ if(EMSCRIPTEN) target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_BINARY_DIR}/lang/english.lng@/lang/english.lng") target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/bin/ai@/ai") target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/bin/game@/game") + # Documentation files for the in-game text file viewer + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/README.md@/README.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/CREDITS.md@/CREDITS.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/CONTRIBUTING.md@/CONTRIBUTING.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/COPYING.md@/COPYING.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/known-bugs.txt@/known-bugs.txt") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/changelog.txt@/changelog.txt") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/admin_network.md@/docs/admin_network.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/debugging_desyncs.md@/docs/debugging_desyncs.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/desync.md@/docs/desync.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/directory_structure.md@/docs/directory_structure.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/linkgraph.md@/docs/linkgraph.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/logging_and_performance_metrics.md@/docs/logging_and_performance_metrics.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/multiplayer.md@/docs/multiplayer.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/savegame_format.md@/docs/savegame_format.md") # We use IDBFS for persistent storage. target_link_libraries(WASM::WASM INTERFACE "-lidbfs.js") diff --git a/cmake/InstallAndPackage.cmake b/cmake/InstallAndPackage.cmake index 3a894b5a62..b38e88a6c8 100644 --- a/cmake/InstallAndPackage.cmake +++ b/cmake/InstallAndPackage.cmake @@ -37,12 +37,29 @@ install(DIRECTORY install(FILES ${CMAKE_SOURCE_DIR}/COPYING.md ${CMAKE_SOURCE_DIR}/README.md + ${CMAKE_SOURCE_DIR}/CREDITS.md + ${CMAKE_SOURCE_DIR}/CONTRIBUTING.md ${CMAKE_SOURCE_DIR}/changelog.txt - ${CMAKE_SOURCE_DIR}/docs/multiplayer.md ${CMAKE_SOURCE_DIR}/known-bugs.txt DESTINATION ${DOCS_DESTINATION_DIR} COMPONENT docs) +install(FILES + ${CMAKE_SOURCE_DIR}/docs/admin_network.md + ${CMAKE_SOURCE_DIR}/docs/debugging_desyncs.md + ${CMAKE_SOURCE_DIR}/docs/desync.md + ${CMAKE_SOURCE_DIR}/docs/directory_structure.md + ${CMAKE_SOURCE_DIR}/docs/game_coordinator.md + ${CMAKE_SOURCE_DIR}/docs/linkgraph.md + ${CMAKE_SOURCE_DIR}/docs/logging_and_performance_metrics.md + ${CMAKE_SOURCE_DIR}/docs/multiplayer.md + ${CMAKE_SOURCE_DIR}/docs/savegame_format.md + ${CMAKE_SOURCE_DIR}/docs/obg_format.txt + ${CMAKE_SOURCE_DIR}/docs/obm_format.txt + ${CMAKE_SOURCE_DIR}/docs/obs_format.txt + DESTINATION ${DOCS_DESTINATION_DIR}/docs + COMPONENT docs) + # A Linux manual only makes sense when using FHS. Otherwise it is a very odd # file with little context to what it is. if(OPTION_INSTALL_FHS) From 41de0d46f358cc5c08d67fdafcb2ee830ccc236e Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Sun, 18 Jun 2023 17:10:08 +0200 Subject: [PATCH 54/72] Feature: Help and manuals access window --- CMakeLists.txt | 2 + cmake/InstallAndPackage.cmake | 2 + src/CMakeLists.txt | 2 + src/help_gui.cpp | 218 ++++++++++++++++ src/help_gui.h | 15 ++ src/intro_gui.cpp | 12 +- src/lang/english.txt | 26 +- src/textfile_gui.cpp | 463 +++++++++++++++++++++++++++++++++- src/textfile_gui.h | 67 ++++- src/textfile_type.h | 3 + src/toolbar_gui.cpp | 20 +- src/widgets/CMakeLists.txt | 1 + src/widgets/help_widget.h | 25 ++ src/widgets/intro_widget.h | 1 + src/widgets/misc_widget.h | 14 +- src/window_type.h | 6 + 16 files changed, 839 insertions(+), 38 deletions(-) create mode 100644 src/help_gui.cpp create mode 100644 src/help_gui.h create mode 100644 src/widgets/help_widget.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ed01c2101..e2e2b777df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -392,10 +392,12 @@ if(EMSCRIPTEN) target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/debugging_desyncs.md@/docs/debugging_desyncs.md") target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/desync.md@/docs/desync.md") target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/directory_structure.md@/docs/directory_structure.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/eints.md@/docs/eints.md") target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/linkgraph.md@/docs/linkgraph.md") target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/logging_and_performance_metrics.md@/docs/logging_and_performance_metrics.md") target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/multiplayer.md@/docs/multiplayer.md") target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/savegame_format.md@/docs/savegame_format.md") + target_link_libraries(WASM::WASM INTERFACE "--preload-file ${CMAKE_SOURCE_DIR}/docs/symbol_server.md@/docs/symbol_server.md") # We use IDBFS for persistent storage. target_link_libraries(WASM::WASM INTERFACE "-lidbfs.js") diff --git a/cmake/InstallAndPackage.cmake b/cmake/InstallAndPackage.cmake index b38e88a6c8..759f45612c 100644 --- a/cmake/InstallAndPackage.cmake +++ b/cmake/InstallAndPackage.cmake @@ -49,11 +49,13 @@ install(FILES ${CMAKE_SOURCE_DIR}/docs/debugging_desyncs.md ${CMAKE_SOURCE_DIR}/docs/desync.md ${CMAKE_SOURCE_DIR}/docs/directory_structure.md + ${CMAKE_SOURCE_DIR}/docs/eints.md ${CMAKE_SOURCE_DIR}/docs/game_coordinator.md ${CMAKE_SOURCE_DIR}/docs/linkgraph.md ${CMAKE_SOURCE_DIR}/docs/logging_and_performance_metrics.md ${CMAKE_SOURCE_DIR}/docs/multiplayer.md ${CMAKE_SOURCE_DIR}/docs/savegame_format.md + ${CMAKE_SOURCE_DIR}/docs/symbol_server.md ${CMAKE_SOURCE_DIR}/docs/obg_format.txt ${CMAKE_SOURCE_DIR}/docs/obm_format.txt ${CMAKE_SOURCE_DIR}/docs/obs_format.txt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0add42130c..f62231b3c9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -201,6 +201,8 @@ add_files( gui.h heightmap.cpp heightmap.h + help_gui.cpp + help_gui.h highscore.cpp highscore.h highscore_gui.cpp diff --git a/src/help_gui.cpp b/src/help_gui.cpp new file mode 100644 index 0000000000..d575725cdb --- /dev/null +++ b/src/help_gui.cpp @@ -0,0 +1,218 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + + /** @file help_gui.cpp GUI to access manuals and related. */ + +#include "stdafx.h" +#include "gui.h" +#include "window_gui.h" +#include "textfile_gui.h" +#include "fileio_func.h" +#include "table/control_codes.h" +#include "string_func.h" +#include "openttd.h" + +#include "help_gui.h" +#include "widgets/help_widget.h" +#include "widgets/misc_widget.h" + +#include "safeguards.h" + +static const std::string README_FILENAME = "README.md"; +static const std::string CHANGELOG_FILENAME = "changelog.txt"; +static const std::string KNOWN_BUGS_FILENAME = "known-bugs.txt"; +static const std::string LICENSE_FILENAME = "COPYING.md"; + +static const std::string WEBSITE_LINK = "https://www.openttd.org/"; +static const std::string WIKI_LINK = "https://wiki.openttd.org/"; +static const std::string BUGTRACKER_LINK = "https://bugs.openttd.org/"; +static const std::string COMMUNITY_LINK = "https://community.openttd.org/"; + +/** Only show the first 20 changelog versions in the textfile viewer. */ +static constexpr size_t CHANGELOG_VERSIONS_LIMIT = 20; + +/** + * Find the path to the game manual file. + * + * @param filename The filename to find. + * @return std::string The path to the filename if found. + */ +static std::optional FindGameManualFilePath(std::string_view filename) +{ + static const Searchpath searchpaths[] = { + SP_APPLICATION_BUNDLE_DIR, SP_INSTALLATION_DIR, SP_SHARED_DIR, SP_BINARY_DIR, SP_WORKING_DIR + }; + + for (Searchpath sp : searchpaths) { + auto file_path = FioGetDirectory(sp, BASE_DIR) + filename.data(); + if (FioCheckFileExists(file_path, NO_DIRECTORY)) return file_path; + } + + return {}; +} + +/** Window class displaying the game manual textfile viewer. */ +struct GameManualTextfileWindow : public TextfileWindow { + GameManualTextfileWindow(std::string_view filename) : TextfileWindow(TFT_GAME_MANUAL) + { + /* Mark the content of these files as trusted. */ + this->trusted = true; + + auto filepath = FindGameManualFilePath(filename); + /* The user could, in theory, have moved the file. So just show an empty window if that is the case. */ + if (!filepath.has_value()) { + return; + } + + this->filepath = filepath.value(); + this->LoadTextfile(this->filepath, NO_DIRECTORY); + this->OnClick({ 0, 0 }, WID_TF_WRAPTEXT, 1); + } + + void SetStringParameters(int widget) const override + { + if (widget == WID_TF_CAPTION) { + SetDParamStr(0, this->filename); + } + } + + void AfterLoadText() override + { + if (this->filename == CHANGELOG_FILENAME) { + this->link_anchors.clear(); + this->AfterLoadChangelog(); + this->GetWidget(WID_TF_SEL_JUMPLIST)->SetDisplayedPlane(this->jumplist.empty() ? SZSP_HORIZONTAL : 0); + } else { + this->TextfileWindow::AfterLoadText(); + } + } + + /** + * For changelog files, add a jumplist entry for each version. + * + * This is hardcoded and assumes "---" are used to separate versions. + */ + void AfterLoadChangelog() + { + /* Look for lines beginning with ---, they indicate that the previous line was a release name. */ + for (size_t line_index = 0; line_index < this->lines.size(); ++line_index) { + const Line &line = this->lines[line_index]; + if (line.text.find("---", 0) != 0) continue; + + if (this->jumplist.size() >= CHANGELOG_VERSIONS_LIMIT) { + this->lines.resize(line_index - 2); + break; + } + + /* Mark the version header with a colour, and add it to the jumplist. */ + this->lines[line_index - 1].colour = TC_GOLD; + this->lines[line_index].colour = TC_GOLD; + this->jumplist.push_back(line_index - 1); + } + } +}; + +/** Window class displaying the help window. */ +struct HelpWindow : public Window { + + HelpWindow(WindowDesc *desc, WindowNumber number) : Window(desc) + { + this->InitNested(number); + + this->EnableTextfileButton(README_FILENAME, WID_HW_README); + this->EnableTextfileButton(CHANGELOG_FILENAME, WID_HW_CHANGELOG); + this->EnableTextfileButton(KNOWN_BUGS_FILENAME, WID_HW_KNOWN_BUGS); + this->EnableTextfileButton(LICENSE_FILENAME, WID_HW_LICENSE); + } + + void OnClick(Point pt, int widget, int click_count) override + { + switch (widget) { + case WID_HW_README: + new GameManualTextfileWindow(README_FILENAME); + break; + case WID_HW_CHANGELOG: + new GameManualTextfileWindow(CHANGELOG_FILENAME); + break; + case WID_HW_KNOWN_BUGS: + new GameManualTextfileWindow(KNOWN_BUGS_FILENAME); + break; + case WID_HW_LICENSE: + new GameManualTextfileWindow(LICENSE_FILENAME); + break; + case WID_HW_WEBSITE: + OpenBrowser(WEBSITE_LINK.c_str()); + break; + case WID_HW_WIKI: + OpenBrowser(WIKI_LINK.c_str()); + break; + case WID_HW_BUGTRACKER: + OpenBrowser(BUGTRACKER_LINK.c_str()); + break; + case WID_HW_COMMUNITY: + OpenBrowser(COMMUNITY_LINK.c_str()); + break; + } + } + +private: + void EnableTextfileButton(std::string_view filename, int button_widget) + { + this->GetWidget(button_widget)->SetDisabled(!FindGameManualFilePath(filename).has_value()); + } +}; + +static const NWidgetPart _nested_helpwin_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_HELP_WINDOW_CAPTION, STR_NULL), + EndContainer(), + + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), + NWidget(NWID_SPACER), SetMinimalSize(0, 8), + + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetMinimalSize(10, 0), + + NWidget(NWID_VERTICAL), SetPIP(0, 2, 0), + NWidget(WWT_FRAME, COLOUR_DARK_GREEN), SetDataTip(STR_HELP_WINDOW_WEBSITES, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_WEBSITE), SetDataTip(STR_HELP_WINDOW_MAIN_WEBSITE, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_WIKI), SetDataTip(STR_HELP_WINDOW_MANUAL_WIKI, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_BUGTRACKER), SetDataTip(STR_HELP_WINDOW_BUGTRACKER, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_COMMUNITY), SetDataTip(STR_HELP_WINDOW_COMMUNITY, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0), + EndContainer(), + EndContainer(), + + NWidget(NWID_SPACER), SetMinimalSize(10, 0), + + NWidget(NWID_VERTICAL), SetPIP(0, 2, 0), + NWidget(WWT_FRAME, COLOUR_DARK_GREEN), SetDataTip(STR_HELP_WINDOW_DOCUMENTS, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_README), SetDataTip(STR_HELP_WINDOW_README, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_CHANGELOG), SetDataTip(STR_HELP_WINDOW_CHANGELOG, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_KNOWN_BUGS),SetDataTip(STR_HELP_WINDOW_KNOWN_BUGS, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_HW_LICENSE), SetDataTip(STR_HELP_WINDOW_LICENSE, STR_NULL), SetMinimalSize(128, 12), SetFill(1, 0), + EndContainer(), + EndContainer(), + + NWidget(NWID_SPACER), SetMinimalSize(10, 0), + EndContainer(), + + NWidget(NWID_SPACER), SetMinimalSize(0, 8), + EndContainer(), +}; + +static WindowDesc _helpwin_desc( + WDP_CENTER, nullptr, 0, 0, + WC_HELPWIN, WC_NONE, + 0, + std::begin(_nested_helpwin_widgets), std::end(_nested_helpwin_widgets) +); + +void ShowHelpWindow() +{ + AllocateWindowDescFront(&_helpwin_desc, 0); +} diff --git a/src/help_gui.h b/src/help_gui.h new file mode 100644 index 0000000000..8027da6384 --- /dev/null +++ b/src/help_gui.h @@ -0,0 +1,15 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + + /** @file help_gui.h GUI to access manuals and related. */ + +#ifndef HELP_GUI_H +#define HELP_GUI_H + +void ShowHelpWindow(); + +#endif /* HELP_GUI_H */ diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp index e5eef652f3..9ba6dc6b61 100644 --- a/src/intro_gui.cpp +++ b/src/intro_gui.cpp @@ -13,6 +13,7 @@ #include "window_gui.h" #include "window_func.h" #include "textbuf_gui.h" +#include "help_gui.h" #include "network/network.h" #include "genworld.h" #include "network/network_gui.h" @@ -360,6 +361,7 @@ struct SelectGameWindow : public Window { case WID_SGI_OPTIONS: ShowGameOptions(); break; case WID_SGI_HIGHSCORE: ShowHighscoreTable(); break; + case WID_SGI_HELP: ShowHelpWindow(); break; case WID_SGI_SETTINGS_OPTIONS:ShowGameSettings(); break; case WID_SGI_GRF_SETTINGS: ShowNewGRFSettings(true, true, false, &_grfconfig_newgame); break; case WID_SGI_CONTENT_DOWNLOAD: @@ -470,10 +472,12 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), - /* 'Highscore Table' button */ - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_HIGHSCORE), SetMinimalSize(316, 12), - SetDataTip(STR_INTRO_HIGHSCORE, STR_INTRO_TOOLTIP_HIGHSCORE), SetPadding(0, 10, 0, 10), SetFill(1, 0), + /* 'Help and Manuals' and 'Highscore Table' buttons */ + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_HELP), SetMinimalSize(158, 12), + SetDataTip(STR_INTRO_HELP, STR_INTRO_TOOLTIP_HELP), SetPadding(0, 0, 0, 10), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_HIGHSCORE), SetMinimalSize(158, 12), + SetDataTip(STR_INTRO_HIGHSCORE, STR_INTRO_TOOLTIP_HIGHSCORE), SetPadding(0, 10, 0, 0), SetFill(1, 0), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 6), diff --git a/src/lang/english.txt b/src/lang/english.txt index 674eacbc4b..a646f503ee 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -521,8 +521,9 @@ STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Message history STR_NEWS_MENU_DELETE_ALL_MESSAGES :Delete all messages # About menu -###length 10 +###length 11 STR_ABOUT_MENU_LAND_BLOCK_INFO :Land area information +STR_ABOUT_MENU_HELP :Help & manuals STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Toggle console STR_ABOUT_MENU_AI_DEBUG :AI/Game script debug @@ -2124,6 +2125,7 @@ STR_INTRO_MULTIPLAYER :{BLACK}Multipla STR_INTRO_GAME_OPTIONS :{BLACK}Game Options STR_INTRO_HIGHSCORE :{BLACK}Highscore Table +STR_INTRO_HELP :{BLACK}Help & Manuals STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Settings STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Settings STR_INTRO_ONLINE_CONTENT :{BLACK}Check Online Content @@ -2145,6 +2147,7 @@ STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Select ' STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Display game options STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Display highscore table +STR_INTRO_TOOLTIP_HELP :{BLACK}Get access to documentation and online resources STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Display settings STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Display NewGRF settings STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Check for new and updated content to download @@ -2166,6 +2169,19 @@ STR_ABANDON_GAME_CAPTION :{WHITE}Abandon STR_ABANDON_GAME_QUERY :{YELLOW}Are you sure you want to abandon this game? STR_ABANDON_SCENARIO_QUERY :{YELLOW}Are you sure you want to abandon this scenario? +# Help window +STR_HELP_WINDOW_CAPTION :{WHITE}Help & Manuals +STR_HELP_WINDOW_WEBSITES :{BLACK}Websites +STR_HELP_WINDOW_DOCUMENTS :{BLACK}Documents +STR_HELP_WINDOW_README :{BLACK}Readme +STR_HELP_WINDOW_CHANGELOG :{BLACK}Changelog +STR_HELP_WINDOW_KNOWN_BUGS :{BLACK}Known Bugs +STR_HELP_WINDOW_LICENSE :{BLACK}License +STR_HELP_WINDOW_MAIN_WEBSITE :{BLACK}OpenTTD +STR_HELP_WINDOW_MANUAL_WIKI :{BLACK}Manual / Wiki +STR_HELP_WINDOW_BUGTRACKER :{BLACK}Report a Bug +STR_HELP_WINDOW_COMMUNITY :{BLACK}Community + # Cheat window STR_CHEATS :{WHITE}Cheats STR_CHEATS_TOOLTIP :{BLACK}Checkboxes indicate if you have used this cheat before @@ -4699,16 +4715,22 @@ STR_AI_SETTINGS_SETTING :{RAW_STRING}: { # Textfile window +STR_TEXTFILE_JUMPLIST :{WHITE}Table of Contents +STR_TEXTFILE_JUMPLIST_TOOLTIP :{BLACK}Quickly jump to a section in the displayed file via this list +STR_TEXTFILE_JUMPLIST_ITEM :{WHITE}{RAW_STRING} +STR_TEXTFILE_NAVBACK_TOOLTIP :{BLACK}Go back in navigation history +STR_TEXTFILE_NAVFORWARD_TOOLTIP :{BLACK}Return forward in navigation history STR_TEXTFILE_WRAP_TEXT :{WHITE}Wrap text STR_TEXTFILE_WRAP_TEXT_TOOLTIP :{BLACK}Wrap the text of the window so it all fits without having to scroll STR_TEXTFILE_VIEW_README :{BLACK}View readme STR_TEXTFILE_VIEW_CHANGELOG :{BLACK}Changelog STR_TEXTFILE_VIEW_LICENCE :{BLACK}Licence -###length 4 +###length 5 STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} readme of {RAW_STRING} STR_TEXTFILE_CHANGELOG_CAPTION :{WHITE}{STRING} changelog of {RAW_STRING} STR_TEXTFILE_LICENCE_CAPTION :{WHITE}{STRING} licence of {RAW_STRING} STR_TEXTFILE_SURVEY_RESULT_CAPTION :{WHITE}Preview of survey result +STR_TEXTFILE_GAME_MANUAL_CAPTION :{WHITE}OpenTTD document '{RAW_STRING}' # Vehicle loading indicators diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index 37bf6653f2..6eaf754dcb 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -15,10 +15,15 @@ #include "gfx_func.h" #include "string_func.h" #include "textfile_gui.h" +#include "widgets/dropdown_type.h" +#include "gfx_layout.h" +#include "debug.h" +#include "openttd.h" #include "widgets/misc_widget.h" #include "table/strings.h" +#include "table/control_codes.h" #if defined(WITH_ZLIB) #include @@ -28,16 +33,33 @@ #include #endif +#include + #include "safeguards.h" /** Widgets for the textfile window. */ static const NWidgetPart _nested_textfile_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), + NWidget(WWT_PUSHARROWBTN, COLOUR_MAUVE, WID_TF_NAVBACK), SetFill(0, 1), SetMinimalSize(15, 1), SetDataTip(AWV_DECREASE, STR_TEXTFILE_NAVBACK_TOOLTIP), + NWidget(WWT_PUSHARROWBTN, COLOUR_MAUVE, WID_TF_NAVFORWARD), SetFill(0, 1), SetMinimalSize(15, 1), SetDataTip(AWV_INCREASE, STR_TEXTFILE_NAVFORWARD_TOOLTIP), NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_TF_CAPTION), SetDataTip(STR_NULL, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_TEXTBTN, COLOUR_MAUVE, WID_TF_WRAPTEXT), SetDataTip(STR_TEXTFILE_WRAP_TEXT, STR_TEXTFILE_WRAP_TEXT_TOOLTIP), NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE), EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_TF_SEL_JUMPLIST), + NWidget(WWT_PANEL, COLOUR_MAUVE), + NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, 0, WidgetDimensions::unscaled.frametext.right), + /* As this widget can be toggled, it needs to be a multiplier of FS_MONO. So add a spacer that ensures this. */ + NWidget(NWID_SPACER), SetMinimalSize(1, 0), SetMinimalTextLines(2, 0, FS_MONO), + NWidget(NWID_VERTICAL), + NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_TF_JUMPLIST), SetDataTip(STR_TEXTFILE_JUMPLIST, STR_TEXTFILE_JUMPLIST_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 0), + EndContainer(), + EndContainer(), + EndContainer(), + EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_MAUVE, WID_TF_BACKGROUND), SetMinimalSize(200, 125), SetResize(1, 12), SetScrollbar(WID_TF_VSCROLLBAR), EndContainer(), @@ -66,7 +88,10 @@ TextfileWindow::TextfileWindow(TextfileType file_type) : Window(&_textfile_desc) this->hscroll = this->GetScrollbar(WID_TF_HSCROLLBAR); this->FinishInitNested(file_type); this->GetWidget(WID_TF_CAPTION)->SetDataTip(STR_TEXTFILE_README_CAPTION + file_type, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS); + this->GetWidget(WID_TF_SEL_JUMPLIST)->SetDisplayedPlane(SZSP_HORIZONTAL); + this->DisableWidget(WID_TF_NAVBACK); + this->DisableWidget(WID_TF_NAVFORWARD); this->hscroll->SetStepSize(10); // Speed up horizontal scrollbar } @@ -130,6 +155,367 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) this->SetWidgetDisabledState(WID_TF_HSCROLLBAR, IsWidgetLowered(WID_TF_WRAPTEXT)); } + +/** Regular expression that searches for Markdown links. */ +static const std::regex _markdown_link_regex{"\\[(.+?)\\]\\((.+?)\\)", std::regex_constants::ECMAScript | std::regex_constants::optimize}; + +/** Types of link we support in markdown files. */ +enum class LinkType { + Internal, ///< Internal link, or "anchor" in HTML language. + Web, ///< Link to an external website. + File, ///< Link to a local file. + Unknown, ///< Unknown link. +}; + +/** + * Classify the type of hyperlink the destination describes. + * + * @param destination The hyperlink destination. + * @param trusted Whether we trust the content of this file. + * @return LinkType The classification of the link. + */ +static LinkType ClassifyHyperlink(const std::string &destination, bool trusted) +{ + if (destination.empty()) return LinkType::Unknown; + if (StrStartsWith(destination, "#")) return LinkType::Internal; + + /* Only allow external / internal links for sources we trust. */ + if (!trusted) return LinkType::Unknown; + + if (StrStartsWith(destination, "http://")) return LinkType::Web; + if (StrStartsWith(destination, "https://")) return LinkType::Web; + if (StrStartsWith(destination, "./")) return LinkType::File; + return LinkType::Unknown; +} + +/** + * Create a valid slug for the anchor. + * + * @param line The line to create the slug for. + * @return std::string The slug. + */ +static std::string MakeAnchorSlug(const std::string &line) +{ + std::string r = "#"; + uint state = 0; + for (char c : line) { + if (state == 0) { + /* State 0: Skip leading hashmarks and spaces. */ + if (c == '#') continue; + if (c == ' ') continue; + state = 1; + } + if (state == 2) { + /* State 2: Wait for a non-space/dash character. + * When found, output a dash and that character. */ + if (c == ' ' || c == '-') continue; + r += '-'; + state = 1; + } + if (state == 1) { + /* State 1: Normal text. + * Lowercase alphanumerics, + * spaces and dashes become dashes, + * everything else is removed. */ + if (isalnum(c)) { + r += tolower(c); + } else if (c == ' ' || c == '-') { + state = 2; + } + } + } + + return r; +} + +/** + * Find any hyperlinks in a given line. + * + * @param line The line to search for hyperlinks. + * @param line_index The index of the line. + */ +void TextfileWindow::FindHyperlinksInMarkdown(Line &line, size_t line_index) +{ + std::string::const_iterator last_match_end = line.text.cbegin(); + std::string fixed_line; + char ccbuf[5]; + + std::sregex_iterator matcher{ line.text.cbegin(), line.text.cend(), _markdown_link_regex}; + while (matcher != std::sregex_iterator()) { + std::smatch match = *matcher; + + Hyperlink link; + link.line = line_index; + link.destination = match[2].str(); + this->links.push_back(link); + + LinkType link_type = ClassifyHyperlink(link.destination, this->trusted); + StringControlCode link_colour; + switch (link_type) { + case LinkType::Internal: + link_colour = SCC_GREEN; + break; + case LinkType::Web: + link_colour = SCC_LTBLUE; + break; + case LinkType::File: + link_colour = SCC_LTBROWN; + break; + default: + /* Don't make other link types fancy as they aren't handled (yet). */ + link_colour = SCC_CONTROL_END; + break; + } + + if (link_colour != SCC_CONTROL_END) { + /* Format the link to look like a link. */ + fixed_line += std::string(last_match_end, match[0].first); + this->links.back().begin = fixed_line.length(); + fixed_line += std::string(ccbuf, Utf8Encode(ccbuf, SCC_PUSH_COLOUR)); + fixed_line += std::string(ccbuf, Utf8Encode(ccbuf, link_colour)); + fixed_line += match[1].str(); + this->links.back().end = fixed_line.length(); + fixed_line += std::string(ccbuf, Utf8Encode(ccbuf, SCC_POP_COLOUR)); + last_match_end = match[0].second; + } + + /* Find next link. */ + ++matcher; + } + if (last_match_end == line.text.cbegin()) return; // nothing found + + /* Add remaining text on line. */ + fixed_line += std::string(last_match_end, line.text.cend()); + + /* Overwrite original line text with "fixed" line text. */ + line.text = fixed_line; +} + +/** + * Check if the user clicked on a hyperlink, and handle it if so. + * + * @param pt The loation the user clicked. + */ +void TextfileWindow::CheckHyperlinkClick(Point pt) +{ + if (this->links.empty()) return; + + /* Which line was clicked. */ + const int clicked_row = this->GetRowFromWidget(pt.y, WID_TF_BACKGROUND, WidgetDimensions::scaled.frametext.top, FONT_HEIGHT_MONO) + this->GetScrollbar(WID_TF_VSCROLLBAR)->GetPosition(); + size_t line_index; + size_t subline; + if (IsWidgetLowered(WID_TF_WRAPTEXT)) { + auto it = std::find_if(std::begin(this->lines), std::end(this->lines), [clicked_row](const Line &l) { return l.top <= clicked_row && l.bottom > clicked_row; }); + if (it == this->lines.cend()) return; + line_index = it - this->lines.cbegin(); + subline = clicked_row - it->top; + Debug(misc, 4, "TextfileWindow check hyperlink: clicked_row={}, line_index={}, line.top={}, subline={}", clicked_row, line_index, it->top, subline); + } else { + line_index = clicked_row / FONT_HEIGHT_MONO; + subline = 0; + } + + /* Find hyperlinks in this line. */ + std::vector found_links; + for (const auto &link : this->links) { + if (link.line == line_index) found_links.push_back(link); + } + if (found_links.empty()) return; + + /* Build line layout to figure out character position that was clicked. */ + uint window_width = IsWidgetLowered(WID_TF_WRAPTEXT) ? this->GetWidget(WID_TF_BACKGROUND)->current_x - WidgetDimensions::scaled.frametext.Horizontal() : INT_MAX; + Layouter layout(this->lines[line_index].text, window_width, this->lines[line_index].colour, FS_MONO); + assert(subline < layout.size()); + ptrdiff_t char_index = layout.GetCharAtPosition(pt.x - WidgetDimensions::scaled.frametext.left, subline); + if (char_index < 0) return; + Debug(misc, 4, "TextfileWindow check hyperlink click: line={}, subline={}, char_index={}", line_index, subline, (int)char_index); + + /* Found character index in line, check if any links are at that position. */ + for (const auto &link : found_links) { + Debug(misc, 4, "Checking link from char {} to {}", link.begin, link.end); + if ((size_t)char_index >= link.begin && (size_t)char_index < link.end) { + Debug(misc, 4, "Activating link with destination: {}", link.destination); + this->OnHyperlinkClick(link); + return; + } + } +} + +/** + * Append the new location to the history, so the user can go back. + * + * @param filepath The location the user is navigating to. + */ +void TextfileWindow::AppendHistory(const std::string &filepath) +{ + this->history.erase(this->history.begin() + this->history_pos + 1, this->history.end()); + this->UpdateHistoryScrollpos(); + this->history.push_back(HistoryEntry{ filepath, 0 }); + this->EnableWidget(WID_TF_NAVBACK); + this->DisableWidget(WID_TF_NAVFORWARD); + this->history_pos = this->history.size() - 1; +} + +/** + * Update the scroll position to the current, so we can restore there if we go back. + */ +void TextfileWindow::UpdateHistoryScrollpos() +{ + this->history[this->history_pos].scrollpos = this->GetScrollbar(WID_TF_VSCROLLBAR)->GetPosition(); +} + +/** + * Navigate through the history, either forward or backward. + * + * @param delta The direction to navigate. + */ +void TextfileWindow::NavigateHistory(int delta) +{ + if (delta == 0) return; + if (delta < 0 && static_cast(this->history_pos) < -delta) return; + if (delta > 0 && this->history_pos + delta >= this->history.size()) return; + + this->UpdateHistoryScrollpos(); + this->history_pos += delta; + + if (this->history[this->history_pos].filepath != this->filepath) { + this->filepath = this->history[this->history_pos].filepath; + this->filename = this->filepath.substr(this->filepath.find_last_of(PATHSEP) + 1); + this->LoadTextfile(this->filepath, NO_DIRECTORY); + } + + this->SetWidgetDisabledState(WID_TF_NAVFORWARD, this->history_pos + 1 >= this->history.size()); + this->SetWidgetDisabledState(WID_TF_NAVBACK, this->history_pos == 0); + this->GetScrollbar(WID_TF_VSCROLLBAR)->SetPosition(this->history[this->history_pos].scrollpos); + this->GetScrollbar(WID_TF_HSCROLLBAR)->SetPosition(0); + this->SetDirty(); +} + +/* virtual */ void TextfileWindow::OnHyperlinkClick(const Hyperlink &link) +{ + switch (ClassifyHyperlink(link.destination, this->trusted)) { + case LinkType::Internal: + { + auto it = std::find_if(this->link_anchors.cbegin(), this->link_anchors.cend(), [&](const Hyperlink &other) { return link.destination == other.destination; }); + if (it != this->link_anchors.cend()) { + this->AppendHistory(this->filepath); + this->ScrollToLine(it->line); + this->UpdateHistoryScrollpos(); + } + break; + } + + case LinkType::Web: + OpenBrowser(link.destination.c_str()); + break; + + case LinkType::File: + this->NavigateToFile(link.destination, 0); + break; + + default: + /* Do nothing */ + break; + } +} + +/** + * Navigate to the requested file. + * + * @param newfile The file to navigate to. + * @param line The line to scroll to. + */ +void TextfileWindow::NavigateToFile(std::string newfile, size_t line) +{ + /* Double-check that the file link begins with ./ as a relative path. */ + if (!StrStartsWith(newfile, "./")) return; + + /* Get the path portion of the current file path. */ + std::string newpath = this->filepath; + size_t pos = newpath.find_last_of(PATHSEPCHAR); + if (pos == std::string::npos) { + newpath.clear(); + } else { + newpath.erase(pos + 1); + } + + /* Check and remove for anchor in link. Do this before we find the filename, as people might have a / after the hash. */ + size_t anchor_pos = newfile.find_first_of('#'); + std::string anchor; + if (anchor_pos != std::string::npos) { + anchor = newfile.substr(anchor_pos); + newfile.erase(anchor_pos); + } + + /* Now the anchor is gone, check if this is a markdown or textfile. */ + if (!StrEndsWithIgnoreCase(newfile, ".md") && !StrEndsWithIgnoreCase(newfile, ".txt")) return; + + /* Convert link destination to acceptable local filename (replace forward slashes with correct path separator). */ + newfile = newfile.substr(2); + if (PATHSEPCHAR != '/') { + for (char &c : newfile) { + if (c == '/') c = PATHSEPCHAR; + } + } + + /* Paste the two together and check file exists. */ + newpath = newpath + newfile; + if (!FioCheckFileExists(newpath, NO_DIRECTORY)) return; + + /* Update history. */ + this->AppendHistory(newpath); + + /* Load the new file. */ + this->filepath = newpath; + this->filename = newpath.substr(newpath.find_last_of(PATHSEP) + 1); + + this->LoadTextfile(this->filepath, NO_DIRECTORY); + + this->GetScrollbar(WID_TF_HSCROLLBAR)->SetPosition(0); + this->GetScrollbar(WID_TF_VSCROLLBAR)->SetPosition(0); + + if (anchor.empty() || line != 0) { + this->ScrollToLine(line); + } else { + auto anchor_dest = std::find_if(this->link_anchors.cbegin(), this->link_anchors.cend(), [&](const Hyperlink &other) { return anchor == other.destination; }); + if (anchor_dest != this->link_anchors.cend()) { + this->ScrollToLine(anchor_dest->line); + this->UpdateHistoryScrollpos(); + } else { + this->ScrollToLine(0); + } + } +} + +/* virtual */ void TextfileWindow::AfterLoadText() +{ + this->link_anchors.clear(); + + if (StrEndsWithIgnoreCase(this->filename, ".md")) this->AfterLoadMarkdown(); + + this->GetWidget(WID_TF_SEL_JUMPLIST)->SetDisplayedPlane(this->jumplist.empty() ? SZSP_HORIZONTAL : 0); +} + +/** + * Post-processing of markdown files. + */ +void TextfileWindow::AfterLoadMarkdown() +{ + for (size_t line_index = 0; line_index < this->lines.size(); ++line_index) { + Line &line = this->lines[line_index]; + + /* Find and mark all hyperlinks in the line. */ + this->FindHyperlinksInMarkdown(line, line_index); + + /* All lines beginning with # are headings. */ + if (!line.text.empty() && line.text[0] == '#') { + this->jumplist.push_back(line_index); + this->lines[line_index].colour = TC_GOLD; + this->link_anchors.emplace_back(Hyperlink{ line_index, 0, 0, MakeAnchorSlug(line.text) }); + } + } +} + /* virtual */ void TextfileWindow::OnClick(Point pt, int widget, int click_count) { switch (widget) { @@ -137,6 +523,29 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) this->ToggleWidgetLoweredState(WID_TF_WRAPTEXT); this->InvalidateData(); break; + + case WID_TF_JUMPLIST: { + DropDownList list; + for (size_t line : this->jumplist) { + SetDParamStr(0, this->lines[line].text); + DropDownListStringItem *item = new DropDownListStringItem(STR_TEXTFILE_JUMPLIST_ITEM, (int)line, false); + list.emplace_back(item); + } + ShowDropDownList(this, std::move(list), -1, widget); + break; + } + + case WID_TF_NAVBACK: + this->NavigateHistory(-1); + break; + + case WID_TF_NAVFORWARD: + this->NavigateHistory(+1); + break; + + case WID_TF_BACKGROUND: + this->CheckHyperlinkClick(pt); + break; } } @@ -162,9 +571,9 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) int y_offset = (line.top - pos) * line_height; if (IsWidgetLowered(WID_TF_WRAPTEXT)) { - DrawStringMultiLine(0, fr.right, y_offset, fr.bottom, line.text, TC_BLACK, SA_TOP | SA_LEFT, false, FS_MONO); + DrawStringMultiLine(0, fr.right, y_offset, fr.bottom, line.text, line.colour, SA_TOP | SA_LEFT, false, FS_MONO); } else { - DrawString(-this->hscroll->GetPosition(), fr.right, y_offset, line.text, TC_BLACK, SA_TOP | SA_LEFT, false, FS_MONO); + DrawString(-this->hscroll->GetPosition(), fr.right, y_offset, line.text, line.colour, SA_TOP | SA_LEFT, false, FS_MONO); } } } @@ -184,6 +593,26 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) this->SetupScrollbars(true); } +void TextfileWindow::OnDropdownSelect(int widget, int index) +{ + if (widget != WID_TF_JUMPLIST) return; + + this->ScrollToLine(index); +} + +void TextfileWindow::ScrollToLine(size_t line) +{ + Scrollbar *sb = this->GetScrollbar(WID_TF_VSCROLLBAR); + int newpos; + if (this->IsWidgetLowered(WID_TF_WRAPTEXT)) { + newpos = this->lines[line].top; + } else { + newpos = static_cast(line); + } + sb->SetPosition(std::min(newpos, sb->GetCount() - sb->GetCapacity())); + this->SetDirty(); +} + /* virtual */ void TextfileWindow::Reset() { this->search_iterator = 0; @@ -330,14 +759,20 @@ static void Xunzip(byte **bufp, size_t *sizep) */ /* virtual */ void TextfileWindow::LoadTextfile(const std::string &textfile, Subdirectory dir) { - if (textfile.empty()) return; - this->lines.clear(); + this->jumplist.clear(); + + this->GetWidget(WID_TF_SEL_JUMPLIST)->SetDisplayedPlane(SZSP_HORIZONTAL); + this->ReInit(); + + if (textfile.empty()) return; /* Get text from file */ size_t filesize; FILE *handle = FioFOpenFile(textfile, "rb", dir, &filesize); if (handle == nullptr) return; + /* Early return on empty files. */ + if (filesize == 0) return; char *buf = MallocT(filesize); size_t read = fread(buf, 1, filesize, handle); @@ -365,7 +800,13 @@ static void Xunzip(byte **bufp, size_t *sizep) /* Check for the byte-order-mark, and skip it if needed. */ if (StrStartsWith(sv_buf, u8"\ufeff")) sv_buf.remove_prefix(3); - /* Replace any invalid characters with a question-mark. This copies the buf in the process. */ + /* Update the filename. */ + this->filepath = textfile; + this->filename = this->filepath.substr(this->filepath.find_last_of(PATHSEP) + 1); + /* If it's the first file being loaded, add to history. */ + if (this->history.empty()) this->history.push_back(HistoryEntry{ this->filepath, 0 }); + + /* Process the loaded text into lines, and do any further parsing needed. */ this->LoadText(sv_buf); free(buf); } @@ -379,11 +820,11 @@ static void Xunzip(byte **bufp, size_t *sizep) */ void TextfileWindow::LoadText(std::string_view buf) { - this->text = StrMakeValid(buf, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE | SVS_REPLACE_TAB_CR_NL_WITH_SPACE); + std::string text = StrMakeValid(buf, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE | SVS_REPLACE_TAB_CR_NL_WITH_SPACE); this->lines.clear(); /* Split the string on newlines. */ - std::string_view p(this->text); + std::string_view p(text); int row = 0; auto next = p.find_first_of('\n'); while (next != std::string_view::npos) { @@ -402,6 +843,8 @@ void TextfileWindow::LoadText(std::string_view buf) } this->max_length = max_length; + this->AfterLoadText(); + CheckForMissingGlyphs(true, this); } @@ -421,6 +864,9 @@ std::optional GetTextfile(TextfileType type, Subdirectory dir, cons }; static_assert(lengthof(prefixes) == TFT_CONTENT_END); + /* Only the generic text file types allowed for this function */ + if (type >= TFT_CONTENT_END) return std::nullopt; + std::string_view prefix = prefixes[type]; if (filename.empty()) return std::nullopt; @@ -432,11 +878,14 @@ std::optional GetTextfile(TextfileType type, Subdirectory dir, cons static const std::initializer_list extensions{ "txt", + "md", #if defined(WITH_ZLIB) "txt.gz", + "md.gz", #endif #if defined(WITH_LIBLZMA) "txt.xz", + "md.xz", #endif }; diff --git a/src/textfile_gui.h b/src/textfile_gui.h index 6b57abfa24..f4e61fe10e 100644 --- a/src/textfile_gui.h +++ b/src/textfile_gui.h @@ -22,9 +22,6 @@ struct TextfileWindow : public Window, MissingGlyphSearcher { TextfileType file_type; ///< Type of textfile to view. Scrollbar *vscroll; ///< Vertical scrollbar. Scrollbar *hscroll; ///< Horizontal scrollbar. - uint search_iterator; ///< Iterator for the font check search. - - uint max_length; ///< Maximum length of unwrapped text line. TextfileWindow(TextfileType file_type); @@ -33,33 +30,81 @@ struct TextfileWindow : public Window, MissingGlyphSearcher { void DrawWidget(const Rect &r, int widget) const override; void OnResize() override; void OnInvalidateData(int data = 0, bool gui_scope = true) override; + void OnDropdownSelect(int widget, int index) override; void Reset() override; FontSize DefaultSize() override; std::optional NextString() override; bool Monospace() override; void SetFontNames(FontCacheSettings *settings, const char *font_name, const void *os_data) override; + void ScrollToLine(size_t line); virtual void LoadTextfile(const std::string &textfile, Subdirectory dir); protected: - void LoadText(std::string_view buf); - -private: struct Line { - int top; ///< Top scroll position. - int bottom; ///< Bottom scroll position. - std::string_view text; ///< Pointer to text buffer. + int top{0}; ///< Top scroll position in visual lines. + int bottom{0}; ///< Bottom scroll position in visual lines. + std::string text{}; ///< Contents of the line. + TextColour colour{TC_WHITE}; ///< Colour to render text line in. Line(int top, std::string_view text) : top(top), bottom(top + 1), text(text) {} + Line() {} }; - std::string text; ///< Lines of text from the NewGRF's textfile. - std::vector lines; ///< #text, split into lines in a table with lines. + struct Hyperlink { + size_t line; ///< Which line the link is on. + size_t begin; ///< Character position on line the link begins. + size_t end; ///< Character position on line the link end. + std::string destination; ///< Destination for the link. + }; + + struct HistoryEntry { + std::string filepath; ///< File the history entry is in. + int scrollpos; ///< Scrolling position the file was at at navigation time. + }; + + std::string filename{}; ///< Filename of the textfile. + std::string filepath{}; ///< Full path to the filename. + + std::vector lines; ///< #text, split into lines in a table with lines. + std::vector jumplist; ///< Table of contents list, line numbers. + std::vector links; ///< Clickable links in lines. + std::vector link_anchors; ///< Anchor names of headings that can be linked to. + std::vector history; ///< Browsing history in this window. + size_t history_pos{0}; ///< Position in browsing history (for forward movement). + bool trusted{false}; ///< Whether the content is trusted (read: not from content like NewGRFs, etc). + + void LoadText(std::string_view buf); + void FindHyperlinksInMarkdown(Line &line, size_t line_index); + + /** + * Handle the clicking on a hyperlink. + * + * @param link The link that is clicked on. + */ + virtual void OnHyperlinkClick(const Hyperlink &link); + + /** + * Post-processing after the text is loaded. + */ + virtual void AfterLoadText(); + + void NavigateToFile(std::string newfile, size_t line); + void AppendHistory(const std::string &filepath); + void UpdateHistoryScrollpos(); + void NavigateHistory(int delta); + +private: + uint search_iterator{0}; ///< Iterator for the font check search. + uint max_length{0}; ///< Maximum length of unwrapped text line. uint ReflowContent(); uint GetContentHeight(); void SetupScrollbars(bool force_reflow); + void CheckHyperlinkClick(Point pt); + + void AfterLoadMarkdown(); }; #endif /* TEXTFILE_GUI_H */ diff --git a/src/textfile_type.h b/src/textfile_type.h index f45c016440..a1c0c6569b 100644 --- a/src/textfile_type.h +++ b/src/textfile_type.h @@ -21,6 +21,9 @@ enum TextfileType { TFT_CONTENT_END, // This marker is used to generate the above three buttons in sequence by various of places in the code. TFT_SURVEY_RESULT = TFT_CONTENT_END, ///< Survey result (preview) + TFT_GAME_MANUAL, ///< Game manual/documentation file + + TFT_END, }; DECLARE_POSTFIX_INCREMENT(TextfileType) diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 0ec27b6d15..291131b3c5 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -55,6 +55,7 @@ #include "timer/timer.h" #include "timer/timer_window.h" #include "timer/timer_game_calendar.h" +#include "help_gui.h" #include "widgets/toolbar_widget.h" @@ -1104,7 +1105,7 @@ static CallBackFunction PlaceLandBlockInfo() static CallBackFunction ToolbarHelpClick(Window *w) { - PopupMainToolbMenu(w, _game_mode == GM_EDITOR ? (int)WID_TE_HELP : (int)WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 10 : 7); + PopupMainToolbMenu(w, _game_mode == GM_EDITOR ? (int)WID_TE_HELP : (int)WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 11 : 8); return CBF_NONE; } @@ -1164,14 +1165,15 @@ static CallBackFunction MenuClickHelp(int index) { switch (index) { case 0: return PlaceLandBlockInfo(); - case 2: IConsoleSwitch(); break; - case 3: ShowScriptDebugWindow(); break; - case 4: ShowScreenshotWindow(); break; - case 5: ShowFramerateWindow(); break; - case 6: ShowAboutWindow(); break; - case 7: ShowSpriteAlignerWindow(); break; - case 8: ToggleBoundingBoxes(); break; - case 9: ToggleDirtyBlocks(); break; + case 1: ShowHelpWindow(); break; + case 3: IConsoleSwitch(); break; + case 4: ShowScriptDebugWindow(); break; + case 5: ShowScreenshotWindow(); break; + case 6: ShowFramerateWindow(); break; + case 7: ShowAboutWindow(); break; + case 8: ShowSpriteAlignerWindow(); break; + case 9: ToggleBoundingBoxes(); break; + case 10: ToggleDirtyBlocks(); break; } return CBF_NONE; } diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 33e46b6db5..dd28f14c8f 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -24,6 +24,7 @@ add_files( goal_widget.h graph_widget.h group_widget.h + help_widget.h highscore_widget.h industry_widget.h intro_widget.h diff --git a/src/widgets/help_widget.h b/src/widgets/help_widget.h new file mode 100644 index 0000000000..5b898fc01c --- /dev/null +++ b/src/widgets/help_widget.h @@ -0,0 +1,25 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + + /** @file help_widget.h Types related to the help window widgets. */ + +#ifndef WIDGETS_HELP_WIDGET_H +#define WIDGETS_HELP_WIDGET_H + +/** Widgets of the #HelpWindow class. */ +enum HelpWindowWidgets { + WID_HW_README, + WID_HW_CHANGELOG, + WID_HW_KNOWN_BUGS, + WID_HW_LICENSE, + WID_HW_WEBSITE, + WID_HW_WIKI, + WID_HW_BUGTRACKER, + WID_HW_COMMUNITY, +}; + +#endif /* WIDGETS_HELP_WIDGET_H */ diff --git a/src/widgets/intro_widget.h b/src/widgets/intro_widget.h index dc152a488b..6e5e70eea9 100644 --- a/src/widgets/intro_widget.h +++ b/src/widgets/intro_widget.h @@ -28,6 +28,7 @@ enum SelectGameIntroWidgets { WID_SGI_TRANSLATION, ///< Translation errors. WID_SGI_OPTIONS, ///< Options button. WID_SGI_HIGHSCORE, ///< Highscore button. + WID_SGI_HELP, ///< Help and manuals button. WID_SGI_SETTINGS_OPTIONS, ///< Settings button. WID_SGI_GRF_SETTINGS, ///< NewGRF button. WID_SGI_CONTENT_DOWNLOAD, ///< Content Download button. diff --git a/src/widgets/misc_widget.h b/src/widgets/misc_widget.h index f62234405f..61e916d1da 100644 --- a/src/widgets/misc_widget.h +++ b/src/widgets/misc_widget.h @@ -48,11 +48,15 @@ enum QueryWidgets { /** Widgets of the #TextfileWindow class. */ enum TextfileWidgets { - WID_TF_CAPTION, ///< The caption of the window. - WID_TF_WRAPTEXT, ///< Whether or not to wrap the text. - WID_TF_BACKGROUND, ///< Panel to draw the textfile on. - WID_TF_VSCROLLBAR, ///< Vertical scrollbar to scroll through the textfile up-and-down. - WID_TF_HSCROLLBAR, ///< Horizontal scrollbar to scroll through the textfile left-to-right. + WID_TF_CAPTION, ///< The caption of the window. + WID_TF_NAVBACK, ///< Navigate back button. + WID_TF_NAVFORWARD, ///< Navigate forward button. + WID_TF_WRAPTEXT, ///< Whether or not to wrap the text. + WID_TF_JUMPLIST, ///< List to jump around the file. + WID_TF_SEL_JUMPLIST, ///< Selection to display the jump list or not. + WID_TF_BACKGROUND, ///< Panel to draw the textfile on. + WID_TF_VSCROLLBAR, ///< Vertical scrollbar to scroll through the textfile up-and-down. + WID_TF_HSCROLLBAR, ///< Horizontal scrollbar to scroll through the textfile left-to-right. }; #endif /* WIDGETS_MISC_WIDGET_H */ diff --git a/src/window_type.h b/src/window_type.h index 422d373ef6..96a591c30e 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -703,6 +703,12 @@ enum WindowClass { */ WC_SCREENSHOT, + /* + * Help and manuals window; %Window numbers: + * - 0 = #HelpWindowWidgets + */ + WC_HELPWIN, + WC_INVALID = 0xFFFF, ///< Invalid window. }; From ba67f39db6efa2c251999a94668cd0e10eb8f6ad Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 13 Sep 2023 16:11:34 +0200 Subject: [PATCH 55/72] Codechange: vendor the nlohmann-json library (#11290) --- .github/workflows/ci-build.yml | 7 +- .github/workflows/preview-build.yml | 3 +- .github/workflows/release-linux.yml | 1 - .github/workflows/release-macos.yml | 2 - .github/workflows/release-windows.yml | 1 - CMakeLists.txt | 3 - COMPILING.md | 6 +- os/emscripten/Dockerfile | 3 - os/emscripten/README.md | 1 - os/emscripten/cmake/Findnlohmann_json.cmake | 21 - os/emscripten/emsdk-nlohmann-json.patch | 93 - src/3rdparty/CMakeLists.txt | 1 + src/3rdparty/nlohmann/CMakeLists.txt | 3 + src/3rdparty/nlohmann/LICENSE.MIT | 21 + src/3rdparty/nlohmann/json.hpp | 24596 ++++++++++++++++++ src/network/network_survey.cpp | 2 +- src/os/macosx/survey_osx.cpp | 2 +- src/os/unix/survey_unix.cpp | 3 +- src/os/windows/survey_win.cpp | 2 +- src/script/api/script_admin.cpp | 3 +- src/script/api/script_event_types.cpp | 3 +- src/tests/test_script_admin.cpp | 2 +- 22 files changed, 24633 insertions(+), 146 deletions(-) delete mode 100644 os/emscripten/cmake/Findnlohmann_json.cmake delete mode 100644 os/emscripten/emsdk-nlohmann-json.patch create mode 100644 src/3rdparty/nlohmann/CMakeLists.txt create mode 100644 src/3rdparty/nlohmann/LICENSE.MIT create mode 100644 src/3rdparty/nlohmann/json.hpp diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 3faeafe6c3..677fc03db4 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -32,11 +32,10 @@ jobs: path: /emsdk/upstream/emscripten/cache key: 3.1.42-${{ runner.os }} - - name: Patch Emscripten to support LZMA and nlohmann-json + - name: Patch Emscripten to support LZMA run: | cd /emsdk/upstream/emscripten patch -p1 < ${GITHUB_WORKSPACE}/os/emscripten/emsdk-liblzma.patch - patch -p1 < ${GITHUB_WORKSPACE}/os/emscripten/emsdk-nlohmann-json.patch - name: Build (host tools) run: | @@ -118,7 +117,6 @@ jobs: libicu-dev \ liblzma-dev \ liblzo2-dev \ - nlohmann-json3-dev \ ${{ matrix.libraries }} \ zlib1g-dev \ # EOF @@ -215,7 +213,6 @@ jobs: liblzma \ libpng \ lzo \ - nlohmann-json \ zlib \ # EOF @@ -300,7 +297,6 @@ jobs: liblzma \ libpng \ lzo \ - nlohmann-json \ zlib \ # EOF @@ -387,7 +383,6 @@ jobs: mingw-w64-${{ matrix.arch }}-libpng mingw-w64-${{ matrix.arch }}-lld mingw-w64-${{ matrix.arch }}-ninja - mingw-w64-${{ matrix.arch }}-nlohmann-json - name: Install OpenGFX shell: bash diff --git a/.github/workflows/preview-build.yml b/.github/workflows/preview-build.yml index e4e289972d..4f7a1dde8d 100644 --- a/.github/workflows/preview-build.yml +++ b/.github/workflows/preview-build.yml @@ -40,11 +40,10 @@ jobs: path: /emsdk/upstream/emscripten/cache key: 3.1.42-${{ runner.os }} - - name: Patch Emscripten to support LZMA and nlohmann_json + - name: Patch Emscripten to support LZMA run: | cd /emsdk/upstream/emscripten patch -p1 < ${GITHUB_WORKSPACE}/os/emscripten/emsdk-liblzma.patch - patch -p1 < ${GITHUB_WORKSPACE}/os/emscripten/emsdk-nlohmann-json.patch - name: Build (host tools) run: | diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index fad44dec9a..b44c7eabee 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -130,7 +130,6 @@ jobs: liblzma \ libpng \ lzo \ - nlohmann-json \ sdl2 \ zlib \ # EOF diff --git a/.github/workflows/release-macos.yml b/.github/workflows/release-macos.yml index 165bb6b6ab..0e560cc470 100644 --- a/.github/workflows/release-macos.yml +++ b/.github/workflows/release-macos.yml @@ -75,8 +75,6 @@ jobs: libpng:arm64-osx \ lzo:x64-osx \ lzo:arm64-osx \ - nlohmann-json:x64-osx \ - nlohmann-json:arm64-osx \ zlib:x64-osx \ zlib:arm64-osx \ # EOF diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index 7122a57f0b..4b883675bd 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -80,7 +80,6 @@ jobs: liblzma \ libpng \ lzo \ - nlohmann-json \ zlib \ # EOF diff --git a/CMakeLists.txt b/CMakeLists.txt index e2e2b777df..366fe4a136 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,8 +119,6 @@ endif() set(CMAKE_THREAD_PREFER_PTHREAD YES) # Make sure we have Threads available. find_package(Threads REQUIRED) -# nlohmann is used for all our JSON needs. -find_package(nlohmann_json REQUIRED) find_package(ZLIB) find_package(LibLZMA) @@ -310,7 +308,6 @@ link_package(PNG TARGET PNG::PNG ENCOURAGED) link_package(ZLIB TARGET ZLIB::ZLIB ENCOURAGED) link_package(LIBLZMA TARGET LibLZMA::LibLZMA ENCOURAGED) link_package(LZO) -link_package(nlohmann_json) if(NOT WIN32 AND NOT EMSCRIPTEN) link_package(CURL ENCOURAGED) diff --git a/COMPILING.md b/COMPILING.md index 5e7883aefc..299494288b 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -4,7 +4,6 @@ OpenTTD makes use of the following external libraries: -- (required) nlohmann-json: JSON handling - (encouraged) breakpad: creates minidumps on crash - (encouraged) zlib: (de)compressing of old (0.3.0-1.0.5) savegames, content downloads, heightmaps @@ -55,14 +54,13 @@ the `static` versions, and OpenTTD currently needs the following dependencies: - liblzma - libpng - lzo -- nlohmann-json - zlib To install both the x64 (64bit) and x86 (32bit) variants (though only one is necessary), you can use: ```ps -.\vcpkg install breakpad:x64-windows-static liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static nlohmann-json:x64-windows-static zlib:x64-windows-static -.\vcpkg install breakpad:x86-windows-static liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static nlohmann-json:x86-windows-static zlib:x86-windows-static +.\vcpkg install breakpad:x64-windows-static liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static zlib:x64-windows-static +.\vcpkg install breakpad:x86-windows-static liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static zlib:x86-windows-static ``` You can open the folder (as a CMake project). CMake will be detected, and you can compile from there. diff --git a/os/emscripten/Dockerfile b/os/emscripten/Dockerfile index 60a2c6985f..178f56500b 100644 --- a/os/emscripten/Dockerfile +++ b/os/emscripten/Dockerfile @@ -2,6 +2,3 @@ FROM emscripten/emsdk:3.1.42 COPY emsdk-liblzma.patch / RUN cd /emsdk/upstream/emscripten && patch -p1 < /emsdk-liblzma.patch - -COPY emsdk-nlohmann-json.patch / -RUN cd /emsdk/upstream/emscripten && patch -p1 < /emsdk-nlohmann-json.patch diff --git a/os/emscripten/README.md b/os/emscripten/README.md index c16eea2416..9184b0144e 100644 --- a/os/emscripten/README.md +++ b/os/emscripten/README.md @@ -4,7 +4,6 @@ Please use docker with the supplied `Dockerfile` to build for emscripten. It takes care of a few things: - Use a version of emscripten we know works - Patch in LibLZMA support (as this is not supported by upstream) -- Patch in nlohmann-json support (as this is not supported by upstream) First, build the docker image by navigating in the folder this `README.md` is in, and executing: ``` diff --git a/os/emscripten/cmake/Findnlohmann_json.cmake b/os/emscripten/cmake/Findnlohmann_json.cmake deleted file mode 100644 index 8a1c075ad0..0000000000 --- a/os/emscripten/cmake/Findnlohmann_json.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# nlohmann-json is a custom addition to the emscripten SDK, so it is possible -# someone patched their SDK. Test out if the SDK supports nlohmann-json. -include(CheckCXXSourceCompiles) -set(CMAKE_REQUIRED_FLAGS "-sUSE_NLOHMANN_JSON=1") - -check_cxx_source_compiles(" - #include - int main() { return 0; }" - nlohmann_json_FOUND -) - -if (nlohmann_json_FOUND) - add_library(nlohmann_json INTERFACE IMPORTED) - set_target_properties(nlohmann_json PROPERTIES - INTERFACE_COMPILE_OPTIONS "-sUSE_NLOHMANN_JSON=1" - INTERFACE_LINK_LIBRARIES "-sUSE_NLOHMANN_JSON=1" - ) - set(nlohmann_json_LIBRARY "nlohmann_json") -else() - message(WARNING "You are using an emscripten SDK without nlohmann-json support. Please apply 'emsdk-nlohmann_json.patch' to your local emsdk installation.") -endif() diff --git a/os/emscripten/emsdk-nlohmann-json.patch b/os/emscripten/emsdk-nlohmann-json.patch deleted file mode 100644 index 37d052a2a7..0000000000 --- a/os/emscripten/emsdk-nlohmann-json.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0edcedbea375e59f41df10acaee0c483d245751f Mon Sep 17 00:00:00 2001 -From: Patric Stout -Date: Tue, 2 May 2023 21:48:08 +0200 -Subject: [PATCH] Add nlohmmann-json port - ---- - src/settings.js | 4 ++++ - tools/ports/nlohmann_json.py | 46 ++++++++++++++++++++++++++++++++++++ - tools/settings.py | 1 + - 3 files changed, 51 insertions(+) - create mode 100644 tools/ports/nlohmann_json.py - -diff --git a/src/settings.js b/src/settings.js -index f93140d..39f4366 100644 ---- a/src/settings.js -+++ b/src/settings.js -@@ -1483,6 +1483,10 @@ var USE_MPG123 = false; - // [compile+link] - var USE_FREETYPE = false; - -+// 1 = use nlohmann-json from emscripten-ports -+// [compile+link] -+var USE_NLOHMANN_JSON = false; -+ - // Specify the SDL_mixer version that is being linked against. - // Doesn't *have* to match USE_SDL, but a good idea. - // [compile+link] -diff --git a/tools/ports/nlohmann_json.py b/tools/ports/nlohmann_json.py -new file mode 100644 -index 0000000..9e44297 ---- /dev/null -+++ b/tools/ports/nlohmann_json.py -@@ -0,0 +1,46 @@ -+# Copyright 2023 The Emscripten Authors. All rights reserved. -+# Emscripten is available under two separate licenses, the MIT license and the -+# University of Illinois/NCSA Open Source License. Both these licenses can be -+# found in the LICENSE file. -+ -+import os -+ -+TAG = '3.11.2' -+HASH = '99d9e6d588cabe8913a37437f86acb5d4b8b98bce12423e633c11c13b61e6c7f92ef8f9a4e991baa590329ee2b5c09ca9db9894bee1e54bdd68e8d09d83cc245' -+ -+ -+def needed(settings): -+ return settings.USE_NLOHMANN_JSON -+ -+ -+def get(ports, settings, shared): -+ ports.fetch_project('nlohmann_json', -+ f'https://github.com/nlohmann/json/releases/download/v{TAG}/include.zip', -+ sha512hash=HASH) -+ -+ def create(final): -+ source_path = os.path.join(ports.get_dir(), 'nlohmann_json') -+ source_path_include = os.path.join(source_path, 'include', 'nlohmann') -+ ports.install_header_dir(source_path_include, 'nlohmann') -+ -+ # write out a dummy cpp file, to create an empty library -+ # this is needed as emscripten ports expect this, even if it is not used -+ dummy_file = os.path.join(source_path, 'dummy.cpp') -+ shared.safe_ensure_dirs(os.path.dirname(dummy_file)) -+ ports.write_file(dummy_file, 'static void dummy() {}') -+ -+ ports.build_port(source_path, final, 'nlohmann_json', srcs=['dummy.cpp']) -+ -+ return [shared.cache.get_lib('libnlohmann_json.a', create, what='port')] -+ -+ -+def clear(ports, settings, shared): -+ shared.cache.erase_lib('libnlohmann_json.a') -+ -+ -+def process_args(ports): -+ return [] -+ -+ -+def show(): -+ return 'nlohmann-json' -diff --git a/tools/settings.py b/tools/settings.py -index 10d6ca0..8536092 100644 ---- a/tools/settings.py -+++ b/tools/settings.py -@@ -47,6 +47,7 @@ PORTS_SETTINGS = { - 'USE_MPG123', - 'USE_GIFLIB', - 'USE_FREETYPE', -+ 'USE_NLOHMANN_JSON', - 'SDL2_MIXER_FORMATS', - 'SDL2_IMAGE_FORMATS', - 'USE_SQLITE3', --- -2.34.1 diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index e2b72c4bd1..b416e2554c 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -3,4 +3,5 @@ add_subdirectory(fmt) add_subdirectory(icu) add_subdirectory(md5) add_subdirectory(squirrel) +add_subdirectory(nlohmann) add_subdirectory(opengl) diff --git a/src/3rdparty/nlohmann/CMakeLists.txt b/src/3rdparty/nlohmann/CMakeLists.txt new file mode 100644 index 0000000000..6124c3c7e7 --- /dev/null +++ b/src/3rdparty/nlohmann/CMakeLists.txt @@ -0,0 +1,3 @@ +add_files( + json.hpp +) diff --git a/src/3rdparty/nlohmann/LICENSE.MIT b/src/3rdparty/nlohmann/LICENSE.MIT new file mode 100644 index 0000000000..70c6af651e --- /dev/null +++ b/src/3rdparty/nlohmann/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013-2022 Niels Lohmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/3rdparty/nlohmann/json.hpp b/src/3rdparty/nlohmann/json.hpp new file mode 100644 index 0000000000..4d1a37ad7c --- /dev/null +++ b/src/3rdparty/nlohmann/json.hpp @@ -0,0 +1,24596 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +/****************************************************************************\ + * Note on documentation: The source files contain links to the online * + * documentation of the public API at https://json.nlohmann.me. This URL * + * contains the most recent documentation and should also be applicable to * + * previous versions; documentation for deprecated functions is not * + * removed, but marked deprecated. See "Generate documentation" section in * + * file docs/README.md. * +\****************************************************************************/ + +#ifndef INCLUDE_NLOHMANN_JSON_HPP_ +#define INCLUDE_NLOHMANN_JSON_HPP_ + +#include // all_of, find, for_each +#include // nullptr_t, ptrdiff_t, size_t +#include // hash, less +#include // initializer_list +#ifndef JSON_NO_IO + #include // istream, ostream +#endif // JSON_NO_IO +#include // random_access_iterator_tag +#include // unique_ptr +#include // accumulate +#include // string, stoi, to_string +#include // declval, forward, move, pair, swap +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// This file contains all macro definitions affecting or depending on the ABI + +#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK + #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) + #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2 + #warning "Already included a different version of the library!" + #endif + #endif +#endif + +#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_PATCH 2 // NOLINT(modernize-macro-to-enum) + +#ifndef JSON_DIAGNOSTICS + #define JSON_DIAGNOSTICS 0 +#endif + +#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +#endif + +#if JSON_DIAGNOSTICS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag +#else + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS +#endif + +#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp +#else + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION + #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +#endif + +// Construct the namespace ABI tags component +#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b +#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ + NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) + +#define NLOHMANN_JSON_ABI_TAGS \ + NLOHMANN_JSON_ABI_TAGS_CONCAT( \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ + NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) + +// Construct the namespace version component +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ + _v ## major ## _ ## minor ## _ ## patch +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) + +#if NLOHMANN_JSON_NAMESPACE_NO_VERSION +#define NLOHMANN_JSON_NAMESPACE_VERSION +#else +#define NLOHMANN_JSON_NAMESPACE_VERSION \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ + NLOHMANN_JSON_VERSION_MINOR, \ + NLOHMANN_JSON_VERSION_PATCH) +#endif + +// Combine namespace components +#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b +#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ + NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) + +#ifndef NLOHMANN_JSON_NAMESPACE +#define NLOHMANN_JSON_NAMESPACE \ + nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN +#define NLOHMANN_JSON_NAMESPACE_BEGIN \ + namespace nlohmann \ + { \ + inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) \ + { +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_END +#define NLOHMANN_JSON_NAMESPACE_END \ + } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ + } // namespace nlohmann +#endif + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // transform +#include // array +#include // forward_list +#include // inserter, front_inserter, end +#include // map +#include // string +#include // tuple, make_tuple +#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible +#include // unordered_map +#include // pair, declval +#include // valarray + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // nullptr_t +#include // exception +#include // runtime_error +#include // to_string +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // uint8_t +#include // string + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // declval, pair +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// https://en.cppreference.com/w/cpp/experimental/is_detected +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + nonesuch(nonesuch const&&) = delete; + void operator=(nonesuch const&) = delete; + void operator=(nonesuch&&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template class Op, class... Args> +using is_detected = typename detector::value_t; + +template class Op, class... Args> +struct is_detected_lazy : is_detected { }; + +template class Op, class... Args> +using detected_t = typename detector::type; + +template class Op, class... Args> +using detected_or = detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +template class Op, class... Args> +using is_detected_exact = std::is_same>; + +template class Op, class... Args> +using is_detected_convertible = + std::is_convertible, To>; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + + +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson +// SPDX-License-Identifier: MIT + +/* Hedley - https://nemequ.github.io/hedley + * Created by Evan Nemerson + */ + +#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) +#if defined(JSON_HEDLEY_VERSION) + #undef JSON_HEDLEY_VERSION +#endif +#define JSON_HEDLEY_VERSION 15 + +#if defined(JSON_HEDLEY_STRINGIFY_EX) + #undef JSON_HEDLEY_STRINGIFY_EX +#endif +#define JSON_HEDLEY_STRINGIFY_EX(x) #x + +#if defined(JSON_HEDLEY_STRINGIFY) + #undef JSON_HEDLEY_STRINGIFY +#endif +#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) + +#if defined(JSON_HEDLEY_CONCAT_EX) + #undef JSON_HEDLEY_CONCAT_EX +#endif +#define JSON_HEDLEY_CONCAT_EX(a,b) a##b + +#if defined(JSON_HEDLEY_CONCAT) + #undef JSON_HEDLEY_CONCAT +#endif +#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) + +#if defined(JSON_HEDLEY_CONCAT3_EX) + #undef JSON_HEDLEY_CONCAT3_EX +#endif +#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c + +#if defined(JSON_HEDLEY_CONCAT3) + #undef JSON_HEDLEY_CONCAT3 +#endif +#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) + +#if defined(JSON_HEDLEY_VERSION_ENCODE) + #undef JSON_HEDLEY_VERSION_ENCODE +#endif +#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) + #undef JSON_HEDLEY_VERSION_DECODE_MAJOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) + #undef JSON_HEDLEY_VERSION_DECODE_MINOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) + #undef JSON_HEDLEY_VERSION_DECODE_REVISION +#endif +#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) + +#if defined(JSON_HEDLEY_GNUC_VERSION) + #undef JSON_HEDLEY_GNUC_VERSION +#endif +#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#elif defined(__GNUC__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) +#endif + +#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) + #undef JSON_HEDLEY_GNUC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GNUC_VERSION) + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION) + #undef JSON_HEDLEY_MSVC_VERSION +#endif +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) +#elif defined(_MSC_FULL_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) +#elif defined(_MSC_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) + #undef JSON_HEDLEY_MSVC_VERSION_CHECK +#endif +#if !defined(JSON_HEDLEY_MSVC_VERSION) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) +#elif defined(_MSC_VER) && (_MSC_VER >= 1200) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) +#else + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION) + #undef JSON_HEDLEY_INTEL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) +#elif defined(__INTEL_COMPILER) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_VERSION) + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #undef JSON_HEDLEY_INTEL_CL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) + #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION) + #undef JSON_HEDLEY_PGI_VERSION +#endif +#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) + #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) + #undef JSON_HEDLEY_PGI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PGI_VERSION) + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #undef JSON_HEDLEY_SUNPRO_VERSION +#endif +#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) +#elif defined(__SUNPRO_C) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) +#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) +#elif defined(__SUNPRO_CC) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) + #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION +#endif +#if defined(__EMSCRIPTEN__) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION) + #undef JSON_HEDLEY_ARM_VERSION +#endif +#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) +#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) + #undef JSON_HEDLEY_ARM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_ARM_VERSION) + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION) + #undef JSON_HEDLEY_IBM_VERSION +#endif +#if defined(__ibmxl__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) +#elif defined(__xlC__) && defined(__xlC_ver__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) +#elif defined(__xlC__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) + #undef JSON_HEDLEY_IBM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IBM_VERSION) + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_VERSION) + #undef JSON_HEDLEY_TI_VERSION +#endif +#if \ + defined(__TI_COMPILER_VERSION__) && \ + ( \ + defined(__TMS470__) || defined(__TI_ARM__) || \ + defined(__MSP430__) || \ + defined(__TMS320C2000__) \ + ) +#if (__TI_COMPILER_VERSION__ >= 16000000) + #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif +#endif + +#if defined(JSON_HEDLEY_TI_VERSION_CHECK) + #undef JSON_HEDLEY_TI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_VERSION) + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #undef JSON_HEDLEY_TI_CL2000_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) + #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #undef JSON_HEDLEY_TI_CL430_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) + #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #undef JSON_HEDLEY_TI_ARMCL_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) + #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) + #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #undef JSON_HEDLEY_TI_CL6X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) + #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #undef JSON_HEDLEY_TI_CL7X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) + #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #undef JSON_HEDLEY_TI_CLPRU_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) + #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION) + #undef JSON_HEDLEY_CRAY_VERSION +#endif +#if defined(_CRAYC) + #if defined(_RELEASE_PATCHLEVEL) + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) + #else + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) + #undef JSON_HEDLEY_CRAY_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_CRAY_VERSION) + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION) + #undef JSON_HEDLEY_IAR_VERSION +#endif +#if defined(__IAR_SYSTEMS_ICC__) + #if __VER__ > 1000 + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) + #else + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) + #undef JSON_HEDLEY_IAR_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IAR_VERSION) + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION) + #undef JSON_HEDLEY_TINYC_VERSION +#endif +#if defined(__TINYC__) + #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) + #undef JSON_HEDLEY_TINYC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION) + #undef JSON_HEDLEY_DMC_VERSION +#endif +#if defined(__DMC__) + #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) + #undef JSON_HEDLEY_DMC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_DMC_VERSION) + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #undef JSON_HEDLEY_COMPCERT_VERSION +#endif +#if defined(__COMPCERT_VERSION__) + #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) + #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION) + #undef JSON_HEDLEY_PELLES_VERSION +#endif +#if defined(__POCC__) + #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) + #undef JSON_HEDLEY_PELLES_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PELLES_VERSION) + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #undef JSON_HEDLEY_MCST_LCC_VERSION +#endif +#if defined(__LCC__) && defined(__LCC_MINOR__) + #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) + #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION) + #undef JSON_HEDLEY_GCC_VERSION +#endif +#if \ + defined(JSON_HEDLEY_GNUC_VERSION) && \ + !defined(__clang__) && \ + !defined(JSON_HEDLEY_INTEL_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_ARM_VERSION) && \ + !defined(JSON_HEDLEY_CRAY_VERSION) && \ + !defined(JSON_HEDLEY_TI_VERSION) && \ + !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ + !defined(__COMPCERT__) && \ + !defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_ATTRIBUTE +#endif +#if \ + defined(__has_attribute) && \ + ( \ + (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ + ) +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) +#else +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE +#endif +#if \ + defined(__has_cpp_attribute) && \ + defined(__cplusplus) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS +#endif +#if !defined(__cplusplus) || !defined(__has_cpp_attribute) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#elif \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ + (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_BUILTIN) + #undef JSON_HEDLEY_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) +#else + #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) + #undef JSON_HEDLEY_GNUC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) + #undef JSON_HEDLEY_GCC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_FEATURE) + #undef JSON_HEDLEY_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) +#else + #define JSON_HEDLEY_HAS_FEATURE(feature) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) + #undef JSON_HEDLEY_GNUC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) + #undef JSON_HEDLEY_GCC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_EXTENSION) + #undef JSON_HEDLEY_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) +#else + #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) + #undef JSON_HEDLEY_GNUC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) + #undef JSON_HEDLEY_GCC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_WARNING) + #undef JSON_HEDLEY_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) +#else + #define JSON_HEDLEY_HAS_WARNING(warning) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) + #undef JSON_HEDLEY_GNUC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_WARNING) + #undef JSON_HEDLEY_GCC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + defined(__clang__) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ + (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) + #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_PRAGMA(value) __pragma(value) +#else + #define JSON_HEDLEY_PRAGMA(value) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) + #undef JSON_HEDLEY_DIAGNOSTIC_PUSH +#endif +#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) + #undef JSON_HEDLEY_DIAGNOSTIC_POP +#endif +#if defined(__clang__) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) + #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) +#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_PUSH + #define JSON_HEDLEY_DIAGNOSTIC_POP +#endif + +/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") +# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") +# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# endif +#endif +#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x +#endif + +#if defined(JSON_HEDLEY_CONST_CAST) + #undef JSON_HEDLEY_CONST_CAST +#endif +#if defined(__cplusplus) +# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) +#elif \ + JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_REINTERPRET_CAST) + #undef JSON_HEDLEY_REINTERPRET_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) +#else + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_STATIC_CAST) + #undef JSON_HEDLEY_STATIC_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) +#else + #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_CPP_CAST) + #undef JSON_HEDLEY_CPP_CAST +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ + ((T) (expr)) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("diag_suppress=Pe137") \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) +# endif +#else +# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif + +#if defined(JSON_HEDLEY_DEPRECATED) + #undef JSON_HEDLEY_DEPRECATED +#endif +#if defined(JSON_HEDLEY_DEPRECATED_FOR) + #undef JSON_HEDLEY_DEPRECATED_FOR +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) +#elif \ + (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) +#elif defined(__cplusplus) && (__cplusplus >= 201402L) + #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") +#else + #define JSON_HEDLEY_DEPRECATED(since) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) +#endif + +#if defined(JSON_HEDLEY_UNAVAILABLE) + #undef JSON_HEDLEY_UNAVAILABLE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) +#else + #define JSON_HEDLEY_UNAVAILABLE(available_since) +#endif + +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT +#endif +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) +#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) +#elif defined(_Check_return_) /* SAL */ + #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ +#else + #define JSON_HEDLEY_WARN_UNUSED_RESULT + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) +#endif + +#if defined(JSON_HEDLEY_SENTINEL) + #undef JSON_HEDLEY_SENTINEL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) +#else + #define JSON_HEDLEY_SENTINEL(position) +#endif + +#if defined(JSON_HEDLEY_NO_RETURN) + #undef JSON_HEDLEY_NO_RETURN +#endif +#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NO_RETURN __noreturn +#elif \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #define JSON_HEDLEY_NO_RETURN _Noreturn +#elif defined(__cplusplus) && (__cplusplus >= 201103L) + #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#else + #define JSON_HEDLEY_NO_RETURN +#endif + +#if defined(JSON_HEDLEY_NO_ESCAPE) + #undef JSON_HEDLEY_NO_ESCAPE +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) + #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) +#else + #define JSON_HEDLEY_NO_ESCAPE +#endif + +#if defined(JSON_HEDLEY_UNREACHABLE) + #undef JSON_HEDLEY_UNREACHABLE +#endif +#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) + #undef JSON_HEDLEY_UNREACHABLE_RETURN +#endif +#if defined(JSON_HEDLEY_ASSUME) + #undef JSON_HEDLEY_ASSUME +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_ASSUME(expr) __assume(expr) +#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) + #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) +#elif \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #if defined(__cplusplus) + #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) + #else + #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) + #endif +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() +#elif defined(JSON_HEDLEY_ASSUME) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif +#if !defined(JSON_HEDLEY_ASSUME) + #if defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) + #else + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) + #endif +#endif +#if defined(JSON_HEDLEY_UNREACHABLE) + #if \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) + #else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() + #endif +#else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) +#endif +#if !defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif + +JSON_HEDLEY_DIAGNOSTIC_PUSH +#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") + #pragma clang diagnostic ignored "-Wpedantic" +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) + #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#endif +#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) + #if defined(__clang__) + #pragma clang diagnostic ignored "-Wvariadic-macros" + #elif defined(JSON_HEDLEY_GCC_VERSION) + #pragma GCC diagnostic ignored "-Wvariadic-macros" + #endif +#endif +#if defined(JSON_HEDLEY_NON_NULL) + #undef JSON_HEDLEY_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) +#else + #define JSON_HEDLEY_NON_NULL(...) +#endif +JSON_HEDLEY_DIAGNOSTIC_POP + +#if defined(JSON_HEDLEY_PRINTF_FORMAT) + #undef JSON_HEDLEY_PRINTF_FORMAT +#endif +#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) +#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) +#else + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) +#endif + +#if defined(JSON_HEDLEY_CONSTEXPR) + #undef JSON_HEDLEY_CONSTEXPR +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) + #endif +#endif +#if !defined(JSON_HEDLEY_CONSTEXPR) + #define JSON_HEDLEY_CONSTEXPR +#endif + +#if defined(JSON_HEDLEY_PREDICT) + #undef JSON_HEDLEY_PREDICT +#endif +#if defined(JSON_HEDLEY_LIKELY) + #undef JSON_HEDLEY_LIKELY +#endif +#if defined(JSON_HEDLEY_UNLIKELY) + #undef JSON_HEDLEY_UNLIKELY +#endif +#if defined(JSON_HEDLEY_UNPREDICTABLE) + #undef JSON_HEDLEY_UNPREDICTABLE +#endif +#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) + #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) +#elif \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ + (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ + })) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ + })) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) +#else +# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) +# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) +#endif +#if !defined(JSON_HEDLEY_UNPREDICTABLE) + #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) +#endif + +#if defined(JSON_HEDLEY_MALLOC) + #undef JSON_HEDLEY_MALLOC +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_MALLOC __declspec(restrict) +#else + #define JSON_HEDLEY_MALLOC +#endif + +#if defined(JSON_HEDLEY_PURE) + #undef JSON_HEDLEY_PURE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PURE __attribute__((__pure__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) +# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ + ) +# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") +#else +# define JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_CONST) + #undef JSON_HEDLEY_CONST +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_CONST __attribute__((__const__)) +#elif \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_CONST _Pragma("no_side_effect") +#else + #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_RESTRICT) + #undef JSON_HEDLEY_RESTRICT +#endif +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT restrict +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + defined(__clang__) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RESTRICT __restrict +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT _Restrict +#else + #define JSON_HEDLEY_RESTRICT +#endif + +#if defined(JSON_HEDLEY_INLINE) + #undef JSON_HEDLEY_INLINE +#endif +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + (defined(__cplusplus) && (__cplusplus >= 199711L)) + #define JSON_HEDLEY_INLINE inline +#elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) + #define JSON_HEDLEY_INLINE __inline__ +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_INLINE __inline +#else + #define JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_ALWAYS_INLINE) + #undef JSON_HEDLEY_ALWAYS_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) +# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_ALWAYS_INLINE __forceinline +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ + ) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") +#else +# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_NEVER_INLINE) + #undef JSON_HEDLEY_NEVER_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#else + #define JSON_HEDLEY_NEVER_INLINE +#endif + +#if defined(JSON_HEDLEY_PRIVATE) + #undef JSON_HEDLEY_PRIVATE +#endif +#if defined(JSON_HEDLEY_PUBLIC) + #undef JSON_HEDLEY_PUBLIC +#endif +#if defined(JSON_HEDLEY_IMPORT) + #undef JSON_HEDLEY_IMPORT +#endif +#if defined(_WIN32) || defined(__CYGWIN__) +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC __declspec(dllexport) +# define JSON_HEDLEY_IMPORT __declspec(dllimport) +#else +# if \ + JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + ( \ + defined(__TI_EABI__) && \ + ( \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ + ) \ + ) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) +# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) +# else +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC +# endif +# define JSON_HEDLEY_IMPORT extern +#endif + +#if defined(JSON_HEDLEY_NO_THROW) + #undef JSON_HEDLEY_NO_THROW +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NO_THROW __declspec(nothrow) +#else + #define JSON_HEDLEY_NO_THROW +#endif + +#if defined(JSON_HEDLEY_FALL_THROUGH) + #undef JSON_HEDLEY_FALL_THROUGH +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) +#elif defined(__fallthrough) /* SAL */ + #define JSON_HEDLEY_FALL_THROUGH __fallthrough +#else + #define JSON_HEDLEY_FALL_THROUGH +#endif + +#if defined(JSON_HEDLEY_RETURNS_NON_NULL) + #undef JSON_HEDLEY_RETURNS_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) +#elif defined(_Ret_notnull_) /* SAL */ + #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ +#else + #define JSON_HEDLEY_RETURNS_NON_NULL +#endif + +#if defined(JSON_HEDLEY_ARRAY_PARAM) + #undef JSON_HEDLEY_ARRAY_PARAM +#endif +#if \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ + !defined(__STDC_NO_VLA__) && \ + !defined(__cplusplus) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_ARRAY_PARAM(name) (name) +#else + #define JSON_HEDLEY_ARRAY_PARAM(name) +#endif + +#if defined(JSON_HEDLEY_IS_CONSTANT) + #undef JSON_HEDLEY_IS_CONSTANT +#endif +#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) + #undef JSON_HEDLEY_REQUIRE_CONSTEXPR +#endif +/* JSON_HEDLEY_IS_CONSTEXPR_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #undef JSON_HEDLEY_IS_CONSTEXPR_ +#endif +#if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) +#endif +#if !defined(__cplusplus) +# if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) +#endif +# elif \ + ( \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION)) || \ + (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) +#endif +# elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + defined(JSON_HEDLEY_INTEL_VERSION) || \ + defined(JSON_HEDLEY_TINYC_VERSION) || \ + defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ + defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ + defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ + defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ + defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ + defined(__clang__) +# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ + sizeof(void) != \ + sizeof(*( \ + 1 ? \ + ((void*) ((expr) * 0L) ) : \ +((struct { char v[sizeof(void) * 2]; } *) 1) \ + ) \ + ) \ + ) +# endif +#endif +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) +#else + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) (0) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) +#endif + +#if defined(JSON_HEDLEY_BEGIN_C_DECLS) + #undef JSON_HEDLEY_BEGIN_C_DECLS +#endif +#if defined(JSON_HEDLEY_END_C_DECLS) + #undef JSON_HEDLEY_END_C_DECLS +#endif +#if defined(JSON_HEDLEY_C_DECL) + #undef JSON_HEDLEY_C_DECL +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { + #define JSON_HEDLEY_END_C_DECLS } + #define JSON_HEDLEY_C_DECL extern "C" +#else + #define JSON_HEDLEY_BEGIN_C_DECLS + #define JSON_HEDLEY_END_C_DECLS + #define JSON_HEDLEY_C_DECL +#endif + +#if defined(JSON_HEDLEY_STATIC_ASSERT) + #undef JSON_HEDLEY_STATIC_ASSERT +#endif +#if \ + !defined(__cplusplus) && ( \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ + (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + defined(_Static_assert) \ + ) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) +#elif \ + (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) +#else +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) +#endif + +#if defined(JSON_HEDLEY_NULL) + #undef JSON_HEDLEY_NULL +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) + #elif defined(NULL) + #define JSON_HEDLEY_NULL NULL + #else + #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) + #endif +#elif defined(NULL) + #define JSON_HEDLEY_NULL NULL +#else + #define JSON_HEDLEY_NULL ((void*) 0) +#endif + +#if defined(JSON_HEDLEY_MESSAGE) + #undef JSON_HEDLEY_MESSAGE +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_MESSAGE(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(message msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) +#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_WARNING) + #undef JSON_HEDLEY_WARNING +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_WARNING(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(clang warning msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_REQUIRE) + #undef JSON_HEDLEY_REQUIRE +#endif +#if defined(JSON_HEDLEY_REQUIRE_MSG) + #undef JSON_HEDLEY_REQUIRE_MSG +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) +# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") +# define JSON_HEDLEY_REQUIRE(expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), #expr, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), msg, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) +# endif +#else +# define JSON_HEDLEY_REQUIRE(expr) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) +#endif + +#if defined(JSON_HEDLEY_FLAGS) + #undef JSON_HEDLEY_FLAGS +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) + #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) +#else + #define JSON_HEDLEY_FLAGS +#endif + +#if defined(JSON_HEDLEY_FLAGS_CAST) + #undef JSON_HEDLEY_FLAGS_CAST +#endif +#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) +# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("warning(disable:188)") \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) +#endif + +#if defined(JSON_HEDLEY_EMPTY_BASES) + #undef JSON_HEDLEY_EMPTY_BASES +#endif +#if \ + (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) +#else + #define JSON_HEDLEY_EMPTY_BASES +#endif + +/* Remaining macros are deprecated. */ + +#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK +#endif +#if defined(__clang__) + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) +#else + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) + #undef JSON_HEDLEY_CLANG_HAS_BUILTIN +#endif +#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) + +#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) + #undef JSON_HEDLEY_CLANG_HAS_FEATURE +#endif +#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) + +#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) + #undef JSON_HEDLEY_CLANG_HAS_EXTENSION +#endif +#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) + +#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) + #undef JSON_HEDLEY_CLANG_HAS_WARNING +#endif +#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) + +#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ + + +// This file contains all internal macro definitions (except those affecting ABI) +// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them + +// #include + + +// exclude unsupported compilers +#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) + #if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #endif +#endif + +// C++ language standard detection +// if the user manually specified the used c++ version this is skipped +#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) + #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 + #endif + // the cpp 11 flag is always specified because it is the minimal required version + #define JSON_HAS_CPP_11 +#endif + +#ifdef __has_include + #if __has_include() + #include + #endif +#endif + +#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) + #ifdef JSON_HAS_CPP_17 + #if defined(__cpp_lib_filesystem) + #define JSON_HAS_FILESYSTEM 1 + #elif defined(__cpp_lib_experimental_filesystem) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif !defined(__has_include) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #endif + + // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ + #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__clang_major__) && __clang_major__ < 7 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support + #if defined(_MSC_VER) && _MSC_VER < 1914 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before iOS 13 + #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before macOS Catalina + #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + #endif +#endif + +#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_FILESYSTEM + #define JSON_HAS_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_THREE_WAY_COMPARISON + #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ + && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L + #define JSON_HAS_THREE_WAY_COMPARISON 1 + #else + #define JSON_HAS_THREE_WAY_COMPARISON 0 + #endif +#endif + +#ifndef JSON_HAS_RANGES + // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error + #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 + #define JSON_HAS_RANGES 0 + #elif defined(__cpp_lib_ranges) + #define JSON_HAS_RANGES 1 + #else + #define JSON_HAS_RANGES 0 + #endif +#endif + +#ifdef JSON_HAS_CPP_17 + #define JSON_INLINE_VARIABLE inline +#else + #define JSON_INLINE_VARIABLE +#endif + +#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) + #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else + #define JSON_NO_UNIQUE_ADDRESS +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#endif + +// allow disabling exceptions +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) + #define JSON_INTERNAL_CATCH(exception) catch(exception) +#else + #include + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) + #define JSON_INTERNAL_CATCH(exception) if(false) +#endif + +// override exception macros +#if defined(JSON_THROW_USER) + #undef JSON_THROW + #define JSON_THROW JSON_THROW_USER +#endif +#if defined(JSON_TRY_USER) + #undef JSON_TRY + #define JSON_TRY JSON_TRY_USER +#endif +#if defined(JSON_CATCH_USER) + #undef JSON_CATCH + #define JSON_CATCH JSON_CATCH_USER + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_CATCH_USER +#endif +#if defined(JSON_INTERNAL_CATCH_USER) + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER +#endif + +// allow overriding assert +#if !defined(JSON_ASSERT) + #include // assert + #define JSON_ASSERT(x) assert(x) +#endif + +// allow to access some private functions (needed by the test suite) +#if defined(JSON_TESTS_PRIVATE) + #define JSON_PRIVATE_UNLESS_TESTED public +#else + #define JSON_PRIVATE_UNLESS_TESTED private +#endif + +/*! +@brief macro to briefly define a mapping between an enum and JSON +@def NLOHMANN_JSON_SERIALIZE_ENUM +@since version 3.4.0 +*/ +#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.first == e; \ + }); \ + j = ((it != std::end(m)) ? it : std::begin(m))->second; \ + } \ + template \ + inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [&j](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.second == j; \ + }); \ + e = ((it != std::end(m)) ? it : std::begin(m))->first; \ + } + +// Ugly macros to avoid uglier copy-paste when specializing basic_json. They +// may be removed in the future once the class is split. + +#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ + template class ObjectType, \ + template class ArrayType, \ + class StringType, class BooleanType, class NumberIntegerType, \ + class NumberUnsignedType, class NumberFloatType, \ + template class AllocatorType, \ + template class JSONSerializer, \ + class BinaryType> + +#define NLOHMANN_BASIC_JSON_TPL \ + basic_json + +// Macros to simplify conversion from/to types + +#define NLOHMANN_JSON_EXPAND( x ) x +#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME +#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_PASTE64, \ + NLOHMANN_JSON_PASTE63, \ + NLOHMANN_JSON_PASTE62, \ + NLOHMANN_JSON_PASTE61, \ + NLOHMANN_JSON_PASTE60, \ + NLOHMANN_JSON_PASTE59, \ + NLOHMANN_JSON_PASTE58, \ + NLOHMANN_JSON_PASTE57, \ + NLOHMANN_JSON_PASTE56, \ + NLOHMANN_JSON_PASTE55, \ + NLOHMANN_JSON_PASTE54, \ + NLOHMANN_JSON_PASTE53, \ + NLOHMANN_JSON_PASTE52, \ + NLOHMANN_JSON_PASTE51, \ + NLOHMANN_JSON_PASTE50, \ + NLOHMANN_JSON_PASTE49, \ + NLOHMANN_JSON_PASTE48, \ + NLOHMANN_JSON_PASTE47, \ + NLOHMANN_JSON_PASTE46, \ + NLOHMANN_JSON_PASTE45, \ + NLOHMANN_JSON_PASTE44, \ + NLOHMANN_JSON_PASTE43, \ + NLOHMANN_JSON_PASTE42, \ + NLOHMANN_JSON_PASTE41, \ + NLOHMANN_JSON_PASTE40, \ + NLOHMANN_JSON_PASTE39, \ + NLOHMANN_JSON_PASTE38, \ + NLOHMANN_JSON_PASTE37, \ + NLOHMANN_JSON_PASTE36, \ + NLOHMANN_JSON_PASTE35, \ + NLOHMANN_JSON_PASTE34, \ + NLOHMANN_JSON_PASTE33, \ + NLOHMANN_JSON_PASTE32, \ + NLOHMANN_JSON_PASTE31, \ + NLOHMANN_JSON_PASTE30, \ + NLOHMANN_JSON_PASTE29, \ + NLOHMANN_JSON_PASTE28, \ + NLOHMANN_JSON_PASTE27, \ + NLOHMANN_JSON_PASTE26, \ + NLOHMANN_JSON_PASTE25, \ + NLOHMANN_JSON_PASTE24, \ + NLOHMANN_JSON_PASTE23, \ + NLOHMANN_JSON_PASTE22, \ + NLOHMANN_JSON_PASTE21, \ + NLOHMANN_JSON_PASTE20, \ + NLOHMANN_JSON_PASTE19, \ + NLOHMANN_JSON_PASTE18, \ + NLOHMANN_JSON_PASTE17, \ + NLOHMANN_JSON_PASTE16, \ + NLOHMANN_JSON_PASTE15, \ + NLOHMANN_JSON_PASTE14, \ + NLOHMANN_JSON_PASTE13, \ + NLOHMANN_JSON_PASTE12, \ + NLOHMANN_JSON_PASTE11, \ + NLOHMANN_JSON_PASTE10, \ + NLOHMANN_JSON_PASTE9, \ + NLOHMANN_JSON_PASTE8, \ + NLOHMANN_JSON_PASTE7, \ + NLOHMANN_JSON_PASTE6, \ + NLOHMANN_JSON_PASTE5, \ + NLOHMANN_JSON_PASTE4, \ + NLOHMANN_JSON_PASTE3, \ + NLOHMANN_JSON_PASTE2, \ + NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) +#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) +#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) +#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) +#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) +#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) +#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) +#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) +#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) +#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) +#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) +#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) +#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) +#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) +#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) +#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) +#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) +#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) +#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) +#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) +#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) +#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) +#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) +#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) +#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) +#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) +#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) +#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) +#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) +#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) +#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) +#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) +#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) +#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) +#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) +#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) +#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) +#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) +#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) +#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) +#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) +#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) +#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) +#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) +#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) +#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) +#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) +#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) +#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) +#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) +#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) +#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) +#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) +#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) +#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) +#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) +#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) +#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) +#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) +#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) +#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) +#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) +#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) +#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) + +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); +#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + + +// inspired from https://stackoverflow.com/a/26745591 +// allows to call any std function as if (e.g. with begin): +// using std::begin; begin(x); +// +// it allows using the detected idiom to retrieve the return type +// of such an expression +#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ + namespace detail { \ + using std::std_name; \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + } \ + \ + namespace detail2 { \ + struct std_name##_tag \ + { \ + }; \ + \ + template \ + std_name##_tag std_name(T&&...); \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + \ + template \ + struct would_call_std_##std_name \ + { \ + static constexpr auto const value = ::nlohmann::detail:: \ + is_detected_exact::value; \ + }; \ + } /* namespace detail2 */ \ + \ + template \ + struct would_call_std_##std_name : detail2::would_call_std_##std_name \ + { \ + } + +#ifndef JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_USE_IMPLICIT_CONVERSIONS 1 +#endif + +#if JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_EXPLICIT +#else + #define JSON_EXPLICIT explicit +#endif + +#ifndef JSON_DISABLE_ENUM_SERIALIZATION + #define JSON_DISABLE_ENUM_SERIALIZATION 0 +#endif + +#ifndef JSON_USE_GLOBAL_UDLS + #define JSON_USE_GLOBAL_UDLS 1 +#endif + +#if JSON_HAS_THREE_WAY_COMPARISON + #include // partial_ordering +#endif + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/////////////////////////// +// JSON type enumeration // +/////////////////////////// + +/*! +@brief the JSON type enumeration + +This enumeration collects the different JSON types. It is internally used to +distinguish the stored values, and the functions @ref basic_json::is_null(), +@ref basic_json::is_object(), @ref basic_json::is_array(), +@ref basic_json::is_string(), @ref basic_json::is_boolean(), +@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), +@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), +@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and +@ref basic_json::is_structured() rely on it. + +@note There are three enumeration entries (number_integer, number_unsigned, and +number_float), because the library distinguishes these three types for numbers: +@ref basic_json::number_unsigned_t is used for unsigned integers, +@ref basic_json::number_integer_t is used for signed integers, and +@ref basic_json::number_float_t is used for floating-point numbers or to +approximate integers which do not fit in the limits of their respective type. + +@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON +value with the default value for a given type + +@since version 1.0.0 +*/ +enum class value_t : std::uint8_t +{ + null, ///< null value + object, ///< object (unordered set of name/value pairs) + array, ///< array (ordered collection of values) + string, ///< string value + boolean, ///< boolean value + number_integer, ///< number value (signed integer) + number_unsigned, ///< number value (unsigned integer) + number_float, ///< number value (floating-point) + binary, ///< binary array (ordered collection of bytes) + discarded ///< discarded by the parser callback function +}; + +/*! +@brief comparison operator for JSON types + +Returns an ordering that is similar to Python: +- order: null < boolean < number < object < array < string < binary +- furthermore, each type is not smaller than itself +- discarded values are not comparable +- binary is represented as a b"" string in python and directly comparable to a + string; however, making a binary array directly comparable with a string would + be surprising behavior in a JSON file. + +@since version 1.0.0 +*/ +#if JSON_HAS_THREE_WAY_COMPARISON + inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* +#else + inline bool operator<(const value_t lhs, const value_t rhs) noexcept +#endif +{ + static constexpr std::array order = {{ + 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, + 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, + 6 /* binary */ + } + }; + + const auto l_index = static_cast(lhs); + const auto r_index = static_cast(rhs); +#if JSON_HAS_THREE_WAY_COMPARISON + if (l_index < order.size() && r_index < order.size()) + { + return order[l_index] <=> order[r_index]; // *NOPAD* + } + return std::partial_ordering::unordered; +#else + return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; +#endif +} + +// GCC selects the built-in operator< over an operator rewritten from +// a user-defined spaceship operator +// Clang, MSVC, and ICC select the rewritten candidate +// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) +#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) +inline bool operator<(const value_t lhs, const value_t rhs) noexcept +{ + return std::is_lt(lhs <=> rhs); // *NOPAD* +} +#endif + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief replace all occurrences of a substring by another string + +@param[in,out] s the string to manipulate; changed so that all + occurrences of @a f are replaced with @a t +@param[in] f the substring to replace with @a t +@param[in] t the string to replace @a f + +@pre The search string @a f must not be empty. **This precondition is +enforced with an assertion.** + +@since version 2.0.0 +*/ +template +inline void replace_substring(StringType& s, const StringType& f, + const StringType& t) +{ + JSON_ASSERT(!f.empty()); + for (auto pos = s.find(f); // find first occurrence of f + pos != StringType::npos; // make sure f was found + s.replace(pos, f.size(), t), // replace with t, and + pos = s.find(f, pos + t.size())) // find next occurrence of f + {} +} + +/*! + * @brief string escaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to escape + * @return escaped string + * + * Note the order of escaping "~" to "~0" and "/" to "~1" is important. + */ +template +inline StringType escape(StringType s) +{ + replace_substring(s, StringType{"~"}, StringType{"~0"}); + replace_substring(s, StringType{"/"}, StringType{"~1"}); + return s; +} + +/*! + * @brief string unescaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to unescape + * @return unescaped string + * + * Note the order of escaping "~1" to "/" and "~0" to "~" is important. + */ +template +static void unescape(StringType& s) +{ + replace_substring(s, StringType{"~1"}, StringType{"/"}); + replace_substring(s, StringType{"~0"}, StringType{"~"}); +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // size_t + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// struct to capture the start position of the current token +struct position_t +{ + /// the total number of characters read + std::size_t chars_read_total = 0; + /// the number of characters read in the current line + std::size_t chars_read_current_line = 0; + /// the number of lines read + std::size_t lines_read = 0; + + /// conversion to size_t to preserve SAX interface + constexpr operator size_t() const + { + return chars_read_total; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-FileCopyrightText: 2018 The Abseil Authors +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type +#include // index_sequence, make_index_sequence, index_sequence_for + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +using uncvref_t = typename std::remove_cv::type>::type; + +#ifdef JSON_HAS_CPP_14 + +// the following utilities are natively available in C++14 +using std::enable_if_t; +using std::index_sequence; +using std::make_index_sequence; +using std::index_sequence_for; + +#else + +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h +// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. + +//// START OF CODE FROM GOOGLE ABSEIL + +// integer_sequence +// +// Class template representing a compile-time integer sequence. An instantiation +// of `integer_sequence` has a sequence of integers encoded in its +// type through its template arguments (which is a common need when +// working with C++11 variadic templates). `absl::integer_sequence` is designed +// to be a drop-in replacement for C++14's `std::integer_sequence`. +// +// Example: +// +// template< class T, T... Ints > +// void user_function(integer_sequence); +// +// int main() +// { +// // user_function's `T` will be deduced to `int` and `Ints...` +// // will be deduced to `0, 1, 2, 3, 4`. +// user_function(make_integer_sequence()); +// } +template +struct integer_sequence +{ + using value_type = T; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +// index_sequence +// +// A helper template for an `integer_sequence` of `size_t`, +// `absl::index_sequence` is designed to be a drop-in replacement for C++14's +// `std::index_sequence`. +template +using index_sequence = integer_sequence; + +namespace utility_internal +{ + +template +struct Extend; + +// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. +template +struct Extend, SeqSize, 0> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; +}; + +template +struct Extend, SeqSize, 1> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; +}; + +// Recursion helper for 'make_integer_sequence'. +// 'Gen::type' is an alias for 'integer_sequence'. +template +struct Gen +{ + using type = + typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; +}; + +template +struct Gen +{ + using type = integer_sequence; +}; + +} // namespace utility_internal + +// Compile-time sequences of integers + +// make_integer_sequence +// +// This template alias is equivalent to +// `integer_sequence`, and is designed to be a drop-in +// replacement for C++14's `std::make_integer_sequence`. +template +using make_integer_sequence = typename utility_internal::Gen::type; + +// make_index_sequence +// +// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, +// and is designed to be a drop-in replacement for C++14's +// `std::make_index_sequence`. +template +using make_index_sequence = make_integer_sequence; + +// index_sequence_for +// +// Converts a typename pack into an index sequence of the same length, and +// is designed to be a drop-in replacement for C++14's +// `std::index_sequence_for()` +template +using index_sequence_for = make_index_sequence; + +//// END OF CODE FROM GOOGLE ABSEIL + +#endif + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static JSON_INLINE_VARIABLE constexpr T value{}; +}; + +#ifndef JSON_HAS_CPP_17 + template + constexpr T static_const::value; +#endif + +template +inline constexpr std::array make_array(Args&& ... args) +{ + return std::array {{static_cast(std::forward(args))...}}; +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // numeric_limits +#include // false_type, is_constructible, is_integral, is_same, true_type +#include // declval +#include // tuple + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // random_access_iterator_tag + +// #include + +// #include + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +struct iterator_types {}; + +template +struct iterator_types < + It, + void_t> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +// This is required as some compilers implement std::iterator_traits in a way that +// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. +template +struct iterator_traits +{ +}; + +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> +{ + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); + +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); + +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ + #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + #include // int64_t, uint64_t + #include // map + #include // allocator + #include // string + #include // vector + + // #include + + + /*! + @brief namespace for Niels Lohmann + @see https://github.com/nlohmann + @since version 1.0.0 + */ + NLOHMANN_JSON_NAMESPACE_BEGIN + + /*! + @brief default JSONSerializer template argument + + This serializer ignores the template arguments and uses ADL + ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) + for serialization. + */ + template + struct adl_serializer; + + /// a class to store JSON values + /// @sa https://json.nlohmann.me/api/basic_json/ + template class ObjectType = + std::map, + template class ArrayType = std::vector, + class StringType = std::string, class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = + adl_serializer, + class BinaryType = std::vector> + class basic_json; + + /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document + /// @sa https://json.nlohmann.me/api/json_pointer/ + template + class json_pointer; + + /*! + @brief default specialization + @sa https://json.nlohmann.me/api/json/ + */ + using json = basic_json<>; + + /// @brief a minimal map-like container that preserves insertion order + /// @sa https://json.nlohmann.me/api/ordered_map/ + template + struct ordered_map; + + /// @brief specialization that maintains the insertion order of object keys + /// @sa https://json.nlohmann.me/api/ordered_json/ + using ordered_json = basic_json; + + NLOHMANN_JSON_NAMESPACE_END + +#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + +NLOHMANN_JSON_NAMESPACE_BEGIN +/*! +@brief detail namespace with internal helper functions + +This namespace collects functions that should not be exposed, +implementations of some @ref basic_json methods, and meta-programming helpers. + +@since version 2.1.0 +*/ +namespace detail +{ + +///////////// +// helpers // +///////////// + +// Note to maintainers: +// +// Every trait in this file expects a non CV-qualified type. +// The only exceptions are in the 'aliases for detected' section +// (i.e. those of the form: decltype(T::member_function(std::declval()))) +// +// In this case, T has to be properly CV-qualified to constraint the function arguments +// (e.g. to_json(BasicJsonType&, const T&)) + +template struct is_basic_json : std::false_type {}; + +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct is_basic_json : std::true_type {}; + +// used by exceptions create() member functions +// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t +// false_type otherwise +template +struct is_basic_json_context : + std::integral_constant < bool, + is_basic_json::type>::type>::value + || std::is_same::value > +{}; + +////////////////////// +// json_ref helpers // +////////////////////// + +template +class json_ref; + +template +struct is_json_ref : std::false_type {}; + +template +struct is_json_ref> : std::true_type {}; + +////////////////////////// +// aliases for detected // +////////////////////////// + +template +using mapped_type_t = typename T::mapped_type; + +template +using key_type_t = typename T::key_type; + +template +using value_type_t = typename T::value_type; + +template +using difference_type_t = typename T::difference_type; + +template +using pointer_t = typename T::pointer; + +template +using reference_t = typename T::reference; + +template +using iterator_category_t = typename T::iterator_category; + +template +using to_json_function = decltype(T::to_json(std::declval()...)); + +template +using from_json_function = decltype(T::from_json(std::declval()...)); + +template +using get_template_function = decltype(std::declval().template get()); + +// trait checking if JSONSerializer::from_json(json const&, udt&) exists +template +struct has_from_json : std::false_type {}; + +// trait checking if j.get is valid +// use this trait instead of std::is_constructible or std::is_convertible, +// both rely on, or make use of implicit conversions, and thus fail when T +// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) +template +struct is_getable +{ + static constexpr bool value = is_detected::value; +}; + +template +struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if JSONSerializer::from_json(json const&) exists +// this overload is used for non-default-constructible user-defined-types +template +struct has_non_default_from_json : std::false_type {}; + +template +struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if BasicJsonType::json_serializer::to_json exists +// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. +template +struct has_to_json : std::false_type {}; + +template +struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +template +using detect_key_compare = typename T::key_compare; + +template +struct has_key_compare : std::integral_constant::value> {}; + +// obtains the actual object key comparator +template +struct actual_object_comparator +{ + using object_t = typename BasicJsonType::object_t; + using object_comparator_t = typename BasicJsonType::default_object_comparator_t; + using type = typename std::conditional < has_key_compare::value, + typename object_t::key_compare, object_comparator_t>::type; +}; + +template +using actual_object_comparator_t = typename actual_object_comparator::type; + +/////////////////// +// is_ functions // +/////////////////// + +// https://en.cppreference.com/w/cpp/types/conjunction +template struct conjunction : std::true_type { }; +template struct conjunction : B { }; +template +struct conjunction +: std::conditional(B::value), conjunction, B>::type {}; + +// https://en.cppreference.com/w/cpp/types/negation +template struct negation : std::integral_constant < bool, !B::value > { }; + +// Reimplementation of is_constructible and is_default_constructible, due to them being broken for +// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). +// This causes compile errors in e.g. clang 3.5 or gcc 4.9. +template +struct is_default_constructible : std::is_default_constructible {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + + +template +struct is_constructible : std::is_constructible {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + + +template +struct is_iterator_traits : std::false_type {}; + +template +struct is_iterator_traits> +{ + private: + using traits = iterator_traits; + + public: + static constexpr auto value = + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value; +}; + +template +struct is_range +{ + private: + using t_ref = typename std::add_lvalue_reference::type; + + using iterator = detected_t; + using sentinel = detected_t; + + // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator + // and https://en.cppreference.com/w/cpp/iterator/sentinel_for + // but reimplementing these would be too much work, as a lot of other concepts are used underneath + static constexpr auto is_iterator_begin = + is_iterator_traits>::value; + + public: + static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; +}; + +template +using iterator_t = enable_if_t::value, result_of_begin())>>; + +template +using range_value_t = value_type_t>>; + +// The following implementation of is_complete_type is taken from +// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ +// and is written by Xiang Fan who agreed to using it in this library. + +template +struct is_complete_type : std::false_type {}; + +template +struct is_complete_type : std::true_type {}; + +template +struct is_compatible_object_type_impl : std::false_type {}; + +template +struct is_compatible_object_type_impl < + BasicJsonType, CompatibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + // macOS's is_constructible does not play well with nonesuch... + static constexpr bool value = + is_constructible::value && + is_constructible::value; +}; + +template +struct is_compatible_object_type + : is_compatible_object_type_impl {}; + +template +struct is_constructible_object_type_impl : std::false_type {}; + +template +struct is_constructible_object_type_impl < + BasicJsonType, ConstructibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + static constexpr bool value = + (is_default_constructible::value && + (std::is_move_assignable::value || + std::is_copy_assignable::value) && + (is_constructible::value && + std::is_same < + typename object_t::mapped_type, + typename ConstructibleObjectType::mapped_type >::value)) || + (has_from_json::value || + has_non_default_from_json < + BasicJsonType, + typename ConstructibleObjectType::mapped_type >::value); +}; + +template +struct is_constructible_object_type + : is_constructible_object_type_impl {}; + +template +struct is_compatible_string_type +{ + static constexpr auto value = + is_constructible::value; +}; + +template +struct is_constructible_string_type +{ + // launder type through decltype() to fix compilation failure on ICPC +#ifdef __INTEL_COMPILER + using laundered_type = decltype(std::declval()); +#else + using laundered_type = ConstructibleStringType; +#endif + + static constexpr auto value = + conjunction < + is_constructible, + is_detected_exact>::value; +}; + +template +struct is_compatible_array_type_impl : std::false_type {}; + +template +struct is_compatible_array_type_impl < + BasicJsonType, CompatibleArrayType, + enable_if_t < + is_detected::value&& + is_iterator_traits>>::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 + !std::is_same>::value >> +{ + static constexpr bool value = + is_constructible>::value; +}; + +template +struct is_compatible_array_type + : is_compatible_array_type_impl {}; + +template +struct is_constructible_array_type_impl : std::false_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t::value >> + : std::true_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t < !std::is_same::value&& + !is_compatible_string_type::value&& + is_default_constructible::value&& +(std::is_move_assignable::value || + std::is_copy_assignable::value)&& +is_detected::value&& +is_iterator_traits>>::value&& +is_detected::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 +!std::is_same>::value&& + is_complete_type < + detected_t>::value >> +{ + using value_type = range_value_t; + + static constexpr bool value = + std::is_same::value || + has_from_json::value || + has_non_default_from_json < + BasicJsonType, + value_type >::value; +}; + +template +struct is_constructible_array_type + : is_constructible_array_type_impl {}; + +template +struct is_compatible_integer_type_impl : std::false_type {}; + +template +struct is_compatible_integer_type_impl < + RealIntegerType, CompatibleNumberIntegerType, + enable_if_t < std::is_integral::value&& + std::is_integral::value&& + !std::is_same::value >> +{ + // is there an assert somewhere on overflows? + using RealLimits = std::numeric_limits; + using CompatibleLimits = std::numeric_limits; + + static constexpr auto value = + is_constructible::value && + CompatibleLimits::is_integer && + RealLimits::is_signed == CompatibleLimits::is_signed; +}; + +template +struct is_compatible_integer_type + : is_compatible_integer_type_impl {}; + +template +struct is_compatible_type_impl: std::false_type {}; + +template +struct is_compatible_type_impl < + BasicJsonType, CompatibleType, + enable_if_t::value >> +{ + static constexpr bool value = + has_to_json::value; +}; + +template +struct is_compatible_type + : is_compatible_type_impl {}; + +template +struct is_constructible_tuple : std::false_type {}; + +template +struct is_constructible_tuple> : conjunction...> {}; + +template +struct is_json_iterator_of : std::false_type {}; + +template +struct is_json_iterator_of : std::true_type {}; + +template +struct is_json_iterator_of : std::true_type +{}; + +// checks if a given type T is a template specialization of Primary +template