Merge branch 'master' into jgrpp

# Conflicts:
#	cmake/scripts/FindVersion.cmake
#	src/airport_gui.cpp
#	src/industry_gui.cpp
#	src/newgrf.cpp
#	src/newgrf_class_func.h
#	src/newgrf_object.h
#	src/newgrf_roadstop.cpp
#	src/newgrf_roadstop.h
#	src/object_gui.cpp
#	src/rail_gui.cpp
#	src/road_cmd.h
#	src/road_gui.cpp
#	src/station_cmd.h
#	src/strings.cpp
#	src/waypoint_cmd.h
This commit is contained in:
Jonathan G Rennison
2024-06-05 20:42:47 +01:00
22 changed files with 222 additions and 201 deletions

View File

@@ -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}

View File

@@ -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;
}
}

View File

@@ -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<IndustryType, NUM_INDUSTRYTYPES> _sorted_industry_types; ///< Industry types sorted by name.
/**
@@ -1589,21 +1616,22 @@ protected:
/* Industry name */
SetDParam(p++, i->index);
std::array<CargoSuffix, std::tuple_size_v<decltype(i->produced_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<CargoInfo> 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<IndustryDirectoryWindow::SorterType>(this->industries.SortType())) {
@@ -1640,11 +1668,11 @@ protected:
/* Display first 3 cargos */
for (size_t j = 0; j < std::min<size_t>(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);
}

View File

@@ -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}

View File

@@ -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}

View File

@@ -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}

View File

@@ -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}

View File

@@ -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<void(StringID)> func; ///< Function for mapping result.
StringIDMapping(uint32_t grfid, StringID source, std::function<void(StringID)> &&func) : grfid(grfid), source(source), func(std::move(func)) { }
};
typedef std::vector<StringIDMapping> StringIDMappingVector;
static StringIDMappingVector _string_to_grf_mapping;
/** Strings to be mapped during load. */
static std::vector<StringIDMapping> _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<void(StringID)> &&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();

View File

@@ -20,17 +20,14 @@
template <typename Tspec, typename Tid, Tid Tmax>
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<Tspec *> 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<Tspec, Tid, Tmax> classes[Tmax];
void ResetClass();
static inline std::vector<NewGRFClass<Tspec, Tid, Tmax>> 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<Tspec * const> Specs() const { return this->spec; }
/**
* Get read-only span of all classes of this type.
* @return Read-only span of classes.
*/
static std::span<NewGRFClass<Tspec, Tid, Tmax> const> Classes() { return NewGRFClass::classes; }
void Insert(Tspec *spec);
Tid Index() const { return static_cast<Tid>(std::distance(&*std::cbegin(NewGRFClass::classes), this)); }
/** Get the number of allocated specs within the class. */
uint GetSpecCount() const { return static_cast<uint>(this->spec.size()); }
/** Get the number of potentially user-available specs within the class. */

View File

@@ -12,35 +12,19 @@
#include "table/strings.h"
/** Instantiate the array. */
template <typename Tspec, typename Tid, Tid Tmax>
NewGRFClass<Tspec, Tid, Tmax> NewGRFClass<Tspec, Tid, Tmax>::classes[Tmax];
/** Reset the class, i.e. clear everything. */
template <typename Tspec, typename Tid, Tid Tmax>
void NewGRFClass<Tspec, Tid, Tmax>::ResetClass()
{
this->global_id = 0;
this->name = STR_EMPTY;
this->ui_count = 0;
this->spec.clear();
}
/** Reset the classes, i.e. clear everything. */
template <typename Tspec, typename Tid, Tid Tmax>
void NewGRFClass<Tspec, Tid, Tmax>::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<Tspec, Tid, Tmax>::Reset()
template <typename Tspec, typename Tid, Tid Tmax>
Tid NewGRFClass<Tspec, Tid, Tmax>::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<Tid>(0);
}
/**
@@ -83,7 +67,7 @@ void NewGRFClass<Tspec, Tid, Tmax>::Insert(Tspec *spec)
template <typename Tspec, typename Tid, Tid Tmax>
void NewGRFClass<Tspec, Tid, Tmax>::Assign(Tspec *spec)
{
assert(spec->cls_id < Tmax);
assert(static_cast<size_t>(spec->cls_id) < NewGRFClass::classes.size());
Get(spec->cls_id)->Insert(spec);
}
@@ -105,8 +89,8 @@ bool NewGRFClass<Tspec, Tid, Tmax>::IsClassIDValid(Tid cls_id)
template <typename Tspec, typename Tid, Tid Tmax>
NewGRFClass<Tspec, Tid, Tmax> *NewGRFClass<Tspec, Tid, Tmax>::Get(Tid cls_id)
{
assert(cls_id < Tmax);
return classes + cls_id;
assert(static_cast<size_t>(cls_id) < NewGRFClass::classes.size());
return &NewGRFClass::classes[cls_id];
}
/**
@@ -116,9 +100,7 @@ NewGRFClass<Tspec, Tid, Tmax> *NewGRFClass<Tspec, Tid, Tmax>::Get(Tid cls_id)
template <typename Tspec, typename Tid, Tid Tmax>
uint NewGRFClass<Tspec, Tid, Tmax>::GetClassCount()
{
uint i;
for (i = 0; i < Tmax && classes[i].global_id != 0; i++) {}
return i;
return static_cast<uint>(NewGRFClass::classes.size());
}
/**
@@ -128,11 +110,7 @@ uint NewGRFClass<Tspec, Tid, Tmax>::GetClassCount()
template <typename Tspec, typename Tid, Tid Tmax>
uint NewGRFClass<Tspec, Tid, Tmax>::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<Tspec, Tid, Tmax>::HasUIClass()
template <typename Tspec, typename Tid, Tid Tmax>
Tid NewGRFClass<Tspec, Tid, Tmax>::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<Tspec, Tid, Tmax>::GetUIFromIndex(int index) const
template <typename Tspec, typename Tid, Tid Tmax>
const Tspec *NewGRFClass<Tspec, Tid, Tmax>::GetByGrf(uint32_t grfid, uint16_t local_id, int *index)
{
uint j;
for (Tid i = (Tid)0; i < Tmax; i++) {
uint count = static_cast<uint>(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<int>(std::distance(cls.spec.data(), &spec));
return spec;
}
}

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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<RoadStopClassID> : MakeEnumPropsT<RoadStopClassID, uint8_t, ROADSTOP_CLASS_BEGIN, ROADSTOP_CLASS_MAX, ROADSTOP_CLASS_MAX, 16> {};
/* 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<RoadStopClassID> : MakeEnumPropsT<RoadStopClassID, uint8_t, ROADSTOP_CLASS_BEGIN, ROADSTOP_CLASS_MAX, ROADSTOP_CLASS_MAX, 8> {};
using RoadStopClass = NewGRFClass<RoadStopSpec, RoadStopClassID, ROADSTOP_CLASS_MAX>;
void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec, StationType type, int view);

View File

@@ -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);

View File

@@ -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<StationClassID> : MakeEnumPropsT<StationClassID, uint8_t, STAT_CLASS_BEGIN, STAT_CLASS_MAX, STAT_CLASS_MAX, 8> {};
template <> struct EnumPropsT<StationClassID> : MakeEnumPropsT<StationClassID, uint8_t, STAT_CLASS_BEGIN, STAT_CLASS_MAX, STAT_CLASS_MAX, 16> {};
/** Allow incrementing of StationClassID variables */
DECLARE_POSTFIX_INCREMENT(StationClassID)

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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<RoadStopClassID, 0, 8>(p3);
RoadStopClassID spec_class = Extract<RoadStopClassID, 0, 16>(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()) {

View File

@@ -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<StationClassID, 0, 8>(p2);
StationClassID spec_class = Extract<StationClassID, 0, 16>(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<RoadStopClassID, 0, 8>(p3);
RoadStopClassID spec_class = Extract<RoadStopClassID, 0, 16>(p3);
uint16_t spec_index = GB(p3, 16, 16);
/* Check if the given station class is valid */

View File

@@ -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<const char * const> 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<uint>(args.GetNextParameter<uint16_t>(), lengthof(_silly_company_names) - 1)];
builder += _silly_company_names[std::min<size_t>(args.GetNextParameter<uint16_t>(), std::size(_silly_company_names) - 1)];
return;
case 2: // used for Foobar & Co company names

View File

@@ -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<StationClassID, 0, 8>(p2);
StationClassID spec_class = Extract<StationClassID, 0, 16>(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<Axis, 17, 1>(p1);
RoadStopClassID spec_class = Extract<RoadStopClassID, 0, 8>(p2);
RoadStopClassID spec_class = Extract<RoadStopClassID, 0, 16>(p2);
uint spec_index = GB(p3, 0, 32);
/* Check if the given road stop class is valid */