diff --git a/cmake/scripts/FindVersion.cmake b/cmake/scripts/FindVersion.cmake index 9097cd612f..bfbd135644 100644 --- a/cmake/scripts/FindVersion.cmake +++ b/cmake/scripts/FindVersion.cmake @@ -49,7 +49,8 @@ if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git") string(SUBSTRING "${FULLHASH}" 0 10 SHORTHASH) # Get the last commit date - execute_process(COMMAND ${GIT_EXECUTABLE} -C "${CMAKE_SOURCE_DIR}" show -s --pretty=format:%ci HEAD + set(ENV{TZ} "UTC0") + execute_process(COMMAND ${GIT_EXECUTABLE} -C "${CMAKE_SOURCE_DIR}" show -s --date=iso-local --pretty=format:%cd HEAD OUTPUT_VARIABLE COMMITDATE OUTPUT_STRIP_TRAILING_WHITESPACE WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 7cce99c9ac..656082447c 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -233,8 +233,8 @@ class BuildAirportWindow : public PickerWindowBase { { DropDownList list; - for (uint i = 0; AirportClass::IsClassIDValid((AirportClassID)i); i++) { - list.push_back(MakeDropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false)); + for (const auto &cls : AirportClass::Classes()) { + list.push_back(MakeDropDownListStringItem(cls.name, cls.Index())); } return list; @@ -314,8 +314,8 @@ public: switch (widget) { case WID_AP_CLASS_DROPDOWN: { Dimension d = {0, 0}; - for (uint i = 0; i < AirportClass::GetClassCount(); i++) { - d = maxdim(d, GetStringBoundingBox(AirportClass::Get((AirportClassID)i)->name)); + for (const auto &cls : AirportClass::Classes()) { + d = maxdim(d, GetStringBoundingBox(cls.name)); } d.width += padding.width; d.height += padding.height; @@ -538,14 +538,12 @@ public: if (change_class) { /* If that fails, select the first available airport * from the first class where airports are available. */ - for (AirportClassID j = APC_BEGIN; j < APC_MAX; j++) { - AirportClass *apclass = AirportClass::Get(j); - for (uint i = 0; i < apclass->GetSpecCount(); i++) { - const AirportSpec *as = apclass->GetSpec(i); + for (const auto &cls : AirportClass::Classes()) { + for (const auto &as : cls.Specs()) { if (as->IsAvailable()) { - _selected_airport_class = j; - this->vscroll->SetCount(apclass->GetSpecCount()); - this->SelectOtherAirport(i); + _selected_airport_class = cls.Index(); + this->vscroll->SetCount(cls.GetSpecCount()); + this->SelectOtherAirport(as->GetIndex()); return; } } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 7a92b0a0af..9b4a6a46d0 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -184,14 +184,14 @@ static inline void GetAllCargoSuffixes(CargoSuffixInOut use_input, CargoSuffixTy uint cargotype = local_id << 16 | use_input; GetCargoSuffix(cargotype, cst, ind, ind_type, indspec, suffixes[j]); } else { - suffixes[j].text[0] = '\0'; + suffixes[j].text.clear(); suffixes[j].display = CSD_CARGO; } } } else { /* Compatible behaviour with old 3-in-2-out scheme */ for (size_t j = 0; j < std::size(suffixes); j++) { - suffixes[j].text[0] = '\0'; + suffixes[j].text.clear(); suffixes[j].display = CSD_CARGO; } switch (use_input) { @@ -210,6 +210,33 @@ static inline void GetAllCargoSuffixes(CargoSuffixInOut use_input, CargoSuffixTy } } +/** + * Gets the strings to display after the cargo of industries (using callback 37) + * @param use_input get suffixes for output cargo or input cargo? + * @param cst the cargo suffix type (for which window is it requested). @see CargoSuffixType + * @param ind the industry (nullptr if in fund window) + * @param ind_type the industry type + * @param indspec the industry spec + * @param cargo cargotype. for INVALID_CARGO no suffix will be determined + * @param slot accepts/produced slot number, used for old-style 3-in/2-out industries. + * @param suffix is filled with the suffix + */ +void GetCargoSuffix(CargoSuffixInOut use_input, CargoSuffixType cst, const Industry *ind, IndustryType ind_type, const IndustrySpec *indspec, CargoID cargo, uint8_t slot, CargoSuffix &suffix) +{ + suffix.text.clear(); + suffix.display = CSD_CARGO; + if (!IsValidCargoID(cargo)) return; + if (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) { + uint8_t local_id = indspec->grf_prop.grffile->cargo_map[cargo]; // should we check the value for valid? + uint cargotype = local_id << 16 | use_input; + GetCargoSuffix(cargotype, cst, ind, ind_type, indspec, suffix); + } else if (use_input == CARGOSUFFIX_IN) { + if (slot < 3) GetCargoSuffix(slot, cst, ind, ind_type, indspec, suffix); + } else if (use_input == CARGOSUFFIX_OUT) { + if (slot < 2) GetCargoSuffix(slot + 3, cst, ind, ind_type, indspec, suffix); + } +} + std::array _sorted_industry_types; ///< Industry types sorted by name. /** @@ -1589,21 +1616,22 @@ protected: /* Industry name */ SetDParam(p++, i->index); - std::arrayproduced_cargo)>> cargo_suffix{}; - GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_DIR, i, i->type, indsp, i->produced_cargo, cargo_suffix); - /* Get industry productions (CargoID, production, suffix, transported) */ struct CargoInfo { - CargoID cargo_id; - uint32_t production; - const char *suffix; - uint transported; + CargoID cargo_id; ///< Cargo ID. + uint16_t production; ///< Production last month. + uint transported; ///< Percent transported last month. + std::string suffix; ///< Cargo suffix. + + CargoInfo(CargoID cargo_id, uint16_t production, uint transported, std::string &&suffix) : cargo_id(cargo_id), production(production), transported(transported), suffix(std::move(suffix)) {} }; std::vector cargos; for (size_t j = 0; j < std::size(i->produced_cargo); j++) { if (i->produced_cargo[j] == INVALID_CARGO) continue; - cargos.push_back({ i->produced_cargo[j], i->last_month_production[j], cargo_suffix[j].text.c_str(), ToPercent8(i->last_month_pct_transported[j]) }); + CargoSuffix cargo_suffix; + GetCargoSuffix(CARGOSUFFIX_OUT, CST_DIR, i, i->type, indsp, i->produced_cargo[j], j, cargo_suffix); + cargos.emplace_back(i->produced_cargo[j], i->last_month_production[j], ToPercent8(i->last_month_pct_transported[j]), std::move(cargo_suffix.text)); } switch (static_cast(this->industries.SortType())) { @@ -1640,11 +1668,11 @@ protected: /* Display first 3 cargos */ for (size_t j = 0; j < std::min(3, cargos.size()); j++) { - CargoInfo ci = cargos[j]; + CargoInfo &ci = cargos[j]; SetDParam(p++, STR_INDUSTRY_DIRECTORY_ITEM_INFO); SetDParam(p++, ci.cargo_id); SetDParam(p++, ci.production); - SetDParamStr(p++, ci.suffix); + SetDParamStr(p++, std::move(ci.suffix)); SetDParam(p++, ci.transported); } diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 0c5f79b7fa..548f4c9894 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -1620,7 +1620,7 @@ STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT :Área máxima q STR_CONFIG_SETTING_SERVICEATHELIPAD :Manutenção automática de helicópteros em heliportos: {STRING} STR_CONFIG_SETTING_SERVICEATHELIPAD_HELPTEXT :Efetuar manutenção de helicópteros após cada pouso, mesmo se não existir um depósito no aeroporto -STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR :Ligar ferramentas de paisagismo com construção de trilhos/estradas/água/aeroportos: {STRING} +STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR :Ligar ferramentas de paisagismo com construção de trilhos/estrada/aeroporto: {STRING} STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR_HELPTEXT :Ao abrir a barra de ferramentas de construção para um tipo de transporte, abrir também a barra de ferramentas de paisagismo STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR :Cor do solo usada no minimapa: {STRING} @@ -1642,9 +1642,9 @@ STR_CONFIG_SETTING_SCROLLMODE :Comportamento d STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Comportamento de movimentação do mapa. A opção "posição do mouse travada" não funciona em todos os sistemas, tais como versões baseadas na web, telas sensíveis ao toque, Linux com Wayland e outros ###length 4 STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Mover visualização com o Botão Direito, posição do mouse travada -STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Mover mapa com o Botão Direito, posição do mouse travada -STR_CONFIG_SETTING_SCROLLMODE_RMB :Mover mapa com o Botão Direito do Mouse -STR_CONFIG_SETTING_SCROLLMODE_LMB :Mover mapa com o Botão Esquerdo do Mouse +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Mover mapa com Botão Direito, posição do mouse travada +STR_CONFIG_SETTING_SCROLLMODE_RMB :Mover mapa com Botão Direito do Mouse +STR_CONFIG_SETTING_SCROLLMODE_LMB :Mover mapa com Botão Esquerdo do Mouse STR_CONFIG_SETTING_SMOOTH_SCROLLING :Suavizar deslocamento da visualização: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controlar como a visualização principal se move para uma localização específica ao clicar no minimapa ou quando é dado um comando para ir até um objeto específico no mapa. Se ativado, a visualização se move suavemente. Se desativado, a visualização salta diretamente para o destino escolhido @@ -1840,7 +1840,7 @@ STR_CONFIG_SETTING_SERVINT_DISABLED :Desativado STR_CONFIG_SETTING_NOSERVICE :Desativar manutenção quando as quebras estão desativadas: {STRING} STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Quando ativado, veículos não recebem manutenção se não podem quebrar -STR_CONFIG_SETTING_STATION_LENGTH_LOADING_PENALTY :Penalizar a velocidade de carregamento para trens que são mais longos que a estação: {STRING} +STR_CONFIG_SETTING_STATION_LENGTH_LOADING_PENALTY :Penalizar velocidade de carregamento para trens mais longos que a estação: {STRING} STR_CONFIG_SETTING_STATION_LENGTH_LOADING_PENALTY_HELPTEXT :Quando ativado, os trens que são muito compridos para a estação são carregados mais lentamente do que um trem que cabe na estação. Esta configuração não afeta a geração de rotas STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Ativar limite de velocidade para vagões: {STRING} @@ -4781,7 +4781,7 @@ STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}Interrom STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}Ativar/Desativar interrupção quando uma mensagem de registro da IA for igual a esta sequência de caracteres STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}Parar em: STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}Parar em -STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}Quando uma mensagem de registro da IA for igual a esta sequência de caracteres, o jogo é pausado +STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}O jogo é pausado quando uma mensagem de registro da IA for igual a esta sequência de caracteres STR_AI_DEBUG_MATCH_CASE :{BLACK}Diferenciar maiúsculas/minúsculas STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}Ativar/Desativar correspondência de maiúsculas/minúsculas quando comparar as mensagens de registro da IA com a sequência de caracteres de parada STR_AI_DEBUG_CONTINUE :{BLACK}Continuar @@ -5125,7 +5125,7 @@ STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL :{WHITE}... não # Autoreplace related errors STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}{VEHICLE} fica muito longo depois da substituição -STR_ERROR_AUTOREPLACE_NOTHING_TO_DO :{WHITE}Nenhuma regra de substituição automática/renovação aplicada +STR_ERROR_AUTOREPLACE_NOTHING_TO_DO :{WHITE}Nenhuma regra de substituição/renovação automática aplicada STR_ERROR_AUTOREPLACE_MONEY_LIMIT :(limite de dinheiro) STR_ERROR_AUTOREPLACE_INCOMPATIBLE_CARGO :{WHITE}O novo veículo não pode transportar {STRING} STR_ERROR_AUTOREPLACE_INCOMPATIBLE_REFIT :{WHITE}O novo veículo não pode ser adaptado na ordem {NUM} diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 189de7b286..3953b8868c 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -3490,6 +3490,9 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_ROAD_TYPE :Veitype STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}NewGRF-variabel 60+x parameter (heksadesimal) # Sprite aligner window +STR_SPRITE_ALIGNER_CAPTION_NO_ACTION :{WHITE}Forskyver sprite: ({STRING}:{NUM}) +STR_SPRITE_ALIGNER_CAPTION_ACTIONA :{WHITE}Forskyver sprite: Handling 0xA, {COMMA} ({STRING}:{NUM}) +STR_SPRITE_ALIGNER_CAPTION_ACTION5 :{WHITE}Forskyver sprite: Handling 0x5, type {HEX}, {COMMA} ({STRING}:{NUM}) STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Neste sprite STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Fortsett til neste normale sprite og hopp over enhver pseudo-/omfargings-/skrifttype- sprite, samt start om ved begynnelsen STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}Gå til sprite @@ -3498,6 +3501,7 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Forrige STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Fortsett til forrige normale sprite og hopp over enhver pseudo-/omfargings-/skrifttype- sprite, samt start om ved begynnelsen STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Forhåndsvisning av valgt sprite. Innrettingen ignoreres når spriten tegnes STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Flytt på ikonet for å endre X- og Y-forskyvningene. Ctrl+klikk for å flytte ikonet åtte enheter om gangen +STR_SPRITE_ALIGNER_SPRITE :{STRING}:{NUM} ###length 2 STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Offset sentrert @@ -3531,15 +3535,15 @@ STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} krev STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF-filen den var laget for å oversette STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :For mange NewGRF-er er innlastet STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Å laste inn {1:STRING} som statisk NewGRF med {2:STRING} kan forårsake synkroniseringsfeil -STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Uventet sprite (figur {3:NUM}) -STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Ukjent Handling 0 egenskap {4:HEX} (figur {3:NUM}) +STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Uventet sprite (sprite {3:NUM}) +STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Ukjent Handling 0 egenskap {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Forsøk på å bruke ugyldig ID (sprite {3:NUM}) STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{STRING} inneholder en ødelagt sprite. Alle ødelagte spriter blir vist som røde spørsmålstegn (?). -STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Inneholder flere Handling 8-oppføringer (figur {3:NUM}) -STR_NEWGRF_ERROR_READ_BOUNDS :Leste forbi slutten av pseudo-sprite (figur {3:NUM}) -STR_NEWGRF_ERROR_GRM_FAILED :Etterspurte GRF-ressurser ikke tilgjengelig (figur {3:NUM}) +STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Inneholder flere Handling 8-oppføringer (sprite {3:NUM}) +STR_NEWGRF_ERROR_READ_BOUNDS :Leste forbi slutten av pseudo-sprite (sprite {3:NUM}) +STR_NEWGRF_ERROR_GRM_FAILED :Etterspurte GRF-ressurser ikke tilgjengelig (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} ble deaktivert av {STRING} -STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Ugyldig/ukjent sprite layoutformat (figur {3:NUM}) +STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Ugyldig/ukjent sprite layoutformat (sprite {3:NUM}) STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :For mange elementer i fortegnelse over eiendomsverdier (sprite {3:NUM}, property {4:HEX}) STR_NEWGRF_ERROR_INDPROD_CALLBACK :Ugyldig industriprodukjson callback (sprite {3:NUM}, "{2:STRING}") @@ -5834,6 +5838,7 @@ STR_JUST_DATE_ISO :{DATE_ISO} STR_JUST_STRING :{STRING} STR_JUST_STRING1 :{STRING} STR_JUST_STRING2 :{STRING} +STR_JUST_STRING4 :{STRING} STR_JUST_STRING_STRING :{STRING}{STRING} STR_JUST_RAW_STRING :{STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{STRING} diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 1bd5fab913..56dcbbf559 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -3663,6 +3663,9 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_ROAD_TYPE :Тип доро STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}Параметр переменной NewGRF 60+x (шестнадцатеричный) # Sprite aligner window +STR_SPRITE_ALIGNER_CAPTION_NO_ACTION :{WHITE}Выравнивающий спрайт: ({STRING}:{NUM}) +STR_SPRITE_ALIGNER_CAPTION_ACTIONA :{WHITE}Выравнивающий спрайт: Действие 0xA, {COMMA} ({STRING}:{NUM}) +STR_SPRITE_ALIGNER_CAPTION_ACTION5 :{WHITE}Выравнивающий спрайт: Действие 0x5, type {HEX}, {COMMA} ({STRING}:{NUM}) STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Следующий спрайт STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Перейти к следующему нормальному спрайту, пропуская изменяющие цвет, шрифтовые, псевдоспрайты. Переход из конца списка к первому спрайту. STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}Перейти к спрайту @@ -3671,6 +3674,7 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Пред STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Перейти к предыдущему нормальному спрайту, пропуская изменяющие цвет, шрифтовые, псевдоспрайты. Переход из начала списка к последнему спрайту. STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Представление выбранного спрайта. Выравнивание не учитывается при прорисовке этого спрайта. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Двигайте спрайт, изменяя смещение по осям X и Y. С помощью Ctrl+щелчка можно сдвигать спрайты на 8 единиц. +STR_SPRITE_ALIGNER_SPRITE :{STRING}:{NUM} ###length 2 STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Смещение в центре @@ -6056,6 +6060,7 @@ STR_JUST_DATE_ISO :{DATE_ISO} STR_JUST_STRING :{STRING} STR_JUST_STRING1 :{STRING} STR_JUST_STRING2 :{STRING} +STR_JUST_STRING4 :{STRING} STR_JUST_STRING_STRING :{STRING}{STRING} STR_JUST_RAW_STRING :{STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{STRING} diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 9f7dcd3a99..e4921fda2c 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -3489,6 +3489,9 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_ROAD_TYPE :Tipo de carrete STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}Parámetro de variable NewGRF 60+x (hexadecimal) # Sprite aligner window +STR_SPRITE_ALIGNER_CAPTION_NO_ACTION :{WHITE}Alineando sprite: ({STRING}:{NUM}) +STR_SPRITE_ALIGNER_CAPTION_ACTIONA :{WHITE}Alineando sprite: Acción 0xA, {COMMA} ({STRING}:{NUM}) +STR_SPRITE_ALIGNER_CAPTION_ACTION5 :{WHITE}Alineando sprite: Acción 0x5, tipo {HEX}, {COMMA} ({STRING}:{NUM}) STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Siguiente sprite STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Va al siguiente sprite (ignorando pseudosprites, sprites recoloreados y sprites de fuente) y pasa del último al primer sprite STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}Ir a sprite @@ -3497,6 +3500,7 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite a STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Salta al sprite anterior (ignorando pseudosprites, sprites recoloreados y sprites de fuente) y pasa del primer al último sprite STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representa el sprite seleccionado. Su alineamiento es ignorado al dibujarlo STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Mover el sprite, cambiando los ajustes X e Y. Ctrl+clic mueve el sprite ocho unidades de una sola vez +STR_SPRITE_ALIGNER_SPRITE :{STRING}:{NUM} ###length 2 STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Desviación (offset) centrada @@ -5833,6 +5837,7 @@ STR_JUST_DATE_ISO :{DATE_ISO} STR_JUST_STRING :{STRING} STR_JUST_STRING1 :{STRING} STR_JUST_STRING2 :{STRING} +STR_JUST_STRING4 :{STRING} STR_JUST_STRING_STRING :{STRING}{STRING} STR_JUST_RAW_STRING :{STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{STRING} diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 34d70c5411..73061b794f 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -394,10 +394,24 @@ static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = nul struct StringIDMapping { uint32_t grfid; ///< Source NewGRF. StringID source; ///< Source StringID (GRF local). - StringID *target; ///< Destination for mapping result. + std::function func; ///< Function for mapping result. + + StringIDMapping(uint32_t grfid, StringID source, std::function &&func) : grfid(grfid), source(source), func(std::move(func)) { } }; -typedef std::vector StringIDMappingVector; -static StringIDMappingVector _string_to_grf_mapping; + +/** Strings to be mapped during load. */ +static std::vector _string_to_grf_mapping; + +/** + * Record a static StringID for getting translated later. + * @param source Source StringID (GRF local). + * @param func Function to call to set the mapping result. + */ +static void AddStringForMapping(StringID source, std::function &&func) +{ + func(STR_UNDEFINED); + _string_to_grf_mapping.emplace_back(_cur.grffile->grfid, source, std::move(func)); +} /** * Record a static StringID for getting translated later. @@ -406,8 +420,7 @@ static StringIDMappingVector _string_to_grf_mapping; */ static void AddStringForMapping(StringID source, StringID *target) { - *target = STR_UNDEFINED; - _string_to_grf_mapping.push_back({_cur.grffile->grfid, source, target}); + AddStringForMapping(source, [target](StringID str) { *target = str; }); } /** @@ -2113,7 +2126,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, cons break; case 0x1D: // Station Class name - AddStringForMapping(buf->ReadWord(), &StationClass::Get(statspec->cls_id)->name); + AddStringForMapping(buf->ReadWord(), [statspec](StringID str) { StationClass::Get(statspec->cls_id)->name = str; }); break; default: @@ -4376,8 +4389,7 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, const G } case 0x09: { // Class name - ObjectClass *objclass = ObjectClass::Get(spec->cls_id); - AddStringForMapping(buf->ReadWord(), &objclass->name); + AddStringForMapping(buf->ReadWord(), [spec](StringID str) { ObjectClass::Get(spec->cls_id)->name = str; }); break; } @@ -5176,7 +5188,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const if (MappedPropertyLengthMismatch(buf, 2, mapping_entry)) break; [[fallthrough]]; case 0x0B: // Road Stop Class name - AddStringForMapping(buf->ReadWord(), &RoadStopClass::Get(rs->cls_id)->name); + AddStringForMapping(buf->ReadWord(), [rs](StringID str) { RoadStopClass::Get(rs->cls_id)->name = str; }); break; case A0RPI_ROADSTOP_DRAW_MODE: @@ -11616,7 +11628,7 @@ extern void InitGRFTownGeneratorNames(); static void AfterLoadGRFs() { for (StringIDMapping &it : _string_to_grf_mapping) { - *it.target = MapGRFStringID(it.grfid, it.source); + it.func(MapGRFStringID(it.grfid, it.source)); } _string_to_grf_mapping.clear(); diff --git a/src/newgrf_class.h b/src/newgrf_class.h index f8145c8d29..d01c3cab9b 100644 --- a/src/newgrf_class.h +++ b/src/newgrf_class.h @@ -20,17 +20,14 @@ template class NewGRFClass { private: - uint ui_count; ///< Number of specs in this class potentially available to the user. + uint ui_count = 0; ///< Number of specs in this class potentially available to the user. std::vector spec; ///< List of specifications. /** * The actual classes. - * @note We store pointers to members of this array in various places outside this class (e.g. to 'name' for GRF string resolving). - * Thus this must be a static array, and cannot be a self-resizing vector or similar. + * @note This may be reallocated during initialization so pointers may be invalidated. */ - static NewGRFClass classes[Tmax]; - - void ResetClass(); + static inline std::vector> classes; /** Initialise the defaults. */ static void InsertDefaults(); @@ -39,8 +36,24 @@ public: uint32_t global_id; ///< Global ID for class, e.g. 'DFLT', 'WAYP', etc. StringID name; ///< Name of this class. + /* Public constructor as emplace_back needs access. */ + NewGRFClass(uint32_t global_id, StringID name) : global_id(global_id), name(name) { } + + /** + * Get read-only span of specs of this class. + * @return Read-only span of specs. + */ + std::span Specs() const { return this->spec; } + + /** + * Get read-only span of all classes of this type. + * @return Read-only span of classes. + */ + static std::span const> Classes() { return NewGRFClass::classes; } + void Insert(Tspec *spec); + Tid Index() const { return static_cast(std::distance(&*std::cbegin(NewGRFClass::classes), this)); } /** Get the number of allocated specs within the class. */ uint GetSpecCount() const { return static_cast(this->spec.size()); } /** Get the number of potentially user-available specs within the class. */ diff --git a/src/newgrf_class_func.h b/src/newgrf_class_func.h index 2e58c27b20..e4294b07d2 100644 --- a/src/newgrf_class_func.h +++ b/src/newgrf_class_func.h @@ -12,35 +12,19 @@ #include "table/strings.h" -/** Instantiate the array. */ -template -NewGRFClass NewGRFClass::classes[Tmax]; - -/** Reset the class, i.e. clear everything. */ -template -void NewGRFClass::ResetClass() -{ - this->global_id = 0; - this->name = STR_EMPTY; - this->ui_count = 0; - - this->spec.clear(); -} - /** Reset the classes, i.e. clear everything. */ template void NewGRFClass::Reset() { - for (Tid i = (Tid)0; i < Tmax; i++) { - classes[i].ResetClass(); - } + NewGRFClass::classes.clear(); + NewGRFClass::classes.shrink_to_fit(); - InsertDefaults(); + NewGRFClass::InsertDefaults(); } /** * Allocate a class with a given global class ID. - * @param cls_id The global class id, such as 'DFLT'. + * @param global_id The global class id, such as 'DFLT'. * @return The (non global!) class ID for the class. * @note Upon allocating the same global class ID for a * second time, this first allocation will be given. @@ -48,19 +32,19 @@ void NewGRFClass::Reset() template Tid NewGRFClass::Allocate(uint32_t global_id) { - for (Tid i = (Tid)0; i < Tmax; i++) { - if (classes[i].global_id == global_id) { - /* ClassID is already allocated, so reuse it. */ - return i; - } else if (classes[i].global_id == 0) { - /* This class is empty, so allocate it to the global id. */ - classes[i].global_id = global_id; - return i; - } + auto found = std::find_if(std::begin(NewGRFClass::classes), std::end(NewGRFClass::classes), [global_id](const auto &cls) { return cls.global_id == global_id; }); + + /* Id is already allocated, so reuse it. */ + if (found != std::end(NewGRFClass::classes)) return found->Index(); + + /* More slots available, allocate a slot to the global id. */ + if (NewGRFClass::classes.size() < Tmax) { + auto &cls = NewGRFClass::classes.emplace_back(global_id, STR_EMPTY); + return cls.Index(); } grfmsg(2, "ClassAllocate: already allocated %d classes, using default", Tmax); - return (Tid)0; + return static_cast(0); } /** @@ -83,7 +67,7 @@ void NewGRFClass::Insert(Tspec *spec) template void NewGRFClass::Assign(Tspec *spec) { - assert(spec->cls_id < Tmax); + assert(static_cast(spec->cls_id) < NewGRFClass::classes.size()); Get(spec->cls_id)->Insert(spec); } @@ -105,8 +89,8 @@ bool NewGRFClass::IsClassIDValid(Tid cls_id) template NewGRFClass *NewGRFClass::Get(Tid cls_id) { - assert(cls_id < Tmax); - return classes + cls_id; + assert(static_cast(cls_id) < NewGRFClass::classes.size()); + return &NewGRFClass::classes[cls_id]; } /** @@ -116,9 +100,7 @@ NewGRFClass *NewGRFClass::Get(Tid cls_id) template uint NewGRFClass::GetClassCount() { - uint i; - for (i = 0; i < Tmax && classes[i].global_id != 0; i++) {} - return i; + return static_cast(NewGRFClass::classes.size()); } /** @@ -128,11 +110,7 @@ uint NewGRFClass::GetClassCount() template uint NewGRFClass::GetUIClassCount() { - uint cnt = 0; - for (uint i = 0; i < Tmax && classes[i].global_id != 0; i++) { - if (classes[i].GetUISpecCount() > 0) cnt++; - } - return cnt; + return std::count_if(std::begin(NewGRFClass::classes), std::end(NewGRFClass::classes), [](const auto &cls) { return cls.GetUISpecCount() > 0; }); } /** @@ -156,9 +134,9 @@ bool NewGRFClass::HasUIClass() template Tid NewGRFClass::GetUIClass(uint index) { - for (uint i = 0; i < Tmax && classes[i].global_id != 0; i++) { - if (classes[i].GetUISpecCount() == 0) continue; - if (index-- == 0) return (Tid)i; + for (const auto &cls : NewGRFClass::classes) { + if (cls.GetUISpecCount() == 0) continue; + if (index-- == 0) return cls.Index(); } NOT_REACHED(); } @@ -217,15 +195,11 @@ int NewGRFClass::GetUIFromIndex(int index) const template const Tspec *NewGRFClass::GetByGrf(uint32_t grfid, uint16_t local_id, int *index) { - uint j; - - for (Tid i = (Tid)0; i < Tmax; i++) { - uint count = static_cast(classes[i].spec.size()); - for (j = 0; j < count; j++) { - const Tspec *spec = classes[i].spec[j]; + for (const auto &cls : NewGRFClass::classes) { + for (const auto &spec : cls.spec) { if (spec == nullptr) continue; if (spec->grf_prop.grffile->grfid == grfid && spec->grf_prop.local_id == local_id) { - if (index != nullptr) *index = j; + if (index != nullptr) *index = static_cast(std::distance(cls.spec.data(), &spec)); return spec; } } diff --git a/src/newgrf_object.h b/src/newgrf_object.h index eba715e525..dcb8ffb13c 100644 --- a/src/newgrf_object.h +++ b/src/newgrf_object.h @@ -64,9 +64,9 @@ void ResetObjects(); /** Class IDs for objects. */ enum ObjectClassID : uint16_t { - OBJECT_CLASS_BEGIN = 0, ///< The lowest valid value - OBJECT_CLASS_MAX = 0xFFFF, ///< Maximum number of classes. - INVALID_OBJECT_CLASS = 0xFFFF, ///< Class for the less fortunate. + OBJECT_CLASS_BEGIN = 0, ///< The lowest valid value + OBJECT_CLASS_MAX = UINT16_MAX, ///< Maximum number of classes. + INVALID_OBJECT_CLASS = UINT16_MAX, ///< Class for the less fortunate. }; /** Allow incrementing of ObjectClassID variables */ DECLARE_POSTFIX_INCREMENT(ObjectClassID) diff --git a/src/newgrf_optimiser.cpp b/src/newgrf_optimiser.cpp index e727553035..c91f993b59 100644 --- a/src/newgrf_optimiser.cpp +++ b/src/newgrf_optimiser.cpp @@ -3154,11 +3154,9 @@ static std::bitset<256> HandleVarAction2DeadStoreElimination(DeterministicSprite static void PopulateRailStationAdvancedLayoutVariableUsage() { - for (uint i = 0; StationClass::IsClassIDValid((StationClassID)i); i++) { - StationClass *stclass = StationClass::Get((StationClassID)i); - - for (uint j = 0; j < stclass->GetSpecCount(); j++) { - const StationSpec *statspec = stclass->GetSpec(j); + for (const StationClass &cls : StationClass::Classes()) { + for (uint j = 0; j < cls.GetSpecCount(); j++) { + const StationSpec *statspec = cls.GetSpec(j); if (statspec == nullptr) continue; std::bitset<256> bits; diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index f980b55bad..bdac2a8ae3 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -551,13 +551,12 @@ void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTri */ bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype) { - for (uint i = 0; RoadStopClass::IsClassIDValid((RoadStopClassID)i); i++) { + for (const auto &cls : RoadStopClass::Classes()) { /* Ignore the waypoint class. */ - if (i == ROADSTOP_CLASS_WAYP) continue; - const RoadStopClass *roadstopclass = RoadStopClass::Get((RoadStopClassID)i); + if (cls.Index() == ROADSTOP_CLASS_WAYP) continue; /* Ignore the default class with only the default station. */ - if (i == ROADSTOP_CLASS_DFLT && roadstopclass->GetSpecCount() == 1) continue; - if (GetIfClassHasNewStopsByType(roadstopclass, rs, roadtype)) return true; + if (cls.Index() == ROADSTOP_CLASS_DFLT && cls.GetSpecCount() == 1) continue; + if (GetIfClassHasNewStopsByType(&cls, rs, roadtype)) return true; } return false; } @@ -571,8 +570,8 @@ bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype) */ bool GetIfClassHasNewStopsByType(const RoadStopClass *roadstopclass, RoadStopType rs, RoadType roadtype) { - for (uint j = 0; j < roadstopclass->GetSpecCount(); j++) { - if (GetIfStopIsForType(roadstopclass->GetSpec(j), rs, roadtype)) return true; + for (const auto spec : roadstopclass->Specs()) { + if (GetIfStopIsForType(spec, rs, roadtype)) return true; } return false; } diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h index d48f0296c3..44e1cd5b12 100644 --- a/src/newgrf_roadstop.h +++ b/src/newgrf_roadstop.h @@ -22,14 +22,17 @@ /** The maximum amount of roadstops a single GRF is allowed to add */ static const int NUM_ROADSTOPS_PER_GRF = 64000; -enum RoadStopClassID : uint8_t { - ROADSTOP_CLASS_BEGIN = 0, ///< The lowest valid value - ROADSTOP_CLASS_DFLT = 0, ///< Default road stop class. - ROADSTOP_CLASS_WAYP, ///< Waypoint class. - ROADSTOP_CLASS_MAX = 255, ///< Maximum number of classes. +enum RoadStopClassID : uint16_t { + ROADSTOP_CLASS_BEGIN = 0, ///< The lowest valid value + ROADSTOP_CLASS_DFLT = 0, ///< Default road stop class. + ROADSTOP_CLASS_WAYP, ///< Waypoint class (unimplemented: this is reserved for future use with road waypoints). + ROADSTOP_CLASS_MAX = UINT16_MAX, ///< Maximum number of classes. }; DECLARE_POSTFIX_INCREMENT(RoadStopClassID) +template <> +struct EnumPropsT : MakeEnumPropsT {}; + /* Some Triggers etc. */ enum RoadStopRandomTrigger { RSRT_NEW_CARGO, ///< Trigger roadstop on arrival of new cargo. @@ -180,9 +183,6 @@ struct RoadStopSpec { static const RoadStopSpec *Get(uint16_t index); }; -template <> -struct EnumPropsT : MakeEnumPropsT {}; - using RoadStopClass = NewGRFClass; void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec, StationType type, int view); diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 180e0657e6..83c7814a6f 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -1098,12 +1098,10 @@ void DumpStationSpriteGroup(const StationSpec *statspec, BaseStation *st, Sprite void UpdateStationTileCacheFlags(bool force_update) { SimpleChecksum64 checksum; - for (uint i = 0; StationClass::IsClassIDValid((StationClassID)i); i++) { - StationClass *stclass = StationClass::Get((StationClassID)i); - - checksum.Update(stclass->GetSpecCount()); - for (uint j = 0; j < stclass->GetSpecCount(); j++) { - const StationSpec *statspec = stclass->GetSpec(j); + for (const StationClass &cls : StationClass::Classes()) { + checksum.Update(cls.GetSpecCount()); + for (uint j = 0; j < cls.GetSpecCount(); j++) { + const StationSpec *statspec = cls.GetSpec(j); if (statspec == nullptr) continue; checksum.Update(j); diff --git a/src/newgrf_station.h b/src/newgrf_station.h index b68f97672f..5e8d39b252 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -90,13 +90,13 @@ struct StationResolverObject : public ResolverObject { uint32_t GetDebugID() const override; }; -enum StationClassID : uint8_t { +enum StationClassID : uint16_t { STAT_CLASS_BEGIN = 0, ///< the lowest valid value STAT_CLASS_DFLT = 0, ///< Default station class. STAT_CLASS_WAYP, ///< Waypoint class. - STAT_CLASS_MAX = 255, ///< Maximum number of classes. + STAT_CLASS_MAX = UINT16_MAX, ///< Maximum number of classes. }; -template <> struct EnumPropsT : MakeEnumPropsT {}; +template <> struct EnumPropsT : MakeEnumPropsT {}; /** Allow incrementing of StationClassID variables */ DECLARE_POSTFIX_INCREMENT(StationClassID) diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 67c18ed81c..5142a44858 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -143,10 +143,9 @@ public: this->object_classes.clear(); - for (uint i = 0; ObjectClass::IsClassIDValid((ObjectClassID)i); i++) { - ObjectClass *objclass = ObjectClass::Get((ObjectClassID)i); - if (objclass->GetUISpecCount() == 0) continue; // Is this needed here? - object_classes.push_back((ObjectClassID)i); + for (const auto &cls : ObjectClass::Classes()) { + if (cls.GetUISpecCount() == 0) continue; // Is this needed here? + object_classes.push_back(cls.Index()); } this->object_classes.Filter(this->string_filter); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index d1aab76897..a5f5853121 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1326,15 +1326,11 @@ public: this->station_classes.clear(); - for (uint i = 0; StationClass::IsClassIDValid((StationClassID)i); i++) { - StationClassID station_class_id = (StationClassID)i; - if (station_class_id == StationClassID::STAT_CLASS_WAYP) { - // Skip waypoints. - continue; - } - StationClass *station_class = StationClass::Get(station_class_id); - if (station_class->GetUISpecCount() == 0) continue; - station_classes.push_back(station_class_id); + for (const auto &cls : StationClass::Classes()) { + /* Skip waypoints. */ + if (cls.Index() == STAT_CLASS_WAYP) continue; + if (cls.GetUISpecCount() == 0) continue; + station_classes.push_back(cls.Index()); } if (_railstation.newstations) { diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 48eaffbf93..eca3387646 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -204,7 +204,7 @@ void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32_t p1, uint32_ * bit 3: #Axis of the road for drive-through stops. * bit 5..10: The roadtype. * bit 16..31: Station ID to join (NEW_STATION if build new one). - * @param p3 bit 0..7: Roadstop class. + * @param p3 bit 0..15: Roadstop class. * bit 16..31: Roadstopspec index. * @param cmd Unused. * @see CmdBuildRoadStop @@ -219,7 +219,7 @@ void CcRoadStop(const CommandCost &result, TileIndex tile, uint32_t p1, uint32_t bool connect_to_road = true; - RoadStopClassID spec_class = Extract(p3); + RoadStopClassID spec_class = Extract(p3); uint16_t spec_index = GB(p3, 16, 16); if ((uint)spec_class < RoadStopClass::GetClassCount() && spec_index < RoadStopClass::Get(spec_class)->GetSpecCount()) { const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index); @@ -1349,7 +1349,7 @@ public: this->ChangeWindowClass((rs == ROADSTOP_BUS) ? WC_BUS_STATION : WC_TRUCK_STATION); - if (!newstops || _roadstop_gui_settings.roadstop_class >= (int)RoadStopClass::GetClassCount()) { + if (!newstops || _roadstop_gui_settings.roadstop_class >= RoadStopClass::GetClassCount()) { /* There's no new stops available or the list has reduced in size. * Now, set the default road stops as selected. */ _roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT; @@ -1412,14 +1412,10 @@ public: this->roadstop_classes.clear(); - for (uint i = 0; RoadStopClass::IsClassIDValid((RoadStopClassID)i); i++) { - RoadStopClassID rs_id = (RoadStopClassID)i; - if (rs_id == ROADSTOP_CLASS_WAYP) { - // Skip waypoints. - continue; - } - RoadStopClass *rs_class = RoadStopClass::Get(rs_id); - if (GetIfClassHasNewStopsByType(rs_class, this->road_stop_type, _cur_roadtype)) this->roadstop_classes.push_back(rs_id); + for (const auto &cls : RoadStopClass::Classes()) { + /* Skip waypoints. */ + if (cls.Index() == ROADSTOP_CLASS_WAYP) continue; + if (GetIfClassHasNewStopsByType(&cls, this->road_stop_type, _cur_roadtype)) this->roadstop_classes.push_back(cls.Index()); } if (this->ShowNewStops()) { diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 746c01eb88..109039e04f 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1469,7 +1469,7 @@ static void RestoreTrainReservation(Train *v) * - p1 = (bit 16-23) - platform length * - p1 = (bit 24) - allow stations directly adjacent to other stations. * @param p2 various bitstuffed elements - * - p2 = (bit 0- 7) - custom station class + * - p2 = (bit 0-15) - custom station class * - p2 = (bit 16-31) - station ID to join (NEW_STATION if build new one) * @param p3 various bitstuffed elements * - p3 = (bit 0-15) - custom station id @@ -1485,7 +1485,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32_ uint8_t plat_len = GB(p1, 16, 8); bool adjacent = HasBit(p1, 24); - StationClassID spec_class = Extract(p2); + StationClassID spec_class = Extract(p2); uint16_t spec_index = GB(p3, 0, 16); StationID station_to_join = GB(p2, 16, 16); @@ -2108,7 +2108,7 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio * bit 3: #Axis of the road for drive-through stops. * bit 5..10: The roadtype. * bit 16..31: Station ID to join (NEW_STATION if build new one). - * @param p3 bit 0..7: Roadstop class. + * @param p3 bit 0..15: Roadstop class. * bit 16..31: Roadstopspec index. * @param text Unused. * @return The cost of this operation or an error. @@ -2127,7 +2127,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32_t p1, u uint8_t width = (uint8_t)GB(p1, 0, 8); uint8_t length = (uint8_t)GB(p1, 8, 8); - RoadStopClassID spec_class = Extract(p3); + RoadStopClassID spec_class = Extract(p3); uint16_t spec_index = GB(p3, 16, 16); /* Check if the given station class is valid */ diff --git a/src/strings.cpp b/src/strings.cpp index 91391d157b..fb4641b4f2 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -2193,55 +2193,49 @@ static const char _initial_name_letters[] = { 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W', }; -static void GenAndCoName(StringBuilder builder, uint32_t arg) +static std::span GetSurnameOptions() { - const char * const *base; - uint num; + if (_settings_game.game_creation.landscape == LT_TOYLAND) return _silly_surname_list; + return _surname_list; +} - if (_settings_game.game_creation.landscape == LT_TOYLAND) { - base = _silly_surname_list; - num = lengthof(_silly_surname_list); - } else { - base = _surname_list; - num = lengthof(_surname_list); - } +/** + * Get the surname of the president with the given seed. + * @param seed The seed the surname was generated from. + * @return The surname. + */ +static const char *GetSurname(uint32_t seed) +{ + auto surname_options = GetSurnameOptions(); + return surname_options[surname_options.size() * GB(seed, 16, 8) >> 8]; +} - builder += base[num * GB(arg, 16, 8) >> 8]; +static void GenAndCoName(StringBuilder &builder, uint32_t seed) +{ + builder += GetSurname(seed); builder += " & Co."; } -static void GenPresidentName(StringBuilder builder, uint32_t x) +static void GenPresidentName(StringBuilder builder, uint32_t seed) { - char initial[] = "?. "; - const char * const *base; - uint num; - uint i; + builder += _initial_name_letters[std::size(_initial_name_letters) * GB(seed, 0, 8) >> 8]; + builder += ". "; - initial[0] = _initial_name_letters[sizeof(_initial_name_letters) * GB(x, 0, 8) >> 8]; - builder += initial; - - i = (sizeof(_initial_name_letters) + 35) * GB(x, 8, 8) >> 8; - if (i < sizeof(_initial_name_letters)) { - initial[0] = _initial_name_letters[i]; - builder += initial; + /* The second initial is optional. */ + size_t index = (std::size(_initial_name_letters) + 35) * GB(seed, 8, 8) >> 8; + if (index < std::size(_initial_name_letters)) { + builder += _initial_name_letters[index]; + builder += ". "; } - if (_settings_game.game_creation.landscape == LT_TOYLAND) { - base = _silly_surname_list; - num = lengthof(_silly_surname_list); - } else { - base = _surname_list; - num = lengthof(_surname_list); - } - - builder += base[num * GB(x, 16, 8) >> 8]; + builder += GetSurname(seed); } static void GetSpecialNameString(StringBuilder builder, int ind, StringParameters &args) { switch (ind) { case 1: // not used - builder += _silly_company_names[std::min(args.GetNextParameter(), lengthof(_silly_company_names) - 1)]; + builder += _silly_company_names[std::min(args.GetNextParameter(), std::size(_silly_company_names) - 1)]; return; case 2: // used for Foobar & Co company names diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 29b677cd75..3523833480 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -194,7 +194,7 @@ extern CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec * - p1 = (bit 16-23) - height of waypoint * - p1 = (bit 24) - allow waypoints directly adjacent to other waypoints. * @param p2 various bitstuffed elements - * - p2 = (bit 0- 7) - custom station class + * - p2 = (bit 0-15) - custom station class * - p2 = (bit 31-16) - station ID to join * @param p3 various bitstuffed elements * - p3 = (bit 0-31) - custom station id @@ -209,7 +209,7 @@ CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint uint8_t height = GB(p1, 16, 8); bool adjacent = HasBit(p1, 24); - StationClassID spec_class = Extract(p2); + StationClassID spec_class = Extract(p2); StationID station_to_join = GB(p2, 16, 16); uint spec_index = GB(p3, 0, 32); @@ -351,7 +351,7 @@ CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint * bit 8..15: Length of the road stop. * bit 16: Allow stations directly adjacent to other stations. * bit 17: #Axis of the road. - * @param p2 bit 0..7: Custom road stop class + * @param p2 bit 0..15: Custom road stop class * bit 16..31: Station ID to join (NEW_STATION if build new one). * @param p3 various bitstuffed elements * - p3 = (bit 0-31) - custom road stop id @@ -366,7 +366,7 @@ CommandCost CmdBuildRoadWaypoint(TileIndex start_tile, DoCommandFlag flags, uint bool adjacent = HasBit(p1, 16); Axis axis = Extract(p1); - RoadStopClassID spec_class = Extract(p2); + RoadStopClassID spec_class = Extract(p2); uint spec_index = GB(p3, 0, 32); /* Check if the given road stop class is valid */