From 295508fc533a8ce6b8ad9d7ae323ee204011af8e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 15 Jul 2023 20:44:07 +0100 Subject: [PATCH 01/29] Codechange: Avoid lengthof() on std::array. --- src/saveload/afterload.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index cfa3ddfbc5..f8b9202e6e 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1708,14 +1708,15 @@ bool AfterLoadGame() } } + /* At version 78, industry cargo types can be changed, and are stored with the industry. For older save versions + * copy the IndustrySpec's cargo types over to the Industry. */ if (IsSavegameVersionBefore(SLV_78)) { - uint j; - for (Industry * i : Industry::Iterate()) { + for (Industry *i : Industry::Iterate()) { const IndustrySpec *indsp = GetIndustrySpec(i->type); - for (j = 0; j < lengthof(i->produced); j++) { + for (uint j = 0; j < std::size(i->produced); j++) { i->produced[j].cargo = indsp->produced_cargo[j]; } - for (j = 0; j < lengthof(i->accepted); j++) { + for (uint j = 0; j < std::size(i->accepted); j++) { i->accepted[j].cargo = indsp->accepts_cargo[j]; } } From 00e0021e3a21f8073a0707ec0c76dfe98625584c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 29 Nov 2023 21:30:19 +0000 Subject: [PATCH 02/29] Codechange: Don't assume accepted/produced slot exists. --- src/industry.h | 22 +++++++++++ src/industry_cmd.cpp | 9 +++-- src/newgrf_industries.cpp | 56 ++++++++++++++-------------- src/saveload/afterload.cpp | 2 +- src/table/newgrf_debug_data.h | 69 +++++++++++++++++++---------------- 5 files changed, 93 insertions(+), 65 deletions(-) diff --git a/src/industry.h b/src/industry.h index 4a8f41bbcf..2747001aea 100644 --- a/src/industry.h +++ b/src/industry.h @@ -139,6 +139,28 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { return IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->index; } + /** + * Safely get a produced cargo slot, or an empty data if the slot does not exist. + * @param slot produced cargo slot to retrieve. + * @return the real slot, or an empty slot. + */ + inline const ProducedCargo &GetProduced(size_t slot) const + { + static const ProducedCargo empty{INVALID_CARGO, 0, 0, {}}; + return slot < this->produced.size() ? this->produced[slot] : empty; + } + + /** + * Safely get an accepted cargo slot, or an empty data if the slot does not exist. + * @param slot accepted cargo slot to retrieve. + * @return the real slot, or an empty slot. + */ + inline const AcceptedCargo &GetAccepted(size_t slot) const + { + static const AcceptedCargo empty{INVALID_CARGO, 0, {}}; + return slot < this->accepted.size() ? this->accepted[slot] : empty; + } + /** * Get produced cargo slot for a specific cargo type. * @param cargo CargoID to find. diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 46e3d79b08..4f1f448ca1 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1125,8 +1125,9 @@ static bool SearchLumberMillTrees(TileIndex tile, void *) */ static void ChopLumberMillTrees(Industry *i) { - /* Skip production if cargo slot is invalid. */ - if (!IsValidCargoID(i->produced[0].cargo)) return; + /* Don't process lumber mill if cargo is not set up correctly. */ + auto itp = std::begin(i->produced); + if (itp == std::end(i->produced) || !IsValidCargoID(itp->cargo)) return; /* We only want to cut trees if all tiles are completed. */ for (TileIndex tile_cur : i->location) { @@ -1137,7 +1138,7 @@ static void ChopLumberMillTrees(Industry *i) TileIndex tile = i->location.tile; if (CircularTileSearch(&tile, 40, SearchLumberMillTrees, nullptr)) { // 40x40 tiles to search. - i->produced[0].waiting = ClampTo(i->produced[0].waiting + ScaleByCargoScale(45, false)); // Found a tree, add according value to waiting cargo. + itp->waiting = ClampTo(itp->waiting + ScaleByCargoScale(45, false)); // Found a tree, add according value to waiting cargo. } } @@ -2847,7 +2848,7 @@ static void ChangeIndustryProduction(Industry *i, bool monthly) if (original_economy) { if (only_decrease || Chance16(1, 3)) { /* If more than 60% transported, 66% chance of increase, else 33% chance of increase */ - if (!only_decrease && (i->produced[0].history[LAST_MONTH].PctTransported() > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) { + if (!only_decrease && (i->GetProduced(0).history[LAST_MONTH].PctTransported() > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) { mul = 1; // Increase production } else { div = 1; // Decrease production diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index ed68d35a01..7f574fb9b9 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -214,9 +214,9 @@ static uint32_t GetCountAndDistanceOfClosestInstance(uint8_t param_setID, uint8_ if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(callback, CBM_IND_PRODUCTION_256_TICKS)) { if ((indspec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) { if (this->industry->prod_level == 0) return 0; - return ClampTo(this->industry->accepted[variable - 0x40].waiting / this->industry->prod_level); + return ClampTo(this->industry->GetAccepted(variable - 0x40).waiting / this->industry->prod_level); } else { - return ClampTo(this->industry->accepted[variable - 0x40].waiting); + return ClampTo(this->industry->GetAccepted(variable - 0x40).waiting); } } else { return 0; @@ -358,40 +358,40 @@ static uint32_t GetCountAndDistanceOfClosestInstance(uint8_t param_setID, uint8_ case 0x87: return this->industry->location.h;// xy dimensions case 0x88: - case 0x89: return this->industry->produced[variable - 0x88].cargo; - case 0x8A: return this->industry->produced[0].waiting; - case 0x8B: return GB(this->industry->produced[0].waiting, 8, 8); - case 0x8C: return this->industry->produced[1].waiting; - case 0x8D: return GB(this->industry->produced[1].waiting, 8, 8); + case 0x89: return this->industry->GetProduced(variable - 0x88).cargo; + case 0x8A: return this->industry->GetProduced(0).waiting; + case 0x8B: return GB(this->industry->GetProduced(0).waiting, 8, 8); + case 0x8C: return this->industry->GetProduced(1).waiting; + case 0x8D: return GB(this->industry->GetProduced(1).waiting, 8, 8); case 0x8E: - case 0x8F: return this->industry->produced[variable - 0x8E].rate; + case 0x8F: return this->industry->GetProduced(variable - 0x8E).rate; case 0x90: case 0x91: - case 0x92: return this->industry->accepted[variable - 0x90].cargo; + case 0x92: return this->industry->GetAccepted(variable - 0x90).cargo; case 0x93: return this->industry->prod_level; /* amount of cargo produced so far THIS month. */ - case 0x94: return this->industry->produced[0].history[THIS_MONTH].production; - case 0x95: return GB(this->industry->produced[0].history[THIS_MONTH].production, 8, 8); - case 0x96: return this->industry->produced[1].history[THIS_MONTH].production; - case 0x97: return GB(this->industry->produced[1].history[THIS_MONTH].production, 8, 8); + case 0x94: return this->industry->GetProduced(0).history[THIS_MONTH].production; + case 0x95: return GB(this->industry->GetProduced(0).history[THIS_MONTH].production, 8, 8); + case 0x96: return this->industry->GetProduced(1).history[THIS_MONTH].production; + case 0x97: return GB(this->industry->GetProduced(1).history[THIS_MONTH].production, 8, 8); /* amount of cargo transported so far THIS month. */ - case 0x98: return this->industry->produced[0].history[THIS_MONTH].transported; - case 0x99: return GB(this->industry->produced[0].history[THIS_MONTH].transported, 8, 8); - case 0x9A: return this->industry->produced[1].history[THIS_MONTH].transported; - case 0x9B: return GB(this->industry->produced[1].history[THIS_MONTH].transported, 8, 8); + case 0x98: return this->industry->GetProduced(0).history[THIS_MONTH].transported; + case 0x99: return GB(this->industry->GetProduced(0).history[THIS_MONTH].transported, 8, 8); + case 0x9A: return this->industry->GetProduced(1).history[THIS_MONTH].transported; + case 0x9B: return GB(this->industry->GetProduced(1).history[THIS_MONTH].transported, 8, 8); /* fraction of cargo transported LAST month. */ case 0x9C: - case 0x9D: return this->industry->produced[variable - 0x9C].history[LAST_MONTH].PctTransported(); + case 0x9D: return this->industry->GetProduced(variable - 0x9C).history[LAST_MONTH].PctTransported(); /* amount of cargo produced LAST month. */ - case 0x9E: return this->industry->produced[0].history[LAST_MONTH].production; - case 0x9F: return GB(this->industry->produced[0].history[LAST_MONTH].production, 8, 8); - case 0xA0: return this->industry->produced[1].history[LAST_MONTH].production; - case 0xA1: return GB(this->industry->produced[1].history[LAST_MONTH].production, 8, 8); + case 0x9E: return this->industry->GetProduced(0).history[LAST_MONTH].production; + case 0x9F: return GB(this->industry->GetProduced(0).history[LAST_MONTH].production, 8, 8); + case 0xA0: return this->industry->GetProduced(1).history[LAST_MONTH].production; + case 0xA1: return GB(this->industry->GetProduced(1).history[LAST_MONTH].production, 8, 8); /* amount of cargo transported last month. */ - case 0xA2: return this->industry->produced[0].history[LAST_MONTH].transported; - case 0xA3: return GB(this->industry->produced[0].history[LAST_MONTH].transported, 8, 8); - case 0xA4: return this->industry->produced[1].history[LAST_MONTH].transported; - case 0xA5: return GB(this->industry->produced[1].history[LAST_MONTH].transported, 8, 8); + case 0xA2: return this->industry->GetProduced(0).history[LAST_MONTH].transported; + case 0xA3: return GB(this->industry->GetProduced(0).history[LAST_MONTH].transported, 8, 8); + case 0xA4: return this->industry->GetProduced(1).history[LAST_MONTH].transported; + case 0xA5: return GB(this->industry->GetProduced(1).history[LAST_MONTH].transported, 8, 8); case 0xA6: return indspec->grf_prop.local_id; case 0xA7: return this->industry->founder; @@ -642,11 +642,11 @@ void IndustryProductionCallback(Industry *ind, int reason) if (group->version < 2) { /* Callback parameters map directly to industry cargo slot indices */ - for (uint i = 0; i < group->num_input; i++) { + for (uint i = 0; i < group->num_input && i < ind->accepted.size(); i++) { if (!IsValidCargoID(ind->accepted[i].cargo)) continue; ind->accepted[i].waiting = ClampTo(ind->accepted[i].waiting - DerefIndProd(group->subtract_input[i], deref) * multiplier); } - for (uint i = 0; i < group->num_output; i++) { + for (uint i = 0; i < group->num_output && i < ind->produced.size(); i++) { if (!IsValidCargoID(ind->produced[i].cargo)) continue; ind->produced[i].waiting = ClampTo(ind->produced[i].waiting + std::max(DerefIndProd(group->add_output[i], deref), 0) * multiplier); } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index f8b9202e6e..34a9f36d27 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3058,7 +3058,7 @@ bool AfterLoadGame() * The loading routine should put the original singular value into the first array element. */ for (auto &a : i->accepted) { if (IsValidCargoID(a.cargo)) { - a.last_accepted = i->accepted[0].last_accepted; + a.last_accepted = i->GetAccepted(0).last_accepted; } else { a.last_accepted = 0; } diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index f11a1110a7..127a948635 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -274,43 +274,48 @@ static const NIFeature _nif_industrytile = { /*** NewGRF industries ***/ +#define NIP_PRODUCED_CARGO(prop, base, slot, type, name) { name, [] (const void *b) -> const void * { return std::addressof(static_cast(b)->GetProduced(slot).cargo); }, sizeof(CargoID), prop, type } +#define NIP_ACCEPTED_CARGO(prop, base, slot, type, name) { name, [] (const void *b) -> const void * { return std::addressof(static_cast(b)->GetAccepted(slot).cargo); }, sizeof(CargoID), prop, type } static const NIProperty _nip_industries[] = { - NIP(0x25, Industry, produced[ 0].cargo, NIT_CARGO, "produced cargo 0"), - NIP(0x25, Industry, produced[ 1].cargo, NIT_CARGO, "produced cargo 1"), - NIP(0x25, Industry, produced[ 2].cargo, NIT_CARGO, "produced cargo 2"), - NIP(0x25, Industry, produced[ 3].cargo, NIT_CARGO, "produced cargo 3"), - NIP(0x25, Industry, produced[ 4].cargo, NIT_CARGO, "produced cargo 4"), - NIP(0x25, Industry, produced[ 5].cargo, NIT_CARGO, "produced cargo 5"), - NIP(0x25, Industry, produced[ 6].cargo, NIT_CARGO, "produced cargo 6"), - NIP(0x25, Industry, produced[ 7].cargo, NIT_CARGO, "produced cargo 7"), - NIP(0x25, Industry, produced[ 8].cargo, NIT_CARGO, "produced cargo 8"), - NIP(0x25, Industry, produced[ 9].cargo, NIT_CARGO, "produced cargo 9"), - NIP(0x25, Industry, produced[10].cargo, NIT_CARGO, "produced cargo 10"), - NIP(0x25, Industry, produced[11].cargo, NIT_CARGO, "produced cargo 11"), - NIP(0x25, Industry, produced[12].cargo, NIT_CARGO, "produced cargo 12"), - NIP(0x25, Industry, produced[13].cargo, NIT_CARGO, "produced cargo 13"), - NIP(0x25, Industry, produced[14].cargo, NIT_CARGO, "produced cargo 14"), - NIP(0x25, Industry, produced[15].cargo, NIT_CARGO, "produced cargo 15"), - NIP(0x26, Industry, accepted[ 0].cargo, NIT_CARGO, "accepted cargo 0"), - NIP(0x26, Industry, accepted[ 1].cargo, NIT_CARGO, "accepted cargo 1"), - NIP(0x26, Industry, accepted[ 2].cargo, NIT_CARGO, "accepted cargo 2"), - NIP(0x26, Industry, accepted[ 3].cargo, NIT_CARGO, "accepted cargo 3"), - NIP(0x26, Industry, accepted[ 4].cargo, NIT_CARGO, "accepted cargo 4"), - NIP(0x26, Industry, accepted[ 5].cargo, NIT_CARGO, "accepted cargo 5"), - NIP(0x26, Industry, accepted[ 6].cargo, NIT_CARGO, "accepted cargo 6"), - NIP(0x26, Industry, accepted[ 7].cargo, NIT_CARGO, "accepted cargo 7"), - NIP(0x26, Industry, accepted[ 8].cargo, NIT_CARGO, "accepted cargo 8"), - NIP(0x26, Industry, accepted[ 9].cargo, NIT_CARGO, "accepted cargo 9"), - NIP(0x26, Industry, accepted[10].cargo, NIT_CARGO, "accepted cargo 10"), - NIP(0x26, Industry, accepted[11].cargo, NIT_CARGO, "accepted cargo 11"), - NIP(0x26, Industry, accepted[12].cargo, NIT_CARGO, "accepted cargo 12"), - NIP(0x26, Industry, accepted[13].cargo, NIT_CARGO, "accepted cargo 13"), - NIP(0x26, Industry, accepted[14].cargo, NIT_CARGO, "accepted cargo 14"), - NIP(0x26, Industry, accepted[15].cargo, NIT_CARGO, "accepted cargo 15"), + NIP_PRODUCED_CARGO(0x25, Industry, 0, NIT_CARGO, "produced cargo 0"), + NIP_PRODUCED_CARGO(0x25, Industry, 1, NIT_CARGO, "produced cargo 1"), + NIP_PRODUCED_CARGO(0x25, Industry, 2, NIT_CARGO, "produced cargo 2"), + NIP_PRODUCED_CARGO(0x25, Industry, 3, NIT_CARGO, "produced cargo 3"), + NIP_PRODUCED_CARGO(0x25, Industry, 4, NIT_CARGO, "produced cargo 4"), + NIP_PRODUCED_CARGO(0x25, Industry, 5, NIT_CARGO, "produced cargo 5"), + NIP_PRODUCED_CARGO(0x25, Industry, 6, NIT_CARGO, "produced cargo 6"), + NIP_PRODUCED_CARGO(0x25, Industry, 7, NIT_CARGO, "produced cargo 7"), + NIP_PRODUCED_CARGO(0x25, Industry, 8, NIT_CARGO, "produced cargo 8"), + NIP_PRODUCED_CARGO(0x25, Industry, 9, NIT_CARGO, "produced cargo 9"), + NIP_PRODUCED_CARGO(0x25, Industry, 10, NIT_CARGO, "produced cargo 10"), + NIP_PRODUCED_CARGO(0x25, Industry, 11, NIT_CARGO, "produced cargo 11"), + NIP_PRODUCED_CARGO(0x25, Industry, 12, NIT_CARGO, "produced cargo 12"), + NIP_PRODUCED_CARGO(0x25, Industry, 13, NIT_CARGO, "produced cargo 13"), + NIP_PRODUCED_CARGO(0x25, Industry, 14, NIT_CARGO, "produced cargo 14"), + NIP_PRODUCED_CARGO(0x25, Industry, 15, NIT_CARGO, "produced cargo 15"), + NIP_ACCEPTED_CARGO(0x26, Industry, 0, NIT_CARGO, "accepted cargo 0"), + NIP_ACCEPTED_CARGO(0x26, Industry, 1, NIT_CARGO, "accepted cargo 1"), + NIP_ACCEPTED_CARGO(0x26, Industry, 2, NIT_CARGO, "accepted cargo 2"), + NIP_ACCEPTED_CARGO(0x26, Industry, 3, NIT_CARGO, "accepted cargo 3"), + NIP_ACCEPTED_CARGO(0x26, Industry, 4, NIT_CARGO, "accepted cargo 4"), + NIP_ACCEPTED_CARGO(0x26, Industry, 5, NIT_CARGO, "accepted cargo 5"), + NIP_ACCEPTED_CARGO(0x26, Industry, 6, NIT_CARGO, "accepted cargo 6"), + NIP_ACCEPTED_CARGO(0x26, Industry, 7, NIT_CARGO, "accepted cargo 7"), + NIP_ACCEPTED_CARGO(0x26, Industry, 8, NIT_CARGO, "accepted cargo 8"), + NIP_ACCEPTED_CARGO(0x26, Industry, 9, NIT_CARGO, "accepted cargo 9"), + NIP_ACCEPTED_CARGO(0x26, Industry, 10, NIT_CARGO, "accepted cargo 10"), + NIP_ACCEPTED_CARGO(0x26, Industry, 11, NIT_CARGO, "accepted cargo 11"), + NIP_ACCEPTED_CARGO(0x26, Industry, 12, NIT_CARGO, "accepted cargo 12"), + NIP_ACCEPTED_CARGO(0x26, Industry, 13, NIT_CARGO, "accepted cargo 13"), + NIP_ACCEPTED_CARGO(0x26, Industry, 14, NIT_CARGO, "accepted cargo 14"), + NIP_ACCEPTED_CARGO(0x26, Industry, 15, NIT_CARGO, "accepted cargo 15"), NIP_END() }; +#undef NIP_PRODUCED_CARGO +#undef NIP_ACCEPTED_CARGO + #define NICI(cb_id, bit) NIC(cb_id, IndustrySpec, callback_mask, bit) static const NICallback _nic_industries[] = { NICI(CBID_INDUSTRY_PROBABILITY, CBM_IND_PROBABILITY), From 3de8853e2953b086e22c458c6ff625bb526e154c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 14 Jul 2023 11:49:11 +0100 Subject: [PATCH 03/29] Codechange: Store accepted and produced cargo in vector instead of array. Most industries do not use the full 16 slots, so this can save a little memory and iteration time. --- src/industry.h | 16 +++++----- src/industry_cmd.cpp | 57 +++++++++++++++++++++++++++-------- src/saveload/afterload.cpp | 10 ------ src/saveload/industry_sl.cpp | 37 ++++++++++++++--------- src/saveload/oldloader_sl.cpp | 37 ++++++++++++++--------- 5 files changed, 99 insertions(+), 58 deletions(-) diff --git a/src/industry.h b/src/industry.h index 2747001aea..24fe0cef8f 100644 --- a/src/industry.h +++ b/src/industry.h @@ -90,14 +90,14 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { TimerGameEconomy::Date last_accepted; ///< Last day cargo was accepted by this industry }; - using ProducedCargoArray = std::array; - using AcceptedCargoArray = std::array; + using ProducedCargoes = std::vector; + using AcceptedCargoes = std::vector; TileArea location; ///< Location of the industry Town *town; ///< Nearest town Station *neutral_station; ///< Associated neutral station - ProducedCargoArray produced; ///< INDUSTRY_NUM_OUTPUTS production cargo slots - AcceptedCargoArray accepted; ///< INDUSTRY_NUM_INPUTS input cargo slots + ProducedCargoes produced; ///< produced cargo slots + AcceptedCargoes accepted; ///< accepted cargo slots uint8_t prod_level; ///< general production level uint16_t counter; ///< used for animation and/or production (if available cargo) @@ -166,7 +166,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { * @param cargo CargoID to find. * @return Iterator pointing to produced cargo slot if it exists, or the end iterator. */ - inline ProducedCargoArray::iterator GetCargoProduced(CargoID cargo) + inline ProducedCargoes::iterator GetCargoProduced(CargoID cargo) { if (!IsValidCargoID(cargo)) return std::end(this->produced); return std::find_if(std::begin(this->produced), std::end(this->produced), [&cargo](const auto &p) { return p.cargo == cargo; }); @@ -177,7 +177,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { * @param cargo CargoID to find. * @return Iterator pointing to produced cargo slot if it exists, or the end iterator. */ - inline ProducedCargoArray::const_iterator GetCargoProduced(CargoID cargo) const + inline ProducedCargoes::const_iterator GetCargoProduced(CargoID cargo) const { if (!IsValidCargoID(cargo)) return std::end(this->produced); return std::find_if(std::begin(this->produced), std::end(this->produced), [&cargo](const auto &p) { return p.cargo == cargo; }); @@ -188,7 +188,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { * @param cargo CargoID to find. * @return Iterator pointing to accepted cargo slot if it exists, or the end iterator. */ - inline AcceptedCargoArray::iterator GetCargoAccepted(CargoID cargo) + inline AcceptedCargoes::iterator GetCargoAccepted(CargoID cargo) { if (!IsValidCargoID(cargo)) return std::end(this->accepted); return std::find_if(std::begin(this->accepted), std::end(this->accepted), [&cargo](const auto &a) { return a.cargo == cargo; }); @@ -332,4 +332,6 @@ enum IndustryDirectoryInvalidateWindowData { IDIWD_FORCE_RESORT, }; +void TrimIndustryAcceptedProduced(Industry *ind); + #endif /* INDUSTRY_H */ diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 4f1f448ca1..816e36a5e5 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1788,15 +1788,19 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, i->type = type; Industry::IncIndustryTypeCount(type); - for (auto it = std::begin(i->produced); it != std::end(i->produced); ++it) { - size_t index = it - std::begin(i->produced); - it->cargo = indspec->produced_cargo[index]; - it->rate = indspec->production_rate[index]; + for (size_t index = 0; index < lengthof(indspec->produced_cargo); ++index) { + if (!IsValidCargoID(indspec->produced_cargo[index])) break; + + Industry::ProducedCargo &p = i->produced.emplace_back(); + p.cargo = indspec->produced_cargo[index]; + p.rate = indspec->production_rate[index]; } - for (auto it = std::begin(i->accepted); it != std::end(i->accepted); ++it) { - size_t index = it - std::begin(i->accepted); - it->cargo = indspec->accepts_cargo[index]; + for (size_t index = 0; index < lengthof(indspec->accepts_cargo); ++index) { + if (!IsValidCargoID(indspec->accepts_cargo[index])) break; + + Industry::AcceptedCargo &a = i->accepted.emplace_back(); + a.cargo = indspec->accepts_cargo[index]; } /* Randomize inital production if non-original economy is used and there are no production related callbacks. */ @@ -1870,7 +1874,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, if (HasBit(indspec->callback_mask, CBM_IND_INPUT_CARGO_TYPES)) { /* Clear all input cargo types */ - for (auto &a : i->accepted) a.cargo = INVALID_CARGO; + i->accepted.clear(); /* Query actual types */ uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? static_cast(i->accepted.size()) : 3; for (uint j = 0; j < maxcargoes; j++) { @@ -1884,7 +1888,12 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, /* Industries without "unlimited" cargo types support depend on the specific order/slots of cargo types. * They need to be able to blank out specific slots without aborting the callback sequence, * and solve this by returning undefined cargo indexes. Skip these. */ - if (!IsValidCargoID(cargo) && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) continue; + if (!IsValidCargoID(cargo) && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) { + /* As slots are allocated as needed now, this means we do need to add a slot for the invalid cargo. */ + Industry::AcceptedCargo &a = i->accepted.emplace_back(); + a.cargo = INVALID_CARGO; + continue; + } /* Verify valid cargo */ if (std::find(indspec->accepts_cargo, endof(indspec->accepts_cargo), cargo) == endof(indspec->accepts_cargo)) { /* Cargo not in spec, error in NewGRF */ @@ -1896,13 +1905,14 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_INPUT_CARGO_TYPES, res); break; } - i->accepted[j].cargo = cargo; + Industry::AcceptedCargo &a = i->accepted.emplace_back(); + a.cargo = cargo; } } if (HasBit(indspec->callback_mask, CBM_IND_OUTPUT_CARGO_TYPES)) { /* Clear all output cargo types */ - for (auto &p : i->produced) p.cargo = INVALID_CARGO; + i->produced.clear(); /* Query actual types */ uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? static_cast(i->produced.size()) : 2; for (uint j = 0; j < maxcargoes; j++) { @@ -1914,7 +1924,12 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, } CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); /* Allow older GRFs to skip slots. */ - if (!IsValidCargoID(cargo) && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) continue; + if (!IsValidCargoID(cargo) && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) { + /* As slots are allocated as needed now, this means we do need to add a slot for the invalid cargo. */ + Industry::ProducedCargo &p = i->produced.emplace_back(); + p.cargo = INVALID_CARGO; + continue; + } /* Verify valid cargo */ if (std::find(indspec->produced_cargo, endof(indspec->produced_cargo), cargo) == endof(indspec->produced_cargo)) { /* Cargo not in spec, error in NewGRF */ @@ -1926,7 +1941,8 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_OUTPUT_CARGO_TYPES, res); break; } - i->produced[j].cargo = cargo; + Industry::ProducedCargo &p = i->produced.emplace_back(); + p.cargo = cargo; } } @@ -3212,3 +3228,18 @@ bool IndustryCompare::operator() (const IndustryListEntry &lhs, const IndustryLi /* Compare by distance first and use index as a tiebreaker. */ return std::tie(lhs.distance, lhs.industry->index) < std::tie(rhs.distance, rhs.industry->index); } + +/** + * Remove unused industry accepted/produced slots -- entries after the last slot with valid cargo. + * @param ind Industry to trim slots. + */ +void TrimIndustryAcceptedProduced(Industry *ind) +{ + auto ita = std::find_if(std::rbegin(ind->accepted), std::rend(ind->accepted), [](const auto &a) { return IsValidCargoID(a.cargo); }); + ind->accepted.erase(ita.base(), std::end(ind->accepted)); + ind->accepted.shrink_to_fit(); + + auto itp = std::find_if(std::rbegin(ind->produced), std::rend(ind->produced), [](const auto &p) { return IsValidCargoID(p.cargo); }); + ind->produced.erase(itp.base(), std::end(ind->produced)); + ind->produced.shrink_to_fit(); +} diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 34a9f36d27..bc203e16dc 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3044,16 +3044,6 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_EXTEND_INDUSTRY_CARGO_SLOTS)) { /* Make sure added industry cargo slots are cleared */ for (Industry *i : Industry::Iterate()) { - for (auto it = std::begin(i->produced) + 2; it != std::end(i->produced); ++it) { - it->cargo = INVALID_CARGO; - it->waiting = 0; - it->rate = 0; - it->history = {}; - } - for (auto it = std::begin(i->accepted) + 3; it != std::end(i->accepted); ++it) { - it->cargo = INVALID_CARGO; - it->waiting = 0; - } /* Make sure last_cargo_accepted_at is copied to elements for every valid input cargo. * The loading routine should put the original singular value into the first array element. */ for (auto &a : i->accepted) { diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 693fe7160f..342f03d807 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -39,11 +39,12 @@ public: void Load(Industry *i) const override { - size_t len = SlGetStructListLength(i->accepted.size()); + size_t len = SlGetStructListLength(INDUSTRY_NUM_INPUTS); - for (auto &a : i->accepted) { - if (--len > i->accepted.size()) break; // unsigned so wraps after hitting zero. - SlObject(&a, this->GetDescription()); + i->accepted.reserve(len); + for (size_t index = 0; index < len; ++index) { + auto &a = i->accepted.emplace_back(); + SlObject(&a, this->GetLoadDescription()); } } @@ -115,11 +116,12 @@ public: void Load(Industry *i) const override { - size_t len = SlGetStructListLength(i->produced.size()); + size_t len = SlGetStructListLength(INDUSTRY_NUM_OUTPUTS); - for (auto &p : i->produced) { - if (--len > i->produced.size()) break; // unsigned so wraps after hitting zero. - SlObject(&p, this->GetDescription()); + i->produced.reserve(len); + for (size_t index = 0; index < len; ++index) { + auto &p = i->produced.emplace_back(); + SlObject(&p, this->GetLoadDescription()); } } @@ -214,17 +216,19 @@ struct INDYChunkHandler : ChunkHandler { } } - void LoadMoveAcceptsProduced(Industry *i) const + void LoadMoveAcceptsProduced(Industry *i, uint inputs, uint outputs) const { - for (uint j = 0; j != INDUSTRY_NUM_INPUTS; ++j) { - auto &a = i->accepted[j]; + i->accepted.reserve(inputs); + for (uint j = 0; j != inputs; ++j) { + auto &a = i->accepted.emplace_back(); a.cargo = SlIndustryAccepted::old_cargo[j]; a.waiting = SlIndustryAccepted::old_waiting[j]; a.last_accepted = SlIndustryAccepted::old_last_accepted[j]; } - for (uint j = 0; j != INDUSTRY_NUM_OUTPUTS; ++j) { - auto &p = i->produced[j]; + i->produced.reserve(outputs); + for (uint j = 0; j != outputs; ++j) { + auto &p = i->produced.emplace_back(); p.cargo = SlIndustryProduced::old_cargo[j]; p.waiting = SlIndustryProduced::old_waiting[j]; p.rate = SlIndustryProduced::old_rate[j]; @@ -256,8 +260,13 @@ struct INDYChunkHandler : ChunkHandler { i->psa = new PersistentStorage(0, 0, 0); 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); + if (IsSavegameVersionBefore(SLV_EXTEND_INDUSTRY_CARGO_SLOTS)) { + LoadMoveAcceptsProduced(i, 3, 2); + } else if (IsSavegameVersionBefore(SLV_INDUSTRY_CARGO_REORGANISE)) { + LoadMoveAcceptsProduced(i, INDUSTRY_NUM_INPUTS, INDUSTRY_NUM_OUTPUTS); + } Industry::IncIndustryTypeCount(i->type); + TrimIndustryAcceptedProduced(i); } } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index b9d4d632e4..c56b68f7da 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -804,6 +804,10 @@ static bool LoadOldStation(LoadgameState *ls, int num) return true; } +/* Old save games always have 3 input and 2 output slots per industry. */ +static std::array _old_accepted{}; +static std::array _old_produced{}; + static const OldChunks industry_chunk[] = { OCL_SVAR( OC_TILE, Industry, location.tile ), OCL_VAR ( OC_UINT32, 1, &_old_town_index ), @@ -811,29 +815,29 @@ static const OldChunks industry_chunk[] = { OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.h ), OCL_NULL( 2 ), ///< used to be industry's produced_cargo - OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced[0].waiting ), - OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced[1].waiting ), - OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced[0].waiting ), - OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced[1].waiting ), + OCL_VAR( OC_TTD | OC_UINT16, 1, &_old_produced[0].waiting ), + OCL_VAR( OC_TTD | OC_UINT16, 1, &_old_produced[1].waiting ), + OCL_VAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_old_produced[0].waiting ), + OCL_VAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_old_produced[1].waiting ), - OCL_SVAR( OC_UINT8, Industry, produced[0].rate ), - OCL_SVAR( OC_UINT8, Industry, produced[1].rate ), + OCL_VAR( OC_UINT8, 1, &_old_produced[0].rate ), + OCL_VAR( OC_UINT8, 1, &_old_produced[1].rate ), OCL_NULL( 3 ), ///< used to be industry's accepts_cargo OCL_SVAR( OC_UINT8, Industry, prod_level ), - OCL_SVAR( OC_UINT16, Industry, produced[0].history[THIS_MONTH].production ), - OCL_SVAR( OC_UINT16, Industry, produced[1].history[THIS_MONTH].production ), - OCL_SVAR( OC_UINT16, Industry, produced[0].history[THIS_MONTH].transported ), - OCL_SVAR( OC_UINT16, Industry, produced[1].history[THIS_MONTH].transported ), + OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[THIS_MONTH].production ), + OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[THIS_MONTH].production ), + OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[THIS_MONTH].transported ), + OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[THIS_MONTH].transported ), OCL_NULL( 2 ), ///< last_month_pct_transported, now computed on the fly - OCL_SVAR( OC_UINT16, Industry, produced[0].history[LAST_MONTH].production ), - OCL_SVAR( OC_UINT16, Industry, produced[1].history[LAST_MONTH].production ), - OCL_SVAR( OC_UINT16, Industry, produced[0].history[LAST_MONTH].transported ), - OCL_SVAR( OC_UINT16, Industry, produced[1].history[LAST_MONTH].transported ), + OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[LAST_MONTH].production ), + OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[LAST_MONTH].production ), + OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[LAST_MONTH].transported ), + OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[LAST_MONTH].transported ), OCL_SVAR( OC_UINT8, Industry, type ), OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, counter ), @@ -854,6 +858,10 @@ static bool LoadOldIndustry(LoadgameState *ls, int num) if (!LoadChunk(ls, i, industry_chunk)) return false; if (i->location.tile != 0) { + /* Copy data from old fixed arrays to industry. */ + std::copy(std::begin(_old_accepted), std::end(_old_accepted), std::back_inserter(i->accepted)); + std::copy(std::begin(_old_produced), std::end(_old_produced), std::back_inserter(i->produced)); + i->town = RemapTown(i->location.tile); if (_savegame_type == SGT_TTO) { @@ -867,6 +875,7 @@ static bool LoadOldIndustry(LoadgameState *ls, int num) } Industry::IncIndustryTypeCount(i->type); + TrimIndustryAcceptedProduced(i); } else { delete i; } From 11aa3694fa4523d1675708874e8bdea15ade3502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Mon, 1 Apr 2024 22:59:13 +0200 Subject: [PATCH 04/29] Fix: [Win32] Force font mapper to only use TrueType fonts (#12406) --- src/os/windows/font_win32.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index 28be70bb02..d2a5420735 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -115,10 +115,6 @@ bool SetFallbackFont(FontCacheSettings *settings, const std::string &, int winla } -#ifndef ANTIALIASED_QUALITY -#define ANTIALIASED_QUALITY 4 -#endif - /** * Create a new Win32FontCache. * @param fs The font size that is going to be cached. @@ -171,7 +167,8 @@ void Win32FontCache::SetFontSize(int pixels) /* Create GDI font handle. */ this->logfont.lfHeight = -pixels; this->logfont.lfWidth = 0; - this->logfont.lfOutPrecision = ANTIALIASED_QUALITY; + this->logfont.lfOutPrecision = OUT_TT_ONLY_PRECIS; + this->logfont.lfQuality = ANTIALIASED_QUALITY; if (this->font != nullptr) { SelectObject(dc, this->old_font); From 56cac2108631792b4121242929462eb97d0bc92a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 31 Mar 2024 17:31:47 +0100 Subject: [PATCH 05/29] Codechange: Use functions to create common drop down list items. --- src/airport_gui.cpp | 3 +- src/autoreplace_gui.cpp | 5 +- src/build_vehicle_gui.cpp | 9 ++-- src/date_gui.cpp | 7 +-- src/dropdown.cpp | 32 ++++++++++++- src/dropdown_func.h | 8 ++++ src/game/game_gui.cpp | 3 +- src/genworld_gui.cpp | 8 ++-- src/industry_gui.cpp | 10 ++-- src/network/network_gui.cpp | 14 +++--- src/newgrf_gui.cpp | 6 +-- src/order_gui.cpp | 2 +- src/rail_gui.cpp | 9 ++-- src/road_gui.cpp | 14 +++--- src/script/script_gui.cpp | 5 +- src/settings_gui.cpp | 40 ++++++++++------ src/settings_gui.h | 12 +---- src/station_gui.cpp | 9 ++-- src/story_gui.cpp | 4 +- src/textfile_gui.cpp | 3 +- src/toolbar_gui.cpp | 96 +++++++++++++++++++------------------ src/vehicle_gui.cpp | 27 ++++++----- 22 files changed, 190 insertions(+), 136 deletions(-) diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 3e40208db1..a6e4109f59 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -23,6 +23,7 @@ #include "newgrf_airport.h" #include "newgrf_callbacks.h" #include "dropdown_type.h" +#include "dropdown_func.h" #include "core/geometry_func.hpp" #include "hotkeys.h" #include "vehicle_func.h" @@ -241,7 +242,7 @@ class BuildAirportWindow : public PickerWindowBase { DropDownList list; for (uint i = 0; i < AirportClass::GetClassCount(); i++) { - list.push_back(std::make_unique(AirportClass::Get((AirportClassID)i)->name, i, false)); + list.push_back(MakeDropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i)); } return list; diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index a69786dc2f..93f2ae7825 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -24,6 +24,7 @@ #include "core/geometry_func.hpp" #include "rail_gui.h" #include "road_gui.h" +#include "dropdown_type.h" #include "dropdown_func.h" #include "autoreplace_cmd.h" #include "group_cmd.h" @@ -563,8 +564,8 @@ public: case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: { DropDownList list; - list.push_back(std::make_unique(STR_REPLACE_ENGINES, 1, false)); - list.push_back(std::make_unique(STR_REPLACE_WAGONS, 0, false)); + list.push_back(MakeDropDownListStringItem(STR_REPLACE_ENGINES, 1)); + list.push_back(MakeDropDownListStringItem(STR_REPLACE_WAGONS, 0)); ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN); break; } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 0b458f3868..50244c24eb 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -25,6 +25,7 @@ #include "window_func.h" #include "timer/timer_game_calendar.h" #include "vehicle_func.h" +#include "dropdown_type.h" #include "dropdown_func.h" #include "engine_gui.h" #include "cargotype.h" @@ -1565,20 +1566,20 @@ struct BuildVehicleWindow : Window { DropDownList list; /* Add item for disabling filtering. */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false)); + list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY)); /* Specific filters for trains. */ if (this->vehicle_type == VEH_TRAIN) { /* Add item for locomotives only in case of trains. */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES, false)); + list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES)); /* Add item for vehicles not carrying anything, e.g. train engines. * This could also be useful for eyecandy vehicles of other types, but is likely too confusing for joe, */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false)); + list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE)); } /* Add cargos */ Dimension d = GetLargestCargoIconSize(); for (const CargoSpec *cs : _sorted_standard_cargo_specs) { - list.push_back(std::make_unique(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false)); + list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index())); } return list; diff --git a/src/date_gui.cpp b/src/date_gui.cpp index e5c2438cd2..57b2c076a8 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -15,6 +15,7 @@ #include "date_gui.h" #include "core/geometry_func.hpp" #include "dropdown_type.h" +#include "dropdown_func.h" #include "widgets/date_widget.h" @@ -75,14 +76,14 @@ struct SetDateWindow : Window { case WID_SD_DAY: for (uint i = 0; i < 31; i++) { - list.push_back(std::make_unique(STR_DAY_NUMBER_1ST + i, i + 1, false)); + list.push_back(MakeDropDownListStringItem(STR_DAY_NUMBER_1ST + i, i + 1)); } selected = this->date.day; break; case WID_SD_MONTH: for (uint i = 0; i < 12; i++) { - list.push_back(std::make_unique(STR_MONTH_JAN + i, i, false)); + list.push_back(MakeDropDownListStringItem(STR_MONTH_JAN + i, i)); } selected = this->date.month; break; @@ -90,7 +91,7 @@ struct SetDateWindow : Window { case WID_SD_YEAR: for (TimerGameEconomy::Year i = this->min_year; i <= this->max_year; i++) { SetDParam(0, i); - list.push_back(std::make_unique(STR_JUST_INT, i.base(), false)); + list.push_back(MakeDropDownListStringItem(STR_JUST_INT, i.base())); } selected = this->date.year.base(); break; diff --git a/src/dropdown.cpp b/src/dropdown.cpp index 2e70120069..1e334e365e 100644 --- a/src/dropdown.cpp +++ b/src/dropdown.cpp @@ -9,6 +9,7 @@ #include "stdafx.h" #include "dropdown_type.h" +#include "dropdown_func.h" #include "strings_func.h" #include "timer/timer.h" #include "timer/timer_window.h" @@ -20,6 +21,35 @@ #include "safeguards.h" +std::unique_ptr MakeDropDownListDividerItem() +{ + return std::make_unique(-1); +} + +std::unique_ptr MakeDropDownListStringItem(StringID str, int value, bool masked, bool shaded) +{ + return std::make_unique(str, value, masked, shaded); +} + +std::unique_ptr MakeDropDownListStringItem(const std::string &str, int value, bool masked, bool shaded) +{ + return std::make_unique(str, value, masked, shaded); +} + +std::unique_ptr MakeDropDownListIconItem(SpriteID sprite, PaletteID palette, StringID str, int value, bool masked, bool shaded) +{ + return std::make_unique(sprite, palette, str, value, masked, shaded); +} + +std::unique_ptr MakeDropDownListIconItem(const Dimension &dim, SpriteID sprite, PaletteID palette, StringID str, int value, bool masked, bool shaded) +{ + return std::make_unique(dim, sprite, palette, str, value, masked, shaded); +} + +std::unique_ptr MakeDropDownListCheckedItem(bool checked, StringID str, int value, bool masked, bool shaded) +{ + return std::make_unique(checked, str, value, masked, shaded); +} static constexpr NWidgetPart _nested_dropdown_menu_widgets[] = { NWidget(NWID_HORIZONTAL), @@ -408,7 +438,7 @@ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, WidgetID for (uint i = 0; strings[i] != INVALID_STRING_ID; i++) { if (!HasBit(hidden_mask, i)) { - list.push_back(std::make_unique(strings[i], i, HasBit(disabled_mask, i))); + list.push_back(MakeDropDownListStringItem(strings[i], i, HasBit(disabled_mask, i))); } } diff --git a/src/dropdown_func.h b/src/dropdown_func.h index 65e4d272af..dee640e00f 100644 --- a/src/dropdown_func.h +++ b/src/dropdown_func.h @@ -15,4 +15,12 @@ /* Show drop down menu containing a fixed list of strings */ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width = 0); +/* Helper functions for commonly used drop down list items. */ +std::unique_ptr MakeDropDownListDividerItem(); +std::unique_ptr MakeDropDownListStringItem(StringID str, int value, bool masked = false, bool shaded = false); +std::unique_ptr MakeDropDownListStringItem(const std::string &str, int value, bool masked = false, bool shaded = false); +std::unique_ptr MakeDropDownListIconItem(SpriteID sprite, PaletteID palette, StringID str, int value, bool masked = false, bool shaded = false); +std::unique_ptr MakeDropDownListIconItem(const Dimension &dim, SpriteID sprite, PaletteID palette, StringID str, int value, bool masked = false, bool shaded = false); +std::unique_ptr MakeDropDownListCheckedItem(bool checked, StringID str, int value, bool masked = false, bool shaded = false); + #endif /* DROPDOWN_FUNC_H */ diff --git a/src/game/game_gui.cpp b/src/game/game_gui.cpp index b6c6c7588a..aae47f76e8 100644 --- a/src/game/game_gui.cpp +++ b/src/game/game_gui.cpp @@ -14,6 +14,7 @@ #include "../window_func.h" #include "../network/network.h" #include "../network/network_content.h" +#include "../dropdown_type.h" #include "../dropdown_func.h" #include "../timer/timer.h" #include "../timer/timer_window.h" @@ -317,7 +318,7 @@ struct GSConfigWindow : public Window { DropDownList list; for (int i = config_item.min_value; i <= config_item.max_value; i++) { - list.push_back(std::make_unique(config_item.labels.find(i)->second, i, false)); + list.push_back(MakeDropDownListStringItem(config_item.labels.find(i)->second, i)); } ShowDropDownListAt(this, std::move(list), old_val, WID_GSC_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE); diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index d0071b63ca..723df35436 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -338,7 +338,7 @@ static DropDownList BuildMapsizeDropDown() for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) { SetDParam(0, 1LL << i); - list.push_back(std::make_unique(STR_JUST_INT, i, false)); + list.push_back(MakeDropDownListStringItem(STR_JUST_INT, i)); } return list; @@ -351,20 +351,20 @@ static DropDownList BuildTownNameDropDown() /* Add and sort newgrf townnames generators */ const auto &grf_names = GetGRFTownNameList(); for (uint i = 0; i < grf_names.size(); i++) { - list.push_back(std::make_unique(grf_names[i], BUILTIN_TOWNNAME_GENERATOR_COUNT + i, false)); + list.push_back(MakeDropDownListStringItem(grf_names[i], BUILTIN_TOWNNAME_GENERATOR_COUNT + i)); } std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); size_t newgrf_size = list.size(); /* Insert newgrf_names at the top of the list */ if (newgrf_size > 0) { - list.push_back(std::make_unique(-1, false)); // separator line + list.push_back(MakeDropDownListDividerItem()); // separator line newgrf_size++; } /* Add and sort original townnames generators */ for (uint i = 0; i < BUILTIN_TOWNNAME_GENERATOR_COUNT; i++) { - list.push_back(std::make_unique(STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + i, i, false)); + list.push_back(MakeDropDownListStringItem(STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + i, i)); } std::sort(list.begin() + newgrf_size, list.end(), DropDownListStringItem::NatSortFunc); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 6beffe9a73..7bd64396cf 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -1759,14 +1759,14 @@ public: DropDownList list; /* Add item for disabling filtering. */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false)); + list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY)); /* Add item for industries not producing anything, e.g. power plants */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false)); + list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE)); /* Add cargos */ Dimension d = GetLargestCargoIconSize(); for (const CargoSpec *cs : _sorted_standard_cargo_specs) { - list.push_back(std::make_unique(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false)); + list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index())); } return list; @@ -3101,7 +3101,7 @@ struct IndustryCargoesWindow : public Window { DropDownList lst; Dimension d = GetLargestCargoIconSize(); for (const CargoSpec *cs : _sorted_standard_cargo_specs) { - lst.push_back(std::make_unique(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false)); + lst.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index())); } if (!lst.empty()) { int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1; @@ -3115,7 +3115,7 @@ struct IndustryCargoesWindow : public Window { for (IndustryType ind : _sorted_industry_types) { const IndustrySpec *indsp = GetIndustrySpec(ind); if (!indsp->enabled) continue; - lst.push_back(std::make_unique(indsp->name, ind, false)); + lst.push_back(MakeDropDownListStringItem(indsp->name, ind)); } if (!lst.empty()) { int selected = (this->ind_cargo < NUM_INDUSTRYTYPES) ? (int)this->ind_cargo : -1; diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 13e1c76eff..548c29387b 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -72,9 +72,9 @@ static DropDownList BuildVisibilityDropDownList() { DropDownList list; - list.push_back(std::make_unique(STR_NETWORK_SERVER_VISIBILITY_LOCAL, SERVER_GAME_TYPE_LOCAL, false)); - list.push_back(std::make_unique(STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY, SERVER_GAME_TYPE_INVITE_ONLY, false)); - list.push_back(std::make_unique(STR_NETWORK_SERVER_VISIBILITY_PUBLIC, SERVER_GAME_TYPE_PUBLIC, false)); + list.push_back(MakeDropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_LOCAL, SERVER_GAME_TYPE_LOCAL)); + list.push_back(MakeDropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY, SERVER_GAME_TYPE_INVITE_ONLY)); + list.push_back(MakeDropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_PUBLIC, SERVER_GAME_TYPE_PUBLIC)); return list; } @@ -1496,8 +1496,8 @@ private: static void OnClickClientAdmin([[maybe_unused]] NetworkClientListWindow *w, [[maybe_unused]] Point pt, ClientID client_id) { DropDownList list; - list.push_back(std::make_unique(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK, DD_CLIENT_ADMIN_KICK, false)); - list.push_back(std::make_unique(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN, DD_CLIENT_ADMIN_BAN, false)); + list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK, DD_CLIENT_ADMIN_KICK)); + list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN, DD_CLIENT_ADMIN_BAN)); Rect wi_rect; wi_rect.left = pt.x; @@ -1518,8 +1518,8 @@ private: static void OnClickCompanyAdmin([[maybe_unused]] NetworkClientListWindow *w, [[maybe_unused]] Point pt, CompanyID company_id) { DropDownList list; - list.push_back(std::make_unique(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, DD_COMPANY_ADMIN_RESET, NetworkCompanyHasClients(company_id))); - list.push_back(std::make_unique(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK, DD_COMPANY_ADMIN_UNLOCK, !NetworkCompanyIsPassworded(company_id))); + list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, DD_COMPANY_ADMIN_RESET, NetworkCompanyHasClients(company_id))); + list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK, DD_COMPANY_ADMIN_UNLOCK, !NetworkCompanyIsPassworded(company_id))); Rect wi_rect; wi_rect.left = pt.x; diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index d70cfda897..e311fad3c6 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -394,7 +394,7 @@ struct NewGRFParametersWindow : public Window { DropDownList list; for (uint32_t i = par_info.min_value; i <= par_info.max_value; i++) { - list.push_back(std::make_unique(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i, false)); + list.push_back(MakeDropDownListStringItem(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i)); } ShowDropDownListAt(this, std::move(list), old_val, WID_NP_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE); @@ -955,10 +955,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { DropDownList list; /* Add 'None' option for clearing list */ - list.push_back(std::make_unique(STR_NONE, -1, false)); + list.push_back(MakeDropDownListStringItem(STR_NONE, -1)); for (uint i = 0; i < this->grf_presets.size(); i++) { - list.push_back(std::make_unique(this->grf_presets[i], i, false)); + list.push_back(MakeDropDownListStringItem(this->grf_presets[i], i)); } this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window diff --git a/src/order_gui.cpp b/src/order_gui.cpp index f6ee4d9421..95d0d6f941 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1350,7 +1350,7 @@ public: case WID_O_COND_VARIABLE: { DropDownList list; for (uint i = 0; i < lengthof(_order_conditional_variable); i++) { - list.push_back(std::make_unique(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i], false)); + list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i])); } ShowDropDownList(this, std::move(list), this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable(), WID_O_COND_VARIABLE); break; diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 71fc9c6c49..16a0e985b6 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -22,6 +22,7 @@ #include "sound_func.h" #include "company_func.h" #include "dropdown_type.h" +#include "dropdown_func.h" #include "tunnelbridge.h" #include "tilehighlight_func.h" #include "spritecache.h" @@ -2385,7 +2386,7 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) DropDownList list; if (all_option) { - list.push_back(std::make_unique(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE, false)); + list.push_back(MakeDropDownListStringItem(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE)); } Dimension d = { 0, 0 }; @@ -2407,16 +2408,16 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) SetDParam(0, rti->strings.menu_text); SetDParam(1, rti->max_speed); if (for_replacement) { - list.push_back(std::make_unique(rti->strings.replace_text, rt, !HasBit(avail_railtypes, rt))); + list.push_back(MakeDropDownListStringItem(rti->strings.replace_text, rt, !HasBit(avail_railtypes, rt))); } else { StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; - list.push_back(std::make_unique(d, rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt))); + list.push_back(MakeDropDownListIconItem(d, rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt))); } } if (list.empty()) { /* Empty dropdowns are not allowed */ - list.push_back(std::make_unique(STR_NONE, INVALID_RAILTYPE, true)); + list.push_back(MakeDropDownListStringItem(STR_NONE, INVALID_RAILTYPE, true)); } return list; diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 766a3434c4..e966d9b770 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -27,6 +27,8 @@ #include "hotkeys.h" #include "road_gui.h" #include "zoom_func.h" +#include "dropdown_type.h" +#include "dropdown_func.h" #include "engine_base.h" #include "strings_func.h" #include "core/geometry_func.hpp" @@ -1830,7 +1832,7 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b DropDownList list; if (all_option) { - list.push_back(std::make_unique(STR_REPLACE_ALL_ROADTYPE, INVALID_ROADTYPE, false)); + list.push_back(MakeDropDownListStringItem(STR_REPLACE_ALL_ROADTYPE, INVALID_ROADTYPE)); } Dimension d = { 0, 0 }; @@ -1852,16 +1854,16 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b SetDParam(0, rti->strings.menu_text); SetDParam(1, rti->max_speed / 2); if (for_replacement) { - list.push_back(std::make_unique(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt))); + list.push_back(MakeDropDownListStringItem(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt))); } else { StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; - list.push_back(std::make_unique(d, rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt))); + list.push_back(MakeDropDownListIconItem(d, rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt))); } } if (list.empty()) { /* Empty dropdowns are not allowed */ - list.push_back(std::make_unique(STR_NONE, INVALID_ROADTYPE, true)); + list.push_back(MakeDropDownListStringItem(STR_NONE, INVALID_ROADTYPE, true)); } return list; @@ -1894,12 +1896,12 @@ DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts) SetDParam(0, rti->strings.menu_text); SetDParam(1, rti->max_speed / 2); StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; - list.push_back(std::make_unique(d, rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt))); + list.push_back(MakeDropDownListIconItem(d, rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt))); } if (list.empty()) { /* Empty dropdowns are not allowed */ - list.push_back(std::make_unique(STR_NONE, -1, true)); + list.push_back(MakeDropDownListStringItem(STR_NONE, -1, true)); } return list; diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp index d6855bdd6c..21d0a5af0a 100644 --- a/src/script/script_gui.cpp +++ b/src/script/script_gui.cpp @@ -15,9 +15,10 @@ #include "../stringfilter_type.h" #include "../company_base.h" #include "../company_gui.h" +#include "../dropdown_type.h" +#include "../dropdown_func.h" #include "../window_func.h" #include "../network/network.h" -#include "../dropdown_func.h" #include "../hotkeys.h" #include "../company_cmd.h" #include "../misc_cmd.h" @@ -467,7 +468,7 @@ struct ScriptSettingsWindow : public Window { DropDownList list; for (int i = config_item.min_value; i <= config_item.max_value; i++) { - list.push_back(std::make_unique(config_item.labels.find(i)->second, i, false)); + list.push_back(MakeDropDownListStringItem(config_item.labels.find(i)->second, i)); } ShowDropDownListAt(this, std::move(list), old_val, WID_SCRS_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE); diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index bdcc5e5fcd..8c467dc90a 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -126,6 +126,18 @@ void ShowBaseSetTextfileWindow(TextfileType file_type, const TBaseSet *baseset, new BaseSetTextfileWindow(file_type, baseset, content_type); } +template +DropDownList BuildSetDropDownList(int *selected_index) +{ + int n = T::GetNumSets(); + *selected_index = T::GetIndexOfUsedSet(); + DropDownList list; + for (int i = 0; i < n; i++) { + list.push_back(MakeDropDownListStringItem(T::GetSet(i)->GetListLabel(), i)); + } + return list; +} + std::set _refresh_rates = { 30, 60, 75, 90, 100, 120, 144, 240 }; /** @@ -401,18 +413,18 @@ struct GameOptionsWindow : Window { int i = ¤cy - _currency_specs.data(); if (i == CURRENCY_CUSTOM) continue; if (currency.code.empty()) { - list.push_back(std::make_unique(currency.name, i, HasBit(disabled, i))); + list.push_back(MakeDropDownListStringItem(currency.name, i, HasBit(disabled, i))); } else { SetDParam(0, currency.name); SetDParamStr(1, currency.code); - list.push_back(std::make_unique(STR_GAME_OPTIONS_CURRENCY_CODE, i, HasBit(disabled, i))); + list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CODE, i, HasBit(disabled, i))); } } std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); /* Append custom currency at the end */ - list.push_back(std::make_unique(-1, false)); // separator line - list.push_back(std::make_unique(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM))); + list.push_back(MakeDropDownListDividerItem()); // separator line + list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM))); break; } @@ -426,7 +438,7 @@ struct GameOptionsWindow : Window { const StringID *items = _autosave_dropdown; for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) { - list.push_back(std::make_unique(*items, i, false)); + list.push_back(MakeDropDownListStringItem(*items, i)); } break; } @@ -448,7 +460,7 @@ struct GameOptionsWindow : Window { SetDParamStr(0, _languages[i].name); } SetDParam(1, (LANGUAGE_TOTAL_STRINGS - _languages[i].missing) * 100 / LANGUAGE_TOTAL_STRINGS); - list.push_back(std::make_unique(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i, false)); + list.push_back(MakeDropDownListStringItem(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i)); } std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); break; @@ -461,7 +473,7 @@ struct GameOptionsWindow : Window { for (uint i = 0; i < _resolutions.size(); i++) { SetDParam(0, _resolutions[i].width); SetDParam(1, _resolutions[i].height); - list.push_back(std::make_unique(STR_GAME_OPTIONS_RESOLUTION_ITEM, i, false)); + list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_RESOLUTION_ITEM, i)); } break; @@ -470,7 +482,7 @@ struct GameOptionsWindow : Window { auto i = std::distance(_refresh_rates.begin(), it); if (*it == _settings_client.gui.refresh_rate) *selected_index = i; SetDParam(0, *it); - list.push_back(std::make_unique(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i, false)); + list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i)); } break; @@ -2447,15 +2459,15 @@ struct GameSettingsWindow : Window { * we don't want to allow comparing with new game's settings. */ bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame; - list.push_back(std::make_unique(_game_settings_restrict_dropdown[mode], mode, disabled)); + list.push_back(MakeDropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled)); } break; case WID_GS_TYPE_DROPDOWN: - list.push_back(std::make_unique(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false)); - list.push_back(std::make_unique(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME, false)); - list.push_back(std::make_unique(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY, false)); - list.push_back(std::make_unique(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false)); + list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL)); + list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME)); + list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY)); + list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT)); break; } return list; @@ -2620,7 +2632,7 @@ struct GameSettingsWindow : Window { DropDownList list; for (int i = sd->min; i <= (int)sd->max; i++) { sd->SetValueDParams(0, i); - list.push_back(std::make_unique(STR_JUST_STRING2, i, false)); + list.push_back(MakeDropDownListStringItem(STR_JUST_STRING2, i)); } ShowDropDownListAt(this, std::move(list), value, WID_GS_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE); diff --git a/src/settings_gui.h b/src/settings_gui.h index c95345b00a..bca6888ac7 100644 --- a/src/settings_gui.h +++ b/src/settings_gui.h @@ -23,17 +23,7 @@ void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool cl void DrawBoolButton(int x, int y, bool state, bool clickable); template -DropDownList BuildSetDropDownList(int *selected_index) -{ - int n = T::GetNumSets(); - *selected_index = T::GetIndexOfUsedSet(); - DropDownList list; - for (int i = 0; i < n; i++) { - list.push_back(std::make_unique(T::GetSet(i)->GetListLabel(), i, false)); - } - return list; -} - +DropDownList BuildSetDropDownList(int *selected_index); /* Actually implemented in music_gui.cpp */ void ChangeMusicSet(int index); diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 44b90c0714..3f03a1ae68 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -20,6 +20,7 @@ #include "string_func.h" #include "window_func.h" #include "viewport_func.h" +#include "dropdown_type.h" #include "dropdown_func.h" #include "station_base.h" #include "waypoint_base.h" @@ -542,8 +543,8 @@ public: using DropDownListCargoItem = DropDownCheck>; DropDownList list; - list.push_back(std::make_unique(STR_STATION_LIST_CARGO_FILTER_SELECT_ALL, CargoFilterCriteria::CF_SELECT_ALL)); - list.push_back(std::make_unique(-1)); + list.push_back(MakeDropDownListStringItem(STR_STATION_LIST_CARGO_FILTER_SELECT_ALL, CargoFilterCriteria::CF_SELECT_ALL)); + list.push_back(MakeDropDownListDividerItem()); bool any_hidden = false; @@ -565,8 +566,8 @@ public: } if (!expanded && any_hidden) { - if (list.size() > 2) list.push_back(std::make_unique(-1)); - list.push_back(std::make_unique(STR_STATION_LIST_CARGO_FILTER_EXPAND, CargoFilterCriteria::CF_EXPAND_LIST)); + if (list.size() > 2) list.push_back(MakeDropDownListDividerItem()); + list.push_back(MakeDropDownListStringItem(STR_STATION_LIST_CARGO_FILTER_EXPAND, CargoFilterCriteria::CF_EXPAND_LIST)); } return list; diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 61e8e20965..1ed4e950d9 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -253,11 +253,11 @@ protected: for (const StoryPage *p : this->story_pages) { bool current_page = p->index == this->selected_page_id; if (!p->title.empty()) { - list.push_back(std::make_unique(p->title, p->index, current_page)); + list.push_back(MakeDropDownListStringItem(p->title, p->index, current_page)); } else { /* No custom title => use a generic page title with page number. */ SetDParam(0, page_num); - list.push_back(std::make_unique(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page)); + list.push_back(MakeDropDownListStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page)); } page_num++; } diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index 843a28faac..194c3c6a4c 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -16,6 +16,7 @@ #include "string_func.h" #include "textfile_gui.h" #include "dropdown_type.h" +#include "dropdown_func.h" #include "gfx_layout.h" #include "debug.h" #include "openttd.h" @@ -534,7 +535,7 @@ void TextfileWindow::AfterLoadMarkdown() DropDownList list; for (size_t line : this->jumplist) { SetDParamStr(0, this->lines[line].text); - list.push_back(std::make_unique(STR_TEXTFILE_JUMPLIST_ITEM, (int)line, false)); + list.push_back(MakeDropDownListStringItem(STR_TEXTFILE_JUMPLIST_ITEM, (int)line)); } ShowDropDownList(this, std::move(list), -1, widget); break; diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index c45db8a0b6..04d7387cb9 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -13,6 +13,8 @@ #include "window_func.h" #include "viewport_func.h" #include "command_func.h" +#include "dropdown_type.h" +#include "dropdown_func.h" #include "vehicle_gui.h" #include "rail_gui.h" #include "road.h" @@ -127,9 +129,9 @@ static void PopupMainToolbarMenu(Window *w, WidgetID widget, const std::initiali int i = 0; for (StringID string : strings) { if (string == STR_NULL) { - list.push_back(std::make_unique(-1, false)); + list.push_back(MakeDropDownListDividerItem()); } else { - list.push_back(std::make_unique(string, i, false)); + list.push_back(MakeDropDownListStringItem(string, i)); i++; } } @@ -156,18 +158,18 @@ static void PopupMainCompanyToolbMenu(Window *w, WidgetID widget, CompanyMask gr if (!_networking) break; /* Add the client list button for the companies menu */ - list.push_back(std::make_unique(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false)); + list.push_back(MakeDropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST)); if (_local_company != COMPANY_SPECTATOR) { - list.push_back(std::make_unique(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, false)); + list.push_back(MakeDropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE)); } break; case WID_TN_STORY: - list.push_back(std::make_unique(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR, false)); + list.push_back(MakeDropDownListStringItem(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR)); break; case WID_TN_GOAL: - list.push_back(std::make_unique(STR_GOALS_SPECTATOR, CTMN_SPECTATOR, false)); + list.push_back(MakeDropDownListStringItem(STR_GOALS_SPECTATOR, CTMN_SPECTATOR)); break; } @@ -250,30 +252,30 @@ enum OptionMenuEntries { static CallBackFunction ToolbarOptionsClick(Window *w) { DropDownList list; - list.push_back(std::make_unique(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false)); - list.push_back(std::make_unique(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS, false)); + list.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS)); + list.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS)); /* Changes to the per-AI settings don't get send from the server to the clients. Clients get * the settings once they join but never update it. As such don't show the window at all * to network clients. */ if (!_networking || _network_server) { - list.push_back(std::make_unique(STR_SETTINGS_MENU_AI_SETTINGS, OME_AI_SETTINGS, false)); - list.push_back(std::make_unique(STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS, OME_GAMESCRIPT_SETTINGS, false)); + list.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_AI_SETTINGS, OME_AI_SETTINGS)); + list.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS, OME_GAMESCRIPT_SETTINGS)); } - list.push_back(std::make_unique(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false)); + list.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS)); if (_game_mode != GM_EDITOR && !_networking) { - list.push_back(std::make_unique(STR_SETTINGS_MENU_SANDBOX_OPTIONS, OME_SANDBOX, false)); + list.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_SANDBOX_OPTIONS, OME_SANDBOX)); } - list.push_back(std::make_unique(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false)); - list.push_back(std::make_unique(-1, false)); - list.push_back(std::make_unique(HasBit(_display_opt, DO_SHOW_TOWN_NAMES), STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false)); - list.push_back(std::make_unique(HasBit(_display_opt, DO_SHOW_STATION_NAMES), STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false)); - list.push_back(std::make_unique(HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES), STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false)); - list.push_back(std::make_unique(HasBit(_display_opt, DO_SHOW_SIGNS), STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false)); - list.push_back(std::make_unique(HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS), STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false)); - list.push_back(std::make_unique(HasBit(_display_opt, DO_FULL_ANIMATION), STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false)); - list.push_back(std::make_unique(HasBit(_display_opt, DO_FULL_DETAIL), STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false)); - list.push_back(std::make_unique(IsTransparencySet(TO_HOUSES), STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false)); - list.push_back(std::make_unique(IsTransparencySet(TO_SIGNS), STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false)); + list.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES)); + list.push_back(MakeDropDownListDividerItem()); + list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_TOWN_NAMES), STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES)); + list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_STATION_NAMES), STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES)); + list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES), STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES)); + list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_SIGNS), STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS)); + list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS), STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS)); + list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_FULL_ANIMATION), STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION)); + list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_FULL_DETAIL), STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS)); + list.push_back(MakeDropDownListCheckedItem(IsTransparencySet(TO_HOUSES), STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS)); + list.push_back(MakeDropDownListCheckedItem(IsTransparencySet(TO_SIGNS), STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS)); ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); @@ -405,10 +407,10 @@ enum MapMenuEntries { static CallBackFunction ToolbarMapClick(Window *w) { DropDownList list; - list.push_back(std::make_unique(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); - list.push_back(std::make_unique(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false)); - list.push_back(std::make_unique(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false)); - list.push_back(std::make_unique(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); + list.push_back(MakeDropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP)); + list.push_back(MakeDropDownListStringItem(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS)); + list.push_back(MakeDropDownListStringItem(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH)); + list.push_back(MakeDropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS)); PopupMainToolbarMenu(w, WID_TN_SMALL_MAP, std::move(list), 0); return CBF_NONE; } @@ -416,11 +418,11 @@ static CallBackFunction ToolbarMapClick(Window *w) static CallBackFunction ToolbarScenMapTownDir(Window *w) { DropDownList list; - list.push_back(std::make_unique(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); - list.push_back(std::make_unique(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false)); - list.push_back(std::make_unique(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); - list.push_back(std::make_unique(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY, false)); - list.push_back(std::make_unique(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY, false)); + list.push_back(MakeDropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP)); + list.push_back(MakeDropDownListStringItem(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS)); + list.push_back(MakeDropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS)); + list.push_back(MakeDropDownListStringItem(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY)); + list.push_back(MakeDropDownListStringItem(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY)); PopupMainToolbarMenu(w, WID_TE_SMALL_MAP, std::move(list), 0); return CBF_NONE; } @@ -628,13 +630,13 @@ static void AddDropDownLeagueTableOptions(DropDownList &list) { if (LeagueTable::GetNumItems() > 0) { for (LeagueTable *lt : LeagueTable::Iterate()) { - list.push_back(std::make_unique(lt->title, lt->index, false)); + list.push_back(MakeDropDownListStringItem(lt->title, lt->index)); } } else { - list.push_back(std::make_unique(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE, false)); - list.push_back(std::make_unique(STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING, LTMN_PERFORMANCE_RATING, false)); + list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE)); + list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING, LTMN_PERFORMANCE_RATING)); if (!_networking) { - list.push_back(std::make_unique(STR_GRAPH_MENU_HIGHSCORE, LTMN_HIGHSCORE, false)); + list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_HIGHSCORE, LTMN_HIGHSCORE)); } } } @@ -643,12 +645,12 @@ static CallBackFunction ToolbarGraphsClick(Window *w) { DropDownList list; - list.push_back(std::make_unique(STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, GRMN_OPERATING_PROFIT_GRAPH, false)); - list.push_back(std::make_unique(STR_GRAPH_MENU_INCOME_GRAPH, GRMN_INCOME_GRAPH, false)); - list.push_back(std::make_unique(STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH, GRMN_DELIVERED_CARGO_GRAPH, false)); - list.push_back(std::make_unique(STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH, GRMN_PERFORMANCE_HISTORY_GRAPH, false)); - list.push_back(std::make_unique(STR_GRAPH_MENU_COMPANY_VALUE_GRAPH, GRMN_COMPANY_VALUE_GRAPH, false)); - list.push_back(std::make_unique(STR_GRAPH_MENU_CARGO_PAYMENT_RATES, GRMN_CARGO_PAYMENT_RATES, false)); + list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, GRMN_OPERATING_PROFIT_GRAPH)); + list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_INCOME_GRAPH, GRMN_INCOME_GRAPH)); + list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH, GRMN_DELIVERED_CARGO_GRAPH)); + list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH, GRMN_PERFORMANCE_HISTORY_GRAPH)); + list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_COMPANY_VALUE_GRAPH, GRMN_COMPANY_VALUE_GRAPH)); + list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_CARGO_PAYMENT_RATES, GRMN_CARGO_PAYMENT_RATES)); if (_toolbar_mode != TB_NORMAL) AddDropDownLeagueTableOptions(list); @@ -913,7 +915,7 @@ static CallBackFunction MenuClickBuildTram(int index) static CallBackFunction ToolbarBuildWaterClick(Window *w) { DropDownList list; - list.push_back(std::make_unique(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0, false)); + list.push_back(MakeDropDownListIconItem(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0)); ShowDropDownList(w, std::move(list), 0, WID_TN_WATER, 140, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; @@ -935,7 +937,7 @@ static CallBackFunction MenuClickBuildWater(int) static CallBackFunction ToolbarBuildAirClick(Window *w) { DropDownList list; - list.push_back(std::make_unique(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0, false)); + list.push_back(MakeDropDownListIconItem(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0)); ShowDropDownList(w, std::move(list), 0, WID_TN_AIR, 140, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; @@ -957,9 +959,9 @@ static CallBackFunction MenuClickBuildAir(int) static CallBackFunction ToolbarForestClick(Window *w) { DropDownList list; - list.push_back(std::make_unique(SPR_IMG_LANDSCAPING, PAL_NONE, STR_LANDSCAPING_MENU_LANDSCAPING, 0, false)); - list.push_back(std::make_unique(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1, false)); - list.push_back(std::make_unique(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2, false)); + list.push_back(MakeDropDownListIconItem(SPR_IMG_LANDSCAPING, PAL_NONE, STR_LANDSCAPING_MENU_LANDSCAPING, 0)); + list.push_back(MakeDropDownListIconItem(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1)); + list.push_back(MakeDropDownListIconItem(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2)); ShowDropDownList(w, std::move(list), 0, WID_TN_LANDSCAPE, 100, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 0768c64b49..e0f9e0dee5 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -26,6 +26,7 @@ #include "vehicle_func.h" #include "autoreplace_gui.h" #include "string_func.h" +#include "dropdown_type.h" #include "dropdown_func.h" #include "timetable.h" #include "articulated_vehicles.h" @@ -427,17 +428,17 @@ DropDownList BaseVehicleListWindow::BuildCargoDropDownList(bool full) const DropDownList list; /* Add item for disabling filtering. */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false)); + list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY)); /* Add item for freight (i.e. vehicles with cargo capacity and with no passenger capacity). */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_FREIGHT), CargoFilterCriteria::CF_FREIGHT, false)); + list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_FREIGHT), CargoFilterCriteria::CF_FREIGHT)); /* Add item for vehicles not carrying anything, e.g. train engines. */ - list.push_back(std::make_unique(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false)); + list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE)); /* Add cargos */ Dimension d = GetLargestCargoIconSize(); for (const CargoSpec *cs : _sorted_cargo_specs) { if (!full && !HasBit(this->used_cargoes, cs->Index())) continue; - list.push_back(std::make_unique(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false, !HasBit(this->used_cargoes, cs->Index()))); + list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false, !HasBit(this->used_cargoes, cs->Index()))); } return list; @@ -456,23 +457,23 @@ DropDownList BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplac /* Autoreplace actions. */ if (show_autoreplace) { - list.push_back(std::make_unique(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false)); - list.push_back(std::make_unique(-1, false)); + list.push_back(MakeDropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE)); + list.push_back(MakeDropDownListDividerItem()); } /* Group actions. */ if (show_group) { - list.push_back(std::make_unique(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false)); - list.push_back(std::make_unique(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false)); - list.push_back(std::make_unique(-1, false)); + list.push_back(MakeDropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED)); + list.push_back(MakeDropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL)); + list.push_back(MakeDropDownListDividerItem()); } else if (show_create) { - list.push_back(std::make_unique(STR_VEHICLE_LIST_CREATE_GROUP, ADI_CREATE_GROUP, false)); - list.push_back(std::make_unique(-1, false)); + list.push_back(MakeDropDownListStringItem(STR_VEHICLE_LIST_CREATE_GROUP, ADI_CREATE_GROUP)); + list.push_back(MakeDropDownListDividerItem()); } /* Depot actions. */ - list.push_back(std::make_unique(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false)); - list.push_back(std::make_unique(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false)); + list.push_back(MakeDropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE)); + list.push_back(MakeDropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT)); return list; } From 2047c274454090875ad4aab29077370a1f13cdb7 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 31 Mar 2024 17:31:47 +0100 Subject: [PATCH 06/29] Codechange: Move drop down list item definitions to separate header. This reduces the scope of the definitions which are no longer needed to create the common lists. --- src/CMakeLists.txt | 1 + src/company_gui.cpp | 1 + src/dropdown.cpp | 1 + src/dropdown_common_type.h | 178 +++++++++++++++++++++++++++++++++++++ src/dropdown_type.h | 160 --------------------------------- src/genworld_gui.cpp | 1 + src/settings.cpp | 1 + src/settings_gui.cpp | 1 + src/station_gui.cpp | 1 + src/toolbar_gui.cpp | 1 + 10 files changed, 186 insertions(+), 160 deletions(-) create mode 100644 src/dropdown_common_type.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7951048ee0..597c4331f5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -139,6 +139,7 @@ add_files( driver.cpp driver.h dropdown.cpp + dropdown_common_type.h dropdown_func.h dropdown_type.h economy.cpp diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 74ce478601..a72569f1a9 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -24,6 +24,7 @@ #include "strings_func.h" #include "timer/timer_game_economy.h" #include "dropdown_type.h" +#include "dropdown_common_type.h" #include "tilehighlight_func.h" #include "company_base.h" #include "core/geometry_func.hpp" diff --git a/src/dropdown.cpp b/src/dropdown.cpp index 1e334e365e..7c7285a8e8 100644 --- a/src/dropdown.cpp +++ b/src/dropdown.cpp @@ -10,6 +10,7 @@ #include "stdafx.h" #include "dropdown_type.h" #include "dropdown_func.h" +#include "dropdown_common_type.h" #include "strings_func.h" #include "timer/timer.h" #include "timer/timer_window.h" diff --git a/src/dropdown_common_type.h b/src/dropdown_common_type.h new file mode 100644 index 0000000000..a851c216ec --- /dev/null +++ b/src/dropdown_common_type.h @@ -0,0 +1,178 @@ +/* + * 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 dropdown_common_type.h Common drop down list components. */ + +#ifndef DROPDOWN_COMMON_TYPE_H +#define DROPDOWN_COMMON_TYPE_H + +#include "gfx_func.h" +#include "gfx_type.h" +#include "palette_func.h" +#include "string_func.h" +#include "strings_func.h" +#include "table/strings.h" +#include "window_gui.h" + +/** + * Drop down divider component. + * @tparam TBase Base component. + * @tparam TFs Font size -- used to determine height. + */ +template +class DropDownDivider : public TBase { +public: + template + explicit DropDownDivider(Args&&... args) : TBase(std::forward(args)...) {} + + bool Selectable() const override { return false; } + uint Height() const override { return std::max(GetCharacterHeight(TFs), this->TBase::Height()); } + + void Draw(const Rect &full, const Rect &, bool, Colours bg_colour) const override + { + uint8_t c1 = GetColourGradient(bg_colour, SHADE_DARK); + uint8_t c2 = GetColourGradient(bg_colour, SHADE_LIGHTEST); + + int mid = CenterBounds(full.top, full.bottom, 0); + GfxFillRect(full.left, mid - WidgetDimensions::scaled.bevel.bottom, full.right, mid - 1, c1); + GfxFillRect(full.left, mid, full.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2); + } +}; + +/** + * Drop down string component. + * @tparam TBase Base component. + * @tparam TFs Font size. + * @tparam TEnd Position string at end if true, or start if false. + */ +template +class DropDownString : public TBase { + std::string string; ///< String to be drawn. + Dimension dim; ///< Dimensions of string. +public: + template + explicit DropDownString(StringID string, Args&&... args) : TBase(std::forward(args)...) + { + this->SetString(GetString(string)); + } + + template + explicit DropDownString(const std::string &string, Args&&... args) : TBase(std::forward(args)...) + { + SetDParamStr(0, string); + this->SetString(GetString(STR_JUST_RAW_STRING)); + } + + void SetString(std::string &&string) + { + this->string = std::move(string); + this->dim = GetStringBoundingBox(this->string, TFs); + } + + uint Height() const override + { + return std::max(this->dim.height, this->TBase::Height()); + } + + uint Width() const override { return this->dim.width + this->TBase::Width(); } + + void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override + { + bool rtl = TEnd ^ (_current_text_dir == TD_RTL); + DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), this->string, this->GetColour(sel), SA_CENTER, false, TFs); + this->TBase::Draw(full, r.Indent(this->dim.width, rtl), sel, bg_colour); + } + + /** + * Natural sorting comparator function for DropDownList::sort(). + * @param first Left side of comparison. + * @param second Right side of comparison. + * @return true if \a first precedes \a second. + * @warning All items in the list need to be derivates of DropDownListStringItem. + */ + static bool NatSortFunc(std::unique_ptr const &first, std::unique_ptr const &second) + { + const std::string &str1 = static_cast(first.get())->string; + const std::string &str2 = static_cast(second.get())->string; + return StrNaturalCompare(str1, str2) < 0; + } +}; + +/** + * Drop down icon component. + * @tparam TBase Base component. + * @tparam TEnd Position icon at end if true, or start if false. + */ +template +class DropDownIcon : public TBase { + SpriteID sprite; ///< Sprite ID to be drawn. + PaletteID palette; ///< Palette ID to use. + Dimension dsprite; ///< Bounding box dimensions of sprite. + Dimension dbounds; ///< Bounding box dimensions of bounds. +public: + template + explicit DropDownIcon(SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward(args)...), sprite(sprite), palette(palette) + { + this->dsprite = GetSpriteSize(this->sprite); + this->dbounds = this->dsprite; + } + + template + explicit DropDownIcon(const Dimension &dim, SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward(args)...), sprite(sprite), palette(palette), dbounds(dim) + { + this->dsprite = GetSpriteSize(this->sprite); + } + + uint Height() const override { return std::max(this->dbounds.height, this->TBase::Height()); } + uint Width() const override { return this->dbounds.width + WidgetDimensions::scaled.hsep_normal + this->TBase::Width(); } + + void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override + { + bool rtl = TEnd ^ (_current_text_dir == TD_RTL); + Rect ir = r.WithWidth(this->dbounds.width, rtl); + DrawSprite(this->sprite, this->palette, CenterBounds(ir.left, ir.right, this->dsprite.width), CenterBounds(r.top, r.bottom, this->dsprite.height)); + this->TBase::Draw(full, r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), sel, bg_colour); + } +}; + +/** + * Drop down checkmark component. + * @tparam TBase Base component. + * @tparam TFs Font size. + * @tparam TEnd Position checkmark at end if true, or start if false. + */ +template +class DropDownCheck : public TBase { + bool checked; ///< Is item checked. + Dimension dim; ///< Dimension of checkmark. +public: + template + explicit DropDownCheck(bool checked, Args&&... args) : TBase(std::forward(args)...), checked(checked) + { + this->dim = GetStringBoundingBox(STR_JUST_CHECKMARK, TFs); + } + + uint Height() const override { return std::max(this->dim.height, this->TBase::Height()); } + uint Width() const override { return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); } + + void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override + { + bool rtl = TEnd ^ (_current_text_dir == TD_RTL); + if (this->checked) { + DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), STR_JUST_CHECKMARK, this->GetColour(sel), SA_CENTER, false, TFs); + } + this->TBase::Draw(full, r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), sel, bg_colour); + } +}; + +/* Commonly used drop down list items. */ +using DropDownListDividerItem = DropDownDivider; +using DropDownListStringItem = DropDownString; +using DropDownListIconItem = DropDownIcon>; +using DropDownListCheckedItem = DropDownCheck>; + +#endif /* DROPDOWN_COMMON_TYPE_H */ diff --git a/src/dropdown_type.h b/src/dropdown_type.h index fd102b43f2..1a6cb71eb1 100644 --- a/src/dropdown_type.h +++ b/src/dropdown_type.h @@ -14,9 +14,6 @@ #include "gfx_func.h" #include "gfx_type.h" #include "palette_func.h" -#include "string_func.h" -#include "strings_func.h" -#include "table/strings.h" #include "window_gui.h" /** @@ -47,163 +44,6 @@ public: } }; -/** - * Drop down divider component. - * @tparam TBase Base component. - * @tparam TFs Font size -- used to determine height. - */ -template -class DropDownDivider : public TBase { -public: - template - explicit DropDownDivider(Args&&... args) : TBase(std::forward(args)...) {} - - bool Selectable() const override { return false; } - uint Height() const override { return std::max(GetCharacterHeight(TFs), this->TBase::Height()); } - - void Draw(const Rect &full, const Rect &, bool, Colours bg_colour) const override - { - uint8_t c1 = GetColourGradient(bg_colour, SHADE_DARK); - uint8_t c2 = GetColourGradient(bg_colour, SHADE_LIGHTEST); - - int mid = CenterBounds(full.top, full.bottom, 0); - GfxFillRect(full.left, mid - WidgetDimensions::scaled.bevel.bottom, full.right, mid - 1, c1); - GfxFillRect(full.left, mid, full.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2); - } -}; - -/** - * Drop down string component. - * @tparam TBase Base component. - * @tparam TFs Font size. - * @tparam TEnd Position string at end if true, or start if false. - */ -template -class DropDownString : public TBase { - std::string string; ///< String to be drawn. - Dimension dim; ///< Dimensions of string. -public: - template - explicit DropDownString(StringID string, Args&&... args) : TBase(std::forward(args)...) - { - this->SetString(GetString(string)); - } - - template - explicit DropDownString(const std::string &string, Args&&... args) : TBase(std::forward(args)...) - { - SetDParamStr(0, string); - this->SetString(GetString(STR_JUST_RAW_STRING)); - } - - void SetString(std::string &&string) - { - this->string = std::move(string); - this->dim = GetStringBoundingBox(this->string, TFs); - } - - uint Height() const override - { - return std::max(this->dim.height, this->TBase::Height()); - } - - uint Width() const override { return this->dim.width + this->TBase::Width(); } - - void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override - { - bool rtl = TEnd ^ (_current_text_dir == TD_RTL); - DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), this->string, this->GetColour(sel), SA_CENTER, false, TFs); - this->TBase::Draw(full, r.Indent(this->dim.width, rtl), sel, bg_colour); - } - - /** - * Natural sorting comparator function for DropDownList::sort(). - * @param first Left side of comparison. - * @param second Right side of comparison. - * @return true if \a first precedes \a second. - * @warning All items in the list need to be derivates of DropDownListStringItem. - */ - static bool NatSortFunc(std::unique_ptr const &first, std::unique_ptr const &second) - { - const std::string &str1 = static_cast(first.get())->string; - const std::string &str2 = static_cast(second.get())->string; - return StrNaturalCompare(str1, str2) < 0; - } -}; - -/** - * Drop down icon component. - * @tparam TBase Base component. - * @tparam TEnd Position icon at end if true, or start if false. - */ -template -class DropDownIcon : public TBase { - SpriteID sprite; ///< Sprite ID to be drawn. - PaletteID palette; ///< Palette ID to use. - Dimension dsprite; ///< Bounding box dimensions of sprite. - Dimension dbounds; ///< Bounding box dimensions of bounds. -public: - template - explicit DropDownIcon(SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward(args)...), sprite(sprite), palette(palette) - { - this->dsprite = GetSpriteSize(this->sprite); - this->dbounds = this->dsprite; - } - - template - explicit DropDownIcon(const Dimension &dim, SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward(args)...), sprite(sprite), palette(palette), dbounds(dim) - { - this->dsprite = GetSpriteSize(this->sprite); - } - - uint Height() const override { return std::max(this->dbounds.height, this->TBase::Height()); } - uint Width() const override { return this->dbounds.width + WidgetDimensions::scaled.hsep_normal + this->TBase::Width(); } - - void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override - { - bool rtl = TEnd ^ (_current_text_dir == TD_RTL); - Rect ir = r.WithWidth(this->dbounds.width, rtl); - DrawSprite(this->sprite, this->palette, CenterBounds(ir.left, ir.right, this->dsprite.width), CenterBounds(r.top, r.bottom, this->dsprite.height)); - this->TBase::Draw(full, r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), sel, bg_colour); - } -}; - -/** - * Drop down checkmark component. - * @tparam TBase Base component. - * @tparam TFs Font size. - * @tparam TEnd Position checkmark at end if true, or start if false. - */ -template -class DropDownCheck : public TBase { - bool checked; ///< Is item checked. - Dimension dim; ///< Dimension of checkmark. -public: - template - explicit DropDownCheck(bool checked, Args&&... args) : TBase(std::forward(args)...), checked(checked) - { - this->dim = GetStringBoundingBox(STR_JUST_CHECKMARK, TFs); - } - - uint Height() const override { return std::max(this->dim.height, this->TBase::Height()); } - uint Width() const override { return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); } - - void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override - { - bool rtl = TEnd ^ (_current_text_dir == TD_RTL); - if (this->checked) { - DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), STR_JUST_CHECKMARK, this->GetColour(sel), SA_CENTER, false, TFs); - } - this->TBase::Draw(full, r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), sel, bg_colour); - } -}; - -/* Commonly used drop down list items. */ -using DropDownListDividerItem = DropDownDivider; -using DropDownListStringItem = DropDownString; -using DropDownListIconItem = DropDownIcon>; -using DropDownListCheckedItem = DropDownCheck>; - /** * A drop down list is a collection of drop down list items. */ diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 723df35436..8c34d91f8e 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -19,6 +19,7 @@ #include "fios.h" #include "string_func.h" #include "dropdown_type.h" +#include "dropdown_common_type.h" #include "dropdown_func.h" #include "querystring_gui.h" #include "town.h" diff --git a/src/settings.cpp b/src/settings.cpp index 6ba8df735e..bb4f0966d6 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -32,6 +32,7 @@ #include "command_func.h" #include "console_func.h" #include "genworld.h" +#include "string_func.h" #include "window_func.h" #include "company_func.h" #include "rev.h" diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 8c467dc90a..6304b7771e 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -21,6 +21,7 @@ #include "string_func.h" #include "dropdown_type.h" #include "dropdown_func.h" +#include "dropdown_common_type.h" #include "slider_func.h" #include "highscore.h" #include "base_media_base.h" diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 3f03a1ae68..a9c45fb5da 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -21,6 +21,7 @@ #include "window_func.h" #include "viewport_func.h" #include "dropdown_type.h" +#include "dropdown_common_type.h" #include "dropdown_func.h" #include "station_base.h" #include "waypoint_base.h" diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 04d7387cb9..26fcfa798d 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -15,6 +15,7 @@ #include "command_func.h" #include "dropdown_type.h" #include "dropdown_func.h" +#include "dropdown_common_type.h" #include "vehicle_gui.h" #include "rail_gui.h" #include "road.h" From 72b5c6a5918ebe9568db1c4cd7c648086099ee4f Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 2 Apr 2024 04:41:36 +0000 Subject: [PATCH 07/29] Update: Translations from eints vietnamese: 1 change by KhoiCanDev greek: 83 changes by gh658804 german: 3 changes by Wuzzy2 ukrainian: 54 changes by Quantom2 spanish: 4 changes by MontyMontana portuguese (brazilian): 2 changes by pasantoro --- src/lang/afrikaans.txt | 2 - src/lang/arabic_egypt.txt | 2 - src/lang/basque.txt | 2 - src/lang/belarusian.txt | 2 - src/lang/brazilian_portuguese.txt | 6 +- src/lang/bulgarian.txt | 2 - src/lang/catalan.txt | 2 - src/lang/croatian.txt | 2 - src/lang/czech.txt | 2 - src/lang/danish.txt | 2 - src/lang/dutch.txt | 2 - src/lang/english_AU.txt | 2 - src/lang/english_US.txt | 2 - src/lang/esperanto.txt | 2 - src/lang/estonian.txt | 2 - src/lang/faroese.txt | 2 - src/lang/finnish.txt | 2 - src/lang/french.txt | 2 - src/lang/frisian.txt | 2 - src/lang/gaelic.txt | 2 - src/lang/galician.txt | 2 - src/lang/german.txt | 8 +- src/lang/greek.txt | 168 +++++++++++++++--------------- src/lang/hebrew.txt | 2 - src/lang/hungarian.txt | 2 - src/lang/icelandic.txt | 2 - src/lang/indonesian.txt | 2 - src/lang/irish.txt | 2 - src/lang/italian.txt | 2 - src/lang/japanese.txt | 2 - src/lang/korean.txt | 2 - src/lang/latin.txt | 2 - src/lang/latvian.txt | 2 - src/lang/lithuanian.txt | 2 - src/lang/luxembourgish.txt | 2 - src/lang/malay.txt | 2 - src/lang/norwegian_bokmal.txt | 2 - src/lang/norwegian_nynorsk.txt | 2 - src/lang/persian.txt | 2 - src/lang/polish.txt | 2 - src/lang/portuguese.txt | 2 - src/lang/romanian.txt | 2 - src/lang/russian.txt | 2 - src/lang/serbian.txt | 2 - src/lang/simplified_chinese.txt | 2 - src/lang/slovak.txt | 2 - src/lang/slovenian.txt | 2 - src/lang/spanish.txt | 10 +- src/lang/spanish_MX.txt | 2 - src/lang/swedish.txt | 2 - src/lang/tamil.txt | 2 - src/lang/thai.txt | 2 - src/lang/traditional_chinese.txt | 2 - src/lang/turkish.txt | 2 - src/lang/ukrainian.txt | 110 ++++++++++--------- src/lang/vietnamese.txt | 4 +- src/lang/welsh.txt | 2 - 57 files changed, 147 insertions(+), 261 deletions(-) diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index 1464775f3b..39c3d41dfa 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -4258,9 +4258,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Beraamde STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Stoor van speletjie is nog besig,{}wag asb tot dit klaar is! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Outostoor het misluk STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan nie skyf lees nie -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Speletjie Spaar Misluk{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan nie lêer uitvee nie -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Speletjie Laai Misluk{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interne fout: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Gebreekte gespaarde spel - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spaarspeletjie is gemaak met nuwer uitgawe diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 8372a2ecfa..9a0bbec625 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -4058,9 +4058,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}الدخ STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}الحفظ مازال جاريا الآن{}الرجاء الأنتظار حتر ينتهي STR_ERROR_AUTOSAVE_FAILED :{WHITE}فشل الحفظ التلقائي STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}لا يمكن قرائة القرص -STR_ERROR_GAME_SAVE_FAILED :{WHITE}فشل حفظ اللعبة{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}لا يمكن حذف الملف -STR_ERROR_GAME_LOAD_FAILED :{WHITE}فشل فتح اللعبة{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :خطأ داخلي: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :لعبه محفوظه غير صالحه - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :اللعبة حفظت بنسخة أحدث diff --git a/src/lang/basque.txt b/src/lang/basque.txt index 1cf05d136b..bfbd18e830 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -4014,9 +4014,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Gutxi go STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Oraindik artxiboa gordetzen,{}mesedez itxaron amaitu arte! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Gordetze automatikoak huts egin du STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Ezin izan da driverra irakurri -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Jokoa gordetzeak huts egin du{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Ezin izan da artxiboa ezabatu -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Jokoa kargatzeak huts egin du{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Barne akatsa: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Gordetako jokoa hautsia dago - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Gordetako jokoa bertsio berriago batekin egin da diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 70152eab27..7f2ed1e1b9 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -5250,9 +5250,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Мерк STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Ідзе захаваньне,{}калі ласка, дачакайцеся завяршэньня! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Памылка аўтазахаваньня STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Не атрымалася прачытаць дыск -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Немагчыма захаваць гульню{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Немагчыма выдаліць файл -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Немагчыма загрузіць гульню{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Унутраная памылка: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Файл пашкоджаны — {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Захаваньне зроблена ў больш новай вэрсіі diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 609943fac6..aa8b7d6a99 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -668,7 +668,7 @@ STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total: STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP_YEARS :{BLACK}Número de veículos que geraram lucro no último ano. Isso inclui veículos rodoviários, trens, embarcações e aeronaves STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP_PERIODS :{BLACK}Número de veículos que geraram lucro no último período. Isso inclui veículos rodoviários, trens, embarcações e aeronaves -STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Número de estações atendidas recentemente. Estações de trem, paradas de ônibus, aeroportos, etc. são contados separadamente, mesmo que pertençam à mesma estação +STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Número de estações atendidas recentemente. Estações de trem, paradas de ônibus, aeroportos, etc., são contados separadamente, mesmo que pertençam à mesma estação STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP_YEARS :{BLACK}Lucro do veículo com o menor rendimento (apenas veículos com mais de dois anos são considerados) STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP_PERIODS :{BLACK}Lucro do veículo com o menor rendimento (apenas veículos com mais de dois períodos são considerados) STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Quantia de dinheiro obtida no trimestre com o menor lucro dos últimos 12 trimestres @@ -1749,7 +1749,7 @@ STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION :Mostrar caminho STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT :Usar uma cor diferente nos trajetos reservados para auxiliar na solução de problemas com trens que se recusam a entrar em seções controlados por sinais de caminho STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :Manter as ferramentas de construção ativas após o uso: {STRING} -STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Manter as ferramentas de construção de pontes, túneis, etc. abertas após o uso +STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Manter as ferramentas de construção de pontes, túneis, etc., abertas após o uso STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :Remover automaticamente os sinais durante a construção de ferrovias: {STRING} STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT :Remover automaticamente os sinais durante a construção de ferrovias se os sinais estiverem no caminho. Isso pode, potencialmente, causar acidentes de trens @@ -4900,9 +4900,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Receita STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Gravação ainda sendo executada,{}por favor aguarde até terminar! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Salvamento automático falhou STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Não é possível ler a unidade -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Salvar Jogo Falhou{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Não é possível apagar o arquivo -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Abrir Jogo Falhou{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Erro interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Jogo salvo está corrompido - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Jogo salvo foi feito com uma versão mais recente diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index b87e821ef3..a4d9052309 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -4290,9 +4290,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Приб STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Записването продължава,{}моля изчакайте да сръши! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Автозапазването е неуспешно STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Не може да прочете диска -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Запазването на играта е неуспешно{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Изтриването на файла е неуспешно -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Отварянето на играта е неуспешно{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Вътрешна грешка: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Запазената игра е повредена - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Запазената игра е направена от по-нова версия diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index d7d186a725..113987983f 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -4900,9 +4900,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Ingresso STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Es desa la partida.{}Espera que acabi l'operació! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Ha fallat el desat automàtic STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Impossible llegir la unitat de disc -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Error guardant la partida{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Impossible esborrar l'arxiu -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Error carregant la partida{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Error Intern: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :L'arxiu de la partida està corromput - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :La partida està desada amb una versió més moderna diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 724e182ef3..1b4c9abb6f 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -4444,9 +4444,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Predviđ STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Spremanje još u tijeku,{}molimo pričekajte dok se ne završi! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatsko spremanje neuspješno STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Ne mogu pročitati disk -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Spremanje igre nije uspjelo{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Ne mogu obrisati datoteku -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Učitavanje igre nije uspjelo{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interna greška: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Pokvarena spremljena igra - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spremljena igra je stvorena s novijom verzijom diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 7789f85d76..bab4f69f32 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -4988,9 +4988,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Odhadova STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Ukládání ještě běží,{}počkej prosím, než doběhne! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatické uložení selhalo STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Nelze číst z jednotky -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Uložení hry selhalo{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Nelze smazat soubor -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Nelze otevřít hru{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Vnitřní chyba: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Poškozená hra - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Uložená hra je z novější verze diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 144d89d38b..6ac32bfd39 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -4899,9 +4899,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Anslået STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Gemmer stadig,{}vent venligst! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Fejl under autogem STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan ikke læse drevet -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Fejl under gemning af spil{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan ikke slette fil -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Fejl under indlæsning af spil{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Intern fejl: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Ødelagt gemt spil - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spillet er gemt med en nyere version diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index ec62376bf9..32c7857259 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -4899,9 +4899,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Verwacht STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Opslaan van spel is nog bezig,{}Wacht tot dit voltooid is! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatisch opslaan mislukt STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan niet lezen van schijf -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Opslaan spel mislukt{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan bestand niet verwijderen -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Laden spel mislukt{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interne fout: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Opgeslagen spel beschadigd - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Opgeslagen spel hoort bij een nieuwere versie diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 7a041367d2..9f4762c403 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -4899,9 +4899,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Estimate STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Saving still in progress,{}please wait until it is finished! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autosave failed STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Unable to read drive -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Game Save Failed{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Unable to delete file -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Game Load Failed{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Internal error: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Broken savegame - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Savegame is made with newer version diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 13fba7db15..f2e68f6a6e 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -4899,9 +4899,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Estimate STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Saving still in progress,{}please wait until it is finished! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autosave failed STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Unable to read drive -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Game Save Failed{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Unable to delete file -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Game Load Failed{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Internal error: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Broken savegame - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Savegame is made with newer version diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index 56e91dbcf5..a9c026defe 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -4772,9 +4772,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Atendata STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Ankoraŭ konservas,{}bv atendi ĝis finiĝo! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Fiaskis aŭtomate konservi STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Ne eblas legi diskon -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Ludkonservado Fiaskis{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Ne eblas forviŝi dosieron -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Ludŝarĝado Fiaskis{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interna eraro: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Rompa konservludo - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Tiu ĉi ludo estis konservita per pli nova versio diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index db972c203b..da14456b8d 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -4953,9 +4953,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Eeldatav STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Ikka salvestamisel,{}palun oota salvestuse lõpuni! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Välpsalvestus ebaõnnestus STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Ei suuda kettalt lugeda -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Mängu salvestamine nurjus{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Faili ei saa kustutada -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Mängu laadimine nurjus{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Süsteemi viga: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Katkine salvestus - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Salvestus on tehtud uuemas osas diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 64d5129a6b..de440942b3 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -3673,9 +3673,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Inntøku STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Goyming er enn í gongd,{}vinarliga bíða til ta er liðugt! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Sjálvgoymsla eydnaðist ikki STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Ikki ført fyri at lesa drev -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Eydnaðist ikki at goyma spæl{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Ikki ført fyri at strika fílu -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Eydnaðist ikki at heinta spæl{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Innanhýsis villa: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Goymda spæli er broti - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Goymda spæli er frá nýggjari útgávu diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index b2c3a9f219..e8dc798d97 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -4899,9 +4899,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Arvioitu STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Tallentaminen käynnissä,{}odota, kunnes se päättyy! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automaattitallennus epäonnistui. STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Asemaa ei voi lukea. -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Tallennus epäonnistui.{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Tiedostoa ei voi poistaa. -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Lataus epäonnistui.{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Sisäinen virhe: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Viallinen tallennus – {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Tallennus on tehty uudemmalla versiolla diff --git a/src/lang/french.txt b/src/lang/french.txt index 88351d273f..bf07d3f45a 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -4900,9 +4900,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Revenu e STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Sauvegarde en cours...{}Veuillez attendre la fin du processus{NBSP}! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Échec de l'enregistrement automatique STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Impossible d'accéder au disque -STR_ERROR_GAME_SAVE_FAILED :{WHITE}La sauvegarde a échoué{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Impossible de supprimer le fichier -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Le chargement a échoué{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Erreur interne{NBSP}: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Sauvegarde corrompue − {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Sauvegarde modifiée avec une version plus récente diff --git a/src/lang/frisian.txt b/src/lang/frisian.txt index fd4860a2ac..b0c7608282 100644 --- a/src/lang/frisian.txt +++ b/src/lang/frisian.txt @@ -3861,9 +3861,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Dit gjit STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Spul noch an it bewarjen,{}graach nog efkes geduld! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatysk opslaan net slagge STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Koe net fan 'e skiif lêze -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Opslaan Mislearre{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kin bestân net fuortsmite -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Laden Mislearre{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interne flater: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Stikkene savegame - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spul is makke mei in neiere fersje diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index c164597285..59b87fb62d 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -4401,9 +4401,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Tuairmse STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Ga shàbhaladh fhathast,{}fuirich greis gus am bi e deiseil! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Dh’fhàillig leis an fhèin-shàbhaladh STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Cha ghabh an draibh leughadh -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Dh’fhàillig le sàbhaladh a’ gheama{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Cha ghabh am faidhle sguabadh às -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Dh’fhàillig le luchdadh a’ gheama{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Mearachd taobh a-staigh: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Tha an geama air shàbhaladh briste - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Chaidh an sàbhaladh seo a dhèanamh le tionndadh as ùire dhen gheama diff --git a/src/lang/galician.txt b/src/lang/galician.txt index dfd284472d..86dd8f30c6 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -4898,9 +4898,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Ingreso STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Gravación en progreso,{}por favor agarda ata que remate! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autogravado fallido STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}No se pode lee-la unidade -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Gravación da partida fallida{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Non se pode borra-lo arquivo -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Carga da partida fallida{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Erro interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Partida gravada corrupta - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :A partida gravouse cunha versión máis nova do xogo diff --git a/src/lang/german.txt b/src/lang/german.txt index db7508884e..73a9b4d2b0 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -4450,10 +4450,10 @@ STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kapazit STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer-Einnahmen: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS :{BLACK}Wartungsintervall: {LTBLUE}{COMMA}{NBSP}Tag{P "" e} {BLACK} {STRING} -STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES :{BLACK}Wartungsintervall: {LTBLUE}{COMMA}{NBSP}Minute{P "" n}{BLACK} {STRING} +STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES :{BLACK}Wartungsintervall: {LTBLUE}{COMMA}{NBSP}Minuten{BLACK} {STRING} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Wartungsintervall: {LTBLUE}{COMMA}%{BLACK} {STRING} STR_VEHICLE_DETAILS_LAST_SERVICE_DATE :Zuletzt gewartet: {LTBLUE}{DATE_LONG} -STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO :Zuletzt gewartet: vor {LTBLUE}{NUM} Minuten +STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO :Zuletzt gewartet: vor {LTBLUE}{NUM} Minute{P "" n} STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_DAYS :{BLACK}Erhöhe Serviceintervall um 10 Tage. Strg+Klick um das Serviceintervall um 5 Tage zu erhöhen STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_MINUTES :{BLACK}Erhöhe Serviceintervall um 5 Minuten. Strg+Klick um das Serviceintervall um 1 Minute zu erhöhen STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_PERCENT :{BLACK}Erhöhe Serviceintervall um 10 Prozent. Strg+Klick um das Serviceintervall um 5 Prozent zu erhöhen @@ -4644,7 +4644,7 @@ STR_ORDER_REFIT_ORDER :(auf {STRING} u STR_ORDER_REFIT_STOP_ORDER :(auf {STRING} umrüsten und stoppen) STR_ORDER_STOP_ORDER :(Stopp) -STR_ORDER_WAIT_TO_UNBUNCH :(warte auf Entpulkung) +STR_ORDER_WAIT_TO_UNBUNCH :(Warte auf Entpulkung) STR_ORDER_GO_TO_STATION :{STRING} {STATION} {STRING} STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(Station unbenutzbar){POP_COLOUR} {STRING} {STATION} {STRING} @@ -4900,9 +4900,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Geschät STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Speichern läuft,{}bitte warten, bis es beendet ist! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autosicherung fehlgeschlagen STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Laufwerk nicht betriebsbereit -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Spielspeicherung fehlgeschlagen{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Datei kann nicht gelöscht werden -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Laden des Spieles fehlgeschlagen{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interner Fehler: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Spielstandsdatei defekt – {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spielstand wurde mit einer neueren Spielversion erstellt diff --git a/src/lang/greek.txt b/src/lang/greek.txt index e03ed82e41..18af4e3dd8 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -344,7 +344,7 @@ STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Κλεί STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Τίτλος παραθύρου - σύρετε το για να το μετακινήσετε STR_TOOLTIP_SHADE :{BLACK}Σκίαση παραθύρου - Εμφάνιση μόνο της μπάρας τιτλου STR_TOOLTIP_DEBUG :{BLACK}Εμφάνιση πληροφοριών αποσφαλμάτωσης για NewGRF -STR_TOOLTIP_DEFSIZE :{BLACK}Κλιμακώνει το παράθυρο στο προκαθορισμένο μέγεθος. Με Ctrl+Click αποθηκεύεται το τρέχον μέγεθος ως προκαθορισμένο +STR_TOOLTIP_DEFSIZE :{BLACK}Κλιμακώνει το παράθυρο στο προκαθορισμένο μέγεθος. Με Ctrl+Κλικ αποθηκεύεται το τρέχον μέγεθος ως προκαθορισμένο STR_TOOLTIP_STICKY :{BLACK}Σημειώστε αυτό το παραθύρο ωστέ να μην κλείνει από το πλήκτρο «Κλείσιμο Όλων των Παραθύρων». Πατήστε Ctrl+Κλικ για να αποθηκεύσετε την κατάσταση απο επιλογή STR_TOOLTIP_RESIZE :{BLACK}Κάντε κλίκ και σύρετε για να αλλάξετε το μέγεθος του παραθύρου STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Εναλλαγή μεγάλου/μικρού παραθύρου @@ -972,7 +972,7 @@ STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_OIL :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM :{BIG_FONT}{BLACK}Βελτιωμένες μέθοδοι καλλιέργειας στην {INDUSTRY} αναμένονται να διπλασιάσουν την παραγωγή! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK} Η παραγωγή {STRING.geniki} στ{G o η ο} {INDUSTRY} αυξήθηκε κατά {COMMA}%! STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL :{BIG_FONT}{BLACK}Η παραγωγή στ{G o η ο} {INDUSTRY} μειώθηκε κατά 50% -STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM :{BIG_FONT}{BLACK}Μόλυνση από έντομα προκαλεί καταστροφή στη {INDUSTRY}!{}Η παραγωγή μειώθηκε κατά 50% +STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM :{BIG_FONT}{BLACK}Προσβολή από έντομα προκαλεί καταστροφή στη {INDUSTRY}!{}Η παραγωγή μειώθηκε κατά 50% STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK} Η παραγωγή {STRING.geniki} στ{G o η ο} {INDUSTRY} μειώθηκε κατά {COMMA}%! ###length VEHICLE_TYPES @@ -1460,13 +1460,13 @@ STR_CONFIG_SETTING_INFLATION :Πληθωρι STR_CONFIG_SETTING_INFLATION_HELPTEXT :Ενεργοποίηση του πληθωρισμού στην οικονομία, όπου τα κόστη αυξάνονται ελάχιστα ταχύτερα από τις πληρωμές STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH :Μέγιστο μήκος γέφυρας: {STRING} -STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH_HELPTEXT :Μέγιστο μήκος για κτίσιμο γεφυρών +STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH_HELPTEXT :Μέγιστο μήκος για κατασκευή γεφυρών STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT :Μέγιστο ύψος γέφυρας: {STRING} -STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT_HELPTEXT :Μέγιστο ύψος για το χτίσιμο γεφυρών +STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT_HELPTEXT :Μέγιστο ύψος για την κατασκευή γεφυρών STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH :Μέγιστο μήκος σήραγγας: {STRING} -STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :Μέγιστο μήκος για κτίσιμο συράγγων +STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :Μέγιστο μήκος για κατασκευή σηράγγων STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :Χειροκίνητη μέθοδος κατασκευής βιομηχανιών πρώτων υλών: {STRING} STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :Μέθοδος χρηματοδότησης πρωτογενούς βιομηχανίας. «Καμία» σημαίνει ότι δεν γίνεται να χρηματοδοτηθεί καμία βιομηχανία, «Αναζήτηση» σημαίνει ότι η χρηματοδότηση είναι εφικτή, αλλά η κατασκευή πραγματοποιείται σε τυχαίο σημείο του χάρτη και είναι πιθανό να αποτύχει, «Όπως οι άλλες βιομηχανίες» σημαίνει πως οι πρωτογενείς βιομηχανίες είναι εφικτό να κατασκευαστούν από εταιρείες όπως οι δευτερογενείς βιομηχανίες σε οποιαδήποτε θέση θέλουν @@ -1476,7 +1476,7 @@ STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NORMAL :Όπως οι STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_PROSPECTING :Διερεύνηση προοπτικών STR_CONFIG_SETTING_INDUSTRY_PLATFORM :Επίπεδη περιοχή γύρω από βιομηχανίες: {STRING} -STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :Επίπεδος χώρος γύρω από μια βιομηχανία. Αυτό εξασφαλίζει ότι θα παραμείνει διαθέσιμος κενός χώρος γύρω από μια βιομηχανία για να κτισθούν γραμμές, κλπ +STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :Επίπεδος χώρος γύρω από μια βιομηχανία. Αυτό εξασφαλίζει ότι θα παραμείνει διαθέσιμος κενός χώρος γύρω από μια βιομηχανία για να κατασκευαστούν γραμμές, κλπ STR_CONFIG_SETTING_MULTIPINDTOWN :Επιτρέπονται πολλαπλές όμοιες βιομηχανίες ανά πόλη: {STRING} STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :Συνήθως, μια πόλη δεν επιθυμεί περισσότερες από μία βιομηχανία κάθε είδους. Αυτή η ρύθμιση επιτρέπει περισσότερες βιομηχανίες του ίδιου είδους στην ίδια πόλη. @@ -2018,7 +2018,7 @@ STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA} τετ STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :Όταν σύρετε, διατηρείται σταθερή απόσταση μεταξύ των σημάτων: {STRING} STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Επιλέξτε τη συμπεριφορά της τοποθέτησης σημάτων όταν πατάτε Ctrl και σύρετε. Όταν είναι απενεργοποιημένο, τα σήματα τοποθετούνται γύρω από σήραγγες και γέφυρες για να αποφεύγονται μεγάλα τμήματα χωρίς σήματα. Όταν είναι ενεργοποιημένο, τα σήματα τοποθετούνται κάθε n τετραγωνίδια, κάνοντας ευκολότερη την ευθυγράμμιση των σημάτων σε παράλληλες γραμμές -STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Αυτόματο κτίσιμο σηματοφόρων πριν από το: {STRING} +STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Αυτόματη κατασκευή σηματοφόρων πριν από το: {STRING} STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Ορίζεται το έτος κατά το οποίο θα χρησιμοποιούνται τα ηλεκτρικά σήματα στις σιδηροτροχιές. Πριν από αυτό, θα χρησιμοποιούνται μηχανικά σήματα (που έχουν ακριβώς την ίδια λειτουργία, αλλά έχουν διαφορετική μορφή) STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Περιήγηση στους τύπους σηματοδότησης: {STRING} @@ -2042,9 +2042,9 @@ STR_CONFIG_SETTING_TOWN_LAYOUT_2X2_GRID :πλέγμα 2x STR_CONFIG_SETTING_TOWN_LAYOUT_3X3_GRID :πλέγμα 3x3 STR_CONFIG_SETTING_TOWN_LAYOUT_RANDOM :Τυχαίο -STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :Οι πόλεις επιτρέπεται να χτίσουν δρόμους: {STRING} +STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :Οι πόλεις επιτρέπεται να κατασκευάζουν δρόμους: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Επιτρέπεται στις πόλεις να κατασκευάζουν δρόμους για ανάπτυξη. Απενεργοποιήστε για να αποτρέπονται οι τοπικές αρχές από την αυτόνομη κατασκευή δρόμων -STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Οι πόλεις επιτρέπουν το κτίσιμο ισόπεδων διασταυρώσεων: {STRING} +STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Οι πόλεις επιτρέπουν την κατασκευή ισόπεδων διασταυρώσεων: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Ενεργοποιώντας αυτήν τη ρύθμιση επιτρέπει στις πόλεις να κατασκευάζουν επίπεδες διαβάσεις STR_CONFIG_SETTING_NOISE_LEVEL :Περιορισμός τοποθέτησης αεροδρομίων ανάλογα με το επίπεδο θορύβου: {STRING} @@ -2755,7 +2755,7 @@ STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP :{BLACK}Μαρκ STR_CONTENT_UNSELECT_ALL_CAPTION :{BLACK}Αποεπιλογή όλων STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP :{BLACK}Σημείωση όλων των περιεχομένων να μην κατέβουν STR_CONTENT_SEARCH_EXTERNAL :{BLACK}Αναζήτηση εξωτερικών ιστοσελίδων -STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}Ψάξτε για περιεχόμενο που δεν είναι διαθέσιμο μέσω την υπηρεσία λήψης περιεχομένου του OpenTTD σε ιστοσελίδες που δεν είναι συνδεδεμένες με το OpenTTD +STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}Αναζήτηση για περιεχόμενο που δεν είναι διαθέσιμο μέσω την υπηρεσία λήψης περιεχομένου του OpenTTD σε ιστοσελίδες που δεν σχετίζονται με το OpenTTD STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}Φεύγετε από το OpenTTD! STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER :{WHITE}Οι όροι και προϋποθέσεις για τη λήψη περιεχομένου από εξωτερικές ιστοσελίδες διαφέρουν.{}Θα πρέπει να αναφερθείτε στις εξωτερικές ιστοσελίδες για οδηγίες περί της εγκατάστασης του περιεχομένου στο OpenTTD.{}Θέλετε να συνεχίσετε; STR_CONTENT_FILTER_TITLE :{BLACK}Ετικέτα/όνομα φίλτρου: @@ -2773,7 +2773,7 @@ STR_CONTENT_DETAIL_SUBTITLE_AUTOSELECTED :{SILVER}Αυτ STR_CONTENT_DETAIL_SUBTITLE_ALREADY_HERE :{SILVER}Το έχετε ήδη αυτό STR_CONTENT_DETAIL_SUBTITLE_DOES_NOT_EXIST :{SILVER}Αυτό το περιεχόμενο είναι άγνωστο και δεν γίνεται να κατέβει από το OpenTTD -STR_CONTENT_DETAIL_UPDATE :{SILVER}Αυτό είναι αντικατάσταση ενός υπάρχοντος {STRING} +STR_CONTENT_DETAIL_UPDATE :{SILVER}Αυτό αντικαθιστά ένα υπάρχον {STRING} STR_CONTENT_DETAIL_NAME :{SILVER}Όνομα: {WHITE}{STRING} STR_CONTENT_DETAIL_VERSION :{SILVER}Έκδοση: {WHITE}{STRING} STR_CONTENT_DETAIL_DESCRIPTION :{SILVER}Περιγραφή: {WHITE}{STRING} @@ -2830,7 +2830,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Εναλ STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Εναλλαγή διαφάνειας για γέφυρες. Ctrl+Κλικ για να την κλειδώσετε STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Εναλλαγή διαφάνειας για κτίρια όπως φάρους και κεραίες. Ctrl+Κλικ για να την κλειδώσετε STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Εναλλαγή διαφάνειας για τις συνδέσεις. Ctrl+Κλικ για να την κλειδώσετε -STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK}Εναλλαγή διαφάνειας για φόρτωση και κείμενο κόστους/εσόδων. Ctrl+Click για να την κλειδώσετε +STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK}Εναλλαγή διαφάνειας για φόρτωση και κείμενο κόστους/εσόδων. Ctrl+Κλικ για να την κλειδώσετε STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Επιλέξτε τα αντικείμενα που θα είναι αόρατα αντί για διάφανα # Linkgraph legend window @@ -2864,10 +2864,10 @@ STR_STATION_BUILD_INFRASTRUCTURE_COST_PERIOD :{BLACK}Κόστ # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Συνένωση σταθμού -STR_JOIN_STATION_CREATE_SPLITTED_STATION :{YELLOW}Χτίστε ένα ξεχωριστό σταθμό +STR_JOIN_STATION_CREATE_SPLITTED_STATION :{YELLOW}Κατασκευάστε ένα ξεχωριστό σταθμό STR_JOIN_WAYPOINT_CAPTION :{WHITE}Συνένωση σημείου καθοδήγησης -STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT :{YELLOW}Κτίσιμο ενός ξεχωριστού σημείου καθοδήγησης +STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT :{YELLOW}κατασκευή ενός ξεχωριστού σημείου καθοδήγησης # Generic toolbar STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE :{BLACK}Απενεργοποιημένο διότι δεν υπάρχουν διαθέσιμα οχήματα για αυτή την υποδομή @@ -2914,7 +2914,7 @@ STR_STATION_BUILD_DRAG_DROP :{BLACK}Σύρε STR_STATION_BUILD_DRAG_DROP_TOOLTIP :{BLACK}Φτιάξε ένα σταθμό χρησιμοποιώντας σύρσιμο και ελευθέρωση STR_STATION_BUILD_STATION_CLASS_TOOLTIP :{BLACK}Επιλογή τύπου σταθμών για εμφάνιση -STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}Επιλέξτε τον τύπο του σταθμού προς κτίσιμο +STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}Επιλέξτε τον τύπο του σταθμού προς κατασκευή STR_STATION_CLASS_DFLT :Προεπιλεγμένος STR_STATION_CLASS_DFLT_STATION :Προεπιλεγμένος σταθμός @@ -2928,16 +2928,16 @@ STR_BUILD_SIGNAL_TOGGLE_ADVANCED_SIGNAL_TOOLTIP :{BLACK}Εναλ STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Σηματοδότες Τμήματος (σηματοφόρος){}Αυτός είναι ο πιο βασικός τύπος σηματοδότη, επιτρέποντας μόνο ένα τρένο να βρίσκεται σε κάθε τμήμα κάθε φορά STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Σηματοδότης-Εισόδου (σηματοφόρος){}Πράσινο όσο υπάρχει ένας ή περισσότεροι πράσινοι σηματοδότες-εξόδου στο επόμενο τμήμα γράμμης. Διαφορετικά δείχνει κόκκινο STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Σηματοδότης-Εξόδου (σηματοφόρος){}Συμπεριφέρεται με τον ίδιο τρόπο οπως οι σηματοδότες τμήματος αλλά είναι απαραίτητο να τεθεί το σωστό χρώμα στους προ-σηματοδότες είσοδου και συνδυαστικούς -STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Συνδυαστικός Σηματοδότης (σηματοφόρος){}Ο συνδυαστικός σηματοδότης απλά λειτουργεί ταυτόχρονα ως σηματοδότης εισόδου και εξόδου. Αυτό επιτρέπει το κτίσιμο μεγάλυτερων «δέντρων» με προ-σηματοδότες +STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Συνδυαστικός Σηματοδότης (σηματοφόρος){}Ο συνδυαστικός σηματοδότης απλά λειτουργεί ταυτόχρονα ως σηματοδότης εισόδου και εξόδου. Αυτό επιτρέπει την κατασκευή μεγάλυτερων «δέντρων» με προ-σηματοδότες STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Σηματοδότης Τροχιάς (σηματοφόρος){}Ένας σηματοδότης τροχιάς επιτρέπει σε περισσότερα από ένα τρένο να είναι σε ένα κομμάτι ελέγχου την ίδια στιγμή, εάν το τρένο μπορεί να δεσμεύσει τροχιά σε ασφαλές σημείο στάσης. Κανονικοί σηματοδότες τροχιάς μπορούν να περαστούν από την πίσω πλευρά STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Μονόδρομος Σηματοδότης Τροχιάς (σηματοφόρος){}Ένας σηματοδότης τροχιάς επιτρέπει σε περισσότερα από ένα τρένο να είναι σε ένα κομμάτι ελέγχου την ίδια στιγμή, εάν το τρένο μπορεί να δεσμεύσει τροχιά σε ασφαλές σημείο στάσης. Μονόδρομοι σηματοδότες τροχιάς δεν μπορούν να περαστούν από την πίσω πλευρά. STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Σηματοδότης Τμήματος (ηλεκτρικός){}Αυτός είναι ο πιο βασικός τύπος σηματοδότη, επιτρέποντας μόνο ένα τρένο να είναι στο ίδιο τμήμα την ίδια στιγμή. STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Σηματοδότης Εισόδου (ηλεκτρικός){}Πράσινο όσο υπάρχει ένας ή περισσότεροι πράσινοι σηματοδότες εξόδου στο επόμενο τμήμα γραμμής. Διαφορετικά είναι κόκκινο STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Σηματοδότης Εξόδου (ηλεκτρικός){}Συμπεριφέρεται με τον ίδιο τρόπο όπως οι σηματοδότες τμήματος αλλά είναι απαραίτητο να θέσει το σωστό χρώμα στους προ-σηματοδότες εισόδου και συνδυαστικούς -STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Συνδυαστικός Σηματοδότης (ηλεκτρικός){}Ο συνδυαστικός σηματοδότης δουλεύει απλά ως σηματοδότης εισόδου και εξόδου ταυτόχρονα. Αυτό σας επιτρέπει το κτίσιμο μεγάλων «δέντρων» με προ-σηματοδότες +STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Συνδυαστικός Σηματοδότης (ηλεκτρικός){}Ο συνδυαστικός σηματοδότης δουλεύει απλά ως σηματοδότης εισόδου και εξόδου ταυτόχρονα. Αυτό σας επιτρέπει την κατασκευή μεγάλων «δέντρων» με προ-σηματοδότες STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Σηματοδότης Τροχιάς (ηλεκτρικός){}Ένας σηματοδότης τροχιάς επιτρέπει σε περισσότερα από ένα τρένο να είναι σε ένα κομμάτι ελέγχου την ίδια στιγμή, εάν το τρένο μπορεί να δεσμεύσει τροχιά σε ασφαλές σημείο στάσης. Κανονικοί σηματοδότες τροχιάς μπορούν να περαστούν από την πίσω πλευρά STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Μονόδρομος Σηματοδότης Τροχιάς (ηλεκτρικός){}Ένας σηματοδότης τροχιάς επιτρέπει σε περισσότερα από ένα τρένο να είναι σε ένα κομμάτι ελέγχου την ίδια στιγμή, εάν το τρένο μπορεί να δεσμεύσει τροχιά σε ασφαλές σημείο στάσης. Μονόδρομοι σηματοδότες τροχιάς δεν μπορούν να περαστούν από την πίσω πλευρά -STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Μετατροπή σήματος{}Κάντε κλικ σε ένα υπάρχον σήμα για να το μετατρέψετε στον επιλεγμένο τύπο και παραλλαγή. Ctrl+Click για εναλλαγή της υπάρχουσας παραλλαγής. Το Shift+Click εμφανίζει το εκτιμώμενο κόστος μετατροπής +STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Μετατροπή σήματος{}Κάντε κλικ σε ένα υπάρχον σήμα για να το μετατρέψετε στον επιλεγμένο τύπο και παραλλαγή. Ctrl+Κλικ για εναλλαγή της υπάρχουσας παραλλαγής. Το Shift+Κλικ εμφανίζει το εκτιμώμενο κόστος μετατροπής STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Απόσταση μεταξύ σηματοδοτών με σύρσιμο STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Μείωση απόστασης μεταξύ σηματοδοτών με σύρσιμο STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Αύξηση απόστασης μεταξύ σηματοδοτών με σύρσιμο @@ -2979,7 +2979,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Κατα STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Κατασκευή τούνελ δρόμου. Επιπρόσθετα, με Shift εμφανίζεται εκτίμηση κόστους μόνο STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Κατασκευή τούνελ τροχιοδρόμου. Επιπρόσθετα πατήστε το Shift για εμφάνιση εκτίμησης κόστους μόνο STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Εναλλαγή κατασκευής/αφαίρεσης για αυτοκινητόδρομους -STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Εναλλαγή κτισίματος/αφαίρεσης της κατασκευής τροχιόδρομου +STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Εναλλαγή προσθήκης/αφαίρεσης για την κατασκευή τροχιόδρομου STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Μετατρέψτε/Αναβαθμίστε τον τύπο του δρόμου. Επιπρόσθετα, με Shift εμφανίζεται εκτίμηση κόστους μόνο STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Μετατρέψτε/Αναβαθμίστε τον τύπο του τραμ. Επιπρόσθετα, με Shift εμφανίζεται εκτίμηση κόστους μόνο @@ -3058,7 +3058,7 @@ STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Αγορ # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Επιλογή Αντικείμενου STR_OBJECT_BUILD_TOOLTIP :{BLACK}Επιλογή αντικείμενου για κατασκευή. Ctrl+Κλικ+Σύρσιμο για διαγώνια επιλογή. Επιπρόσθετα, με Shift εμφανίζεται εκτίμηση κόστους μόνο -STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Επιλογή της κατηγορίας του αντικείμενου για κτίσιμο +STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Επιλογή της κατηγορίας του αντικείμενου για κατασκευή STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Προεπισκόπηση του αντικείμενου STR_OBJECT_BUILD_SIZE :{BLACK}Μέγεθος: {GOLD}{NUM} x {NUM} τετράγωνα @@ -3135,7 +3135,7 @@ STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP :{BLACK}Γέμι STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION :{WHITE}Δημιουργία τυχαίων βιομηχανιών STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_QUERY :{YELLOW}Σίγουρα θέλετε να δημιουργήσετε πολλές τυχαίες βιομηχανίες; STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST :{BLACK}Κόστος: {YELLOW}{CURRENCY_LONG} -STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK}Διερεύνηση +STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK}Προοπτική STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY :{BLACK}Κατασκευή STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY :{BLACK}Χρηματοδότηση STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES :{BLACK}Αφαίρεση όλων των βιομηχανιών @@ -3379,7 +3379,7 @@ STR_SAVELOAD_OSKTITLE :{BLACK}Δώστ # World generation STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}Δημιουργία Κόσμου STR_MAPGEN_MAPSIZE :{BLACK}Διάσταση χάρτη: -STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Επιλέξτε το μέγεθος του χάρτη σε τετραγωνίδια. Ο αριθμός των τετραγωνίδιων διαθέσιμα για κτίσιμο θα είναι λίγο χαμηλότερος +STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Επιλέξτε το μέγεθος του χάρτη σε τετραγωνίδια. Ο αριθμός των τετραγωνίδιων διαθέσιμα για κατασκευή θα είναι λίγο χαμηλότερος STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Αριθμός πόλεων: STR_MAPGEN_NUMBER_OF_TOWNS_TOOLTIP :Επιλέξτε την πυκνότητα των πόλεων ή έναν προσαρμοσμένο αριθμό @@ -3748,7 +3748,7 @@ STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN :Μικρή δι STR_LOCAL_AUTHORITY_ACTION_MEDIUM_ADVERTISING_CAMPAIGN :Μεσαία διαφημιστική καμπάνια STR_LOCAL_AUTHORITY_ACTION_LARGE_ADVERTISING_CAMPAIGN :Μεγάλη διαφημιστική καμπάνια STR_LOCAL_AUTHORITY_ACTION_ROAD_RECONSTRUCTION :Επιχορήγηση ανακατασκευής τοπικού οδικού δικτύου -STR_LOCAL_AUTHORITY_ACTION_STATUE_OF_COMPANY :Κτίσιμο αγάλματος του ιδιοκτήτη της εταιρίας +STR_LOCAL_AUTHORITY_ACTION_STATUE_OF_COMPANY :Κατασκευή αγάλματος του ιδιοκτήτη της εταιρίας STR_LOCAL_AUTHORITY_ACTION_NEW_BUILDINGS :Επιχορήγηση νέων κτιρίων STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Αγορά αποκλειστικών δικαιωμάτων μεταφοράς STR_LOCAL_AUTHORITY_ACTION_BRIBE :Δωροδοκήστε την τοπική αρχή @@ -3759,7 +3759,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{Y STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Έναρξη μεγάλης τοπικής διαφημιστικής καμπάνιας, για να προσελκύσετε περισσότερους επιβάτες και εμπορεύματα στις μεταφορικές σας υπηρεσίες.{}Παρέχει μία προσωρινή ώθηση στην βαθμολογία σταθμού σε μία μεγάλη ακτίνα γύρω από το κέντρο της πόλης.{}{POP_COLOUR} Κόστος: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION_MONTHS :{PUSH_COLOUR}{YELLOW}Χρηματοδοτήστε την ανακατασκευή του αστικού οδικού δικτύου.{}Προκαλεί σημαντική αναστάτωση της οδικής κυκλοφορίας για έως και 6 μήνες.{}{POP_COLOUR}Κόστος: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION_MINUTES :{PUSH_COLOUR}{YELLOW}Χρηματοδοτήστε την ανακατασκευή του αστικού οδικού δικτύου.{}Προκαλεί σημαντική αναστάτωση της οδικής κυκλοφορίας για έως και 6 λεπτά.{}{POP_COLOUR}Κόστος: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Χτίστε ένα άγαλμα προς τιμήν της εταιρίας σας.{}Παρέχει μία μόνιμη ώθηση στην βαθμολογία σταθμών σε αυτή την πόλη.{}{POP_COLOUR}Κόστος: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Κατασκευάστε ένα άγαλμα προς τιμήν της εταιρίας σας.{}Παρέχει μία μόνιμη ώθηση στην βαθμολογία σταθμών σε αυτή την πόλη.{}{POP_COLOUR}Κόστος: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Χρηματοδοτήστε την κατασκευή νέων κτιρίων στην πόλη.{}Παρέχει μια προσωρινή ώθηση στην ανάπτυξη αυτής της πόλης.{}{POP_COLOUR}Κόστος: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT_MONTHS :{PUSH_COLOUR}{YELLOW}Αγοράστε αποκλειστικά δικαιώματα μεταφοράς στην πόλη για 12 μήνες.{}Η δημοτική αρχή δεν θα επιτρέψει στους επιβάτες και στο φορτίο να χρησιμοποιούν τους σταθμούς των ανταγωνιστών σας. Μια επιτυχημένη δωροδοκία από έναν ανταγωνιστή θα ακυρώσει αυτό το συμβόλαιο.{}{POP_COLOUR}Κόστος: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT_MINUTES :{PUSH_COLOUR}{YELLOW}Αγοράστε αποκλειστικά δικαιώματα μεταφοράς στην πόλη για 12 λεπτά.{}Η δημοτική αρχή δεν θα επιτρέψει στους επιβάτες και στο φορτίο να χρησιμοποιούν τους σταθμούς των ανταγωνιστών σας. Μια επιτυχημένη δωροδοκία από έναν ανταγωνιστή θα ακυρώσει αυτό το συμβόλαιο.{}{POP_COLOUR}Κόστος: {CURRENCY_LONG} @@ -3988,8 +3988,8 @@ STR_COMPANY_VIEW_INFRASTRUCTURE_STATION :{WHITE}{COMMA} STR_COMPANY_VIEW_INFRASTRUCTURE_AIRPORT :{WHITE}{COMMA} αεροδρόμι{P ο α} STR_COMPANY_VIEW_INFRASTRUCTURE_NONE :{WHITE}Τίποτα -STR_COMPANY_VIEW_BUILD_HQ_BUTTON :{BLACK}Κτίσιμο Αρχηγείου -STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP :{BLACK}Κτίσιμο αρχηγείου εταιρίας +STR_COMPANY_VIEW_BUILD_HQ_BUTTON :{BLACK}Κατασκευή Αρχηγείου +STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP :{BLACK}Κατασκευή αρχηγείου εταιρίας STR_COMPANY_VIEW_VIEW_HQ_BUTTON :{BLACK}Προβολή Αρχηγείου STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}Προβολή αρχηγείου εταιρίας STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Ανοικοδόμηση Αρχηγείου @@ -4014,7 +4014,7 @@ STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION :Όνομα Ετ STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION :Όνομα Διευθυντή STR_COMPANY_VIEW_GIVE_MONEY_QUERY_CAPTION :Εισάγετε το χρηματικό ποσό που θέλετε να δώσετε -STR_BUY_COMPANY_MESSAGE :{WHITE}Ψάχνουμε μία εταιρία μεταφορών για να εξαγοράσει την εταιρία μας.{}{}Θέλετε να εξαγοράσετε την {COMPANY} για {CURRENCY_LONG}; +STR_BUY_COMPANY_MESSAGE :{WHITE}Αναζητούμε μια εταιρία μεταφορών για να εξαγοράσει την εταιρία μας.{}{}Θέλετε να εξαγοράσετε την {COMPANY} για {CURRENCY_LONG}; STR_BUY_COMPANY_HOSTILE_TAKEOVER :{WHITE}Σε μια εχθρική εξαγορά της {COMPANY} θα αγοράσετε όλα τα περιουσιακά στοιχεία, θα εξοφλήσετε όλα τα δάνεια και θα πληρώσετε κέρδη δύο ετών.{}{}Το σύνολο εκτιμάται ότι είναι {CURRENCY_LONG}.{}{}Θέλετε να προχωρήσετε με αυτήν την εχθρική εξαγορά; # Company infrastructure window @@ -4429,7 +4429,7 @@ STR_REPLACE_TRAM_VEHICLES :Οχήματα STR_REPLACE_REMOVE_WAGON :{BLACK}Αφαίρεση βαγονιού: ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Υποχρεώνει την αυτόματη αντικατάσταση να διατηρεί σταθερό το μήκος του τρένου αφαιρώντας βαγόνια (ξεκινώντας από μπροστά), όταν η αντικατάσταση της μηχανής κάνει το τρένο μεγαλύτερο -STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Πατήστε Ctrl+Click για εφαρμογή επίσης στην υπό-ομάδα +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Πατήστε Ctrl+Κλικ για εφαρμογή επίσης στην υπό-ομάδα # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -4553,12 +4553,12 @@ STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES :{BLACK}Διάσ STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Διάστημα επισκευών: {LTBLUE}{COMMA}%{BLACK} {STRING} STR_VEHICLE_DETAILS_LAST_SERVICE_DATE :Τελευταίο service: {LTBLUE}{DATE_LONG} STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO :Τελευταίο service: {LTBLUE}{NUM} λεπτ{P 0 ό ά} πριν -STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_DAYS :{BLACK}Αύξηση του διαστήματος συντήρησης κατά 10 ημέρες. Ctrl+Click για αύξηση του διαστήματος συντήρησης κατά 5 ημέρες -STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_MINUTES :{BLACK}Αύξηση του διαστήματος συντήρησης κατά 5 λεπτά. Ctrl+Click για αύξηση του διαστήματος συντήρησης κατά 1 λεπτό -STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_PERCENT :{BLACK}Αύξηση του διαστήματος εξυπηρέτησης κατά 10 τοις εκατό. Ctrl+Click για αύξηση του διαστήματος εξυπηρέτησης κατά 5 τοις εκατό -STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP_DAYS :Μειώστε το διάστημα μεταξύ των σέρβις κατά 10 ημέρες. Ctrl+Click για να μειώσετε το διάστημα συντήρησης κατά 5 ημέρες -STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP_MINUTES :Μειώστε το διάστημα μεταξύ των σέρβις κατά 5 λεπτά. Ctrl+Click για να μειώσετε το διάστημα συντήρησης κατά 1 λεπτό -STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP_PERCENT :Μειώστε το διάστημα μεταξύ των σέρβις κατά 10 τοις εκατό. Ctrl+Click για να μειώσετε το διάστημα συντήρησης κατά 5 τοις εκατό. +STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_DAYS :{BLACK}Αύξηση του διαστήματος συντήρησης κατά 10 ημέρες. Ctrl+Κλικ για αύξηση του διαστήματος συντήρησης κατά 5 ημέρες +STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_MINUTES :{BLACK}Αύξηση του διαστήματος συντήρησης κατά 5 λεπτά. Ctrl+Κλικ για αύξηση του διαστήματος συντήρησης κατά 1 λεπτό +STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_PERCENT :{BLACK}Αύξηση του διαστήματος εξυπηρέτησης κατά 10 τοις εκατό. Ctrl+Κλικ για αύξηση του διαστήματος εξυπηρέτησης κατά 5 τοις εκατό +STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP_DAYS :{BLACK}Μειώστε το διάστημα μεταξύ των σέρβις κατά 10 ημέρες. Ctrl+Κλικ για να μειώσετε το διάστημα συντήρησης κατά 5 ημέρες +STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP_MINUTES :{BLACK}Μειώστε το διάστημα μεταξύ των σέρβις κατά 5 λεπτά. Ctrl+Κλικ για να μειώσετε το διάστημα συντήρησης κατά 1 λεπτό +STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP_PERCENT :{BLACK}Μειώστε το διάστημα μεταξύ των σέρβις κατά 10 τοις εκατό. Ctrl+Κλικ για να μειώσετε το διάστημα συντήρησης κατά 5 τοις εκατό. STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP :{BLACK}Αλλάξτε τον τύπο διαστήματος επισκευών STR_VEHICLE_DETAILS_DEFAULT :Προκαθορισμένο @@ -4632,7 +4632,7 @@ STR_ORDER_INDEX :{COMMA}:{NBSP} STR_ORDER_TEXT :{STRING} {STRING} {STRING} {STRING} STR_ORDERS_END_OF_ORDERS :- - Τέλος Εντολών - - -STR_ORDERS_END_OF_SHARED_ORDERS :- - Τέλος Μοιρασμένων Οδηγιών - - +STR_ORDERS_END_OF_SHARED_ORDERS :- - Τέλος Διαμοιρασμένων Εντολών - - # Order bottom buttons STR_ORDER_NON_STOP :{BLACK}Χωρίς στάση @@ -4717,7 +4717,7 @@ STR_ORDER_GO_TO_NEAREST_DEPOT :Πήγαινε STR_ORDER_GO_TO_NEAREST_HANGAR :Πήγαινε στο κοντινότερο υπόστεγο STR_ORDER_CONDITIONAL :Εκτέλεση εντόλης υπο προυπόθεση STR_ORDER_SHARE :Μοίρασμα εντολών -STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Εισάγετε μια νέα εντολή πριν την επιλεγμένη ή προσθέστε στο τέλος της λίστας. Ctrl+Κλικ σε έναν σταθμό για ορισμό εντολής σε "πλήρης φόρτωση οποιουδήποτε εμπορεύματος", σε σημείο διαδρομής για αντιστροφή εντολής "χωρίς στάση εξ ορισμού" ή σε αμαξοστάσιο για "αποσύνδεση". Κάντε κλικ σε άλλο όχημα για να αντιγράψετε τις εντολές του ή Ctrl+Click για διαμοιρασμό εντολών. Μια εντολή αμαξοστασίου απενεργοποιεί την αυτόματη συντήρηση του οχήματος +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Εισάγετε μια νέα εντολή πριν την επιλεγμένη ή προσθέστε στο τέλος της λίστας. Ctrl+Κλικ σε έναν σταθμό για ορισμό εντολής σε "πλήρης φόρτωση οποιουδήποτε εμπορεύματος", σε σημείο διαδρομής για αντιστροφή εντολής "χωρίς στάση εξ ορισμού" ή σε αμαξοστάσιο για "αποσύνδεση". Κάντε κλικ σε άλλο όχημα για να αντιγράψετε τις εντολές του ή Ctrl+Κλικ για διαμοιρασμό εντολών. Μια εντολή αμαξοστασίου απενεργοποιεί την αυτόματη συντήρηση του οχήματος STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Εμφάνιση όλων των οχημάτων που μοιράζονται αυτό το δρομολόγιο @@ -4825,7 +4825,7 @@ STR_TIMETABLE_STATUS_START_AT_DATE :{BLACK}Αυτό STR_TIMETABLE_STATUS_START_IN_SECONDS :{BLACK}Αυτό το δρομολόγιο θα ξεκινήσει σε {COMMA} δευτερόλεπτα STR_TIMETABLE_START :{BLACK}Εκκίνηση δρομολογίου -STR_TIMETABLE_START_TOOLTIP :{BLACK}Επιλέξτε πότε ξεκινά αυτό το δρομολόγιο. Ctrl+Click για ομοιόμορφη κατανομή της εκκίνησης όλων των οχημάτων που μοιράζονται αυτήν την εντολή με βάση τη σχετική τους εντολή, εάν η εντολή είναι πλήρως προγραμματισμένη +STR_TIMETABLE_START_TOOLTIP :{BLACK}Επιλέξτε πότε ξεκινά αυτό το δρομολόγιο. Ctrl+Κλικ για ομοιόμορφη κατανομή της εκκίνησης όλων των οχημάτων που μοιράζονται αυτήν την εντολή με βάση τη σχετική τους εντολή, εάν η εντολή είναι πλήρως προγραμματισμένη STR_TIMETABLE_START_SECONDS_QUERY :Δευτερόλεπτα μέχρι την έναρξη του δρομολογίου @@ -4913,7 +4913,7 @@ STR_AI_CONFIG_AI :{SILVER}AI STR_AI_CONFIG_CHANGE_AI :{BLACK}Διάλεξε ΤΝ STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Δέσμη Ενεργειών -STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Φόρτωση άλλης δέσμης ενεργειών. Ctrl+Click για εμφάνιση όλων των διαθέσιμων εκδόσεων +STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Φόρτωση άλλης δέσμης ενεργειών. Ctrl+Κλικ για εμφάνιση όλων των διαθέσιμων εκδόσεων STR_AI_CONFIG_CONFIGURE :{BLACK}Ρυθμίσεις STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Ρύθμιση των παραμέτρων της Δέσμης Ενεργειών @@ -4999,9 +4999,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Υπολ STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Η αποθήκευση είναι σε εξέλιξη,{}παρακαλώ περιμένετε να τελειώσει! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Η αυτόματη αποθήκευση απέτυχε STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Αδύνατη η ανάγνωση του δίσκου -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Η Αποθήκευση Παιχνιδιού Απέτυχε{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Αδύνατη η διαγραφή του αρχείου -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Η Φόρτωση Παιχνιδιού Απέτυχε{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Εσωτερικό λάθος: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Χαλασμένο αποθηκευμένο παιχνίδι - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Το αποθηκευμένο παιχνίδι είναι φτιαγμένο με νεότερη έκδοση @@ -5054,7 +5052,7 @@ STR_ERROR_CAN_T_DO_THIS :{WHITE}Αυτό STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Το κτίριο πρέπει πρώτα να κατεδαφιστεί STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Είναι αδύνατο να καθαριστεί αυτή η περιοχή... STR_ERROR_SITE_UNSUITABLE :{WHITE}... ακατάλληλη περιοχή -STR_ERROR_ALREADY_BUILT :{WHITE}... ήδη κτισμένο +STR_ERROR_ALREADY_BUILT :{WHITE}... ήδη κατασκευασμένο STR_ERROR_OWNED_BY :{WHITE}... ιδιοκτησία του {STRING} STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... η περιοχή είναι ιδιοκτησία άλλης εταιρίας STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}... υπερβαίνει το όριο διαμόρφωσης του εδάφους @@ -5092,12 +5090,12 @@ STR_ERROR_CAN_T_REPAY_LOAN :{WHITE}Αδύν STR_ERROR_INSUFFICIENT_FUNDS :{WHITE}Δεν είναι δυνατό να δοθούν χρήματα που είναι δανεισμένα από τη τράπεζα... STR_ERROR_CAN_T_GIVE_MONEY :{WHITE}Δεν μπορείτε να δώσετε χρήματα σε αυτή την εταιρία... STR_ERROR_CAN_T_BUY_COMPANY :{WHITE}Αδύνατη η εξαγορά της εταιρίας... -STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Δεν μπορεί να κτιστεί αρχηγείο εταιρίας... +STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Δεν μπορεί να κατασκευαστεί αρχηγείο εταιρίας... # Town related errors STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}Αδύνατο να κατασκευαστούν πόλεις... STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}Δεν μπορεί να μετονομαστεί η πόλη... -STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}Αδύνατο να κτιστεί πόλη εδώ... +STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}Αδύνατο να ιδρυθεί πόλη εδώ... STR_ERROR_CAN_T_EXPAND_TOWN :{WHITE}Δεν μπορεί να γίνει επέκταση της πόλης... STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... πολύ κοντά στην άκρη του χάρτη STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... πολύ κοντά σε άλλη πόλη @@ -5110,22 +5108,22 @@ STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... δε # Industry related errors STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... πάρα πολλές βιομηχανίες STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Δε γίνεται να δημιουργηθούν βιομηχανίες... -STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Δεν μπορεί να κτιστεί {G ο η το} {STRING} εδώ... -STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Δεν είναι δυνατό να κτιστεί αυτός ο τύπος βιομηχανίας εδώ... +STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί {G ο η το} {STRING} εδώ... +STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Δεν είναι δυνατό να κατασκευαστεί αυτός ο τύπος βιομηχανίας εδώ... STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Δεν βρέθηκαν ευκαιρίες για τη βιομηχανία... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... πολύ κοντά σε άλλη βιομηχανία -STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... πρέπει να κτιστεί πόλη πρώτα +STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... πρέπει να ιδρυθεί πόλη πρώτα STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... επιτρέπεται μόνο μία ανά πόλη -STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 :{WHITE}... μπορεί να κτιστεί μόνο σε πόλεις με πληθυσμό άνω των 1200 -STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}... μπορεί να κτιστεί μόνο σε δασώδεις περιοχές -STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}... μπορεί να κτιστεί μόνο σε ερημικές περιοχές -STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... μπορεί να κτιστεί μόνο σε πόλεις (αντικαθιστώντας σπίτια) -STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER :{WHITE}... μπορεί να κτιστεί μόνο κοντά σε κέντρα πόλεων -STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS :{WHITE}... μπορεί να κτιστεί μόνο σε χαμηλές περιοχές +STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 :{WHITE}... μπορεί να κατασκευαστεί μόνο σε πόλεις με πληθυσμό άνω των 1200 +STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}... μπορεί να κατασκευαστεί μόνο σε δασώδεις περιοχές +STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}... μπορεί να κατασκευαστεί μόνο σε ερημικές περιοχές +STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... μπορεί να κατασκευαστεί μόνο σε πόλεις (αντικαθιστώντας σπίτια) +STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER :{WHITE}... μπορεί να κατασκευαστεί μόνο κοντά σε κέντρα πόλεων +STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS :{WHITE}... μπορεί να κατασκευαστεί μόνο σε χαμηλές περιοχές STR_ERROR_CAN_ONLY_BE_POSITIONED :{WHITE}... μπορούν να τοποθετηθούν μόνο στις άκρες του χάρτη STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... δάση μπορούν να φυτευτούν μόνο πάνω από τη γραμμή του χιονιού -STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... μπορεί να κτιστεί μόνο πάνω από τη γραμμή του χιονιού -STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... μπορεί να κτιστεί μόνο κάτω από τη γραμμή του χιονιού +STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... μπορεί να κατασκευαστεί μόνο πάνω από τη γραμμή του χιονιού +STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... μπορεί να κατασκευαστεί μόνο κάτω από τη γραμμή του χιονιού STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Η χρηματοδότηση απέτυχε να προσκομήσει αποτελέσματα λόγω κακής τύχης· δοκιμάστε ξάνα STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Δεν υπήρχαν κατάλληλα μέρη για προοπτική για αυτόν τον κλάδο @@ -5133,13 +5131,13 @@ STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Δεν STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Αλλαγή παραμέτρων δημιουργίας χάρτη για καλύτερα αποτελέσματα # Station construction related errors -STR_ERROR_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Δεν μπορεί να κτιστεί σταθμός τρένων εδώ... -STR_ERROR_CAN_T_BUILD_BUS_STATION :{WHITE}Δεν μπορεί να κτιστεί στάση λεωφορείων... -STR_ERROR_CAN_T_BUILD_TRUCK_STATION :{WHITE}Δεν μπορεί να κτιστεί σταθμός φορτηγών... -STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION :{WHITE}Δεν μπορεί να κτιστεί επιβατικός σταθμός τραμ... -STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION :{WHITE}Δεν μπορεί να κτιστεί σταθμός τραμ... -STR_ERROR_CAN_T_BUILD_DOCK_HERE :{WHITE}Δεν μπορεί να κτιστεί λιμένας εδώ... -STR_ERROR_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Δεν μπορεί να κτιστεί αεροδρόμιο εδώ... +STR_ERROR_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Δεν μπορεί να κατασκευαστεί σταθμός τρένων εδώ... +STR_ERROR_CAN_T_BUILD_BUS_STATION :{WHITE}Δεν μπορεί να κατασκευαστεί στάση λεωφορείων... +STR_ERROR_CAN_T_BUILD_TRUCK_STATION :{WHITE}Δεν μπορεί να κατασκευαστεί σταθμός φορτηγών... +STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION :{WHITE}Δεν μπορεί να κατασκευαστεί επιβατικός σταθμός τραμ... +STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION :{WHITE}Δεν μπορεί να κατασκευαστεί σταθμός τραμ... +STR_ERROR_CAN_T_BUILD_DOCK_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί λιμένας εδώ... +STR_ERROR_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί αεροδρόμιο εδώ... STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Γειτονεύει με περισσότερες από μια υπάρχουσες περιοχές σταθμών/φόρτωσης STR_ERROR_STATION_TOO_SPREAD_OUT :{WHITE}... ο σταθμός είναι υπερβολικά απλωμένος @@ -5177,7 +5175,7 @@ STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Πρέπ STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Προστίθεται σε περισσότερο από ένα υπάρχον σημείο καθοδήγησης STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT :{WHITE}Πολύ κοντά σε άλλο σημείο καθοδήγησης -STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT :{WHITE}Δεν μπορεί να χτιστεί σημείο καθοδήγησης τρένου εδώ... +STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT :{WHITE}Δεν μπορεί να κατασκευαστεί σημείο καθοδήγησης τρένου εδώ... STR_ERROR_CAN_T_POSITION_BUOY_HERE :{WHITE}Δεν μπορεί να τοποθετηθεί σημαδούρα εδώ... STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}Αδύνατο να αλλαχτεί το όνομα του σημείου καθοδήγησης... @@ -5187,10 +5185,10 @@ STR_ERROR_BUOY_IN_THE_WAY :{WHITE}... ση STR_ERROR_BUOY_IS_IN_USE :{WHITE}... σημαδούρα σε χρήση από άλλη εταιρία! # Depot related errors -STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Δεν μπορεί να κτιστεί αμαξοστάσιο εδώ... -STR_ERROR_CAN_T_BUILD_ROAD_DEPOT :{WHITE}Δεν μπορεί να κτιστεί σταθμός οχημάτων εδώ... -STR_ERROR_CAN_T_BUILD_TRAM_DEPOT :{WHITE}Δεν μπορεί να κτιστεί σταθμαρχείο τραμ εδώ... -STR_ERROR_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Δεν μπορεί να κτιστεί ναυπηγείο πλοίων εδώ... +STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}Δεν μπορεί να κατασκευαστεί αμαξοστάσιο εδώ... +STR_ERROR_CAN_T_BUILD_ROAD_DEPOT :{WHITE}Δεν μπορεί να κατασκευαστεί σταθμός οχημάτων εδώ... +STR_ERROR_CAN_T_BUILD_TRAM_DEPOT :{WHITE}Δεν μπορεί να κατασκευαστεί σταθμαρχείο τραμ εδώ... +STR_ERROR_CAN_T_BUILD_SHIP_DEPOT :{WHITE}Δεν μπορεί να κατασκευαστεί ναυπηγείο πλοίων εδώ... STR_ERROR_CAN_T_RENAME_DEPOT :{WHITE}Δεν μπορεί να μετονομαστεί το αμαξοστάσιο/ναυπηγείο... @@ -5235,7 +5233,7 @@ STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Η δρ STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Δεν επιτρέπονται ισόπεδες διασταυρώσεις για αυτόν τον τύπο σιδηροδρόμου STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Οι ισόπεδες διαβάσεις δεν επιτρέπονται για αυτό τον τύπο δρόμου STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Δεν μπορούν να τοποθετοηθούν σηματοδότες εδώ... -STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Δεν μπορεί να κτιστεί σιδηρόδρομος εδώ... +STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Δεν μπορεί να κατασκευαστεί σιδηρόδρομος εδώ... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Δεν μπορεί να αφαιρεθεί σιδηρόδρομος από εδώ... STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Αδύνατο να αφαιρεθούν σηματοδότες από εδώ... STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE :{WHITE}Δεν μπορούν να μετατραπούν οι σηματοδότες εδώ... @@ -5247,8 +5245,8 @@ STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}Δε γ # Road construction errors STR_ERROR_MUST_REMOVE_ROAD_FIRST :{WHITE}Πρέπει πρώτα να αφαιρεθεί ο δρόμος STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION :{WHITE}... οι μονόδρομοι δεν μπορούν να έχουν διασταυρώσεις -STR_ERROR_CAN_T_BUILD_ROAD_HERE :{WHITE}Δεν μπορεί να κτιστεί δρόμος εδώ... -STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE :{WHITE}Δεν μπορεί να κτιστεί τροχιοδρόμος εδώ... +STR_ERROR_CAN_T_BUILD_ROAD_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί δρόμος εδώ... +STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί τροχιοδρόμος εδώ... STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Αδύνατο να αφαιρεθεί δρόμος από εδώ... STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Δεν μπορεί να αφαιρεθεί τροχιόδρομος από εδώ... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... δεν υπάρχει δρόμος @@ -5259,16 +5257,16 @@ STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Δεν STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Καμία κατάλληλη γραμμή του τραμ # Waterway construction errors -STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Δεν μπορεί να κτιστεί κανάλι εδώ -STR_ERROR_CAN_T_BUILD_LOCKS :{WHITE}Δεν μπορεί να κτιστεί υδατοφράκτης εδώ... +STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Δεν μπορεί να κατασκευαστεί κανάλι εδώ +STR_ERROR_CAN_T_BUILD_LOCKS :{WHITE}Δεν μπορεί να κατασκευαστεί υδατοφράκτης εδώ... STR_ERROR_CAN_T_PLACE_RIVERS :{WHITE}Δεν μπορούν να τοποθετηθούν ποτάμια εδώ... -STR_ERROR_MUST_BE_BUILT_ON_WATER :{WHITE}... πρέπει να κτιστεί στο νερό -STR_ERROR_CAN_T_BUILD_ON_WATER :{WHITE}... αδύνατο να κτιστεί στο νερό -STR_ERROR_CAN_T_BUILD_ON_SEA :{WHITE}... αδύνατο να κτιστεί στην ανοικτή θάλασσα -STR_ERROR_CAN_T_BUILD_ON_CANAL :{WHITE}... αδύνατο να κτιστεί σε κανάλι -STR_ERROR_CAN_T_BUILD_ON_RIVER :{WHITE}... αδύνατο να κτιστεί σε ποτάμι +STR_ERROR_MUST_BE_BUILT_ON_WATER :{WHITE}... πρέπει να κατασκευαστεί στο νερό +STR_ERROR_CAN_T_BUILD_ON_WATER :{WHITE}... αδύνατο να κατασκευαστεί στο νερό +STR_ERROR_CAN_T_BUILD_ON_SEA :{WHITE}... αδύνατο να κατασκευαστεί στην ανοικτή θάλασσα +STR_ERROR_CAN_T_BUILD_ON_CANAL :{WHITE}... αδύνατο να κατασκευαστεί σε κανάλι +STR_ERROR_CAN_T_BUILD_ON_RIVER :{WHITE}... αδύνατο να κατασκευαστεί σε ποτάμι STR_ERROR_MUST_DEMOLISH_CANAL_FIRST :{WHITE}Πρέπει να κατεδαφιστεί το κανάλι πρώτα -STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE :{WHITE}Δεν μπορεί να κτιστεί κανάλι εδώ... +STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί κανάλι εδώ... # Tree related errors STR_ERROR_TREE_ALREADY_HERE :{WHITE}... υπάρχει ήδη δέντρο εδώ @@ -5276,7 +5274,7 @@ STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE :{WHITE}... λά STR_ERROR_CAN_T_PLANT_TREE_HERE :{WHITE}Δεν γίνεται να φυτευτεί δέντρο εδώ... # Bridge related errors -STR_ERROR_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Δεν μπορεί να κτιστεί γέφυρα εδώ... +STR_ERROR_CAN_T_BUILD_BRIDGE_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί γέφυρα εδώ... STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Πρέπει πρώτα να καταστραφεί η γέφυρα STR_ERROR_CAN_T_START_AND_END_ON :{WHITE}Δεν γίνεται να ξεκινάει και να τελειώνει στο ίδιο σημείο STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT :{WHITE}Η γέφυρα δεν καταλήγει στο ίδιο επίπεδο @@ -5288,7 +5286,7 @@ STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... η STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Η γέφυρα θα καταλήξει εκτός χάρτη # Tunnel related errors -STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Δεν μπορεί να κτιστεί τούνελ εδώ... +STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί τούνελ εδώ... STR_ERROR_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}Ακατάλληλη τοποθεσία για είσοδο τούνελ STR_ERROR_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}Πρέπει πρώτα να καταστραφεί το τούνελ STR_ERROR_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}Υπάρχει άλλο τούνελ στη μέση @@ -5298,10 +5296,10 @@ STR_ERROR_TUNNEL_TOO_LONG :{WHITE}... το # Object related errors STR_ERROR_TOO_MANY_OBJECTS :{WHITE}... πάρα πολλά αντικείμενα -STR_ERROR_CAN_T_BUILD_OBJECT :{WHITE}Δεν μπορεί να κτιστεί το αντικείμενο... +STR_ERROR_CAN_T_BUILD_OBJECT :{WHITE}Δεν μπορεί να κατασκευαστεί το αντικείμενο... STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Αντικείμενο στη μέση STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... κεντρικά γραφεία εταιρίας στη μέση -STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Αδύνατο να αγοραστεί το έδαφος... +STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Αδύνατο να γίνει αγορά αυτής της περιοχής εδάφους... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... είστε ήδη ιδιοκτήτης! STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... έχετε φτάσει το όριο οικοδομήσεων @@ -5354,10 +5352,10 @@ STR_ERROR_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Δεν STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}Δεν μπορεί να σταλθεί το αεροσκάφος στο υπόστεγο... ###length VEHICLE_TYPES -STR_ERROR_CAN_T_BUY_TRAIN :{WHITE}Δεν μπορεί να αγοραστεί όχημα σιδηρόδρομου... -STR_ERROR_CAN_T_BUY_ROAD_VEHICLE :{WHITE}Δεν μπορεί να αγοραστεί όχημα δρόμου... -STR_ERROR_CAN_T_BUY_SHIP :{WHITE}Δεν μπορεί να αγοραστεί πλοίο... -STR_ERROR_CAN_T_BUY_AIRCRAFT :{WHITE}Δεν μπορεί να αγοραστεί αεροσκάφος... +STR_ERROR_CAN_T_BUY_TRAIN :{WHITE}Δεν μπορεί να γίνει αγορά οχήματος σιδηροδρόμου... +STR_ERROR_CAN_T_BUY_ROAD_VEHICLE :{WHITE}Δεν μπορεί να γίνει αγορά οχήματος δρόμου... +STR_ERROR_CAN_T_BUY_SHIP :{WHITE}Δεν μπορεί να γίνει αγορά πλοίου... +STR_ERROR_CAN_T_BUY_AIRCRAFT :{WHITE}Δεν μπορεί να γίνει αγορά αεροσκάφους... ###length VEHICLE_TYPES STR_ERROR_CAN_T_RENAME_TRAIN_TYPE :{WHITE}Δεν μπορεί να μετονομαστεί ο τύπος τρένου... diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index 61153d52f4..f0e4e8e050 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -4320,9 +4320,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}{CURRENC STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}!שמירה מתבצעת,{} אנא המתן עד לסיום השמירה STR_ERROR_AUTOSAVE_FAILED :{WHITE}שמירה אוטומטית נכשלה STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}לא ניתן לקרוא מהדיסק -STR_ERROR_GAME_SAVE_FAILED :{WHITE}שמירת המשחק נכשלה{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}לא ניתן למחוק את הקובץ -STR_ERROR_GAME_LOAD_FAILED :{WHITE}טעינת המשחק נכשלה{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :שגיאה פנימית: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :קובץ השמיקה פגום - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :קובץ השמירה נשמר עם גירסא חדישה יותר של המשחק diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index b36d8f0d3f..6a5c4626bc 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -4960,9 +4960,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Becsült STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}A mentés még tart,{}kérlek várd meg a végét! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatikus mentés sikertelen STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Nem olvasható a meghajtó -STR_ERROR_GAME_SAVE_FAILED :{WHITE}A mentés nem sikerült{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Nem sikerült törölni a fájlt -STR_ERROR_GAME_LOAD_FAILED :{WHITE}A betöltés nem sikerült{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Belső hiba: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Hibás játékállás-mentés - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :A játékállást újabb verzió mentette el diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index 1c647aa56c..efaa345255 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -3902,9 +3902,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Áætla STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Vistun er enn í gangi,{}vinsamlegast bíddu á meðan hún klárst! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Sjálfvirk vistun mistókst STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Get ekki lesið af drifi -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Vistun leiks mistókst{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Get ekki eytt skrá -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Mistókst að opna leik{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Innri villa: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Bilun í vistuðum leik - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Leikur er vistaður í nýrri útgáfu diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index 1b86a05322..fc35a85f1e 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -4785,9 +4785,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Perkiraa STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Penyimpanan sedang berlangsung,{}mohon tunggu hingga selesai STR_ERROR_AUTOSAVE_FAILED :{WHITE}Simpan otomatis gagal STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Tidak dapat membaca drive -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Penyimpanan Game gagal{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Tidak mampu untuk menghapus file/berkas -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Gagal membuka permainan{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Kesalahan Internal: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Berkas simpanan permainan rusak - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Berkas simpanan dibuat dari versi yang lebih baru diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 0c924c4744..80d9f5a895 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -4494,9 +4494,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Ioncam M STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Fós ag sábháil,{}fan go mbeidh sé críochnaithe! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Theip ar uathshábháil STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Ní féidir an tiomántán a léamh -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Theip ar Shábháil Cluiche{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Ní féidir comhad a scriosadh -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Theip ar Lódáil Cluiche{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Earráid inmheánach: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Cluiche sábháilte briste - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Rinneadh an cluiche sábháilte le leagan níos nuaí diff --git a/src/lang/italian.txt b/src/lang/italian.txt index c9169f681e..150c81a623 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -4938,9 +4938,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Ricavo s STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Salvataggio in corso,{}prego attenderne la fine! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Salvataggio automatico non riuscito STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Impossibile leggere dall'unità -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Salvataggio non riuscito{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Impossibile eliminare il file -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Caricamento non riuscito{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Errore interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Salvataggio danneggiato - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Salvataggio creato con una versione più recente diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index 0e03d0d796..84b2a8ae91 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -4612,9 +4612,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}収益( STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}ゲームを保存しています{}完了までしばらくお待ちください! STR_ERROR_AUTOSAVE_FAILED :{WHITE}自動保存に失敗しました STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}ドライブを読み込めません -STR_ERROR_GAME_SAVE_FAILED :{WHITE}ゲームの保存に失敗しました{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}ファイルを削除できません -STR_ERROR_GAME_LOAD_FAILED :{WHITE}ゲームの読み込みに失敗しました{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :内部エラー: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :破損したセーブゲーム: {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :このファイルは上位のバージョンによって保存されたものです diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 25b8d1f611..45ea38ea68 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -4900,9 +4900,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}예상 STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}저장 중입니다.{}끝날 때까지 기다려주세요! STR_ERROR_AUTOSAVE_FAILED :{WHITE}자동 저장 실패 STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}드라이브를 읽을 수 없습니다 -STR_ERROR_GAME_SAVE_FAILED :{WHITE}게임 저장 실패{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}파일을 삭제할 수 없습니다 -STR_ERROR_GAME_LOAD_FAILED :{WHITE}게임 불러오기 실패{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :내부 오류: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :손상된 게임 저장 파일 - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :상위 버전의 게임 저장 파일입니다 diff --git a/src/lang/latin.txt b/src/lang/latin.txt index c7d49e4dee..0aa15daf06 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -4392,9 +4392,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Reditus STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Adhuc in servando,{}maneas usque ad terminum! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autoservare defecit STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Non poterat discum legere -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Servare Ludum Defecit{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Non poterat fasciculum delere -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Legere Ludum Defecit{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Mendum internum: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Ludus corruptus - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Ludus servatus est in editione noviore diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 04c0579bfe..16c5ab140e 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -4908,9 +4908,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Plānoti STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Notiek saglabāšana,{}lLūdzu uzgaidiet! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automātiskā saglabāšana neizdevās STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Nevar lasīt disku -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Spēles saglabāšana neizdevās{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Nevar dzēst failu -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Spēles ielādēšana neizdevās{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Iekšēja kļūda: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Bojāts saglabātās spēles fails - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spēle ir saglabāta ar jaunāku versiju diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index 5775ec7d33..5f5198f4c5 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -4817,9 +4817,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Numatomo STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Vyksta išsaugojimas,{}palaukite kol baigsis! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatinis išsaugojimas nepavyko STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Negali pasiekti disko -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Žaidimo išsaugoti nepavyko{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Failo ištrinti nepavyko -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Žaidimo atverti nepavyko{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Vidinė klaida: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Sugadintas išsaugotas žaidimas - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Išsaugotas žaidimas iš naujesnės versijos diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index c792bcc4c0..3a15cff1eb 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -4896,9 +4896,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Geschät STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Nach amgaangen ze späicheren.{} W.e.g. waarde bis daat fäerdeg ass! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Fehler beim Autospäicheren STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kann net um Laafwierk liesen -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Fehler beim Späicheren{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kann d'Datei net läschen -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Fehler beim Lueden{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interne Feeler: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Futtissen Späicherstand - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spillstand ass mat enger méi neier Versioun gemaach diff --git a/src/lang/malay.txt b/src/lang/malay.txt index ed6e37ed7a..4e8d12693c 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -3808,9 +3808,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Jangkaan STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Penyimpanan sedang berlaku,{}sila tunggu sehingga selesai! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Penyimpanan automatik gagal dilakukan STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Gagal dalam membaca cakera -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Penyimpanan Permainan Gagal{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Tidak boleh memadamkan fail -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Pembukaan Permainan Gagal{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Kesilapan dalaman: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Simpanan permainan yang rosak - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Simpanan permainan ini telah dibuat dengan versi yang lebih baru diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 6654abd5f7..0096ed5655 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -4901,9 +4901,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Anslått STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Lagring pågår enda,{}vennligst vent til den er klar! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatisk lagring mislyktes STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan ikke lese fra disk -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Lagring av spillet mislyktes{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan ikke slette fil -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Lasting av spill mislyktes{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Intern feil: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Ødelagt lagret spill - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spillet er lagret i en nyere versjon diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index 5cc21b2d1b..e0adda199c 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -4036,9 +4036,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Berekna STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Lagring foregår framleis,{}ver venleg å vente til det er ferdig! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autolagring gjekk gale STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan ikkje lese frå disk -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Lagring av spelet mislukkast{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan ikkje slette fil -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Feil ved henting av spel{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Intern feil: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Øydelagd lagra spel - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spelet er lagra i ein nyare versjon diff --git a/src/lang/persian.txt b/src/lang/persian.txt index 68274b0bdf..f184fdb6d8 100644 --- a/src/lang/persian.txt +++ b/src/lang/persian.txt @@ -3494,9 +3494,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}در آ # Saveload messages STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}درایو خوانده می شود -STR_ERROR_GAME_SAVE_FAILED :{WHITE}بازی ذخیره نشد{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}فایل حذف نمی شود -STR_ERROR_GAME_LOAD_FAILED :{WHITE}بازی بارگزاری نشد{}{STRING} # Map generation messages diff --git a/src/lang/polish.txt b/src/lang/polish.txt index fb7c10d992..2f4ec34ac0 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -5285,9 +5285,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Szacowan STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Zapisywanie trwa,{}proszę zaczekać do zakończenia! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Błąd autozapisu STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Nie można odczytać napędu -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Nie można zapisać gry{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Nie można usunąć pliku -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Nie można wczytać gry{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Błąd wewnętrzny: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Zepsuta zapisana gra - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Zapisana gra zrobiona w nowszej wersji diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index b9b503ba75..e087cf92a8 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -4900,9 +4900,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Lucro Es STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Gravação ainda em curso,{}por favor aguarde! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Falha ao guardar automaticamente STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Não é possível ler unidade -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Falha ao guardar jogo{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Não é possível eliminar ficheiro -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Falha ao abrir jogo{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Erro interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Ficheiro corrompido - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Jogo gravado numa versão mais recente do jogo diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index ae588cd4d6..0d7686fa32 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -4892,9 +4892,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Venit es STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Salvarea se efectueaza încã,{}vã rugãm asteptati pânã se încheie! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Auto-salvarea a esuat STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Discul nu a putut fi citit -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Salvarea jocului eșuată{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Ștergerea fișierului a eșuat -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Încărcarea jocului eșuată{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Eroare internă: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Salvare eronată - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Salvarea a fost făcută cu o versiune mai nouă diff --git a/src/lang/russian.txt b/src/lang/russian.txt index f4d7f5da4f..ef7719ce68 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -5086,9 +5086,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Пред STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Идёт сохранение;{}пожалуйста, дождитесь завершения! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Ошибка автосохранения STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Не удалось прочитать диск -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Невозможно сохранить игру{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Невозможно удалить файл -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Невозможно загрузить игру{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Внутренняя ошибка: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Файл повреждён - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Сохранение сделано в более новой версии diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index a46c855be2..0eb1a5fe9c 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -5004,9 +5004,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Procena STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Čuvanje je još u toku,{}molimo sačekaj dok se ne završi! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Neuspešno automatsko čuvanje STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Čitanje sa diska nije uspelo -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Čuvanje pozicije nije uspelo{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Brisanje datoteke nije uspelo -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Učitavanje pozicije nije uspelo{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Unutrašnja greška: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Neispravno sačuvana igra - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Igra je sačuvana sa novijom verzijom igre diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index f6bed665f7..366cbcb7cf 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -4899,9 +4899,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}预计 STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}保存仍在继续{}请耐心等待…… STR_ERROR_AUTOSAVE_FAILED :{WHITE}自动保存失败 STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}不能读取驱动器 -STR_ERROR_GAME_SAVE_FAILED :{WHITE}保存游戏失败{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}不能删除文件 -STR_ERROR_GAME_LOAD_FAILED :{WHITE}游戏存档读取失败{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :内部错误: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :无法识别的存档 - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :该存档是新版本的。当前版本无法读取。 diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 4284d488a5..4366fb9c1c 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -4967,9 +4967,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Odhadova STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Ukladanie hry ešte beží,{}počkajte prosím na dokončenie! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatické ukladanie zlyhalo STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Zariadenie je nečitateľné -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Uloženie hry zlyhalo{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Súbor sa nedá vymazať -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Nahratie hry zlyhalo{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interná chyba: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Poškodená uložená hra - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Hra bola uložená vo vyššej verzii diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index de8be0e05c..2a88be52f2 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -4285,9 +4285,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Predvide STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Shranjevanje poteka,{}Prosim počakaj, da se zaključi! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Samodejno shranjevanje spodletelo STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Pogona ni mogoče prebrati -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Shranjevanje igre ni uspelo{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Datoteke ni mogoče zbrisati -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Nalaganje igre ni uspelo{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interna napaka: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Napaka v shranjeni igri - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Igra je bila shranjena z novejso razlicico diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index e6782944b2..7c3463a32a 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -4450,10 +4450,10 @@ STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacida STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Créditos de Transferencia: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS :{BLACK}Intervalo de mantenimiento: {LTBLUE}{COMMA}{NBSP}días{BLACK} {STRING} -STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES :{BLACK}Intervalo de mantenimiento: {LTBLUE}{COMMA}{NBSP}minutos{BLACK} {STRING} +STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES :{BLACK}Intervalo de mantenimiento: {LTBLUE}{COMMA}{NBSP}minuto{P "" s}{BLACK} {STRING} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Intervalo de mantenimiento: {LTBLUE}{COMMA}%{BLACK} {STRING} STR_VEHICLE_DETAILS_LAST_SERVICE_DATE :Último mantenimiento: {LTBLUE}{DATE_LONG} -STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO :Último mantenimiento: {LTBLUE}hace {NUM} minutos +STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO :Último mantenimiento: {LTBLUE}hace {NUM} minuto{P "" s} STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_DAYS :{BLACK}Incrementar el intervalo de mantenimiento en 10 días. Ctrl+clic para incrementar el período en 5 días STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_MINUTES :{BLACK}Incrementar el intervalo de mantenimiento en 5 minutos. Ctrl+clic para incrementar el período en un minuto STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP_PERCENT :{BLACK}Incrementar el intervalo de mantenimiento en un 10%. Ctrl+clic para incrementar el período en un 5% @@ -4644,7 +4644,7 @@ STR_ORDER_REFIT_ORDER :(Reformar a {ST STR_ORDER_REFIT_STOP_ORDER :(Reformar a {STRING} y detenerse) STR_ORDER_STOP_ORDER :(Detenerse) -STR_ORDER_WAIT_TO_UNBUNCH :(esperar para distanciarse) +STR_ORDER_WAIT_TO_UNBUNCH :(Esperar para distanciarse) STR_ORDER_GO_TO_STATION :{STRING} {STATION} {STRING} STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(No puede usar la estación){POP_COLOUR} {STRING} {STATION} {STRING} @@ -4900,9 +4900,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Ingreso STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}El guardado está en progreso,{}¡por favor espera hasta que termine! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Error al autoguardar STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}No es posible leer la unidad -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Error guardando partida{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}No es posible borrar el archivo -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Carga de Partida Errónea{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Error interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Partida guardada corrupta - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :La partida guardada ha sido realizada con una versión más nueva @@ -4996,7 +4994,7 @@ STR_ERROR_CAN_T_BUY_COMPANY :{WHITE}No se pu STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}No puede construirse la sede de la empresa... # Town related errors -STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}No se puede construir ningún municipio +STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}No se puede generar ningún municipio... STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}No se puede renombrar el municipio... STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}No se puede construir un municipio aquí... STR_ERROR_CAN_T_EXPAND_TOWN :{WHITE}No se puede expandir este municipio... diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index 8b127708c1..eec6d84e01 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -4781,9 +4781,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Ingreso STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Se sigue guardando la partida,{}¡por favor espera hasta que termine! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Error en guardado automático STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}No es posible leer la unidad de disco -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Error guardando partida{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}No es posible eliminar el archivo -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Error al cargar partida{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Error interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Archivo con errores - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :La partida guardada es de una versión más reciente del juego diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 532a9ca307..4e4c6ec3ab 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -4899,9 +4899,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Uppskatt STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Sparar fortfarande,{}vänta tills det är slutfört! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autosparning misslyckades STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan inte läsa från disk -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Sparandet av spelet misslyckades{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan inte ta bort filen -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Inläsningen av spelet misslyckades{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Internt fel: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Trasig sparfil - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Sparfilen är gjord med en nyare version diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index 4ff1227a29..2193062821 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -4498,9 +4498,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}மத STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}பதிவாகிக்கொண்டிருக்கிறது,{}சிறிது நேரம் பொறுங்கள்,! STR_ERROR_AUTOSAVE_FAILED :{WHITE}தானியங்கிபதிவு தோல்வியடைந்தது STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}கணினி சேமிப்பகத்தினை படிக்க இயலவில்லை -STR_ERROR_GAME_SAVE_FAILED :{WHITE}ஆட்டத்தின் படிவு தோல்வியடைந்தது{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}கோப்பினை நீக்க இயலவில்லை -STR_ERROR_GAME_LOAD_FAILED :{WHITE}ஆட்டம் பதிவேறுவது தோல்வியடைந்தது{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :உள்பிழை: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :உடைந்த பதிவுஆட்டம் - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :புதிய பதிப்பினால் பதிவுஆட்டம் உருவாக்கப்பட்டுள்ளது diff --git a/src/lang/thai.txt b/src/lang/thai.txt index 274479bae1..e943336d16 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -4242,9 +4242,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}รา STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}ขณะนี้กำลังบันทึก,{}โปรดรอจนกว่าจะเสร็จ! STR_ERROR_AUTOSAVE_FAILED :{WHITE}บันทึกอัตโนมัติล้มเหลว!!! STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}ไม่สามารถอ่านข้อมูลได้ -STR_ERROR_GAME_SAVE_FAILED :{WHITE}บันทึกเกมล้มเหลว!!!{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}ไม่สามารถทำการลบไฟล์ -STR_ERROR_GAME_LOAD_FAILED :{WHITE}โหลดเกมล้มเหลว{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :ข้อผิดพลาดจากภายใน: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :เกมที่บันทึกไว้ เสีย - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :เกมที่บันทึกไว้ สำหรับเวอร์ชันใหม่ diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index e25c202054..53866eae5f 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -4726,9 +4726,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}預估 STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}遊戲還在儲存中,{}請稍候! STR_ERROR_AUTOSAVE_FAILED :{WHITE}自動儲存失敗 STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}無法讀取磁碟 -STR_ERROR_GAME_SAVE_FAILED :{WHITE}遊戲儲存失敗{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}無法刪除檔案 -STR_ERROR_GAME_LOAD_FAILED :{WHITE}遊戲載入失敗{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :內部錯誤:{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :損壞的存檔 - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :該存檔是由較新版本的遊戲所產生 diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index 6d2ab610d8..2d5b6fa1a9 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -4898,9 +4898,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Tahmini STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Kayıt işlemi sürüyor,{}lütfen bitene kadar bekleyin! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Otomatik kayıt başarısız STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Sürücü okunamıyor -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Oyun kaydedilemedi{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Dosya silinemedi -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Dosya yüklenemedi{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :İç hata: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Bozuk kayıtlı oyun - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Oyun yeni bir sürümle kaydedilmiş. diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index b3d071428f..e0201cbca5 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -1871,7 +1871,7 @@ STR_CONFIG_SETTING_TIMETABLE_MODE_TICKS :Цоків STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Показувати час прибуття та відправлення у розкладах: {STRING} STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Відображати очікуваний час прибуття та відправлення у розкладі -STR_CONFIG_SETTING_QUICKGOTO :Прискорене створення наказів транспорту: {STRING} +STR_CONFIG_SETTING_QUICKGOTO :Прискорене створення завдань для транспорту: {STRING} STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :При відображенні списка завдань транспортного засобу автоматично натискається кнопка створення нових завдань STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :Тип колії на початку нової/завантаженної гри: {STRING} @@ -2227,8 +2227,8 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_IMPERIAL :Імперсь STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_METRIC :Метричні (л) STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_SI :СІ (м³) -STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE :Одиниці тяглової сили: {STRING} -STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_HELPTEXT :Якщо тяглова сила відображається на інтерфейсі: показувати її в обраній одиниці виміру +STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE :Одиниці тягового зусилля: {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_HELPTEXT :Якщо тягове зусилля відображається на інтерфейсі: показувати її в обраній одиниці виміру ###length 3 STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_IMPERIAL :Імперські (фунт-сили) STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_METRIC :Метричні (кгс) @@ -2413,17 +2413,17 @@ STR_LIVERY_AIRCRAFT_GROUP_EMPTY :Не налаш ###length 23 STR_LIVERY_DEFAULT :Базовий колір -STR_LIVERY_STEAM :Паровоз -STR_LIVERY_DIESEL :Тепловоз -STR_LIVERY_ELECTRIC :Електровоз +STR_LIVERY_STEAM :Паротяг +STR_LIVERY_DIESEL :Теплотяг +STR_LIVERY_ELECTRIC :Електротяг STR_LIVERY_MONORAIL :Монорейковий локомотив STR_LIVERY_MAGLEV :Магнітний локомотив -STR_LIVERY_DMU :Багатосекційний тепловоз -STR_LIVERY_EMU :Багатосекційний електровоз -STR_LIVERY_PASSENGER_WAGON_STEAM :Пасажирський вагон (паровоз) -STR_LIVERY_PASSENGER_WAGON_DIESEL :Пасажирський вагон (тепловоз) -STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Пасажирський вагон (електровоз) -STR_LIVERY_PASSENGER_WAGON_MONORAIL :Пасажирський вагон (монорейка) +STR_LIVERY_DMU :Багатосекційний теплотяг +STR_LIVERY_EMU :Багатосекційний електротяг +STR_LIVERY_PASSENGER_WAGON_STEAM :Пасажирський вагон (паротяговий) +STR_LIVERY_PASSENGER_WAGON_DIESEL :Пасажирський вагон (теплотяговий) +STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Пасажирський вагон (електротяговий) +STR_LIVERY_PASSENGER_WAGON_MONORAIL :Пасажирський вагон (монорейковий) STR_LIVERY_PASSENGER_WAGON_MAGLEV :Пасажирський вагон (маглев) STR_LIVERY_FREIGHT_WAGON :Вантажний вагон STR_LIVERY_BUS :Автобус @@ -2907,8 +2907,8 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Не п STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Підсвічувати зону покриття станції STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Приймає: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Постачає: {GOLD}{CARGO_LIST} -STR_STATION_BUILD_INFRASTRUCTURE_COST_YEAR :{BLACK} Вартість експлуатації: {GOLD}{CURRENCY_SHORT}/рік -STR_STATION_BUILD_INFRASTRUCTURE_COST_PERIOD :{BLACK} Вартість експлуатації: {GOLD}{CURRENCY_SHORT}/період +STR_STATION_BUILD_INFRASTRUCTURE_COST_YEAR :{BLACK}Вартість експлуатації: {GOLD}{CURRENCY_SHORT}/рік +STR_STATION_BUILD_INFRASTRUCTURE_COST_PERIOD :{BLACK}Вартість експлуатації: {GOLD}{CURRENCY_SHORT}/період # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Об'єднати станцію @@ -4213,8 +4213,8 @@ STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Швид STR_PURCHASE_INFO_SPEED :{BLACK}Швидкість: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Швидкість в океані: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_CANAL :{BLACK}Швидкість в каналі/річці: {GOLD}{VELOCITY} -STR_PURCHASE_INFO_RUNNINGCOST_YEAR :{BLACK} Вартість експлуатації: {GOLD}{CURRENCY_LONG}/рік -STR_PURCHASE_INFO_RUNNINGCOST_PERIOD :{BLACK} Вартість експлуатації: {GOLD}{CURRENCY_LONG}/період +STR_PURCHASE_INFO_RUNNINGCOST_YEAR :{BLACK}Вартість експлуатації: {GOLD}{CURRENCY_LONG}/рік +STR_PURCHASE_INFO_RUNNINGCOST_PERIOD :{BLACK}Вартість експлуатації: {GOLD}{CURRENCY_LONG}/період STR_PURCHASE_INFO_CAPACITY :{BLACK}Місткість: {GOLD}{CARGO_LONG} {STRING} STR_PURCHASE_INFO_REFITTABLE :(змінюється) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Рік випуску: {GOLD}{NUM}{BLACK} Вік: {GOLD}{COMMA} р{P ік оки оків} @@ -4231,7 +4231,7 @@ STR_PURCHASE_INFO_ALL_TYPES :Всі типи STR_PURCHASE_INFO_NONE :Нема STR_PURCHASE_INFO_ENGINES_ONLY :Тільки локомотиви STR_PURCHASE_INFO_ALL_BUT :Всі, крім {CARGO_LIST} -STR_PURCHASE_INFO_MAX_TE :{BLACK}Максимальна тягова сила: {GOLD}{FORCE} +STR_PURCHASE_INFO_MAX_TE :{BLACK}Максимальне тягове зусилля: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Дальність: {GOLD}{COMMA} клітинок STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Тип літака: {GOLD}{STRING} @@ -4534,7 +4534,7 @@ STR_VEHICLE_STATUS_TRAIN_STUCK :{ORANGE}Очі STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR :{ORANGE}Занадто далеко до наступного місця призначення STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL :{LTBLUE}{1:VELOCITY} - Прямує до {0:STATION} -STR_VEHICLE_STATUS_NO_ORDERS_VEL :{LTBLUE}{VELOCITY} - Без наказів +STR_VEHICLE_STATUS_NO_ORDERS_VEL :{LTBLUE}{VELOCITY} - Без завдань STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}{1:VELOCITY} - Прямує до {0:WAYPOINT} STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL :{ORANGE}{1:VELOCITY} - Прямує до {0:DEPOT} STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL :{LTBLUE}{1:VELOCITY} - Техогляд у {0:DEPOT} @@ -4565,8 +4565,8 @@ STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}Назв STR_VEHICLE_INFO_AGE :{COMMA} р{P ік оки оків} ({COMMA}) STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} р{P ік оки оків} ({COMMA}) -STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Вік: {LTBLUE}{STRING}{BLACK} Вартість експлуатації: {LTBLUE}{CURRENCY_LONG}/рік -STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD :{BLACK}Вік: {LTBLUE}{STRING}{BLACK} Вартість експлуатації: {LTBLUE}{CURRENCY_LONG}/період +STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Вік: {LTBLUE}{STRING}{BLACK}Вартість експлуатації: {LTBLUE}{CURRENCY_LONG}/рік +STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD :{BLACK}Вік: {LTBLUE}{STRING}{BLACK}Вартість експлуатації: {LTBLUE}{CURRENCY_LONG}/період STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Макс. швидкість: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Макс. швидкість: {LTBLUE}{VELOCITY} {BLACK}Тип: {LTBLUE}{STRING} @@ -4671,8 +4671,8 @@ STR_ORDERS_LIST_TOOLTIP :{BLACK}Марш STR_ORDER_INDEX :{COMMA}:{NBSP} STR_ORDER_TEXT :{STRING} {STRING} {STRING} {STRING} -STR_ORDERS_END_OF_ORDERS :- - Кінець наказів - - -STR_ORDERS_END_OF_SHARED_ORDERS :- - Кінець спільних наказів - - +STR_ORDERS_END_OF_ORDERS :- - Кінець завдань - - +STR_ORDERS_END_OF_SHARED_ORDERS :- - Кінець спільних завдань - - # Order bottom buttons STR_ORDER_NON_STOP :{BLACK}Без зупинки @@ -5041,9 +5041,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Приб STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Збереження...{}зачекайте, доки завершиться! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Помилка автозбереження STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Неможливо прочитати пристрій -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Помилка запису гри{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Неможливо стерти файл -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Помилка завантаження гри{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Внутрішня помилка: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Файл збереженої гри пошкоджений - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Файл збереженої гри зроблений більш новою версією @@ -5435,8 +5433,8 @@ STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN :{WHITE}Немо STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Літак у польоті # Order related errors -STR_ERROR_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Немає місця для наказів -STR_ERROR_TOO_MANY_ORDERS :{WHITE}Дуже багато наказів +STR_ERROR_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Немає місця для нових завдань +STR_ERROR_TOO_MANY_ORDERS :{WHITE}Занадто багато завдань STR_ERROR_CAN_T_INSERT_NEW_ORDER :{WHITE}Неможливо додати наказ... STR_ERROR_CAN_T_DELETE_THIS_ORDER :{WHITE}Неможливо видалити наказ... STR_ERROR_CAN_T_MODIFY_THIS_ORDER :{WHITE}Неможливо змінити наказ... @@ -5658,33 +5656,33 @@ STR_SV_STNAME_FALLBACK :{STRING}, ст ##id 0x8000 ###length 116 # Vehicle names -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (паровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_MJS_250_DIESEL :MJS 250 (тепловоз) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_KIRBY_PAUL_TANK_STEAM :Kirby Paul Tank (паротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_MJS_250_DIESEL :MJS 250 (теплотяг) STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_PLODDYPHUT_CHOO_CHOO :Ploddyphut Choo-Choo STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_POWERNAUT_CHOO_CHOO :Powernaut Choo-Choo STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_MIGHTYMOVER_CHOO_CHOO :MightyMover Choo-Choo -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_PLODDYPHUT_DIESEL :Ploddyphut (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_POWERNAUT_DIESEL :Powernaut (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_WILLS_2_8_0_STEAM :Wills 2-8-0 (паровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (паровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_GINZU_A4_STEAM :Ginzu 'A4' (паровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_8P_STEAM :SH '8P' (паровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_DASH_DIESEL :'Dash' (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_HENDRY_25_DIESEL :SH/Hendry '25' (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_UU_37_DIESEL :UU '37' (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_FLOSS_47_DIESEL :Floss '47' (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_CS_4000_DIESEL :CS 4000 (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_CS_2400_DIESEL :CS 2400 (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_CENTENNIAL_DIESEL :Centennial (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_KELLING_3100_DIESEL :Kelling 3100 (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_TURNER_TURBO_DIESEL :Turner Turbo (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_MJS_1000_DIESEL :MJS 1000 (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_125_DIESEL :SH '125' (тепловоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_30_ELECTRIC :SH '30' (електровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_40_ELECTRIC :SH '40' (електровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_T_I_M_ELECTRIC :'T.I.M.' (електровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_ASIASTAR_ELECTRIC :'AsiaStar' (електровоз) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_PLODDYPHUT_DIESEL :Ploddyphut (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_POWERNAUT_DIESEL :Powernaut (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_WILLS_2_8_0_STEAM :Wills 2-8-0 (паротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_CHANEY_JUBILEE_STEAM :Chaney 'Jubilee' (паротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_GINZU_A4_STEAM :Ginzu 'A4' (паротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_8P_STEAM :SH '8P' (паротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_MANLEY_MOREL_DMU_DIESEL :Manley-Morel DMU (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_DASH_DIESEL :'Dash' (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_HENDRY_25_DIESEL :SH/Hendry '25' (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_UU_37_DIESEL :UU '37' (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_FLOSS_47_DIESEL :Floss '47' (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_CS_4000_DIESEL :CS 4000 (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_CS_2400_DIESEL :CS 2400 (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_CENTENNIAL_DIESEL :Centennial (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_KELLING_3100_DIESEL :Kelling 3100 (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_TURNER_TURBO_DIESEL :Turner Turbo (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_MJS_1000_DIESEL :MJS 1000 (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_125_DIESEL :SH '125' (теплотяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_30_ELECTRIC :SH '30' (електротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_40_ELECTRIC :SH '40' (електротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_T_I_M_ELECTRIC :'T.I.M.' (електротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_ASIASTAR_ELECTRIC :'AsiaStar' (електротяг) STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PASSENGER_CAR :Пасажирський вагон STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_MAIL_VAN :Поштовий вагон STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COAL_CAR :Вагон для вугілля @@ -5712,8 +5710,8 @@ STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOY_VAN :Вагон дл STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_BATTERY_TRUCK :Вагон для батарейок STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FIZZY_DRINK_TRUCK :Вагон для газованої води STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PLASTIC_TRUCK :Вагон для пластиліну -STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_X2001_ELECTRIC :'X2001' (електровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (електровоз) +STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_X2001_ELECTRIC :'X2001' (електротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (електротяг) STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_WIZZOWOW_Z99 :Wizzowow Z99 STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PASSENGER_CAR :Пасажирський вагон STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_MAIL_VAN :Поштовий вагон @@ -5742,10 +5740,10 @@ STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :Вагон дл STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BATTERY_TRUCK :Вагон для батарейок STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :Вагон для газованої води STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PLASTIC_TRUCK :Вагон для пластиліну -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (електровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (електровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (електровоз) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (електровоз) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (електротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (електротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (електротяг) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (електротяг) STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PASSENGER_CAR :Пасажирський вагон STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_MAIL_VAN :Поштовий вагон diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index b23f17c21b..e92e3b05f7 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -4643,7 +4643,7 @@ STR_ORDER_REFIT_ORDER :(Cải biến t STR_ORDER_REFIT_STOP_ORDER :(Cải biến thành {STRING} và dừng) STR_ORDER_STOP_ORDER :(Dừng) -STR_ORDER_WAIT_TO_UNBUNCH :(chờ để gỡ gộp) +STR_ORDER_WAIT_TO_UNBUNCH :(Chờ để gỡ gộp) STR_ORDER_GO_TO_STATION :{STRING} {STATION} {STRING} STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(Không thể sử dụng trạm){POP_COLOUR} {STRING} {STATION} {STRING} @@ -4899,9 +4899,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Thu nh STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Đang lưu vào đĩa,{}hãy chờ cho đến khi hoàn thành! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Tự lưu gặp lỗi STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Không đọc được đĩa -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Lưu ván chơi có lỗi{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Không thể xoá file -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Nạp ván chơi thất bại{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Lỗi kỹ thuật: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Bản lưu ván chơi bị hỏng - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Bản lưu ván chơi dành cho phiên bản mới hơn diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 1a4deca7a4..c92814a9d1 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -4899,9 +4899,7 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Amcangyf STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Mae'r gêm wrthi'n cael ei chadw,{}Arhoswch nes y bydd y broses wedi'i chwblhau! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Methodd yr Awtogadw STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Methu darllen y gyriant -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Methwyd â Chadw Gêm{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Methu Dileu Ffeil -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Methwyd â Llwytho Gêm{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Gwall mewnol: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Mae'r gêm a gadwyd wedi torri - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Mae'r gêm a gadwyd wedi ei chadw mewn fersiwn ddiweddarach From 975082659087af55f9da3738cb657334e6111625 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 2 Apr 2024 13:29:15 +0100 Subject: [PATCH 08/29] Fix a29766d: Wrong scrolling dropdown list position with RTL. (#12412) --- src/dropdown.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dropdown.cpp b/src/dropdown.cpp index 7c7285a8e8..292d524132 100644 --- a/src/dropdown.cpp +++ b/src/dropdown.cpp @@ -192,7 +192,12 @@ struct DropdownWindow : Window { this->position.y = button_rect.bottom + 1; } - this->position.x = (_current_text_dir == TD_RTL) ? button_rect.right + 1 - (int)widget_dim.width : button_rect.left; + if (_current_text_dir == TD_RTL) { + /* In case the list is wider than the parent button, the list should be right aligned to the button and overflow to the left. */ + this->position.x = button_rect.right + 1 - (int)(widget_dim.width + (list_dim.height > widget_dim.height ? NWidgetScrollbar::GetVerticalDimension().width : 0)); + } else { + this->position.x = button_rect.left; + } this->items_dim = widget_dim; this->GetWidget(WID_DM_SHOW_SCROLL)->SetDisplayedPlane(list_dim.height > widget_dim.height ? 0 : SZSP_NONE); From 931aa39018ed740a70cc38acd52991d2a979dc95 Mon Sep 17 00:00:00 2001 From: translators Date: Wed, 3 Apr 2024 04:40:31 +0000 Subject: [PATCH 09/29] Update: Translations from eints english (au): 2 changes by krysclarke swedish: 2 changes by joeax910 greek: 2 changes by gh658804 russian: 3 changes by its5Q catalan: 2 changes by J0anJosep spanish: 2 changes by MontyMontana portuguese: 2 changes by azulcosta portuguese (brazilian): 27 changes by pasantoro polish: 2 changes by pAter-exe --- src/lang/brazilian_portuguese.txt | 52 ++++++++++++++++--------------- src/lang/catalan.txt | 2 ++ src/lang/english_AU.txt | 2 ++ src/lang/greek.txt | 2 ++ src/lang/polish.txt | 2 ++ src/lang/portuguese.txt | 2 ++ src/lang/russian.txt | 4 ++- src/lang/spanish.txt | 2 ++ src/lang/swedish.txt | 2 ++ 9 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index aa8b7d6a99..c341fd49fd 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -405,7 +405,7 @@ STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construi STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Construir infraestrutura rodoviária STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Construir infraestrutura para bondes STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Construir infraestrutura hidroviária -STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Construir aeroportos +STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Construir aeroporto STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Abrir menu de paisagismo, menu de árvores ou colocar uma placa STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Abrir janela de som/música STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Abrir última mensagem/notícia, histórico de mensagens ou apagar todas as mensagens @@ -506,7 +506,7 @@ STR_ROAD_MENU_ROAD_CONSTRUCTION :Construção de STR_ROAD_MENU_TRAM_CONSTRUCTION :Construção de linha de bonde # Waterways construction menu -STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION :Construção de hidrovias +STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION :Construção de hidrovia # Aairport construction menu STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION :Construção de aeroporto @@ -680,7 +680,7 @@ STR_PERFORMANCE_DETAIL_LOAN_TOOLTIP :{BLACK}O montan STR_PERFORMANCE_DETAIL_TOTAL_TOOLTIP :{BLACK}Total de pontos de pontos possíveis # Music window -STR_MUSIC_JAZZ_JUKEBOX_CAPTION :{WHITE}Jukebox de Jazz +STR_MUSIC_JAZZ_JUKEBOX_CAPTION :{WHITE}Jukebox de Música STR_MUSIC_PLAYLIST_ALL :{TINY_FONT}{BLACK}Todos STR_MUSIC_PLAYLIST_OLD_STYLE :{TINY_FONT}{BLACK}Antigo STR_MUSIC_PLAYLIST_NEW_STYLE :{TINY_FONT}{BLACK}Moderno @@ -1530,8 +1530,8 @@ STR_CONFIG_SETTING_ERRMSG_DURATION :Duração da me STR_CONFIG_SETTING_ERRMSG_DURATION_HELPTEXT :Tempo de exibição de mensagens de erro numa janela vermelha. Algumas mensagens de erro (crítico) não são fechadas automaticamente após este tempo e precisam ser fechadas manualmente STR_CONFIG_SETTING_HOVER_DELAY :Mostrar textos de ajuda: {STRING} -STR_CONFIG_SETTING_HOVER_DELAY_HELPTEXT :Tempo que o cursor deve ficar sobre algum elemento da interface para que os textos de ajuda sejam mostrados. Outro modo de exibir os textos de ajuda é fixar este valor em 0 e clicar com o botão direito do mouse -STR_CONFIG_SETTING_HOVER_DELAY_VALUE :Manter o cursor por {COMMA} milissegundo{P 0 "" s} +STR_CONFIG_SETTING_HOVER_DELAY_HELPTEXT :Tempo que o ponteiro do mouse deve ficar sobre algum elemento da interface para que os textos de ajuda sejam mostrados. Outro modo de exibir os textos de ajuda é fixar este valor em 0 e clicar com o botão direito do mouse +STR_CONFIG_SETTING_HOVER_DELAY_VALUE :Manter o ponteiro por {COMMA} milissegundo{P 0 "" s} ###setting-zero-is-special STR_CONFIG_SETTING_HOVER_DELAY_DISABLED :Botão direito @@ -1673,7 +1673,7 @@ STR_CONFIG_SETTING_SCROLLWHEEL_SCROLL :Mover o mapa STR_CONFIG_SETTING_SCROLLWHEEL_OFF :Desativado STR_CONFIG_SETTING_OSK_ACTIVATION :Teclado virtual: {STRING} -STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Escolher o método para mostrar o teclado virtual para inserir texto em caixas de diálogo usando o cursor. Isto é útil para dispositivos pequenos que não possuem teclados +STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Escolher o método para mostrar o teclado virtual para inserir texto em caixas de diálogo usando apenas o cursor. Isto é útil para dispositivos pequenos que não possuem teclados ###length 4 STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :Desativado STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Clique duplo @@ -1736,7 +1736,7 @@ STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Mostrar chegada STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Mostrar os horários previstos de chegada e de partida nos quadros de horários STR_CONFIG_SETTING_QUICKGOTO :Criação rápida de ordens de veículos: {STRING} -STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :Pré-selecionar o cursor 'Ir Para' ao abrir a janela de ordens +STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :Pré-selecionar o 'cursor Ir para' ao abrir a janela de ordens STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :Tipo de trilho padrão (ao iniciar novo/abrir jogo): {STRING} STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :Tipo de trilho a ser selecionado ao iniciar novo/abrir um jogo. 'Primeiro disponível' seleciona o tipo de trilho mais antigo. 'Último disponível' seleciona o tipo mais novo de trilho e 'Mais utilizado' seleciona o tipo que é mais usado atualmente @@ -2912,8 +2912,8 @@ STR_STATION_BUILD_CARGO_TRAM_ORIENTATION :{WHITE}Orienta STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP :{BLACK}Escolher a orientação da estação de bondes de carga # Waterways toolbar (last two for SE only) -STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Construção de Hidrovias -STR_WATERWAYS_TOOLBAR_CAPTION_SE :{WHITE}Hidrovias +STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Construção de Hidrovia +STR_WATERWAYS_TOOLBAR_CAPTION_SE :{WHITE}Hidrovia STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Construir canais. Pressione também Shift para só mostrar o custo estimado STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Construir eclusas. Pressione também Shift para só mostrar o custo estimado STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Construir depósito de embarcações (para compra e manutenção de embarcações). Pressione também Shift para só mostrar o custo estimado @@ -2982,11 +2982,11 @@ STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Plantar STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Plantar Aleatoriamente STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plantar árvores aleatoriamente no terreno STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal -STR_TREES_MODE_NORMAL_TOOLTIP :{BLACK}Plantar árvores isoladas ao arrastar o cursor sobre o terreno +STR_TREES_MODE_NORMAL_TOOLTIP :{BLACK}Plantar árvores isoladas ao arrastar o ponteiro sobre o terreno STR_TREES_MODE_FOREST_SM_BUTTON :{BLACK}Bosque -STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}Plantar florestas pequenas ao arrastar o cursor sobre o terreno +STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}Plantar florestas pequenas ao arrastar o ponteiro sobre o terreno STR_TREES_MODE_FOREST_LG_BUTTON :{BLACK}Floresta -STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Plantar florestas grandes ao arrastar o cursor sobre o terreno +STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Plantar florestas grandes ao arrastar o ponteiro sobre o terreno # Land generation window (SE) STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION :{WHITE}Geração de Terreno @@ -4900,7 +4900,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Receita STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Gravação ainda sendo executada,{}por favor aguarde até terminar! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Salvamento automático falhou STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Não é possível ler a unidade +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Falha ao salvar jogo... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Não é possível apagar o arquivo +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Falha ao abrir jogo... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Erro interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Jogo salvo está corrompido - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Jogo salvo foi feito com uma versão mais recente @@ -4952,7 +4954,7 @@ STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto... STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}A construção deve ser demolida primeiro STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área... -STR_ERROR_SITE_UNSUITABLE :{WHITE}... local inadequado +STR_ERROR_SITE_UNSUITABLE :{WHITE}... local não adequado STR_ERROR_ALREADY_BUILT :{WHITE}... já construído STR_ERROR_OWNED_BY :{WHITE}... pertence a {STRING} STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... área pertence a outra empresa @@ -4970,9 +4972,9 @@ STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE :{WHITE}A autori STR_ERROR_BRIBE_FAILED :{WHITE}A sua tentativa de suborno foi descoberta por um investigador regional # Levelling errors -STR_ERROR_CAN_T_RAISE_LAND_HERE :{WHITE}Não é possível elevar terreno aqui... -STR_ERROR_CAN_T_LOWER_LAND_HERE :{WHITE}Não é possível abaixar terreno aqui... -STR_ERROR_CAN_T_LEVEL_LAND_HERE :{WHITE}Não é possível nivelar o terreno aqui... +STR_ERROR_CAN_T_RAISE_LAND_HERE :{WHITE}Não é possível elevar este terreno... +STR_ERROR_CAN_T_LOWER_LAND_HERE :{WHITE}Não é possível abaixar este terreno... +STR_ERROR_CAN_T_LEVEL_LAND_HERE :{WHITE}Não é possível nivelar este terreno... STR_ERROR_EXCAVATION_WOULD_DAMAGE :{WHITE}A escavação danificaria o túnel STR_ERROR_ALREADY_AT_SEA_LEVEL :{WHITE}... já está ao nível do mar STR_ERROR_TOO_HIGH :{WHITE}... muito alto @@ -5080,7 +5082,7 @@ STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT :{WHITE}Não é STR_ERROR_CAN_T_POSITION_BUOY_HERE :{WHITE}Não é possível colocar boia aqui... STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}Não é possível alterar o nome do ponto de controle... -STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}Não é possível remover ponto de controle de trem daqui... +STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}Não é possível remover ponto de controle de trem aqui... STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}Precisa remover o ponto de controle ferroviário primeiro STR_ERROR_BUOY_IN_THE_WAY :{WHITE}... boia no caminho STR_ERROR_BUOY_IS_IN_USE :{WHITE}... boia está em uso por outra empresa! @@ -5135,25 +5137,25 @@ STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Passagen STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Passagens de nível não são permitidas para este tipo de estrada STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Não é possível construir sinais aqui... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Não é possível construir ferrovia aqui... -STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Não é possível remover ferrovia daqui... -STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Não é possível remover sinais daqui... -STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE :{WHITE}Não é possível converter os sinais daqui... +STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Não é possível remover ferrovia aqui... +STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Não é possível remover sinais aqui... +STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE :{WHITE}Não é possível converter os sinais aqui... STR_ERROR_THERE_IS_NO_RAILROAD_TRACK :{WHITE}... não existe uma ferrovia STR_ERROR_THERE_ARE_NO_SIGNALS :{WHITE}... não existem sinais -STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}Não é possível converter o tipo de trilho daqui... +STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}Não é possível converter o tipo de trilho aqui... # Road construction errors STR_ERROR_MUST_REMOVE_ROAD_FIRST :{WHITE}Precisa remover a estrada primeiro STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION :{WHITE}... estradas de sentido único não podem ter junções STR_ERROR_CAN_T_BUILD_ROAD_HERE :{WHITE}Não é possível construir estrada aqui... STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE :{WHITE}Não é possível construir linha de bonde aqui... -STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Não é possível remover estrada daqui... -STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Não é possível remover linha de bonde daqui... +STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Não é possível remover estrada aqui... +STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Não é possível remover linha de bonde aqui... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... não existe uma estrada STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... não existe uma linha de bonde -STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Não é possível converter o tipo de estrada daqui... -STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Não é possível converter o tipo de linha de bonde daqui... +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Não é possível converter o tipo de estrada aqui... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Não é possível converter o tipo de linha de bonde aqui... STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Estrada não adequada STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Linha de bonde não adequada diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 113987983f..519ab8d79d 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -4900,7 +4900,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Ingresso STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Es desa la partida.{}Espera que acabi l'operació! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Ha fallat el desat automàtic STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Impossible llegir la unitat de disc +STR_ERROR_GAME_SAVE_FAILED :{WHITE}La partida no s'ha pogut desar... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Impossible esborrar l'arxiu +STR_ERROR_GAME_LOAD_FAILED :{WHITE}La partida no s'ha pogut carregar... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Error Intern: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :L'arxiu de la partida està corromput - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :La partida està desada amb una versió més moderna diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 9f4762c403..03b42319c3 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -4899,7 +4899,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Estimate STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Saving still in progress,{}please wait until it is finished! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autosave failed STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Unable to read drive +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Game save failed... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Unable to delete file +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Game load failed... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Internal error: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Broken savegame - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Savegame is made with newer version diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 18af4e3dd8..556f5ee773 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -4999,7 +4999,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Υπολ STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Η αποθήκευση είναι σε εξέλιξη,{}παρακαλώ περιμένετε να τελειώσει! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Η αυτόματη αποθήκευση απέτυχε STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Αδύνατη η ανάγνωση του δίσκου +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Η αποθήκευση του παιχνιδιού απέτυχε... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Αδύνατη η διαγραφή του αρχείου +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Το φόρτωμα του παιχνιδιού απέτυχε... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Εσωτερικό λάθος: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Χαλασμένο αποθηκευμένο παιχνίδι - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Το αποθηκευμένο παιχνίδι είναι φτιαγμένο με νεότερη έκδοση diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 2f4ec34ac0..8ac204df73 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -5285,7 +5285,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Szacowan STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Zapisywanie trwa,{}proszę zaczekać do zakończenia! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Błąd autozapisu STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Nie można odczytać napędu +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Nie można zapisać gry... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Nie można usunąć pliku +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Nie można wczytać gry... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Błąd wewnętrzny: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Zepsuta zapisana gra - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Zapisana gra zrobiona w nowszej wersji diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index e087cf92a8..8fe6e61310 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -4900,7 +4900,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Lucro Es STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Gravação ainda em curso,{}por favor aguarde! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Falha ao guardar automaticamente STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Não é possível ler unidade +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Falha ao guardar jogo... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Não é possível eliminar ficheiro +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Falha ao carregar jogo... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Erro interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Ficheiro corrompido - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Jogo gravado numa versão mais recente do jogo diff --git a/src/lang/russian.txt b/src/lang/russian.txt index ef7719ce68..1ced93984e 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -2822,7 +2822,7 @@ STR_CONTENT_OPEN_URL :{BLACK}Веб- STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Посетить веб-сайт с информацией об этом модуле STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Скачать STR_CONTENT_DOWNLOAD_CAPTION_TOOLTIP :{BLACK}Начать загрузку выбранного контента -STR_CONTENT_TOTAL_DOWNLOAD_SIZE :{SILVER}Всего для загруки: {WHITE}{BYTES} +STR_CONTENT_TOTAL_DOWNLOAD_SIZE :{SILVER}Всего для загрузки: {WHITE}{BYTES} STR_CONTENT_DETAIL_TITLE :{SILVER}ИНФОРМАЦИЯ О КОНТЕНТЕ ###length 5 @@ -5086,7 +5086,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Пред STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Идёт сохранение;{}пожалуйста, дождитесь завершения! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Ошибка автосохранения STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Не удалось прочитать диск +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Невозможно сохранить игру... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Невозможно удалить файл +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Невозможно загрузить игру... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Внутренняя ошибка: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Файл повреждён - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Сохранение сделано в более новой версии diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 7c3463a32a..76df3cab47 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -4900,7 +4900,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Ingreso STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}El guardado está en progreso,{}¡por favor espera hasta que termine! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Error al autoguardar STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}No es posible leer la unidad +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Error al guardar la partida... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}No es posible borrar el archivo +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Error al cargar la partida... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Error interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Partida guardada corrupta - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :La partida guardada ha sido realizada con una versión más nueva diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 4e4c6ec3ab..f7627ee22c 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -4899,7 +4899,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Uppskatt STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Sparar fortfarande,{}vänta tills det är slutfört! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autosparning misslyckades STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan inte läsa från disk +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Sparandet av spelet misslyckades... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan inte ta bort filen +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Inläsningen av spelet misslyckades... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Internt fel: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Trasig sparfil - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Sparfilen är gjord med en nyare version From 243c6bead327f2654455c8da6fc1a1cef4f5cf62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Wed, 3 Apr 2024 23:16:36 +0200 Subject: [PATCH 10/29] Fix #12415, 9c49a61, df400ef: Aircraft::tile is valid only for front vehicle (#12416) --- src/aircraft.h | 1 + src/economy.cpp | 14 +++++++------- src/vehicle_base.h | 2 ++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/aircraft.h b/src/aircraft.h index ef33f85898..6c47d6df56 100644 --- a/src/aircraft.h +++ b/src/aircraft.h @@ -111,6 +111,7 @@ struct Aircraft final : public SpecializedVehicle { void OnNewEconomyDay() override; uint Crash(bool flooded = false) override; TileIndex GetOrderStationLocation(StationID station) override; + TileIndex GetCargoTile() const override { return this->First()->tile; } ClosestDepot FindClosestDepot() override; /** diff --git a/src/economy.cpp b/src/economy.cpp index 9e880a51df..868b1acb5a 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1301,7 +1301,7 @@ void PrepareUnload(Vehicle *front_v) front_v->last_station_visited, next_station, front_v->current_order.GetUnloadType(), ge, front_v->cargo_payment, - v->tile); + v->GetCargoTile()); if (v->cargo.UnloadCount() > 0) SetBit(v->vehicle_flags, VF_CARGO_UNLOADING); } } @@ -1441,7 +1441,7 @@ struct ReturnCargoAction */ bool operator()(Vehicle *v) { - v->cargo.Return(UINT_MAX, &this->st->goods[v->cargo_type].cargo, this->next_hop, v->tile); + v->cargo.Return(UINT_MAX, &this->st->goods[v->cargo_type].cargo, this->next_hop, v->GetCargoTile()); return true; } }; @@ -1476,7 +1476,7 @@ struct FinalizeRefitAction { if (this->do_reserve) { this->st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(), - &v->cargo, this->next_station, v->tile); + &v->cargo, this->next_station, v->GetCargoTile()); } this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount(); return true; @@ -1567,7 +1567,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, *next_station, v->tile); + &v->cargo, *next_station, v->GetCargoTile()); } return true; @@ -1701,7 +1701,7 @@ static void LoadUnloadVehicle(Vehicle *front) uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER); if (v->cargo_cap < new_remaining) { /* Return some of the reserved cargo to not overload the vehicle. */ - v->cargo.Return(new_remaining - v->cargo_cap, &ge->cargo, INVALID_STATION, v->tile); + v->cargo.Return(new_remaining - v->cargo_cap, &ge->cargo, INVALID_STATION, v->GetCargoTile()); } /* Keep instead of delivering. This may lead to no cargo being unloaded, so ...*/ @@ -1728,7 +1728,7 @@ static void LoadUnloadVehicle(Vehicle *front) } } - amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, payment, v->tile); + amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, payment, v->GetCargoTile()); remaining = v->cargo.UnloadCount() > 0; if (amount_unloaded > 0) { dirty_vehicle = true; @@ -1798,7 +1798,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, next_station, v->tile); + uint loaded = ge->cargo.Load(cap_left, &v->cargo, next_station, v->GetCargoTile()); 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/vehicle_base.h b/src/vehicle_base.h index 592063323c..6accdd7425 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -791,6 +791,8 @@ public: */ virtual TileIndex GetOrderStationLocation([[maybe_unused]] StationID station) { return INVALID_TILE; } + virtual TileIndex GetCargoTile() const { return this->tile; } + /** * Find the closest depot for this vehicle and tell us the location, * DestinationID and whether we should reverse. From 08cf106fc613c56ff8628046440e243b5dcd58c7 Mon Sep 17 00:00:00 2001 From: translators Date: Thu, 4 Apr 2024 04:41:30 +0000 Subject: [PATCH 11/29] Update: Translations from eints english (us): 2 changes by 2TallTyler finnish: 2 changes by hpiirai ukrainian: 2 changes by Quantom2 danish: 2 changes by beruic portuguese (brazilian): 22 changes by pasantoro --- src/lang/brazilian_portuguese.txt | 44 +++++++++++++++---------------- src/lang/danish.txt | 2 ++ src/lang/english_US.txt | 2 ++ src/lang/finnish.txt | 2 ++ src/lang/ukrainian.txt | 2 ++ 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index c341fd49fd..f14c43a26b 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -270,7 +270,7 @@ STR_UNITS_PERIODS :{NUM}{NBSP}per # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Filtro: STR_LIST_FILTER_OSKTITLE :{BLACK}Inserir uma ou mais palavras-chave para filtrar a lista -STR_LIST_FILTER_TOOLTIP :{BLACK}Digite uma ou mais palavras-chave para procurar na lista +STR_LIST_FILTER_TOOLTIP :{BLACK}Introduza uma ou mais palavras-chave para procurar na lista STR_TOOLTIP_GROUP_ORDER :{BLACK}Escolher a ordem de agrupamento STR_TOOLTIP_SORT_ORDER :{BLACK}Escolher a ordenação (descendente/ascendente) @@ -418,7 +418,7 @@ STR_SCENEDIT_TOOLBAR_OPENTTD :{YELLOW}OpenTTD STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR :{YELLOW}Editor de Cenário STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD :{BLACK}Mover a data inicial 1 ano para trás STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD :{BLACK}Mover a data inicial 1 ano para frente -STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Clique para digitar o ano de início +STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Clique para alterar o ano de início STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Abrir mapa, visualização extra, lista de placas, de localidades ou de indústrias STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Abrir menu de paisagismo ou gerar um novo mundo STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Construir ou gerar localidades @@ -2420,8 +2420,8 @@ STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Adiciona STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Iniciar servidor STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Iniciar um servidor próprio -STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Digitar o seu nome -STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Digitar o endereço de servidor ou código de convite +STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Introduza o seu nome +STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Introduza o endereço de servidor ou código de convite # Start new multiplayer server STR_NETWORK_START_SERVER_CAPTION :{WHITE}Iniciar novo jogo multijogador @@ -2440,7 +2440,7 @@ STR_NETWORK_START_SERVER_COMPANIES_SELECT :{BLACK}{NUM} em STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES :{BLACK}Número máximo de empresas: STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES_TOOLTIP :{BLACK}Limitar o servidor a um certo número de empresas -STR_NETWORK_START_SERVER_NEW_GAME_NAME_OSKTITLE :{BLACK}Coloque o nome para o jogo em rede +STR_NETWORK_START_SERVER_NEW_GAME_NAME_OSKTITLE :{BLACK}Introduza um nome para o jogo em rede # Network connecting window STR_NETWORK_CONNECTING_CAPTION :{WHITE}Conectando... @@ -2461,8 +2461,8 @@ STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Obtendo STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Desconectar -STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Servidor protegido. Digite a senha -STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Empresa protegida. Digite a senha +STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Servidor protegido. Introduza a senha +STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Empresa protegida. Introduza a senha # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Jogadores conectados @@ -2560,7 +2560,7 @@ STR_NETWORK_CHAT_CLIENT :[Privado] {STRI STR_NETWORK_CHAT_TO_CLIENT :[Privado] Para {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_ALL :[Todos] {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_EXTERNAL :[{3:STRING}] {0:STRING}: {WHITE}{1:STRING} -STR_NETWORK_CHAT_OSKTITLE :{BLACK}Digitar a mensagem para conversar na rede +STR_NETWORK_CHAT_OSKTITLE :{BLACK}Introduza a mensagem para conversar na rede # Network messages STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Não foram encontradas interfaces de rede ou o jogo foi compilado sem ENABLE_NETWORK @@ -2646,14 +2646,14 @@ STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servid STR_NETWORK_MESSAGE_KICKED :*** {STRING} foi expulso. Motivo: ({STRING}) STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Falha ao registrar o servidor -STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE :{WHITE}Outro servidor com o mesmo código de convite foi registrado. Mudando para o tipo de jogo "local". +STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE :{WHITE}Outro servidor com o mesmo código de convite foi registrado. Mudando o jogo para o tipo "local". STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}O seu servidor não permite conexões remotas STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Outros jogadores não poderão se conectar ao seu servidor # Content downloading window STR_CONTENT_TITLE :{WHITE}Download de conteúdo STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo -STR_CONTENT_TYPE_CAPTION_TOOLTIP :{BLACK}Tipo do conteúdo +STR_CONTENT_TYPE_CAPTION_TOOLTIP :{BLACK}Tipo de conteúdo STR_CONTENT_NAME_CAPTION :{BLACK}Nome STR_CONTENT_NAME_CAPTION_TOOLTIP :{BLACK}Nome do conteúdo STR_CONTENT_MATRIX_TOOLTIP :{BLACK}Clique numa linha para ver os detalhes{}Clique na caixa de seleção para marcar e fazer o download @@ -3014,8 +3014,8 @@ STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expandir STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Fazer com que todas as localidades cresçam ligeiramente STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nome da localidade: -STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Digitar o nome da localidade -STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Clique para digitar o nome da localidade +STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Introduza o nome da localidade +STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Clique para editar o nome da localidade STR_FOUND_TOWN_NAME_RANDOM_BUTTON :{BLACK}Nome aleatório STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP :{BLACK}Gerar novo nome aleatório @@ -3283,7 +3283,7 @@ STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Você q STR_SAVELOAD_DIRECTORY :{STRING} (Diretório) STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (Diretório raiz) -STR_SAVELOAD_OSKTITLE :{BLACK}Digitar um nome para o jogo que será gravado +STR_SAVELOAD_OSKTITLE :{BLACK}Introduza um nome para o jogo que será gravado # World generation STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}Geração de Mapas @@ -3459,7 +3459,7 @@ STR_NEWGRF_SETTINGS_INCOMPATIBLE :{RED}Incompatí # NewGRF save preset window STR_SAVE_PRESET_CAPTION :{WHITE}Salvar predefinição STR_SAVE_PRESET_LIST_TOOLTIP :{BLACK}Lista de predefinições disponíveis, selecione uma para copiar o nome e usar na gravação abaixo -STR_SAVE_PRESET_TITLE :{BLACK}Digitar um nome para a predefinição +STR_SAVE_PRESET_TITLE :{BLACK}Introduza um nome para a predefinição STR_SAVE_PRESET_EDITBOX_TOOLTIP :{BLACK}Nome que está selecionado para salvar a predefinição STR_SAVE_PRESET_CANCEL :{BLACK}Cancelar STR_SAVE_PRESET_CANCEL_TOOLTIP :{BLACK}Não alterar a predefinição @@ -3603,7 +3603,7 @@ STR_EDIT_SIGN_LOCATION_TOOLTIP :{BLACK}Centrali STR_EDIT_SIGN_NEXT_SIGN_TOOLTIP :{BLACK}Ir para a próxima placa STR_EDIT_SIGN_PREVIOUS_SIGN_TOOLTIP :{BLACK}Ir para a placa anterior -STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Digitar um nome para a placa +STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Introduza um nome para a placa # Town directory window STR_TOWN_DIRECTORY_CAPTION :{WHITE}Localidades @@ -3920,7 +3920,7 @@ STR_COMPANY_VIEW_PRESIDENT_NAME_TOOLTIP :{BLACK}Alterar STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION :Nome da Empresa STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION :Nome do Presidente -STR_COMPANY_VIEW_GIVE_MONEY_QUERY_CAPTION :Digitar a quantia de dinheiro que você quer dar +STR_COMPANY_VIEW_GIVE_MONEY_QUERY_CAPTION :Introduza o valor que você quer dar STR_BUY_COMPANY_MESSAGE :{WHITE}Estamos procurando uma empresa de transportes para comprar a nossa empresa.{}{}Você deseja comprar {COMPANY} por {CURRENCY_LONG}? STR_BUY_COMPANY_HOSTILE_TAKEOVER :{WHITE}Na aquisição hostil de {COMPANY} você irá adquirir todos os ativos, liquidar todos os empréstimos e pagar dois anos de lucros.{}{}O total estimado é de {CURRENCY_LONG}.{}{}Você deseja continuar esta aquisição hostil? @@ -4271,9 +4271,9 @@ STR_ENGINE_PREVIEW_SHIP :{G=f}embarcaç STR_ENGINE_PREVIEW_TEXT3 :{BLACK}{STRING}{}{5:STRING}{}{STRING} STR_ENGINE_PREVIEW_TEXT4 :{BLACK}{STRING}{}{STRING}{}{STRING}{}{STRING} STR_ENGINE_PREVIEW_COST_WEIGHT :Custo: {CURRENCY_LONG} Peso: {WEIGHT_SHORT} -STR_ENGINE_PREVIEW_COST_MAX_SPEED :Custo: {CURRENCY_LONG} Velocidade máx.: {VELOCITY} +STR_ENGINE_PREVIEW_COST_MAX_SPEED :Custo: {CURRENCY_LONG} Veloc. máx.: {VELOCITY} STR_ENGINE_PREVIEW_SPEED_POWER :Velocidade: {VELOCITY} Potência: {POWER} -STR_ENGINE_PREVIEW_SPEED_POWER_MAX_TE :Velocidade: {VELOCITY} Potência: {POWER} Tração máx.: {FORCE} +STR_ENGINE_PREVIEW_SPEED_POWER_MAX_TE :Veloc.: {VELOCITY} Potência: {POWER} Tração máx.: {FORCE} STR_ENGINE_PREVIEW_TYPE :Tipo de aeronave: {STRING} STR_ENGINE_PREVIEW_TYPE_RANGE :Tipo de aeronave: {STRING} Autonomia: {COMMA} quadrados STR_ENGINE_PREVIEW_RUNCOST_YEAR :Custo Operacional: {CURRENCY_LONG}/ano @@ -4431,9 +4431,9 @@ STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD :{BLACK}Idade: { STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Velocidade máx.: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Velocidade máx.: {LTBLUE}{VELOCITY} {BLACK}Tipo de aeronave: {LTBLUE}{STRING} -STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Velocidade máx.: {LTBLUE}{VELOCITY} {BLACK}Tipo de aeronave: {LTBLUE}{STRING} {BLACK}Autonomia: {LTBLUE}{COMMA} quadrados -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potência: {LTBLUE}{POWER}{BLACK} Velocidade máx.: {LTBLUE}{VELOCITY} -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potência: {LTBLUE}{POWER}{BLACK} Velocidade máx.: {LTBLUE}{VELOCITY} {BLACK}Força de Tração máx.: {LTBLUE}{FORCE} +STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Veloc. máx.: {LTBLUE}{VELOCITY} {BLACK}Tipo de aeronave: {LTBLUE}{STRING} {BLACK}Autonomia: {LTBLUE}{COMMA} quadrados +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potência: {LTBLUE}{POWER}{BLACK} Veloc. máx.: {LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potência: {LTBLUE}{POWER}{BLACK} Veloc. máx.: {LTBLUE}{VELOCITY} {BLACK}Tração máx.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucro neste ano: {LTBLUE}{CURRENCY_LONG} (último ano: {CURRENCY_LONG}) STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Lucro neste ano: {LTBLUE}{CURRENCY_LONG} (último ano: {CURRENCY_LONG}) {BLACK}Desempenho mín.: {LTBLUE}{POWER_TO_WEIGHT} @@ -4602,7 +4602,7 @@ STR_ORDER_CONDITIONAL_COMPARATOR_IS_TRUE :for verdadeiro STR_ORDER_CONDITIONAL_COMPARATOR_IS_FALSE :for falso STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}O valor para comparar com os dados do veículo -STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Digitar um valor para comparar +STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Introduza um valor para comparar STR_ORDERS_SKIP_BUTTON :{BLACK}Saltar STR_ORDERS_SKIP_TOOLTIP :{BLACK}Saltar a ordem atual e iniciar a próxima. Ctrl+Clique para saltar até a ordem selecionada diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 6ac32bfd39..1e81cb03c9 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -4899,7 +4899,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Anslået STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Gemmer stadig,{}vent venligst! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Fejl under autogem STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan ikke læse drevet +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Fejl under lagring af spil... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan ikke slette fil +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Fejl under indlæsning af spil... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Intern fejl: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Ødelagt gemt spil - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spillet er gemt med en nyere version diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index f2e68f6a6e..c2d29d3cd4 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -4899,7 +4899,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Estimate STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Saving still in progress,{}please wait until it is finished! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Autosave failed STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Unable to read drive +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Game save failed... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Unable to delete file +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Game load failed... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Internal error: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Broken savegame - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Savegame is made with newer version diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index e8dc798d97..962a27f6e6 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -4899,7 +4899,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Arvioitu STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Tallentaminen käynnissä,{}odota, kunnes se päättyy! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automaattitallennus epäonnistui. STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Asemaa ei voi lukea. +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Pelin tallennus epäonnistui… STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Tiedostoa ei voi poistaa. +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Pelin lataus epäonnistui… STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Sisäinen virhe: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Viallinen tallennus – {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Tallennus on tehty uudemmalla versiolla diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index e0201cbca5..76bc68375b 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -5041,7 +5041,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Приб STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Збереження...{}зачекайте, доки завершиться! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Помилка автозбереження STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Неможливо прочитати пристрій +STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Неможливо стерти файл +STR_ERROR_GAME_LOAD_FAILED : STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Внутрішня помилка: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Файл збереженої гри пошкоджений - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Файл збереженої гри зроблений більш новою версією From f6a88e40a4540dbf58f664d0c322b39f6a929169 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 4 Apr 2024 07:53:14 +0100 Subject: [PATCH 12/29] Codechange: Use std::list for News Items. (#12338) --- src/crashlog.cpp | 9 +- src/news_func.h | 2 +- src/news_gui.cpp | 329 ++++++++++++++++++------------------------ src/news_gui.h | 2 +- src/news_type.h | 5 +- src/statusbar_gui.cpp | 4 +- 6 files changed, 155 insertions(+), 196 deletions(-) diff --git a/src/crashlog.cpp b/src/crashlog.cpp index dfa029ca44..b728406fd8 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -56,11 +56,12 @@ static void SurveyRecentNews(nlohmann::json &json) json = nlohmann::json::array(); int i = 0; - for (NewsItem *news = _latest_news; i < 32 && news != nullptr; news = news->prev, i++) { - TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(news->date); + for (const auto &news : GetNews()) { + TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(news.date); json.push_back(fmt::format("({}-{:02}-{:02}) StringID: {}, Type: {}, Ref1: {}, {}, Ref2: {}, {}", - ymd.year, ymd.month + 1, ymd.day, news->string_id, news->type, - news->reftype1, news->ref1, news->reftype2, news->ref2)); + ymd.year, ymd.month + 1, ymd.day, news.string_id, news.type, + news.reftype1, news.ref1, news.reftype2, news.ref2)); + if (++i > 32) break; } } diff --git a/src/news_func.h b/src/news_func.h index 614f29cf7e..e24b115258 100644 --- a/src/news_func.h +++ b/src/news_func.h @@ -55,7 +55,7 @@ inline void AddIndustryNewsItem(StringID string, NewsType type, IndustryID indus void NewsLoop(); void InitNewsItemStructs(); -extern const NewsItem *_statusbar_news_item; +const NewsItem *GetStatusbarNews(); void DeleteInvalidEngineNews(); void DeleteVehicleNews(VehicleID vid, StringID news); diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 36200d003d..fe7710ca8d 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -21,7 +21,6 @@ #include "town.h" #include "sound_func.h" #include "string_func.h" -#include "dropdown_func.h" #include "statusbar_gui.h" #include "company_manager_face.h" #include "company_func.h" @@ -44,25 +43,42 @@ #include "safeguards.h" -const NewsItem *_statusbar_news_item = nullptr; +static const uint MIN_NEWS_AMOUNT = 30; ///< preferred minimum amount of news messages. +static const uint MAX_NEWS_AMOUNT = 1U << 10; ///< Do not exceed this number of news messages. -static uint MIN_NEWS_AMOUNT = 30; ///< preferred minimum amount of news messages -static uint MAX_NEWS_AMOUNT = 1 << 10; ///< Do not exceed this number of news messages -static uint _total_news = 0; ///< current number of news items -static NewsItem *_oldest_news = nullptr; ///< head of news items queue -NewsItem *_latest_news = nullptr; ///< tail of news items queue +static NewsContainer _news; ///< List of news, with newest items at the start. /** * Forced news item. * Users can force an item by accessing the history or "last message". - * If the message being shown was forced by the user, a pointer is stored - * in _forced_news. Otherwise, \a _forced_news variable is nullptr. + * If the message being shown was forced by the user, an iterater is stored + * in _forced_news. Otherwise, \a _forced_news variable is the end of \a _news. */ -static const NewsItem *_forced_news = nullptr; +static NewsIterator _forced_news = std::end(_news); /** Current news item (last item shown regularly). */ -static const NewsItem *_current_news = nullptr; +static NewsIterator _current_news = std::end(_news); +/** Current status bar news item. */ +static NewsIterator _statusbar_news = std::end(_news); + +/** + * Get pointer to the current status bar news item. + * @return Pointer to the current status bar news item, or nullptr if there is none. + */ +const NewsItem *GetStatusbarNews() +{ + return (_statusbar_news == std::end(_news)) ? nullptr : &*_statusbar_news; +} + +/** + * Get read-only reference to all news items. + * @return Read-only reference to all news items. + */ +const NewsContainer &GetNews() +{ + return _news; +} /** * Get the position a news-reference is referencing. @@ -484,7 +500,7 @@ struct NewsWindow : Window { case WID_N_CLOSEBOX: NewsWindow::duration = 0; this->Close(); - _forced_news = nullptr; + _forced_news = std::end(_news); break; case WID_N_CAPTION: @@ -622,29 +638,21 @@ static void ShowNewspaper(const NewsItem *ni) } /** Show news item in the ticker */ -static void ShowTicker(const NewsItem *ni) +static void ShowTicker(NewsIterator ni) { if (_settings_client.sound.news_ticker) SndPlayFx(SND_16_NEWS_TICKER); - _statusbar_news_item = ni; + _statusbar_news = ni; InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SHOW_TICKER); } /** Initialize the news-items data structures */ void InitNewsItemStructs() { - for (NewsItem *ni = _oldest_news; ni != nullptr; ) { - NewsItem *next = ni->next; - delete ni; - ni = next; - } - - _total_news = 0; - _oldest_news = nullptr; - _latest_news = nullptr; - _forced_news = nullptr; - _current_news = nullptr; - _statusbar_news_item = nullptr; + _news.clear(); + _forced_news = std::end(_news); + _current_news = std::end(_news); + _statusbar_news = std::end(_news); NewsWindow::duration = 0; } @@ -654,7 +662,7 @@ void InitNewsItemStructs() */ static bool ReadyForNextTickerItem() { - const NewsItem *ni = _statusbar_news_item; + const NewsItem *ni = GetStatusbarNews(); if (ni == nullptr) return true; /* Ticker message @@ -668,8 +676,7 @@ static bool ReadyForNextTickerItem() */ static bool ReadyForNextNewsItem() { - const NewsItem *ni = _forced_news == nullptr ? _current_news : _forced_news; - if (ni == nullptr) return true; + if (_forced_news == std::end(_news) && _current_news == std::end(_news)) return true; /* neither newsticker nor newspaper are running */ return (NewsWindow::duration <= 0 || FindWindowById(WC_NEWS_WINDOW, 0) == nullptr); @@ -678,116 +685,98 @@ static bool ReadyForNextNewsItem() /** Move to the next ticker item */ static void MoveToNextTickerItem() { + assert(!std::empty(_news)); + /* There is no status bar, so no reason to show news; * especially important with the end game screen when * there is no status bar but possible news. */ if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return; - /* if we're not at the last item, then move on */ - while (_statusbar_news_item != _latest_news) { - _statusbar_news_item = (_statusbar_news_item == nullptr) ? _oldest_news : _statusbar_news_item->next; - const NewsItem *ni = _statusbar_news_item; - const NewsType type = ni->type; + /* if we're not at the latest item, then move on */ + while (_statusbar_news != std::begin(_news)) { + --_statusbar_news; + const NewsType type = _statusbar_news->type; /* check the date, don't show too old items */ - if (TimerGameEconomy::date - _news_type_data[type].age > ni->economy_date) continue; + if (TimerGameEconomy::date - _news_type_data[type].age > _statusbar_news->economy_date) continue; switch (_news_type_data[type].GetDisplay()) { default: NOT_REACHED(); case ND_OFF: // Off - show nothing only a small reminder in the status bar InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SHOW_REMINDER); - break; + return; case ND_SUMMARY: // Summary - show ticker - ShowTicker(ni); - break; + ShowTicker(_statusbar_news); + return; case ND_FULL: // Full - show newspaper, skipped here - continue; + break;; } - return; } } /** Move to the next news item */ static void MoveToNextNewsItem() { + assert(!std::empty(_news)); + /* There is no status bar, so no reason to show news; * especially important with the end game screen when * there is no status bar but possible news. */ if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return; CloseWindowById(WC_NEWS_WINDOW, 0); // close the newspapers window if shown - _forced_news = nullptr; + _forced_news = std::end(_news); - /* if we're not at the last item, then move on */ - while (_current_news != _latest_news) { - _current_news = (_current_news == nullptr) ? _oldest_news : _current_news->next; - const NewsItem *ni = _current_news; - const NewsType type = ni->type; + /* if we're not at the latest item, then move on */ + while (_current_news != std::begin(_news)) { + --_current_news; + const NewsType type = _current_news->type; /* check the date, don't show too old items */ - if (TimerGameEconomy::date - _news_type_data[type].age > ni->economy_date) continue; + if (TimerGameEconomy::date - _news_type_data[type].age > _current_news->economy_date) continue; switch (_news_type_data[type].GetDisplay()) { default: NOT_REACHED(); case ND_OFF: // Off - show nothing only a small reminder in the status bar, skipped here - continue; + break; case ND_SUMMARY: // Summary - show ticker, skipped here - continue; + break;; case ND_FULL: // Full - show newspaper - ShowNewspaper(ni); - break; + ShowNewspaper(&*_current_news); + return; } - return; } } /** Delete a news item from the queue */ -static void DeleteNewsItem(NewsItem *ni) +static std::list::iterator DeleteNewsItem(std::list::iterator ni) { - /* Delete the news from the news queue. */ - if (ni->prev != nullptr) { - ni->prev->next = ni->next; - } else { - assert(_oldest_news == ni); - _oldest_news = ni->next; - } - - if (ni->next != nullptr) { - ni->next->prev = ni->prev; - } else { - assert(_latest_news == ni); - _latest_news = ni->prev; - } - - _total_news--; - if (_forced_news == ni || _current_news == ni) { /* When we're the current news, go to the previous item first; * we just possibly made that the last news item. */ - if (_current_news == ni) _current_news = ni->prev; + if (_current_news == ni) _current_news = (_current_news == std::begin(_news)) ? std::end(_news) : std::prev(_current_news); /* About to remove the currently forced item (shown as newspapers) || * about to remove the currently displayed item (newspapers) */ MoveToNextNewsItem(); } - if (_statusbar_news_item == ni) { + if (_statusbar_news == ni) { /* When we're the current news, go to the previous item first; * we just possibly made that the last news item. */ - _statusbar_news_item = ni->prev; + if (_statusbar_news == ni) _statusbar_news = (_statusbar_news == std::begin(_news)) ? std::end(_news) : std::prev(_statusbar_news); /* About to remove the currently displayed item (ticker, or just a reminder) */ InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); // invalidate the statusbar MoveToNextTickerItem(); } - delete ni; - - SetWindowDirty(WC_MESSAGE_HISTORY, 0); + /* Delete the news from the news queue. */ + return _news.erase(ni); } /** @@ -829,27 +818,14 @@ void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceTy if (_game_mode == GM_MENU) return; /* Create new news item node */ - NewsItem *ni = new NewsItem(string, type, flags, reftype1, ref1, reftype2, ref2, data); - - if (_total_news++ == 0) { - assert(_oldest_news == nullptr); - _oldest_news = ni; - ni->prev = nullptr; - } else { - assert(_latest_news->next == nullptr); - _latest_news->next = ni; - ni->prev = _latest_news; - } - - ni->next = nullptr; - _latest_news = ni; + _news.emplace_front(string, type, flags, reftype1, ref1, reftype2, ref2, data); /* Keep the number of stored news items to a managable number */ - if (_total_news > MAX_NEWS_AMOUNT) { - DeleteNewsItem(_oldest_news); + if (std::size(_news) > MAX_NEWS_AMOUNT) { + DeleteNewsItem(std::prev(std::end(_news))); } - SetWindowDirty(WC_MESSAGE_HISTORY, 0); + InvalidateWindowData(WC_MESSAGE_HISTORY, 0); } /** @@ -910,6 +886,29 @@ CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceT return CommandCost(); } +/** + * Delete news items by predicate, and invalidate the message history if necessary. + * @tparam Tmin Stop if the number of news items remaining reaches \a min items. + * @tparam Tpredicate Condition for a news item to be deleted. + */ +template +void DeleteNews(Tpredicate predicate) +{ + bool dirty = false; + for (auto it = std::rbegin(_news); it != std::rend(_news); /* nothing */) { + if constexpr (Tmin > 0) { + if (std::size(_news) <= Tmin) break; + } + if (predicate(*it)) { + it = std::make_reverse_iterator(DeleteNewsItem(std::prev(it.base()))); + dirty = true; + } else { + ++it; + } + } + if (dirty) InvalidateWindowData(WC_MESSAGE_HISTORY, 0); +} + /** * Delete a news item type about a vehicle. * When the news item type is INVALID_STRING_ID all news about the vehicle gets deleted. @@ -918,16 +917,9 @@ CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceT */ void DeleteVehicleNews(VehicleID vid, StringID news) { - NewsItem *ni = _oldest_news; - - while (ni != nullptr) { - NewsItem *next = ni->next; - if (((ni->reftype1 == NR_VEHICLE && ni->ref1 == vid) || (ni->reftype2 == NR_VEHICLE && ni->ref2 == vid)) && - (news == INVALID_STRING_ID || ni->string_id == news)) { - DeleteNewsItem(ni); - } - ni = next; - } + DeleteNews([&](const auto &ni) { + return ((ni.reftype1 == NR_VEHICLE && ni.ref1 == vid) || (ni.reftype2 == NR_VEHICLE && ni.ref2 == vid)) && (news == INVALID_STRING_ID || ni.string_id == news); + }); } /** @@ -937,15 +929,9 @@ void DeleteVehicleNews(VehicleID vid, StringID news) */ void DeleteStationNews(StationID sid) { - NewsItem *ni = _oldest_news; - - while (ni != nullptr) { - NewsItem *next = ni->next; - if ((ni->reftype1 == NR_STATION && ni->ref1 == sid) || (ni->reftype2 == NR_STATION && ni->ref2 == sid)) { - DeleteNewsItem(ni); - } - ni = next; - } + DeleteNews([&](const auto &ni) { + return (ni.reftype1 == NR_STATION && ni.ref1 == sid) || (ni.reftype2 == NR_STATION && ni.ref2 == sid); + }); } /** @@ -954,15 +940,9 @@ void DeleteStationNews(StationID sid) */ void DeleteIndustryNews(IndustryID iid) { - NewsItem *ni = _oldest_news; - - while (ni != nullptr) { - NewsItem *next = ni->next; - if ((ni->reftype1 == NR_INDUSTRY && ni->ref1 == iid) || (ni->reftype2 == NR_INDUSTRY && ni->ref2 == iid)) { - DeleteNewsItem(ni); - } - ni = next; - } + DeleteNews([&](const auto &ni) { + return (ni.reftype1 == NR_INDUSTRY && ni.ref1 == iid) || (ni.reftype2 == NR_INDUSTRY && ni.ref2 == iid); + }); } /** @@ -970,25 +950,17 @@ void DeleteIndustryNews(IndustryID iid) */ void DeleteInvalidEngineNews() { - NewsItem *ni = _oldest_news; - - while (ni != nullptr) { - NewsItem *next = ni->next; - if ((ni->reftype1 == NR_ENGINE && (!Engine::IsValidID(ni->ref1) || !Engine::Get(ni->ref1)->IsEnabled())) || - (ni->reftype2 == NR_ENGINE && (!Engine::IsValidID(ni->ref2) || !Engine::Get(ni->ref2)->IsEnabled()))) { - DeleteNewsItem(ni); - } - ni = next; - } + DeleteNews([](const auto &ni) { + return (ni.reftype1 == NR_ENGINE && (!Engine::IsValidID(ni.ref1) || !Engine::Get(ni.ref1)->IsEnabled())) || + (ni.reftype2 == NR_ENGINE && (!Engine::IsValidID(ni.ref2) || !Engine::Get(ni.ref2)->IsEnabled())); + }); } static void RemoveOldNewsItems() { - NewsItem *next; - for (NewsItem *cur = _oldest_news; _total_news > MIN_NEWS_AMOUNT && cur != nullptr; cur = next) { - next = cur->next; - if (TimerGameEconomy::date - _news_type_data[cur->type].age * _settings_client.gui.news_message_timeout > cur->economy_date) DeleteNewsItem(cur); - } + DeleteNews([](const auto &ni) { + return TimerGameEconomy::date - _news_type_data[ni.type].age * _settings_client.gui.news_message_timeout > ni.economy_date; + }); } /** @@ -999,17 +971,17 @@ static void RemoveOldNewsItems() */ void ChangeVehicleNews(VehicleID from_index, VehicleID to_index) { - for (NewsItem *ni = _oldest_news; ni != nullptr; ni = ni->next) { - if (ni->reftype1 == NR_VEHICLE && ni->ref1 == from_index) ni->ref1 = to_index; - if (ni->reftype2 == NR_VEHICLE && ni->ref2 == from_index) ni->ref2 = to_index; - if (ni->flags & NF_VEHICLE_PARAM0 && ni->params[0].data == from_index) ni->params[0] = to_index; + for (auto &ni : _news) { + if (ni.reftype1 == NR_VEHICLE && ni.ref1 == from_index) ni.ref1 = to_index; + if (ni.reftype2 == NR_VEHICLE && ni.ref2 == from_index) ni.ref2 = to_index; + if (ni.flags & NF_VEHICLE_PARAM0 && ni.params[0].data == from_index) ni.params[0] = to_index; } } void NewsLoop() { /* no news item yet */ - if (_total_news == 0) return; + if (std::empty(_news)) return; static TimerGameEconomy::Month _last_clean_month = 0; @@ -1023,9 +995,9 @@ void NewsLoop() } /** Do a forced show of a specific message */ -static void ShowNewsMessage(const NewsItem *ni) +static void ShowNewsMessage(NewsIterator ni) { - assert(_total_news != 0); + assert(!std::empty(_news)); /* Delete the news window */ CloseWindowById(WC_NEWS_WINDOW, 0); @@ -1033,9 +1005,9 @@ static void ShowNewsMessage(const NewsItem *ni) /* setup forced news item */ _forced_news = ni; - if (_forced_news != nullptr) { + if (_forced_news != std::end(_news)) { CloseWindowById(WC_NEWS_WINDOW, 0); - ShowNewspaper(ni); + ShowNewspaper(&*ni); } } @@ -1054,26 +1026,26 @@ bool HideActiveNewsMessage() /** Show previous news item */ void ShowLastNewsMessage() { - const NewsItem *ni = nullptr; - if (_total_news == 0) { - return; - } else if (_forced_news == nullptr) { + if (std::empty(_news)) return; + + NewsIterator ni; + if (_forced_news == std::end(_news)) { /* Not forced any news yet, show the current one, unless a news window is * open (which can only be the current one), then show the previous item */ - if (_current_news == nullptr) { + if (_current_news == std::end(_news)) { /* No news were shown yet resp. the last shown one was already deleted. - * Threat this as if _forced_news reached _oldest_news; so, wrap around and start anew with the latest. */ - ni = _latest_news; + * Treat this as if _forced_news reached the oldest news; so, wrap around and start anew with the latest. */ + ni = std::begin(_news); } else { const Window *w = FindWindowById(WC_NEWS_WINDOW, 0); - ni = (w == nullptr || (_current_news == _oldest_news)) ? _current_news : _current_news->prev; + ni = (w == nullptr || (std::next(_current_news) == std::end(_news))) ? _current_news : std::next(_current_news); } - } else if (_forced_news == _oldest_news) { + } else if (std::next(_forced_news) == std::end(_news)) { /* We have reached the oldest news, start anew with the latest */ - ni = _latest_news; + ni = std::begin(_news); } else { /* 'Scrolling' through news history show each one in turn */ - ni = _forced_news->prev; + ni = std::next(_forced_news); } bool wrap = false; for (;;) { @@ -1082,11 +1054,11 @@ void ShowLastNewsMessage() break; } - ni = ni->prev; - if (ni == nullptr) { + ++ni; + if (ni == std::end(_news)) { if (wrap) break; /* We have reached the oldest news, start anew with the latest */ - ni = _latest_news; + ni = std::begin(_news); wrap = true; } } @@ -1143,37 +1115,23 @@ struct MessageHistoryWindow : Window { } } - void OnPaint() override - { - this->OnInvalidateData(0); - this->DrawWidgets(); - } - void DrawWidget(const Rect &r, WidgetID widget) const override { - if (widget != WID_MH_BACKGROUND || _total_news == 0) return; - - /* Find the first news item to display. */ - NewsItem *ni = _latest_news; - for (int n = this->vscroll->GetPosition(); n > 0; n--) { - ni = ni->prev; - if (ni == nullptr) return; - } + if (widget != WID_MH_BACKGROUND || std::empty(_news)) return; /* Fill the widget with news items. */ bool rtl = _current_text_dir == TD_RTL; Rect news = r.Shrink(WidgetDimensions::scaled.framerect).Indent(this->date_width + WidgetDimensions::scaled.hsep_wide, rtl); Rect date = r.Shrink(WidgetDimensions::scaled.framerect).WithWidth(this->date_width, rtl); int y = news.top; - for (int n = this->vscroll->GetCapacity(); n > 0; n--) { + + auto [first, last] = this->vscroll->GetVisibleRangeIterators(_news); + for (auto ni = first; ni != last; ++ni) { SetDParam(0, ni->date); DrawString(date.left, date.right, y, STR_JUST_DATE_TINY, TC_WHITE); - DrawNewsString(news.left, news.right, y, TC_WHITE, ni); + DrawNewsString(news.left, news.right, y, TC_WHITE, &*ni); y += this->line_height; - - ni = ni->prev; - if (ni == nullptr) return; } } @@ -1185,19 +1143,18 @@ struct MessageHistoryWindow : Window { void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override { if (!gui_scope) return; - this->vscroll->SetCount(_total_news); + this->vscroll->SetCount(std::size(_news)); } void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override { if (widget == WID_MH_BACKGROUND) { - NewsItem *ni = _latest_news; - if (ni == nullptr) return; - - for (int n = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_MH_BACKGROUND, WidgetDimensions::scaled.framerect.top); n > 0; n--) { - ni = ni->prev; - if (ni == nullptr) return; - } + /* Scheduled window invalidations currently occur after the input loop, which means the scrollbar count + * could be invalid, so ensure it's correct now. Potentially this means that item clicked on might be + * different as well. */ + this->vscroll->SetCount(std::size(_news)); + auto ni = this->vscroll->GetScrolledItemFromWidget(_news, pt.y, this, widget); + if (ni == std::end(_news)) return; ShowNewsMessage(ni); } diff --git a/src/news_gui.h b/src/news_gui.h index 059d51ad32..c7fea6cebd 100644 --- a/src/news_gui.h +++ b/src/news_gui.h @@ -16,6 +16,6 @@ void ShowLastNewsMessage(); void ShowMessageHistory(); bool HideActiveNewsMessage(); -extern NewsItem *_latest_news; +const NewsContainer &GetNews(); #endif /* NEWS_GUI_H */ diff --git a/src/news_type.h b/src/news_type.h index ffe63b6a8e..cbafbef1ce 100644 --- a/src/news_type.h +++ b/src/news_type.h @@ -126,8 +126,6 @@ struct NewsAllocatedData { /** Information about a single item of news. */ struct NewsItem { - NewsItem *prev; ///< Previous news item - NewsItem *next; ///< Next news item StringID string_id; ///< Message text TimerGameCalendar::Date date; ///< Calendar date to show for the news TimerGameEconomy::Date economy_date; ///< Economy date of the news item, never shown but used to calculate age @@ -169,4 +167,7 @@ struct CompanyNewsInformation : NewsAllocatedData { CompanyNewsInformation(const struct Company *c, const struct Company *other = nullptr); }; +using NewsContainer = std::list; ///< Container type for storing news items. +using NewsIterator = NewsContainer::const_iterator; ///< Iterator type for news items. + #endif /* NEWS_TYPE_H */ diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 7229ffd803..69f12dbfdd 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -145,9 +145,9 @@ struct StatusBarWindow : Window { } else if (_pause_mode != PM_UNPAUSED) { StringID msg = (_pause_mode & PM_PAUSED_LINK_GRAPH) ? STR_STATUSBAR_PAUSED_LINK_GRAPH : STR_STATUSBAR_PAUSED; DrawString(tr, msg, TC_FROMSTRING, SA_HOR_CENTER); - } else if (this->ticker_scroll < TICKER_STOP && _statusbar_news_item != nullptr && _statusbar_news_item->string_id != 0) { + } else if (this->ticker_scroll < TICKER_STOP && GetStatusbarNews() != nullptr && GetStatusbarNews()->string_id != 0) { /* Draw the scrolling news text */ - if (!DrawScrollingStatusText(_statusbar_news_item, ScaleGUITrad(this->ticker_scroll), tr.left, tr.right, tr.top, tr.bottom)) { + if (!DrawScrollingStatusText(GetStatusbarNews(), ScaleGUITrad(this->ticker_scroll), tr.left, tr.right, tr.top, tr.bottom)) { InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); if (Company::IsValidID(_local_company)) { /* This is the default text */ From 338def1b06537732f617d388134080cd9d6bbdf9 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 4 Apr 2024 14:39:15 +0100 Subject: [PATCH 13/29] Fix: Segfault when using -q without providing a . character. (#12418) Use std::filesystem::path to find extension instead of strrchr. --- src/openttd.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openttd.cpp b/src/openttd.cpp index 31b9220bbb..7414fe29b1 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -628,7 +628,8 @@ int openttd_main(int argc, char *argv[]) return ret; } - auto [_, title] = FiosGetSavegameListCallback(SLO_LOAD, mgo.opt, strrchr(mgo.opt, '.')); + std::string extension = std::filesystem::path(_file_to_saveload.name).extension().string(); + auto [_, title] = FiosGetSavegameListCallback(SLO_LOAD, mgo.opt, extension); _load_check_data.Clear(); SaveOrLoadResult res = SaveOrLoad(mgo.opt, SLO_CHECK, DFT_GAME_FILE, SAVE_DIR, false); From 197fb00d316370ed67c1a0e62a1b1cfa0c45b6d8 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 4 Apr 2024 17:56:16 +0100 Subject: [PATCH 14/29] Fix #12395: Ensure president name widget is tall enough. (#12419) --- src/company_cmd.cpp | 1 + src/company_gui.cpp | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 2f68a61817..a92ced1154 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -1182,6 +1182,7 @@ CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text) } } + InvalidateWindowClassesData(WC_COMPANY, 1); MarkWholeScreenDirty(); CompanyAdminUpdate(c); } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index a72569f1a9..27f014b408 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -2452,6 +2452,14 @@ struct CompanyWindow : Window } } + void OnResize() override + { + NWidgetResizeBase *wid = this->GetWidget(WID_C_FACE_TITLE); + SetDParam(0, this->owner); + int y = GetStringHeight(STR_COMPANY_VIEW_PRESIDENT_MANAGER_TITLE, wid->current_x); + if (wid->UpdateVerticalSize(y)) this->ReInit(0, 0); + } + void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override { switch (widget) { @@ -2587,6 +2595,14 @@ struct CompanyWindow : Window break; } } + + void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override + { + if (gui_scope && data == 1) { + /* Manually call OnResize to adjust minimum height of president name widget. */ + OnResize(); + } + } }; static WindowDesc _company_desc( From 7c322ebcf109c26a109f896cc45bd72d463862fd Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 4 Apr 2024 20:27:11 +0100 Subject: [PATCH 15/29] Codechange: Define a ZOOM_LVL for minimum text effect visibility. --- src/texteff.cpp | 8 ++++---- src/zoom_type.h | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/texteff.cpp b/src/texteff.cpp index 01dca6087c..930df8421c 100644 --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -102,10 +102,10 @@ IntervalTimer move_all_text_effects_interval = {std::chrono::millis continue; } - te.MarkDirty(ZOOM_LVL_OUT_8X); + te.MarkDirty(ZOOM_LVL_TEXT_EFFECT); te.duration -= count; te.top -= count * ZOOM_LVL_BASE; - te.MarkDirty(ZOOM_LVL_OUT_8X); + te.MarkDirty(ZOOM_LVL_TEXT_EFFECT); } }}; @@ -118,13 +118,13 @@ void InitTextEffects() void DrawTextEffects(DrawPixelInfo *dpi) { /* Don't draw the text effects when zoomed out a lot */ - if (dpi->zoom > ZOOM_LVL_OUT_8X) return; + if (dpi->zoom > ZOOM_LVL_TEXT_EFFECT) return; if (IsTransparencySet(TO_TEXT)) return; for (TextEffect &te : _text_effects) { if (te.string_id == INVALID_STRING_ID) continue; if (te.mode == TE_RISING || _settings_client.gui.loading_indicators) { CopyInDParam(te.params); - ViewportAddString(dpi, ZOOM_LVL_OUT_8X, &te, te.string_id, te.string_id - 1, STR_NULL); + ViewportAddString(dpi, ZOOM_LVL_TEXT_EFFECT, &te, te.string_id, te.string_id - 1, STR_NULL); } } } diff --git a/src/zoom_type.h b/src/zoom_type.h index bc6d58d8be..f5db67e2fc 100644 --- a/src/zoom_type.h +++ b/src/zoom_type.h @@ -38,7 +38,8 @@ enum ZoomLevel : uint8_t { ZOOM_LVL_ROADVEH = ZOOM_LVL_OUT_4X, ///< Default zoom level for the road vehicle view. ZOOM_LVL_WORLD_SCREENSHOT = ZOOM_LVL_OUT_4X, ///< Default zoom level for the world screen shot. - ZOOM_LVL_DETAIL = ZOOM_LVL_OUT_8X, ///< All zoomlevels below or equal to this, will result in details on the screen, like road-work, ... + ZOOM_LVL_DETAIL = ZOOM_LVL_OUT_8X, ///< All zoom levels below or equal to this will result in details on the screen, like road-work, ... + ZOOM_LVL_TEXT_EFFECT = ZOOM_LVL_OUT_8X, ///< All zoom levels above this will not show text effects. ZOOM_LVL_MIN = ZOOM_LVL_NORMAL, ///< Minimum zoom level. ZOOM_LVL_MAX = ZOOM_LVL_OUT_32X, ///< Maximum zoom level. From 3c94e81665d1f3eaf3c416a48306d7a45ee15ab7 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 4 Apr 2024 18:49:37 +0100 Subject: [PATCH 16/29] Codechange: Use ZOOM_LVL_MIN to refer to first zoom level. Many uses of ZOOM_LVL_NORMAL actually just want the first zoom level slot, so use ZOOM_LVL_MIN to make this clearer. --- src/blitter/32bpp_optimized.cpp | 14 +++---- src/blitter/32bpp_simple.cpp | 14 +++---- src/blitter/32bpp_sse2.cpp | 14 +++---- src/blitter/8bpp_optimized.cpp | 14 +++---- src/blitter/8bpp_simple.cpp | 14 +++---- src/blitter/null.cpp | 8 ++-- src/fontcache/freetypefontcache.cpp | 4 +- src/gfx.cpp | 14 +++---- src/newgrf_debug_gui.cpp | 2 +- src/openttd.cpp | 2 +- src/os/macosx/font_osx.cpp | 4 +- src/os/windows/font_win32.cpp | 4 +- src/spritecache.cpp | 58 +++++++++++++++-------------- src/spriteloader/grf.cpp | 4 +- src/video/opengl.cpp | 12 +++--- src/viewport.cpp | 10 ++--- src/window.cpp | 2 +- src/zoom_func.h | 10 ++--- 18 files changed, 103 insertions(+), 101 deletions(-) diff --git a/src/blitter/32bpp_optimized.cpp b/src/blitter/32bpp_optimized.cpp index 65fa193576..943e9a0297 100644 --- a/src/blitter/32bpp_optimized.cpp +++ b/src/blitter/32bpp_optimized.cpp @@ -306,9 +306,9 @@ template Sprite *Blitter_32bppOptimized::EncodeInternal(const ZoomLevel zoom_min; ZoomLevel zoom_max; - if (sprite[ZOOM_LVL_NORMAL].type == SpriteType::Font) { - zoom_min = ZOOM_LVL_NORMAL; - zoom_max = ZOOM_LVL_NORMAL; + if (sprite[ZOOM_LVL_MIN].type == SpriteType::Font) { + zoom_min = ZOOM_LVL_MIN; + zoom_max = ZOOM_LVL_MIN; } else { zoom_min = _settings_client.gui.zoom_min; zoom_max = _settings_client.gui.zoom_max; @@ -416,10 +416,10 @@ template Sprite *Blitter_32bppOptimized::EncodeInternal(const Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(SpriteData) + len); - dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height; - dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width; - dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs; - dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs; + dest_sprite->height = sprite[ZOOM_LVL_MIN].height; + dest_sprite->width = sprite[ZOOM_LVL_MIN].width; + dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs; + dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs; SpriteData *dst = (SpriteData *)dest_sprite->data; memset(dst, 0, sizeof(*dst)); diff --git a/src/blitter/32bpp_simple.cpp b/src/blitter/32bpp_simple.cpp index 00c0497109..653b2a4b38 100644 --- a/src/blitter/32bpp_simple.cpp +++ b/src/blitter/32bpp_simple.cpp @@ -118,17 +118,17 @@ void Blitter_32bppSimple::DrawColourMappingRect(void *dst, int width, int height Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) { Blitter_32bppSimple::Pixel *dst; - Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_NORMAL].height * (size_t)sprite[ZOOM_LVL_NORMAL].width * sizeof(*dst)); + Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_MIN].height * (size_t)sprite[ZOOM_LVL_MIN].width * sizeof(*dst)); - dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height; - dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width; - dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs; - dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs; + dest_sprite->height = sprite[ZOOM_LVL_MIN].height; + dest_sprite->width = sprite[ZOOM_LVL_MIN].width; + dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs; + dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs; dst = (Blitter_32bppSimple::Pixel *)dest_sprite->data; - SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite[ZOOM_LVL_NORMAL].data; + SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite[ZOOM_LVL_MIN].data; - for (int i = 0; i < sprite[ZOOM_LVL_NORMAL].height * sprite[ZOOM_LVL_NORMAL].width; i++) { + for (int i = 0; i < sprite[ZOOM_LVL_MIN].height * sprite[ZOOM_LVL_MIN].width; i++) { if (src->m == 0) { dst[i].r = src->r; dst[i].g = src->g; diff --git a/src/blitter/32bpp_sse2.cpp b/src/blitter/32bpp_sse2.cpp index 6c486d1b5e..72919b9bc4 100644 --- a/src/blitter/32bpp_sse2.cpp +++ b/src/blitter/32bpp_sse2.cpp @@ -26,9 +26,9 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri * Second uint32_t of a line = the number of transparent pixels from the right. * Then all RGBA then all MV. */ - ZoomLevel zoom_min = ZOOM_LVL_NORMAL; - ZoomLevel zoom_max = ZOOM_LVL_NORMAL; - if (sprite[ZOOM_LVL_NORMAL].type != SpriteType::Font) { + ZoomLevel zoom_min = ZOOM_LVL_MIN; + ZoomLevel zoom_max = ZOOM_LVL_MIN; + if (sprite[ZOOM_LVL_MIN].type != SpriteType::Font) { zoom_min = _settings_client.gui.zoom_min; zoom_max = _settings_client.gui.zoom_max; if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_MAX; @@ -52,10 +52,10 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri } Sprite *dst_sprite = (Sprite *) allocator(sizeof(Sprite) + sizeof(SpriteData) + all_sprites_size); - dst_sprite->height = sprite[ZOOM_LVL_NORMAL].height; - dst_sprite->width = sprite[ZOOM_LVL_NORMAL].width; - dst_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs; - dst_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs; + dst_sprite->height = sprite[ZOOM_LVL_MIN].height; + dst_sprite->width = sprite[ZOOM_LVL_MIN].width; + dst_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs; + dst_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs; memcpy(dst_sprite->data, &sd, sizeof(SpriteData)); /* Copy colours and determine flags. */ diff --git a/src/blitter/8bpp_optimized.cpp b/src/blitter/8bpp_optimized.cpp index 710f117255..3d050744cb 100644 --- a/src/blitter/8bpp_optimized.cpp +++ b/src/blitter/8bpp_optimized.cpp @@ -128,9 +128,9 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri ZoomLevel zoom_min; ZoomLevel zoom_max; - if (sprite[ZOOM_LVL_NORMAL].type == SpriteType::Font) { - zoom_min = ZOOM_LVL_NORMAL; - zoom_max = ZOOM_LVL_NORMAL; + if (sprite[ZOOM_LVL_MIN].type == SpriteType::Font) { + zoom_min = ZOOM_LVL_MIN; + zoom_max = ZOOM_LVL_MIN; } else { zoom_min = _settings_client.gui.zoom_min; zoom_max = _settings_client.gui.zoom_max; @@ -221,10 +221,10 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri /* Allocate the exact amount of memory we need */ Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + size); - dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height; - dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width; - dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs; - dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs; + dest_sprite->height = sprite[ZOOM_LVL_MIN].height; + dest_sprite->width = sprite[ZOOM_LVL_MIN].width; + dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs; + dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs; memcpy(dest_sprite->data, temp_dst, size); return dest_sprite; diff --git a/src/blitter/8bpp_simple.cpp b/src/blitter/8bpp_simple.cpp index a80ceba115..58c7cb36fa 100644 --- a/src/blitter/8bpp_simple.cpp +++ b/src/blitter/8bpp_simple.cpp @@ -64,16 +64,16 @@ void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoom Sprite *Blitter_8bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) { Sprite *dest_sprite; - dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_NORMAL].height * (size_t)sprite[ZOOM_LVL_NORMAL].width); + dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_MIN].height * (size_t)sprite[ZOOM_LVL_MIN].width); - dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height; - dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width; - dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs; - dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs; + dest_sprite->height = sprite[ZOOM_LVL_MIN].height; + dest_sprite->width = sprite[ZOOM_LVL_MIN].width; + dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs; + dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs; /* Copy over only the 'remap' channel, as that is what we care about in 8bpp */ - for (int i = 0; i < sprite[ZOOM_LVL_NORMAL].height * sprite[ZOOM_LVL_NORMAL].width; i++) { - dest_sprite->data[i] = sprite[ZOOM_LVL_NORMAL].data[i].m; + for (int i = 0; i < sprite[ZOOM_LVL_MIN].height * sprite[ZOOM_LVL_MIN].width; i++) { + dest_sprite->data[i] = sprite[ZOOM_LVL_MIN].data[i].m; } return dest_sprite; diff --git a/src/blitter/null.cpp b/src/blitter/null.cpp index f73b5ae331..865c225917 100644 --- a/src/blitter/null.cpp +++ b/src/blitter/null.cpp @@ -20,10 +20,10 @@ Sprite *Blitter_Null::Encode(const SpriteLoader::SpriteCollection &sprite, Alloc Sprite *dest_sprite; dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite)); - dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height; - dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width; - dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs; - dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs; + dest_sprite->height = sprite[ZOOM_LVL_MIN].height; + dest_sprite->width = sprite[ZOOM_LVL_MIN].width; + dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs; + dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs; return dest_sprite; } diff --git a/src/fontcache/freetypefontcache.cpp b/src/fontcache/freetypefontcache.cpp index bcbfbc2a52..00d45a251a 100644 --- a/src/fontcache/freetypefontcache.cpp +++ b/src/fontcache/freetypefontcache.cpp @@ -272,8 +272,8 @@ const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa) /* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */ SpriteLoader::SpriteCollection spritecollection; - SpriteLoader::Sprite &sprite = spritecollection[ZOOM_LVL_NORMAL]; - sprite.AllocateData(ZOOM_LVL_NORMAL, static_cast(width) * height); + SpriteLoader::Sprite &sprite = spritecollection[ZOOM_LVL_MIN]; + sprite.AllocateData(ZOOM_LVL_MIN, static_cast(width) * height); sprite.type = SpriteType::Font; sprite.colours = (aa ? SCC_PAL | SCC_ALPHA : SCC_PAL); sprite.width = width; diff --git a/src/gfx.cpp b/src/gfx.cpp index 595592139f..2731220f0c 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -53,7 +53,7 @@ static uint8_t _stringwidth_table[FS_END][224]; ///< Cache containing width of o DrawPixelInfo *_cur_dpi; static void GfxMainBlitterViewport(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = nullptr, SpriteID sprite_id = SPR_CURSOR_MOUSE); -static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = nullptr, SpriteID sprite_id = SPR_CURSOR_MOUSE, ZoomLevel zoom = ZOOM_LVL_NORMAL); +static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = nullptr, SpriteID sprite_id = SPR_CURSOR_MOUSE, ZoomLevel zoom = ZOOM_LVL_MIN); static ReusableBuffer _cursor_backup; @@ -99,7 +99,7 @@ void GfxScroll(int left, int top, int width, int height, int xo, int yo) /** * Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen. * - * @pre dpi->zoom == ZOOM_LVL_NORMAL, right >= left, bottom >= top + * @pre dpi->zoom == ZOOM_LVL_MIN, right >= left, bottom >= top * @param left Minimum X (inclusive) * @param top Minimum Y (inclusive) * @param right Maximum X (inclusive) @@ -118,7 +118,7 @@ void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectM const int otop = top; const int oleft = left; - if (dpi->zoom != ZOOM_LVL_NORMAL) return; + if (dpi->zoom != ZOOM_LVL_MIN) return; if (left > right || top > bottom) return; if (right < dpi->left || left >= dpi->left + dpi->width) return; if (bottom < dpi->top || top >= dpi->top + dpi->height) return; @@ -198,7 +198,7 @@ static std::vector MakePolygonSegments(const std::vector &sh * The odd-even winding rule is used, i.e. self-intersecting polygons will have holes in them. * Left and top edges are inclusive, right and bottom edges are exclusive. * @note For rectangles the GfxFillRect function will be faster. - * @pre dpi->zoom == ZOOM_LVL_NORMAL + * @pre dpi->zoom == ZOOM_LVL_MIN * @param shape List of points on the polygon. * @param colour An 8 bit palette index (FILLRECT_OPAQUE and FILLRECT_CHECKER) or a recolour spritenumber (FILLRECT_RECOLOUR). * @param mode @@ -210,7 +210,7 @@ void GfxFillPolygon(const std::vector &shape, int colour, FillRectMode mo { Blitter *blitter = BlitterFactory::GetCurrentBlitter(); const DrawPixelInfo *dpi = _cur_dpi; - if (dpi->zoom != ZOOM_LVL_NORMAL) return; + if (dpi->zoom != ZOOM_LVL_MIN) return; std::vector segments = MakePolygonSegments(shape, Point{ dpi->left, dpi->top }); @@ -1565,7 +1565,7 @@ bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int heigh Blitter *blitter = BlitterFactory::GetCurrentBlitter(); const DrawPixelInfo *o = _cur_dpi; - n->zoom = ZOOM_LVL_NORMAL; + n->zoom = ZOOM_LVL_MIN; assert(width > 0); assert(height > 0); @@ -1789,7 +1789,7 @@ void UpdateGUIZoom() _gui_scale = Clamp(_gui_scale_cfg, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE); } - int8_t new_zoom = ScaleGUITrad(1) <= 1 ? ZOOM_LVL_OUT_4X : ScaleGUITrad(1) >= 4 ? ZOOM_LVL_MIN : ZOOM_LVL_OUT_2X; + int8_t new_zoom = ScaleGUITrad(1) <= 1 ? ZOOM_LVL_OUT_4X : ScaleGUITrad(1) >= 4 ? ZOOM_LVL_NORMAL : ZOOM_LVL_OUT_2X; /* Font glyphs should not be clamped to min/max zoom. */ _font_zoom = static_cast(new_zoom); /* Ensure the gui_zoom is clamped between min/max. */ diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index e470e55c71..d626296108 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -1078,7 +1078,7 @@ struct SpriteAlignerWindow : Window { } SpriteAlignerWindow::zoom = Clamp(SpriteAlignerWindow::zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); - for (ZoomLevel z = ZOOM_LVL_NORMAL; z < ZOOM_LVL_END; z++) { + for (ZoomLevel z = ZOOM_LVL_BEGIN; z < ZOOM_LVL_END; z++) { this->SetWidgetsDisabledState(z < _settings_client.gui.zoom_min || z > _settings_client.gui.zoom_max, WID_SA_ZOOM + z); this->SetWidgetsLoweredState(SpriteAlignerWindow::zoom == z, WID_SA_ZOOM + z); } diff --git a/src/openttd.cpp b/src/openttd.cpp index 7414fe29b1..7ae3cba92d 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -770,7 +770,7 @@ int openttd_main(int argc, char *argv[]) InitializeSpriteSorter(); /* Initialize the zoom level of the screen to normal */ - _screen.zoom = ZOOM_LVL_NORMAL; + _screen.zoom = ZOOM_LVL_MIN; /* The video driver is now selected, now initialise GUI zoom */ AdjustGUIZoom(false); diff --git a/src/os/macosx/font_osx.cpp b/src/os/macosx/font_osx.cpp index 3905c3c734..6339f7f64e 100644 --- a/src/os/macosx/font_osx.cpp +++ b/src/os/macosx/font_osx.cpp @@ -241,8 +241,8 @@ const Sprite *CoreTextFontCache::InternalGetGlyph(GlyphID key, bool use_aa) if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) UserError("Font glyph is too large"); SpriteLoader::SpriteCollection spritecollection; - SpriteLoader::Sprite &sprite = spritecollection[ZOOM_LVL_NORMAL]; - sprite.AllocateData(ZOOM_LVL_NORMAL, width * height); + SpriteLoader::Sprite &sprite = spritecollection[ZOOM_LVL_MIN]; + sprite.AllocateData(ZOOM_LVL_MIN, width * height); sprite.type = SpriteType::Font; sprite.colours = (use_aa ? SCC_PAL | SCC_ALPHA : SCC_PAL); sprite.width = width; diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index d2a5420735..d5c50d0f41 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -229,8 +229,8 @@ void Win32FontCache::ClearFontCache() /* GDI has rendered the glyph, now we allocate a sprite and copy the image into it. */ SpriteLoader::SpriteCollection spritecollection; - SpriteLoader::Sprite &sprite = spritecollection[ZOOM_LVL_NORMAL]; - sprite.AllocateData(ZOOM_LVL_NORMAL, width * height); + SpriteLoader::Sprite &sprite = spritecollection[ZOOM_LVL_MIN]; + sprite.AllocateData(ZOOM_LVL_MIN, width * height); sprite.type = SpriteType::Font; sprite.colours = (aa ? SCC_PAL | SCC_ALPHA : SCC_PAL); sprite.width = width; diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 3c5ce15e6b..2ef7784c0f 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -243,11 +243,11 @@ static bool ResizeSpriteIn(SpriteLoader::SpriteCollection &sprite, ZoomLevel src static void ResizeSpriteOut(SpriteLoader::SpriteCollection &sprite, ZoomLevel zoom) { /* Algorithm based on 32bpp_Optimized::ResizeSprite() */ - sprite[zoom].width = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].width, zoom); - sprite[zoom].height = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].height, zoom); - sprite[zoom].x_offs = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].x_offs, zoom); - sprite[zoom].y_offs = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].y_offs, zoom); - sprite[zoom].colours = sprite[ZOOM_LVL_NORMAL].colours; + sprite[zoom].width = UnScaleByZoom(sprite[ZOOM_LVL_MIN].width, zoom); + sprite[zoom].height = UnScaleByZoom(sprite[ZOOM_LVL_MIN].height, zoom); + sprite[zoom].x_offs = UnScaleByZoom(sprite[ZOOM_LVL_MIN].x_offs, zoom); + sprite[zoom].y_offs = UnScaleByZoom(sprite[ZOOM_LVL_MIN].y_offs, zoom); + sprite[zoom].colours = sprite[ZOOM_LVL_MIN].colours; sprite[zoom].AllocateData(zoom, static_cast(sprite[zoom].height) * sprite[zoom].width); @@ -375,22 +375,24 @@ static bool ResizeSprites(SpriteLoader::SpriteCollection &sprite, uint8_t sprite { /* Create a fully zoomed image if it does not exist */ ZoomLevel first_avail = static_cast(FindFirstBit(sprite_avail)); - if (first_avail != ZOOM_LVL_NORMAL) { - if (!ResizeSpriteIn(sprite, first_avail, ZOOM_LVL_NORMAL)) return false; - SetBit(sprite_avail, ZOOM_LVL_NORMAL); + if (first_avail != ZOOM_LVL_MIN) { + if (!ResizeSpriteIn(sprite, first_avail, ZOOM_LVL_MIN)) return false; + SetBit(sprite_avail, ZOOM_LVL_MIN); } /* Pad sprites to make sizes match. */ if (!PadSprites(sprite, sprite_avail, encoder)) return false; /* Create other missing zoom levels */ - for (ZoomLevel zoom = ZOOM_LVL_OUT_2X; zoom != ZOOM_LVL_END; zoom++) { + for (ZoomLevel zoom = ZOOM_LVL_BEGIN; zoom != ZOOM_LVL_END; zoom++) { + if (zoom == ZOOM_LVL_MIN) continue; + if (HasBit(sprite_avail, zoom)) { /* Check that size and offsets match the fully zoomed image. */ - assert(sprite[zoom].width == UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].width, zoom)); - assert(sprite[zoom].height == UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].height, zoom)); - assert(sprite[zoom].x_offs == UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].x_offs, zoom)); - assert(sprite[zoom].y_offs == UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].y_offs, zoom)); + assert(sprite[zoom].width == UnScaleByZoom(sprite[ZOOM_LVL_MIN].width, zoom)); + assert(sprite[zoom].height == UnScaleByZoom(sprite[ZOOM_LVL_MIN].height, zoom)); + assert(sprite[zoom].x_offs == UnScaleByZoom(sprite[ZOOM_LVL_MIN].x_offs, zoom)); + assert(sprite[zoom].y_offs == UnScaleByZoom(sprite[ZOOM_LVL_MIN].y_offs, zoom)); } /* Zoom level is not available, or unusable, so create it */ @@ -465,7 +467,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty SpriteLoader::SpriteCollection sprite; uint8_t sprite_avail = 0; - sprite[ZOOM_LVL_NORMAL].type = sprite_type; + sprite[ZOOM_LVL_MIN].type = sprite_type; SpriteLoaderGrf sprite_loader(file.GetContainerVersion()); if (sprite_type != SpriteType::MapGen && encoder->Is32BppSupported()) { @@ -492,15 +494,15 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty * Ugly: yes. Other solution: no. Blame the original author or * something ;) The image should really have been a data-stream * (so type = 0xFF basically). */ - uint num = sprite[ZOOM_LVL_NORMAL].width * sprite[ZOOM_LVL_NORMAL].height; + uint num = sprite[ZOOM_LVL_MIN].width * sprite[ZOOM_LVL_MIN].height; Sprite *s = (Sprite *)allocator(sizeof(*s) + num); - s->width = sprite[ZOOM_LVL_NORMAL].width; - s->height = sprite[ZOOM_LVL_NORMAL].height; - s->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs; - s->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs; + s->width = sprite[ZOOM_LVL_MIN].width; + s->height = sprite[ZOOM_LVL_MIN].height; + s->x_offs = sprite[ZOOM_LVL_MIN].x_offs; + s->y_offs = sprite[ZOOM_LVL_MIN].y_offs; - SpriteLoader::CommonPixel *src = sprite[ZOOM_LVL_NORMAL].data; + SpriteLoader::CommonPixel *src = sprite[ZOOM_LVL_MIN].data; uint8_t *dest = s->data; while (num-- > 0) { *dest++ = src->m; @@ -515,14 +517,14 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty return (void*)GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, allocator, encoder); } - if (sprite[ZOOM_LVL_NORMAL].type == SpriteType::Font && _font_zoom != ZOOM_LVL_NORMAL) { - /* Make ZOOM_LVL_NORMAL be ZOOM_LVL_GUI */ - sprite[ZOOM_LVL_NORMAL].width = sprite[_font_zoom].width; - sprite[ZOOM_LVL_NORMAL].height = sprite[_font_zoom].height; - sprite[ZOOM_LVL_NORMAL].x_offs = sprite[_font_zoom].x_offs; - sprite[ZOOM_LVL_NORMAL].y_offs = sprite[_font_zoom].y_offs; - sprite[ZOOM_LVL_NORMAL].data = sprite[_font_zoom].data; - sprite[ZOOM_LVL_NORMAL].colours = sprite[_font_zoom].colours; + if (sprite[ZOOM_LVL_MIN].type == SpriteType::Font && _font_zoom != ZOOM_LVL_MIN) { + /* Make ZOOM_LVL_MIN be ZOOM_LVL_GUI */ + sprite[ZOOM_LVL_MIN].width = sprite[_font_zoom].width; + sprite[ZOOM_LVL_MIN].height = sprite[_font_zoom].height; + sprite[ZOOM_LVL_MIN].x_offs = sprite[_font_zoom].x_offs; + sprite[ZOOM_LVL_MIN].y_offs = sprite[_font_zoom].y_offs; + sprite[ZOOM_LVL_MIN].data = sprite[_font_zoom].data; + sprite[ZOOM_LVL_MIN].colours = sprite[_font_zoom].colours; } return encoder->Encode(sprite, allocator); diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp index a34e4e8428..0463497c1d 100644 --- a/src/spriteloader/grf.cpp +++ b/src/spriteloader/grf.cpp @@ -230,7 +230,7 @@ uint8_t LoadSpriteV1(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, s /* Type 0xFF indicates either a colourmap or some other non-sprite info; we do not handle them here */ if (type == 0xFF) return 0; - ZoomLevel zoom_lvl = (sprite_type != SpriteType::MapGen) ? ZOOM_LVL_OUT_4X : ZOOM_LVL_NORMAL; + ZoomLevel zoom_lvl = (sprite_type != SpriteType::MapGen) ? ZOOM_LVL_OUT_4X : ZOOM_LVL_MIN; sprite[zoom_lvl].height = file.ReadByte(); sprite[zoom_lvl].width = file.ReadWord(); @@ -299,7 +299,7 @@ uint8_t LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, s } if (is_wanted_colour_depth && is_wanted_zoom_lvl) { - ZoomLevel zoom_lvl = (sprite_type != SpriteType::MapGen) ? zoom_lvl_map[zoom] : ZOOM_LVL_NORMAL; + ZoomLevel zoom_lvl = (sprite_type != SpriteType::MapGen) ? zoom_lvl_map[zoom] : ZOOM_LVL_MIN; if (HasBit(loaded_sprites, zoom_lvl)) { /* We already have this zoom level, skip sprite. */ diff --git a/src/video/opengl.cpp b/src/video/opengl.cpp index 4889fb5ca2..ee9883c169 100644 --- a/src/video/opengl.cpp +++ b/src/video/opengl.cpp @@ -1270,17 +1270,17 @@ void OpenGLBackend::ReleaseAnimBuffer(const Rect &update_rect) Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(OpenGLSprite)); OpenGLSprite *gl_sprite = (OpenGLSprite *)dest_sprite->data; - new (gl_sprite) OpenGLSprite(sprite[ZOOM_LVL_NORMAL].width, sprite[ZOOM_LVL_NORMAL].height, sprite[ZOOM_LVL_NORMAL].type == SpriteType::Font ? 1 : ZOOM_LVL_END, sprite[ZOOM_LVL_NORMAL].colours); + new (gl_sprite) OpenGLSprite(sprite[ZOOM_LVL_MIN].width, sprite[ZOOM_LVL_MIN].height, sprite[ZOOM_LVL_MIN].type == SpriteType::Font ? 1 : ZOOM_LVL_END, sprite[ZOOM_LVL_MIN].colours); /* Upload texture data. */ - for (int i = 0; i < (sprite[ZOOM_LVL_NORMAL].type == SpriteType::Font ? 1 : ZOOM_LVL_END); i++) { + for (int i = 0; i < (sprite[ZOOM_LVL_MIN].type == SpriteType::Font ? 1 : ZOOM_LVL_END); i++) { gl_sprite->Update(sprite[i].width, sprite[i].height, i, sprite[i].data); } - dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height; - dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width; - dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs; - dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs; + dest_sprite->height = sprite[ZOOM_LVL_MIN].height; + dest_sprite->width = sprite[ZOOM_LVL_MIN].width; + dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs; + dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs; return dest_sprite; } diff --git a/src/viewport.cpp b/src/viewport.cpp index fefe970aab..d940d52b1f 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1772,7 +1772,7 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom DrawPixelInfo dp = _vd.dpi; ZoomLevel zoom = _vd.dpi.zoom; - dp.zoom = ZOOM_LVL_NORMAL; + dp.zoom = ZOOM_LVL_MIN; dp.width = UnScaleByZoom(dp.width, zoom); dp.height = UnScaleByZoom(dp.height, zoom); _cur_dpi = &dp; @@ -2006,10 +2006,10 @@ static bool MarkViewportDirty(const Viewport *vp, int left, int top, int right, /** * Mark all viewports that display an area as dirty (in need of repaint). - * @param left Left edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_NORMAL) - * @param top Top edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_NORMAL) - * @param right Right edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_NORMAL) - * @param bottom Bottom edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_NORMAL) + * @param left Left edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_MIN) + * @param top Top edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_MIN) + * @param right Right edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_MIN) + * @param bottom Bottom edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_MIN) * @return true if at least one viewport has a dirty block * @ingroup dirty */ diff --git a/src/window.cpp b/src/window.cpp index 1e92885755..1df0ccf199 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -905,7 +905,7 @@ static void DrawOverlappedWindow(Window *w, int left, int top, int right, int bo dp->top = top - w->top; dp->pitch = _screen.pitch; dp->dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(_screen.dst_ptr, left, top); - dp->zoom = ZOOM_LVL_NORMAL; + dp->zoom = ZOOM_LVL_MIN; w->OnPaint(); } diff --git a/src/zoom_func.h b/src/zoom_func.h index faaddbc49b..25d8b92e8a 100644 --- a/src/zoom_func.h +++ b/src/zoom_func.h @@ -13,7 +13,7 @@ #include "zoom_type.h" /** - * Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_NORMAL) + * Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_MIN) * When shifting right, value is rounded up * @param value value to shift * @param zoom zoom level to shift to @@ -25,7 +25,7 @@ inline int ScaleByZoom(int value, ZoomLevel zoom) } /** - * Scale by zoom level, usually shift right (when zoom > ZOOM_LVL_NORMAL) + * Scale by zoom level, usually shift right (when zoom > ZOOM_LVL_MIN) * When shifting right, value is rounded up * @param value value to shift * @param zoom zoom level to shift to @@ -48,7 +48,7 @@ inline int AdjustByZoom(int value, int zoom) } /** - * Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_NORMAL) + * Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_MIN) * @param value value to shift * @param zoom zoom level to shift to * @return shifted value @@ -59,7 +59,7 @@ inline int ScaleByZoomLower(int value, ZoomLevel zoom) } /** - * Scale by zoom level, usually shift right (when zoom > ZOOM_LVL_NORMAL) + * Scale by zoom level, usually shift right (when zoom > ZOOM_LVL_MIN) * @param value value to shift * @param zoom zoom level to shift to * @return shifted value @@ -71,7 +71,7 @@ inline int UnScaleByZoomLower(int value, ZoomLevel zoom) /** * Short-hand to apply GUI zoom level. - * @param value Pixel amount at #ZOOM_LVL_BEGIN (full zoom in). + * @param value Pixel amount at #ZOOM_LVL_MIN (full zoom in). * @return Pixel amount at #ZOOM_LVL_GUI (current interface size). */ inline int UnScaleGUI(int value) From 9854553e10f279256e929612c64260650312386f Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 4 Apr 2024 18:27:34 +0100 Subject: [PATCH 17/29] Codechange: ZOOM_LVL_SHIFT/BASE are not actually ZOOM_LVLs. Rename to ZOOM_BASE_SHIFT and ZOOM_BASE respectively, and derive from ZOOM_LVL instead of numeric value. --- src/fontcache/spritefontcache.cpp | 4 ++-- src/gfx.cpp | 2 +- src/landscape.h | 6 ++--- src/saveload/afterload.cpp | 6 ++--- src/signs.cpp | 2 +- src/smallmap_gui.cpp | 2 +- src/station_cmd.cpp | 4 ++-- src/texteff.cpp | 2 +- src/tile_type.h | 10 ++++---- src/town_cmd.cpp | 2 +- src/vehicle.cpp | 20 ++++++++-------- src/viewport.cpp | 40 +++++++++++++++---------------- src/waypoint_cmd.cpp | 2 +- src/widget.cpp | 4 ++-- src/zoom_func.h | 6 ++--- src/zoom_type.h | 7 +++--- 16 files changed, 59 insertions(+), 60 deletions(-) diff --git a/src/fontcache/spritefontcache.cpp b/src/fontcache/spritefontcache.cpp index aa577e1b11..264a691526 100644 --- a/src/fontcache/spritefontcache.cpp +++ b/src/fontcache/spritefontcache.cpp @@ -23,12 +23,12 @@ static const int ASCII_LETTERSTART = 32; ///< First printable ASCII letter. /** * Scale traditional pixel dimensions to font zoom level, for drawing sprite fonts. - * @param value Pixel amount at #ZOOM_LVL_BASE (traditional "normal" interface size). + * @param value Pixel amount at #ZOOM_BASE (traditional "normal" interface size). * @return Pixel amount at _font_zoom (current interface size). */ static int ScaleFontTrad(int value) { - return UnScaleByZoom(value * ZOOM_LVL_BASE, _font_zoom); + return UnScaleByZoom(value * ZOOM_BASE, _font_zoom); } /** diff --git a/src/gfx.cpp b/src/gfx.cpp index 2731220f0c..a4a3267548 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -1210,7 +1210,7 @@ std::unique_ptr DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel static void GfxMainBlitterViewport(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub, SpriteID sprite_id) { - GfxBlitter(sprite, x, y, mode, sub, sprite_id, _cur_dpi->zoom); + GfxBlitter(sprite, x, y, mode, sub, sprite_id, _cur_dpi->zoom); } static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub, SpriteID sprite_id, ZoomLevel zoom) diff --git a/src/landscape.h b/src/landscape.h index 7d92ce1273..98221c5019 100644 --- a/src/landscape.h +++ b/src/landscape.h @@ -79,8 +79,8 @@ inline std::tuple GetFoundationPixelSlope(TileIndex tile) inline Point RemapCoords(int x, int y, int z) { Point pt; - pt.x = (y - x) * 2 * ZOOM_LVL_BASE; - pt.y = (y + x - z) * ZOOM_LVL_BASE; + pt.x = (y - x) * 2 * ZOOM_BASE; + pt.y = (y + x - z) * ZOOM_BASE; return pt; } @@ -108,7 +108,7 @@ inline Point RemapCoords2(int x, int y) */ inline Point InverseRemapCoords(int x, int y) { - Point pt = {(y * 2 - x) >> (2 + ZOOM_LVL_SHIFT), (y * 2 + x) >> (2 + ZOOM_LVL_SHIFT)}; + Point pt = {(y * 2 - x) >> (2 + ZOOM_BASE_SHIFT), (y * 2 + x) >> (2 + ZOOM_BASE_SHIFT)}; return pt; } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index bc203e16dc..9bfb99506b 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2838,9 +2838,9 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_165)) { /* Adjust zoom level to account for new levels */ - _saved_scrollpos_zoom = static_cast(_saved_scrollpos_zoom + ZOOM_LVL_SHIFT); - _saved_scrollpos_x *= ZOOM_LVL_BASE; - _saved_scrollpos_y *= ZOOM_LVL_BASE; + _saved_scrollpos_zoom = static_cast(_saved_scrollpos_zoom + ZOOM_BASE_SHIFT); + _saved_scrollpos_x *= ZOOM_BASE; + _saved_scrollpos_y *= ZOOM_BASE; } /* When any NewGRF has been changed the availability of some vehicles might diff --git a/src/signs.cpp b/src/signs.cpp index 0f1d7a78f0..453c55841b 100644 --- a/src/signs.cpp +++ b/src/signs.cpp @@ -50,7 +50,7 @@ void Sign::UpdateVirtCoord() if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeSign(this->index)); SetDParam(0, this->index); - this->sign.UpdatePosition(pt.x, pt.y - 6 * ZOOM_LVL_BASE, STR_WHITE_SIGN); + this->sign.UpdatePosition(pt.x, pt.y - 6 * ZOOM_BASE, STR_WHITE_SIGN); _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeSign(this->index)); } diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 4bfa47b6de..18d25d7083 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -843,7 +843,7 @@ protected: void SetNewScroll(int sx, int sy, int sub) { const NWidgetBase *wi = this->GetWidget(WID_SM_MAP); - Point hv = InverseRemapCoords(wi->current_x * ZOOM_LVL_BASE * TILE_SIZE / 2, wi->current_y * ZOOM_LVL_BASE * TILE_SIZE / 2); + Point hv = InverseRemapCoords(wi->current_x * ZOOM_BASE * TILE_SIZE / 2, wi->current_y * ZOOM_BASE * TILE_SIZE / 2); hv.x *= this->zoom; hv.y *= this->zoom; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 5ae1b6735d..5385d78887 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -441,8 +441,8 @@ void Station::UpdateVirtCoord() { Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE); - pt.y -= 32 * ZOOM_LVL_BASE; - if ((this->facilities & FACIL_AIRPORT) && this->airport.type == AT_OILRIG) pt.y -= 16 * ZOOM_LVL_BASE; + pt.y -= 32 * ZOOM_BASE; + if ((this->facilities & FACIL_AIRPORT) && this->airport.type == AT_OILRIG) pt.y -= 16 * ZOOM_BASE; if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeStation(this->index)); diff --git a/src/texteff.cpp b/src/texteff.cpp index 930df8421c..10b276232e 100644 --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -104,7 +104,7 @@ IntervalTimer move_all_text_effects_interval = {std::chrono::millis te.MarkDirty(ZOOM_LVL_TEXT_EFFECT); te.duration -= count; - te.top -= count * ZOOM_LVL_BASE; + te.top -= count * ZOOM_BASE; te.MarkDirty(ZOOM_LVL_TEXT_EFFECT); } }}; diff --git a/src/tile_type.h b/src/tile_type.h index 261fe58fc2..d1a7a3eb93 100644 --- a/src/tile_type.h +++ b/src/tile_type.h @@ -14,12 +14,12 @@ static const uint TILE_SIZE = 16; ///< Tile size in world coordinates. static const uint TILE_UNIT_MASK = TILE_SIZE - 1; ///< For masking in/out the inner-tile world coordinate units. -static const uint TILE_PIXELS = 32; ///< Pixel distance between tile columns/rows in #ZOOM_LVL_BASE. -static const uint TILE_HEIGHT = 8; ///< Height of a height level in world coordinate AND in pixels in #ZOOM_LVL_BASE. +static const uint TILE_PIXELS = 32; ///< Pixel distance between tile columns/rows in #ZOOM_BASE. +static const uint TILE_HEIGHT = 8; ///< Height of a height level in world coordinate AND in pixels in #ZOOM_BASE. -static const uint MAX_BUILDING_PIXELS = 200; ///< Maximum height of a building in pixels in #ZOOM_LVL_BASE. (Also applies to "bridge buildings" on the bridge floor.) -static const int MAX_VEHICLE_PIXEL_X = 192; ///< Maximum width of a vehicle in pixels in #ZOOM_LVL_BASE. -static const int MAX_VEHICLE_PIXEL_Y = 96; ///< Maximum height of a vehicle in pixels in #ZOOM_LVL_BASE. +static const uint MAX_BUILDING_PIXELS = 200; ///< Maximum height of a building in pixels in #ZOOM_BASE. (Also applies to "bridge buildings" on the bridge floor.) +static const int MAX_VEHICLE_PIXEL_X = 192; ///< Maximum width of a vehicle in pixels in #ZOOM_BASE. +static const int MAX_VEHICLE_PIXEL_Y = 96; ///< Maximum height of a vehicle in pixels in #ZOOM_BASE. static const uint MAX_TILE_HEIGHT = 255; ///< Maximum allowed tile height diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index c44cf48b04..8634fb0b7a 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -409,7 +409,7 @@ void Town::UpdateVirtCoord() SetDParam(0, this->index); SetDParam(1, this->cache.population); - this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_LVL_BASE, + this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE, _settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN, STR_VIEWPORT_TOWN_TINY_WHITE); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 7d6e8489ea..c8fefff234 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -74,13 +74,13 @@ static const uint GEN_HASHX_BUCKET_BITS = 7; static const uint GEN_HASHY_BUCKET_BITS = 6; /* Compute hash for vehicle coord */ -#define GEN_HASHX(x) GB((x), GEN_HASHX_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHX_BITS) -#define GEN_HASHY(y) (GB((y), GEN_HASHY_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHY_BITS) << GEN_HASHX_BITS) +#define GEN_HASHX(x) GB((x), GEN_HASHX_BUCKET_BITS + ZOOM_BASE_SHIFT, GEN_HASHX_BITS) +#define GEN_HASHY(y) (GB((y), GEN_HASHY_BUCKET_BITS + ZOOM_BASE_SHIFT, GEN_HASHY_BITS) << GEN_HASHX_BITS) #define GEN_HASH(x, y) (GEN_HASHY(y) + GEN_HASHX(x)) /* Maximum size until hash repeats */ -static const int GEN_HASHX_SIZE = 1 << (GEN_HASHX_BUCKET_BITS + GEN_HASHX_BITS + ZOOM_LVL_SHIFT); -static const int GEN_HASHY_SIZE = 1 << (GEN_HASHY_BUCKET_BITS + GEN_HASHY_BITS + ZOOM_LVL_SHIFT); +static const int GEN_HASHX_SIZE = 1 << (GEN_HASHX_BUCKET_BITS + GEN_HASHX_BITS + ZOOM_BASE_SHIFT); +static const int GEN_HASHY_SIZE = 1 << (GEN_HASHY_BUCKET_BITS + GEN_HASHY_BITS + ZOOM_BASE_SHIFT); /* Increments to reach next bucket in hash table */ static const int GEN_HASHX_INC = 1; @@ -1158,8 +1158,8 @@ void ViewportAddVehicles(DrawPixelInfo *dpi) const int b = dpi->top + dpi->height; /* Border size of MAX_VEHICLE_PIXEL_xy */ - const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE; - const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE; + const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_BASE; + const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_BASE; /* The hash area to scan */ int xl, xu, yl, yu; @@ -1254,8 +1254,8 @@ Vehicle *CheckClickOnVehicle(const Viewport *vp, int x, int y) y = ScaleByZoom(y, vp->zoom) + vp->virtual_top; /* Border size of MAX_VEHICLE_PIXEL_xy */ - const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE; - const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE; + const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_BASE; + const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_BASE; /* The hash area to scan */ int xl = GEN_HASHX(x - xb); @@ -1695,8 +1695,8 @@ void Vehicle::UpdateBoundingBoxCoordinates(bool update_cache) const Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos); new_coord.left += pt.x; new_coord.top += pt.y; - new_coord.right += pt.x + 2 * ZOOM_LVL_BASE; - new_coord.bottom += pt.y + 2 * ZOOM_LVL_BASE; + new_coord.right += pt.x + 2 * ZOOM_BASE; + new_coord.bottom += pt.y + 2 * ZOOM_BASE; if (update_cache) { /* diff --git a/src/viewport.cpp b/src/viewport.cpp index d940d52b1f..3e82735c79 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -106,10 +106,10 @@ ViewportSignKdtree _viewport_sign_kdtree(&Kdtree_ViewportSignXYFunc); static int _viewport_sign_maxwidth = 0; -static const int MAX_TILE_EXTENT_LEFT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner. -static const int MAX_TILE_EXTENT_RIGHT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner. -static const int MAX_TILE_EXTENT_TOP = ZOOM_LVL_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges). -static const int MAX_TILE_EXTENT_BOTTOM = ZOOM_LVL_BASE * (TILE_PIXELS + 2 * TILE_HEIGHT); ///< Maximum bottom extent of tile relative to north corner (worst case: #SLOPE_STEEP_N). +static const int MAX_TILE_EXTENT_LEFT = ZOOM_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner. +static const int MAX_TILE_EXTENT_RIGHT = ZOOM_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner. +static const int MAX_TILE_EXTENT_TOP = ZOOM_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges). +static const int MAX_TILE_EXTENT_BOTTOM = ZOOM_BASE * (TILE_PIXELS + 2 * TILE_HEIGHT); ///< Maximum bottom extent of tile relative to north corner (worst case: #SLOPE_STEEP_N). struct StringSpriteToDraw { std::string string; @@ -570,9 +570,9 @@ void DrawGroundSpriteAt(SpriteID image, PaletteID pal, int32_t x, int32_t y, int if (_vd.foundation[_vd.foundation_part] != -1) { Point pt = RemapCoords(x, y, z); - AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, pt.x + extra_offs_x * ZOOM_LVL_BASE, pt.y + extra_offs_y * ZOOM_LVL_BASE); + AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, pt.x + extra_offs_x * ZOOM_BASE, pt.y + extra_offs_y * ZOOM_BASE); } else { - AddTileSpriteToDraw(image, pal, _cur_ti.x + x, _cur_ti.y + y, _cur_ti.z + z, sub, extra_offs_x * ZOOM_LVL_BASE, extra_offs_y * ZOOM_LVL_BASE); + AddTileSpriteToDraw(image, pal, _cur_ti.x + x, _cur_ti.y + y, _cur_ti.z + z, sub, extra_offs_x * ZOOM_BASE, extra_offs_y * ZOOM_BASE); } } @@ -614,8 +614,8 @@ void OffsetGroundSprite(int x, int y) /* _vd.last_child == nullptr if foundation sprite was clipped by the viewport bounds */ if (_vd.last_child != nullptr) _vd.foundation[_vd.foundation_part] = (uint)_vd.parent_sprites_to_draw.size() - 1; - _vd.foundation_offset[_vd.foundation_part].x = x * ZOOM_LVL_BASE; - _vd.foundation_offset[_vd.foundation_part].y = y * ZOOM_LVL_BASE; + _vd.foundation_offset[_vd.foundation_part].x = x * ZOOM_BASE; + _vd.foundation_offset[_vd.foundation_part].y = y * ZOOM_BASE; _vd.last_foundation_child[_vd.foundation_part] = _vd.last_child; } @@ -845,8 +845,8 @@ void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool tran cs.image = image; cs.pal = pal; cs.sub = sub; - cs.x = scale ? x * ZOOM_LVL_BASE : x; - cs.y = scale ? y * ZOOM_LVL_BASE : y; + cs.x = scale ? x * ZOOM_BASE : x; + cs.y = scale ? y * ZOOM_BASE : y; cs.relative = relative; cs.next = -1; @@ -892,7 +892,7 @@ static void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *t AddTileSpriteToDraw(image, pal, ti->x, ti->y, ti->z + z_offset, nullptr, extra_offs_x, extra_offs_y); } else { /* draw on top of foundation */ - AddChildSpriteToFoundation(image, pal, nullptr, foundation_part, extra_offs_x, extra_offs_y - z_offset * ZOOM_LVL_BASE); + AddChildSpriteToFoundation(image, pal, nullptr, foundation_part, extra_offs_x, extra_offs_y - z_offset * ZOOM_BASE); } } @@ -1177,7 +1177,7 @@ draw_inner: static int GetViewportY(Point tile) { /* Each increment in X or Y direction moves down by half a tile, i.e. TILE_PIXELS / 2. */ - return (tile.y * (int)(TILE_PIXELS / 2) + tile.x * (int)(TILE_PIXELS / 2) - TilePixelHeightOutsideMap(tile.x, tile.y)) << ZOOM_LVL_SHIFT; + return (tile.y * (int)(TILE_PIXELS / 2) + tile.x * (int)(TILE_PIXELS / 2) - TilePixelHeightOutsideMap(tile.x, tile.y)) << ZOOM_BASE_SHIFT; } /** @@ -1207,7 +1207,7 @@ static void ViewportAddLandscape() int left_column = (upper_left.y - upper_left.x) / (int)TILE_SIZE - 2; int right_column = (upper_right.y - upper_right.x) / (int)TILE_SIZE + 2; - int potential_bridge_height = ZOOM_LVL_BASE * TILE_HEIGHT * _settings_game.construction.max_bridge_height; + int potential_bridge_height = ZOOM_BASE * TILE_HEIGHT * _settings_game.construction.max_bridge_height; /* Rows overlap with neighbouring rows by a half tile. * The first row that could possibly be visible is the row above upper_left (if it is at height 0). @@ -1267,7 +1267,7 @@ static void ViewportAddLandscape() if (IsBridgeAbove(_cur_ti.tile)) { /* Is the bridge visible? */ TileIndex bridge_tile = GetNorthernBridgeEnd(_cur_ti.tile); - int bridge_height = ZOOM_LVL_BASE * (GetBridgePixelHeight(bridge_tile) - TilePixelHeight(_cur_ti.tile)); + int bridge_height = ZOOM_BASE * (GetBridgePixelHeight(bridge_tile) - TilePixelHeight(_cur_ti.tile)); if (min_visible_height < bridge_height + MAX_TILE_EXTENT_TOP) tile_visible = true; } @@ -1883,7 +1883,7 @@ static inline void ClampViewportToMap(const Viewport *vp, int *scroll_x, int *sc static void ClampSmoothScroll(uint32_t delta_ms, int64_t delta_hi, int64_t delta_lo, int &delta_hi_clamped, int &delta_lo_clamped) { /** A tile is 64 pixels in width at 1x zoom; viewport coordinates are in 4x zoom. */ - constexpr int PIXELS_PER_TILE = TILE_PIXELS * 2 * ZOOM_LVL_BASE; + constexpr int PIXELS_PER_TILE = TILE_PIXELS * 2 * ZOOM_BASE; assert(delta_hi != 0); @@ -2053,7 +2053,7 @@ void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_heigh Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, tile_height_override * TILE_HEIGHT); MarkAllViewportsDirty( pt.x - MAX_TILE_EXTENT_LEFT, - pt.y - MAX_TILE_EXTENT_TOP - ZOOM_LVL_BASE * TILE_HEIGHT * bridge_level_offset, + pt.y - MAX_TILE_EXTENT_TOP - ZOOM_BASE * TILE_HEIGHT * bridge_level_offset, pt.x + MAX_TILE_EXTENT_RIGHT, pt.y + MAX_TILE_EXTENT_BOTTOM); } @@ -2131,15 +2131,15 @@ static void SetSelectionTilesDirty() /* the 'x' coordinate of 'top' and 'bot' is the same (and always in the same distance from tile middle), * tile height/slope affects only the 'y' on-screen coordinate! */ - int l = top.x - TILE_PIXELS * ZOOM_LVL_BASE; // 'x' coordinate of left side of the dirty rectangle + int l = top.x - TILE_PIXELS * ZOOM_BASE; // 'x' coordinate of left side of the dirty rectangle int t = top.y; // 'y' coordinate of top side of the dirty rectangle - int r = top.x + TILE_PIXELS * ZOOM_LVL_BASE; // 'x' coordinate of right side of the dirty rectangle + int r = top.x + TILE_PIXELS * ZOOM_BASE; // 'x' coordinate of right side of the dirty rectangle int b = bot.y; // 'y' coordinate of bottom side of the dirty rectangle - static const int OVERLAY_WIDTH = 4 * ZOOM_LVL_BASE; // part of selection sprites is drawn outside the selected area (in particular: terraforming) + static const int OVERLAY_WIDTH = 4 * ZOOM_BASE; // part of selection sprites is drawn outside the selected area (in particular: terraforming) /* For halftile foundations on SLOPE_STEEP_S the sprite extents some more towards the top */ - MarkAllViewportsDirty(l - OVERLAY_WIDTH, t - OVERLAY_WIDTH - TILE_HEIGHT * ZOOM_LVL_BASE, r + OVERLAY_WIDTH, b + OVERLAY_WIDTH); + MarkAllViewportsDirty(l - OVERLAY_WIDTH, t - OVERLAY_WIDTH - TILE_HEIGHT * ZOOM_BASE, r + OVERLAY_WIDTH, b + OVERLAY_WIDTH); /* haven't we reached the topmost tile yet? */ if (top_x != x_start) { diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 52e0ca725c..2bf7ce5e52 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -44,7 +44,7 @@ void Waypoint::UpdateVirtCoord() if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeWaypoint(this->index)); SetDParam(0, this->index); - this->sign.UpdatePosition(pt.x, pt.y - 32 * ZOOM_LVL_BASE, STR_VIEWPORT_WAYPOINT); + this->sign.UpdatePosition(pt.x, pt.y - 32 * ZOOM_BASE, STR_VIEWPORT_WAYPOINT); _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeWaypoint(this->index)); diff --git a/src/widget.cpp b/src/widget.cpp index dd91856b05..820534ddcb 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -29,7 +29,7 @@ WidgetDimensions WidgetDimensions::scaled = {}; /** * Scale a RectPadding to GUI zoom level. - * @param r RectPadding at ZOOM_LVL_BASE (traditional "normal" interface size). + * @param r RectPadding at ZOOM_BASE (traditional "normal" interface size). * @return RectPadding at #ZOOM_LVL_GUI (current interface size). */ static inline RectPadding ScaleGUITrad(const RectPadding &r) @@ -39,7 +39,7 @@ static inline RectPadding ScaleGUITrad(const RectPadding &r) /** * Scale a Dimension to GUI zoom level. - * @param d Dimension at ZOOM_LVL_BASE (traditional "normal" interface size). + * @param d Dimension at ZOOM_BASE (traditional "normal" interface size). * @return Dimension at #ZOOM_LVL_GUI (current interface size). */ static inline Dimension ScaleGUITrad(const Dimension &dim) diff --git a/src/zoom_func.h b/src/zoom_func.h index 25d8b92e8a..4ff4a84a10 100644 --- a/src/zoom_func.h +++ b/src/zoom_func.h @@ -101,17 +101,17 @@ inline ZoomLevel UnScaleZoomGUI(ZoomLevel value) /** * Scale traditional pixel dimensions to GUI zoom level, for drawing sprites. - * @param value Pixel amount at #ZOOM_LVL_BASE (traditional "normal" interface size). + * @param value Pixel amount at #ZOOM_BASE (traditional "normal" interface size). * @return Pixel amount at #ZOOM_LVL_GUI (current interface size). */ inline int ScaleSpriteTrad(int value) { - return UnScaleGUI(value * ZOOM_LVL_BASE); + return UnScaleGUI(value * ZOOM_BASE); } /** * Scale traditional pixel dimensions to GUI zoom level. - * @param value Pixel amount at #ZOOM_LVL_BASE (traditional "normal" interface size). + * @param value Pixel amount at #ZOOM_BASE (traditional "normal" interface size). * @return Pixel amount at #ZOOM_LVL_GUI (current interface size). */ inline int ScaleGUITrad(int value) diff --git a/src/zoom_type.h b/src/zoom_type.h index f5db67e2fc..9552fceca9 100644 --- a/src/zoom_type.h +++ b/src/zoom_type.h @@ -12,9 +12,6 @@ #include "core/enum_type.hpp" -static uint const ZOOM_LVL_SHIFT = 2; -static uint const ZOOM_LVL_BASE = 1 << ZOOM_LVL_SHIFT; - /** All zoom levels we know. */ enum ZoomLevel : uint8_t { /* Our possible zoom-levels */ @@ -43,11 +40,13 @@ enum ZoomLevel : uint8_t { ZOOM_LVL_MIN = ZOOM_LVL_NORMAL, ///< Minimum zoom level. ZOOM_LVL_MAX = ZOOM_LVL_OUT_32X, ///< Maximum zoom level. - }; DECLARE_POSTFIX_INCREMENT(ZoomLevel) DECLARE_ENUM_AS_ADDABLE(ZoomLevel) +static uint const ZOOM_BASE_SHIFT = static_cast(ZOOM_LVL_OUT_4X); +static uint const ZOOM_BASE = 1U << ZOOM_BASE_SHIFT; + extern int _gui_scale; extern int _gui_scale_cfg; From 7572cfd1035c2d36f7439443f9784583176f150d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 4 Apr 2024 18:51:46 +0100 Subject: [PATCH 18/29] Codechange: Redefine ZOOM_LVL so that ZOOM_LVL_NORMAL is 1x zoom. This matches expectations of what normal zoom means. --- src/blitter/32bpp_sse_type.h | 2 +- src/gfx.cpp | 4 ++-- src/graph_gui.cpp | 2 +- src/network/network_gui.cpp | 4 ++-- src/newgrf_debug_gui.cpp | 12 +++++----- src/spritecache.cpp | 8 +++---- src/spriteloader/grf.cpp | 14 ++++++------ src/table/settings/gui_settings.ini | 6 ++--- src/vehicle_gui.cpp | 2 +- src/viewport.cpp | 10 ++++----- src/widget.cpp | 4 ++-- src/zoom_func.h | 4 ++-- src/zoom_type.h | 34 ++++++++++++++--------------- 13 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/blitter/32bpp_sse_type.h b/src/blitter/32bpp_sse_type.h index e8662e4949..57de1d6d58 100644 --- a/src/blitter/32bpp_sse_type.h +++ b/src/blitter/32bpp_sse_type.h @@ -28,7 +28,7 @@ #endif #define META_LENGTH 2 ///< Number of uint32_t inserted before each line of pixels in a sprite. -#define MARGIN_NORMAL_THRESHOLD (zoom == ZOOM_LVL_OUT_32X ? 8 : 4) ///< Minimum width to use margins with BM_NORMAL. +#define MARGIN_NORMAL_THRESHOLD (zoom == ZOOM_LVL_OUT_8X ? 8 : 4) ///< Minimum width to use margins with BM_NORMAL. #define MARGIN_REMAP_THRESHOLD 4 ///< Minimum width to use margins with BM_COLOUR_REMAP. #undef ALIGN diff --git a/src/gfx.cpp b/src/gfx.cpp index a4a3267548..36f62a129d 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -57,7 +57,7 @@ static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, static ReusableBuffer _cursor_backup; -ZoomLevel _gui_zoom = ZOOM_LVL_OUT_4X; ///< GUI Zoom level +ZoomLevel _gui_zoom = ZOOM_LVL_NORMAL; ///< GUI Zoom level ZoomLevel _font_zoom = _gui_zoom; ///< Sprite font Zoom level (not clamped) int _gui_scale = MIN_INTERFACE_SCALE; ///< GUI scale, 100 is 100%. int _gui_scale_cfg; ///< GUI scale in config. @@ -1789,7 +1789,7 @@ void UpdateGUIZoom() _gui_scale = Clamp(_gui_scale_cfg, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE); } - int8_t new_zoom = ScaleGUITrad(1) <= 1 ? ZOOM_LVL_OUT_4X : ScaleGUITrad(1) >= 4 ? ZOOM_LVL_NORMAL : ZOOM_LVL_OUT_2X; + int8_t new_zoom = ScaleGUITrad(1) <= 1 ? ZOOM_LVL_NORMAL : ScaleGUITrad(1) >= 4 ? ZOOM_LVL_IN_4X : ZOOM_LVL_IN_2X; /* Font glyphs should not be clamped to min/max zoom. */ _font_zoom = static_cast(new_zoom); /* Ensure the gui_zoom is clamped between min/max. */ diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 919474d911..af2efd3722 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -117,7 +117,7 @@ static std::unique_ptr MakeNWidgetCompanyLines() { auto vert = std::make_unique(NC_EQUALSIZE); vert->SetPadding(2, 2, 2, 2); - uint sprite_height = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X).height; + uint sprite_height = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_NORMAL).height; for (WidgetID widnum = WID_GL_FIRST_COMPANY; widnum <= WID_GL_LAST_COMPANY; widnum++) { auto panel = std::make_unique(WWT_PANEL, COLOUR_BROWN, widnum); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 548c29387b..a9f6bd4882 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -100,8 +100,8 @@ public: this->Add(std::make_unique(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_YEARS, STR_NETWORK_SERVER_LIST_PLAY_TIME_CAPTION, STR_NETWORK_SERVER_LIST_PLAY_TIME_CAPTION_TOOLTIP)); leaf = std::make_unique(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_INFO, STR_EMPTY, STR_NETWORK_SERVER_LIST_INFO_ICONS_TOOLTIP); - leaf->SetMinimalSize(14 + GetSpriteSize(SPR_LOCK, nullptr, ZOOM_LVL_OUT_4X).width - + GetSpriteSize(SPR_BLOT, nullptr, ZOOM_LVL_OUT_4X).width, 12); + leaf->SetMinimalSize(14 + GetSpriteSize(SPR_LOCK, nullptr, ZOOM_LVL_NORMAL).width + + GetSpriteSize(SPR_BLOT, nullptr, ZOOM_LVL_NORMAL).width, 12); leaf->SetFill(0, 1); this->Add(std::move(leaf)); } diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index d626296108..fe9447edc1 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -1147,12 +1147,12 @@ static constexpr NWidgetPart _nested_sprite_aligner_widgets[] = { NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SA_SCROLLBAR), EndContainer(), NWidget(NWID_VERTICAL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_NORMAL), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_MIN, STR_NULL), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_2X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_IN_2X, STR_NULL), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_4X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_NORMAL, STR_NULL), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_8X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X, STR_NULL), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_16X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X, STR_NULL), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_32X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_IN_4X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_MIN, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_IN_2X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_IN_2X, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_NORMAL), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_NORMAL, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_2X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_4X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_8X), SetDataTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), EndContainer(), diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 2ef7784c0f..28cd97bac8 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -401,8 +401,8 @@ static bool ResizeSprites(SpriteLoader::SpriteCollection &sprite, uint8_t sprite /* Upscale to desired sprite_min_zoom if provided sprite only had zoomed in versions. */ if (first_avail < _settings_client.gui.sprite_zoom_min) { - if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_OUT_4X) ResizeSpriteIn(sprite, ZOOM_LVL_OUT_4X, ZOOM_LVL_OUT_2X); - if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_OUT_2X) ResizeSpriteIn(sprite, ZOOM_LVL_OUT_2X, ZOOM_LVL_NORMAL); + if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_NORMAL) ResizeSpriteIn(sprite, ZOOM_LVL_NORMAL, ZOOM_LVL_IN_2X); + if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_IN_2X) ResizeSpriteIn(sprite, ZOOM_LVL_IN_2X, ZOOM_LVL_IN_4X); } return true; @@ -581,11 +581,11 @@ void ReadGRFSpriteOffsets(SpriteFile &file) if (length > 0) { uint8_t zoom = file.ReadByte(); length--; - if (colour != 0 && zoom == 0) { // ZOOM_LVL_OUT_4X (normal zoom) + if (colour != 0 && zoom == 0) { // ZOOM_LVL_NORMAL (normal zoom) SetBit(offset.control_flags, (colour != SCC_PAL) ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL); SetBit(offset.control_flags, (colour != SCC_PAL) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL); } - if (colour != 0 && zoom == 2) { // ZOOM_LVL_OUT_2X (2x zoomed in) + if (colour != 0 && zoom == 2) { // ZOOM_LVL_IN_2X (2x zoomed in) SetBit(offset.control_flags, (colour != SCC_PAL) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL); } } diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp index 0463497c1d..d365282d2a 100644 --- a/src/spriteloader/grf.cpp +++ b/src/spriteloader/grf.cpp @@ -230,7 +230,7 @@ uint8_t LoadSpriteV1(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, s /* Type 0xFF indicates either a colourmap or some other non-sprite info; we do not handle them here */ if (type == 0xFF) return 0; - ZoomLevel zoom_lvl = (sprite_type != SpriteType::MapGen) ? ZOOM_LVL_OUT_4X : ZOOM_LVL_MIN; + ZoomLevel zoom_lvl = (sprite_type != SpriteType::MapGen) ? ZOOM_LVL_NORMAL : ZOOM_LVL_MIN; sprite[zoom_lvl].height = file.ReadByte(); sprite[zoom_lvl].width = file.ReadWord(); @@ -254,7 +254,7 @@ uint8_t LoadSpriteV1(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, s uint8_t LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags) { - static const ZoomLevel zoom_lvl_map[6] = {ZOOM_LVL_OUT_4X, ZOOM_LVL_NORMAL, ZOOM_LVL_OUT_2X, ZOOM_LVL_OUT_8X, ZOOM_LVL_OUT_16X, ZOOM_LVL_OUT_32X}; + static const ZoomLevel zoom_lvl_map[6] = {ZOOM_LVL_NORMAL, ZOOM_LVL_IN_4X, ZOOM_LVL_IN_2X, ZOOM_LVL_OUT_2X, ZOOM_LVL_OUT_4X, ZOOM_LVL_OUT_8X}; /* Is the sprite not present/stripped in the GRF? */ if (file_pos == SIZE_MAX) return 0; @@ -282,13 +282,13 @@ uint8_t LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, s if (sprite_type != SpriteType::MapGen) { if (zoom < lengthof(zoom_lvl_map)) { is_wanted_zoom_lvl = true; - ZoomLevel zoom_min = sprite_type == SpriteType::Font ? ZOOM_LVL_NORMAL : _settings_client.gui.sprite_zoom_min; - if (zoom_min >= ZOOM_LVL_OUT_2X && - HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_OUT_2X) { + ZoomLevel zoom_min = sprite_type == SpriteType::Font ? ZOOM_LVL_MIN : _settings_client.gui.sprite_zoom_min; + if (zoom_min >= ZOOM_LVL_IN_2X && + HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_IN_2X) { is_wanted_zoom_lvl = false; } - if (zoom_min >= ZOOM_LVL_OUT_4X && - HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_OUT_4X) { + if (zoom_min >= ZOOM_LVL_NORMAL && + HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_NORMAL) { is_wanted_zoom_lvl = false; } } else { diff --git a/src/table/settings/gui_settings.ini b/src/table/settings/gui_settings.ini index 23bd899334..9adeed0029 100644 --- a/src/table/settings/gui_settings.ini +++ b/src/table/settings/gui_settings.ini @@ -260,7 +260,7 @@ type = SLE_UINT8 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN def = ZOOM_LVL_MIN min = ZOOM_LVL_MIN -max = ZOOM_LVL_OUT_4X +max = ZOOM_LVL_NORMAL str = STR_CONFIG_SETTING_ZOOM_MIN strhelp = STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT strval = STR_CONFIG_SETTING_ZOOM_LVL_MIN @@ -272,7 +272,7 @@ var = gui.zoom_max type = SLE_UINT8 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN def = ZOOM_LVL_MAX -min = ZOOM_LVL_OUT_8X +min = ZOOM_LVL_OUT_2X max = ZOOM_LVL_MAX str = STR_CONFIG_SETTING_ZOOM_MAX strhelp = STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT @@ -286,7 +286,7 @@ type = SLE_UINT8 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN def = ZOOM_LVL_MIN min = ZOOM_LVL_MIN -max = ZOOM_LVL_OUT_4X +max = ZOOM_LVL_NORMAL str = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN strhelp = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT strval = STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index e0f9e0dee5..6a2197db25 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -3235,7 +3235,7 @@ public: ShowExtraViewportWindow(TileVirtXY(v->x_pos, v->y_pos)); } else { const Window *mainwindow = GetMainWindow(); - if (click_count > 1 && mainwindow->viewport->zoom <= ZOOM_LVL_OUT_4X) { + if (click_count > 1 && mainwindow->viewport->zoom <= ZOOM_LVL_NORMAL) { /* main window 'follows' vehicle */ mainwindow->viewport->follow_vehicle = v->index; } else { diff --git a/src/viewport.cpp b/src/viewport.cpp index 3e82735c79..9c91b28833 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1420,7 +1420,7 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi) for (const auto *t : towns) { SetDParam(0, t->index); SetDParam(1, t->cache.population); - ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &t->cache.sign, + ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &t->cache.sign, _settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN, STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK); } @@ -1430,7 +1430,7 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi) for (const auto *si : signs) { SetDParam(0, si->index); - ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &si->sign, + ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &si->sign, STR_WHITE_SIGN, (IsTransparencySet(TO_SIGNS) || si->owner == OWNER_DEITY) ? STR_VIEWPORT_SIGN_SMALL_WHITE : STR_VIEWPORT_SIGN_SMALL_BLACK, STR_NULL, (si->owner == OWNER_NONE) ? COLOUR_GREY : (si->owner == OWNER_DEITY ? INVALID_COLOUR : _company_colours[si->owner])); @@ -1441,12 +1441,12 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi) SetDParam(1, st->facilities); if (Station::IsExpected(st)) { /* Station */ - ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &st->sign, + ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &st->sign, STR_VIEWPORT_STATION, STR_VIEWPORT_STATION_TINY, STR_NULL, (st->owner == OWNER_NONE || !st->IsInUse()) ? COLOUR_GREY : _company_colours[st->owner]); } else { /* Waypoint */ - ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &st->sign, + ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &st->sign, STR_VIEWPORT_WAYPOINT, STR_VIEWPORT_WAYPOINT_TINY, STR_NULL, (st->owner == OWNER_NONE || !st->IsInUse()) ? COLOUR_GREY : _company_colours[st->owner]); } @@ -2192,7 +2192,7 @@ void SetSelectionRed(bool b) */ static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y, const ViewportSign *sign) { - bool small = (vp->zoom >= ZOOM_LVL_OUT_16X); + bool small = (vp->zoom >= ZOOM_LVL_OUT_4X); int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, vp->zoom); int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + (small ? GetCharacterHeight(FS_SMALL) : GetCharacterHeight(FS_NORMAL)) + WidgetDimensions::scaled.fullbevel.bottom, vp->zoom); diff --git a/src/widget.cpp b/src/widget.cpp index 820534ddcb..b9aa2c0d76 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -54,7 +54,7 @@ static inline Dimension ScaleGUITrad(const Dimension &dim) Dimension GetScaledSpriteSize(SpriteID sprid) { Point offset; - Dimension d = GetSpriteSize(sprid, &offset, ZOOM_LVL_OUT_4X); + Dimension d = GetSpriteSize(sprid, &offset, ZOOM_LVL_NORMAL); d.width -= offset.x; d.height -= offset.y; return ScaleGUITrad(d); @@ -3207,7 +3207,7 @@ std::unique_ptr MakeCompanyButtonRows(WidgetID widget_first, Widget std::unique_ptr hor = nullptr; // Storage for buttons in one row. int hor_length = 0; - Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X); + Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_NORMAL); sprite_size.width += WidgetDimensions::unscaled.matrix.Horizontal(); sprite_size.height += WidgetDimensions::unscaled.matrix.Vertical(); diff --git a/src/zoom_func.h b/src/zoom_func.h index 4ff4a84a10..4b998839f0 100644 --- a/src/zoom_func.h +++ b/src/zoom_func.h @@ -86,7 +86,7 @@ inline int UnScaleGUI(int value) */ inline ZoomLevel ScaleZoomGUI(ZoomLevel value) { - return std::clamp(ZoomLevel(value + (ZOOM_LVL_GUI - ZOOM_LVL_OUT_4X)), ZOOM_LVL_MIN, ZOOM_LVL_MAX); + return std::clamp(ZoomLevel(value + (ZOOM_LVL_GUI - ZOOM_LVL_NORMAL)), ZOOM_LVL_MIN, ZOOM_LVL_MAX); } /** @@ -96,7 +96,7 @@ inline ZoomLevel ScaleZoomGUI(ZoomLevel value) */ inline ZoomLevel UnScaleZoomGUI(ZoomLevel value) { - return std::clamp(ZoomLevel(value - (ZOOM_LVL_GUI - ZOOM_LVL_OUT_4X)), ZOOM_LVL_MIN, ZOOM_LVL_MAX); + return std::clamp(ZoomLevel(value - (ZOOM_LVL_GUI - ZOOM_LVL_NORMAL)), ZOOM_LVL_MIN, ZOOM_LVL_MAX); } /** diff --git a/src/zoom_type.h b/src/zoom_type.h index 9552fceca9..89c812b06a 100644 --- a/src/zoom_type.h +++ b/src/zoom_type.h @@ -16,35 +16,35 @@ enum ZoomLevel : uint8_t { /* Our possible zoom-levels */ ZOOM_LVL_BEGIN = 0, ///< Begin for iteration. - ZOOM_LVL_NORMAL = 0, ///< The normal zoom level. + ZOOM_LVL_IN_4X = 0, ///< Zoomed 4 times in. + ZOOM_LVL_IN_2X, ///< Zoomed 2 times in. + ZOOM_LVL_NORMAL, ///< The normal zoom level. ZOOM_LVL_OUT_2X, ///< Zoomed 2 times out. ZOOM_LVL_OUT_4X, ///< Zoomed 4 times out. ZOOM_LVL_OUT_8X, ///< Zoomed 8 times out. - ZOOM_LVL_OUT_16X, ///< Zoomed 16 times out. - ZOOM_LVL_OUT_32X, ///< Zoomed 32 times out. ZOOM_LVL_END, ///< End for iteration. /* Here we define in which zoom viewports are */ - ZOOM_LVL_VIEWPORT = ZOOM_LVL_OUT_4X, ///< Default zoom level for viewports. - ZOOM_LVL_NEWS = ZOOM_LVL_OUT_4X, ///< Default zoom level for the news messages. - ZOOM_LVL_INDUSTRY = ZOOM_LVL_OUT_8X, ///< Default zoom level for the industry view. - ZOOM_LVL_TOWN = ZOOM_LVL_OUT_4X, ///< Default zoom level for the town view. - ZOOM_LVL_AIRCRAFT = ZOOM_LVL_OUT_4X, ///< Default zoom level for the aircraft view. - ZOOM_LVL_SHIP = ZOOM_LVL_OUT_4X, ///< Default zoom level for the ship view. - ZOOM_LVL_TRAIN = ZOOM_LVL_OUT_4X, ///< Default zoom level for the train view. - ZOOM_LVL_ROADVEH = ZOOM_LVL_OUT_4X, ///< Default zoom level for the road vehicle view. - ZOOM_LVL_WORLD_SCREENSHOT = ZOOM_LVL_OUT_4X, ///< Default zoom level for the world screen shot. + ZOOM_LVL_VIEWPORT = ZOOM_LVL_NORMAL, ///< Default zoom level for viewports. + ZOOM_LVL_NEWS = ZOOM_LVL_NORMAL, ///< Default zoom level for the news messages. + ZOOM_LVL_INDUSTRY = ZOOM_LVL_OUT_2X, ///< Default zoom level for the industry view. + ZOOM_LVL_TOWN = ZOOM_LVL_NORMAL, ///< Default zoom level for the town view. + ZOOM_LVL_AIRCRAFT = ZOOM_LVL_NORMAL, ///< Default zoom level for the aircraft view. + ZOOM_LVL_SHIP = ZOOM_LVL_NORMAL, ///< Default zoom level for the ship view. + ZOOM_LVL_TRAIN = ZOOM_LVL_NORMAL, ///< Default zoom level for the train view. + ZOOM_LVL_ROADVEH = ZOOM_LVL_NORMAL, ///< Default zoom level for the road vehicle view. + ZOOM_LVL_WORLD_SCREENSHOT = ZOOM_LVL_NORMAL, ///< Default zoom level for the world screen shot. - ZOOM_LVL_DETAIL = ZOOM_LVL_OUT_8X, ///< All zoom levels below or equal to this will result in details on the screen, like road-work, ... - ZOOM_LVL_TEXT_EFFECT = ZOOM_LVL_OUT_8X, ///< All zoom levels above this will not show text effects. + ZOOM_LVL_DETAIL = ZOOM_LVL_OUT_2X, ///< All zoom levels below or equal to this will result in details on the screen, like road-work, ... + ZOOM_LVL_TEXT_EFFECT = ZOOM_LVL_OUT_2X, ///< All zoom levels above this will not show text effects. - ZOOM_LVL_MIN = ZOOM_LVL_NORMAL, ///< Minimum zoom level. - ZOOM_LVL_MAX = ZOOM_LVL_OUT_32X, ///< Maximum zoom level. + ZOOM_LVL_MIN = ZOOM_LVL_IN_4X, ///< Minimum zoom level. + ZOOM_LVL_MAX = ZOOM_LVL_OUT_8X, ///< Maximum zoom level. }; DECLARE_POSTFIX_INCREMENT(ZoomLevel) DECLARE_ENUM_AS_ADDABLE(ZoomLevel) -static uint const ZOOM_BASE_SHIFT = static_cast(ZOOM_LVL_OUT_4X); +static uint const ZOOM_BASE_SHIFT = static_cast(ZOOM_LVL_NORMAL); static uint const ZOOM_BASE = 1U << ZOOM_BASE_SHIFT; extern int _gui_scale; From df3e5ade11db714d06d2ab1b63b2c565eb5917bd Mon Sep 17 00:00:00 2001 From: translators Date: Fri, 5 Apr 2024 04:43:25 +0000 Subject: [PATCH 19/29] Update: Translations from eints korean: 2 changes by telk5093 portuguese (brazilian): 1 change by pasantoro --- src/lang/brazilian_portuguese.txt | 2 +- src/lang/korean.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index f14c43a26b..e2a8bfcdd7 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -2421,7 +2421,7 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Iniciar STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Iniciar um servidor próprio STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Introduza o seu nome -STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Introduza o endereço de servidor ou código de convite +STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Endereço do servidor ou código de convite # Start new multiplayer server STR_NETWORK_START_SERVER_CAPTION :{WHITE}Iniciar novo jogo multijogador diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 45ea38ea68..7a072c7db2 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -4900,7 +4900,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}예상 STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}저장 중입니다.{}끝날 때까지 기다려주세요! STR_ERROR_AUTOSAVE_FAILED :{WHITE}자동 저장 실패 STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}드라이브를 읽을 수 없습니다 +STR_ERROR_GAME_SAVE_FAILED :{WHITE}게임을 저장하지 못 했습니다... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}파일을 삭제할 수 없습니다 +STR_ERROR_GAME_LOAD_FAILED :{WHITE}게임을 불러오지 못 했습니다... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :내부 오류: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :손상된 게임 저장 파일 - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :상위 버전의 게임 저장 파일입니다 From d11622b9a0030ea7c387c78c913e284754f17b5c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 5 Apr 2024 08:17:42 +0100 Subject: [PATCH 20/29] Fix #12114: Viewport coords of crashed aircraft not updated when falling. (#12424) This results in the aircraft glitching as the wrong viewport area is drawn. --- src/aircraft_cmd.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index a85bc5c71b..ebb5c530d8 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1186,6 +1186,7 @@ static bool HandleCrashedAircraft(Aircraft *v) v->crashed_counter = 500; v->z_pos++; } + SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos); } if (v->crashed_counter < 650) { From e8c78df39ef553431f4083f06fd982956bf0c1e5 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 5 Apr 2024 08:18:12 +0100 Subject: [PATCH 21/29] Fix #12233: Mini order list overlaps vehicle group name. (#12423) Move mini order list down one line to make room. --- src/vehicle_gui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 6a2197db25..94fc106bae 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1682,7 +1682,7 @@ uint GetVehicleListHeight(VehicleType type, uint divisor) /* Name + vehicle + profit */ uint base = ScaleGUITrad(GetVehicleHeight(type)) + 2 * GetCharacterHeight(FS_SMALL) + WidgetDimensions::scaled.matrix.Vertical(); /* Drawing of the 4 small orders + profit*/ - if (type >= VEH_SHIP) base = std::max(base, 5U * GetCharacterHeight(FS_SMALL) + WidgetDimensions::scaled.matrix.Vertical()); + if (type >= VEH_SHIP) base = std::max(base, 6U * GetCharacterHeight(FS_SMALL) + WidgetDimensions::scaled.matrix.Vertical()); if (divisor == 1) return base; @@ -1774,7 +1774,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int DrawString(tr.left, tr.right, ir.top, STR_GROUP_NAME, TC_BLACK, SA_LEFT, false, FS_SMALL); } - if (show_orderlist) DrawSmallOrderList(v, olr.left, olr.right, ir.top, this->order_arrow_width, v->cur_real_order_index); + if (show_orderlist) DrawSmallOrderList(v, olr.left, olr.right, ir.top + GetCharacterHeight(FS_SMALL), this->order_arrow_width, v->cur_real_order_index); TextColour tc; if (v->IsChainInDepot()) { @@ -1796,7 +1796,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int DrawVehicleImage(vehgroup.vehicles_begin[i], {image_left + WidgetDimensions::scaled.hsep_wide * i, ir.top, image_right, ir.bottom}, selected_vehicle, EIT_IN_LIST, 0); } - if (show_orderlist) DrawSmallOrderList((vehgroup.vehicles_begin[0])->GetFirstOrder(), olr.left, olr.right, ir.top, this->order_arrow_width); + if (show_orderlist) DrawSmallOrderList((vehgroup.vehicles_begin[0])->GetFirstOrder(), olr.left, olr.right, ir.top + GetCharacterHeight(FS_SMALL), this->order_arrow_width); SetDParam(0, vehgroup.NumVehicles()); DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, STR_JUST_COMMA, TC_BLACK); From 83da886093bc953d6db0292dbf152097c3791d5a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 5 Apr 2024 19:16:22 +0100 Subject: [PATCH 22/29] Fix: Aircraft crash counter was too low to reach ground. (#12425) Aircraft can float above the ground when crashed as the counter limit to reach the ground is too low. Instead reset the counter until the aircraft reaches the ground, then continue the timer. --- src/aircraft_cmd.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index ebb5c530d8..33ab2eba38 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1182,9 +1182,11 @@ static bool HandleCrashedAircraft(Aircraft *v) if (v->crashed_counter < 500 && st == nullptr && ((v->crashed_counter % 3) == 0) ) { int z = GetSlopePixelZ(Clamp(v->x_pos, 0, Map::MaxX() * TILE_SIZE), Clamp(v->y_pos, 0, Map::MaxY() * TILE_SIZE)); v->z_pos -= 1; - if (v->z_pos == z) { + if (v->z_pos <= z) { v->crashed_counter = 500; - v->z_pos++; + v->z_pos = z + 1; + } else { + v->crashed_counter = 0; } SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos); } From 2cc700d6069284b26b3d81b0ef29a11dc9135fc2 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 5 Apr 2024 21:51:36 +0100 Subject: [PATCH 23/29] Codechange: Replace colour_dropdown array with StringID arithmetic. (#12426) This assumes that the string colours are in order, but that is already assumed elsewhere. Removes old C-style array access. --- src/company_gui.cpp | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 27f014b408..3f81d4cfdc 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -551,26 +551,6 @@ void ShowCompanyFinances(CompanyID company) new CompanyFinancesWindow(&_company_finances_desc, company); } -/* List of colours for the livery window */ -static const StringID _colour_dropdown[] = { - STR_COLOUR_DARK_BLUE, - STR_COLOUR_PALE_GREEN, - STR_COLOUR_PINK, - STR_COLOUR_YELLOW, - STR_COLOUR_RED, - STR_COLOUR_LIGHT_BLUE, - STR_COLOUR_GREEN, - STR_COLOUR_DARK_GREEN, - STR_COLOUR_BLUE, - STR_COLOUR_CREAM, - STR_COLOUR_MAUVE, - STR_COLOUR_PURPLE, - STR_COLOUR_ORANGE, - STR_COLOUR_BROWN, - STR_COLOUR_GREY, - STR_COLOUR_WHITE, -}; - /* Association of liveries to livery classes */ static const LiveryClass _livery_class[LS_END] = { LC_OTHER, @@ -588,7 +568,7 @@ static const LiveryClass _livery_class[LS_END] = { template class DropDownListColourItem : public DropDownIcon> { public: - DropDownListColourItem(int colour, bool masked) : DropDownIcon>(TSprite, GENERAL_SPRITE_COLOUR(colour % COLOUR_END), colour < COLOUR_END ? _colour_dropdown[colour] : STR_COLOUR_DEFAULT, colour, masked) + DropDownListColourItem(int colour, bool masked) : DropDownIcon>(TSprite, GENERAL_SPRITE_COLOUR(colour % COLOUR_END), colour < COLOUR_END ? (STR_COLOUR_DARK_BLUE + colour) : STR_COLOUR_DEFAULT, colour, masked) { } }; @@ -646,8 +626,8 @@ private: default_col = (primary ? default_livery->colour1 : default_livery->colour2) + COLOUR_END; list.push_back(std::make_unique>(default_col, false)); } - for (uint i = 0; i < lengthof(_colour_dropdown); i++) { - list.push_back(std::make_unique>(i, HasBit(used_colours, i))); + for (Colours colour = COLOUR_BEGIN; colour != COLOUR_END; colour++) { + list.push_back(std::make_unique>(colour, HasBit(used_colours, colour))); } uint8_t sel; @@ -781,8 +761,8 @@ public: case WID_SCL_PRI_COL_DROPDOWN: { this->square = GetSpriteSize(SPR_SQUARE); int string_padding = this->square.width + WidgetDimensions::scaled.hsep_normal + padding.width; - for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) { - size->width = std::max(size->width, GetStringBoundingBox(*id).width + string_padding); + for (Colours colour = COLOUR_BEGIN; colour != COLOUR_END; colour++) { + size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DARK_BLUE + colour).width + string_padding); } size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + string_padding); break; From a866166673d8295f89f099ca8bcc87dfc95a44d6 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 5 Apr 2024 21:52:50 +0100 Subject: [PATCH 24/29] Codechange: Use initializer_list and range-for for OpenTTD title. (#12430) Replaces C-style array and looping. --- src/main_gui.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main_gui.cpp b/src/main_gui.cpp index d93b9eeb2a..52e5a5491a 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -256,18 +256,18 @@ struct MainWindow : Window { this->DrawWidgets(); if (_game_mode == GM_MENU) { - static const SpriteID title_sprites[] = {SPR_OTTD_O, SPR_OTTD_P, SPR_OTTD_E, SPR_OTTD_N, SPR_OTTD_T, SPR_OTTD_T, SPR_OTTD_D}; + static const std::initializer_list title_sprites = {SPR_OTTD_O, SPR_OTTD_P, SPR_OTTD_E, SPR_OTTD_N, SPR_OTTD_T, SPR_OTTD_T, SPR_OTTD_D}; uint letter_spacing = ScaleGUITrad(10); - int name_width = (lengthof(title_sprites) - 1) * letter_spacing; + int name_width = static_cast(std::size(title_sprites) - 1) * letter_spacing; - for (uint i = 0; i < lengthof(title_sprites); i++) { - name_width += GetSpriteSize(title_sprites[i]).width; + for (const SpriteID &sprite : title_sprites) { + name_width += GetSpriteSize(sprite).width; } int off_x = (this->width - name_width) / 2; - for (uint i = 0; i < lengthof(title_sprites); i++) { - DrawSprite(title_sprites[i], PAL_NONE, off_x, ScaleGUITrad(50)); - off_x += GetSpriteSize(title_sprites[i]).width + letter_spacing; + for (const SpriteID &sprite : title_sprites) { + DrawSprite(sprite, PAL_NONE, off_x, ScaleGUITrad(50)); + off_x += GetSpriteSize(sprite).width + letter_spacing; } } } From 6771dbe62b7aed89e66565e03d0728e8ffbb4de9 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 5 Apr 2024 19:45:32 +0100 Subject: [PATCH 25/29] Codechange: Use range-for to find replacement blitter. --- src/gfxinit.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index 0384bb86c8..a0aac40fd7 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.cpp @@ -292,13 +292,13 @@ static bool SwitchNewGRFBlitter() const bool animation_wanted = HasBit(_display_opt, DO_FULL_ANIMATION); const char *cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName(); - for (uint i = 0; i < lengthof(replacement_blitters); i++) { - if (animation_wanted && (replacement_blitters[i].animation == 0)) continue; - if (!animation_wanted && (replacement_blitters[i].animation == 1)) continue; + for (const auto &replacement_blitter : replacement_blitters) { + if (animation_wanted && (replacement_blitter.animation == 0)) continue; + if (!animation_wanted && (replacement_blitter.animation == 1)) continue; - if (!IsInsideMM(depth_wanted_by_base, replacement_blitters[i].min_base_depth, replacement_blitters[i].max_base_depth + 1)) continue; - if (!IsInsideMM(depth_wanted_by_grf, replacement_blitters[i].min_grf_depth, replacement_blitters[i].max_grf_depth + 1)) continue; - const char *repl_blitter = replacement_blitters[i].name; + if (!IsInsideMM(depth_wanted_by_base, replacement_blitter.min_base_depth, replacement_blitter.max_base_depth + 1)) continue; + if (!IsInsideMM(depth_wanted_by_grf, replacement_blitter.min_grf_depth, replacement_blitter.max_grf_depth + 1)) continue; + const char *repl_blitter = replacement_blitter.name; if (strcmp(repl_blitter, cur_blitter) == 0) { return false; From 8e881471c1c7a420c0cb90a17ac8e40da5cf953f Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 5 Apr 2024 19:46:53 +0100 Subject: [PATCH 26/29] Codechange: Pass replacement blitter name as string_view instead char *. --- src/blitter/factory.hpp | 12 ++++++------ src/gfxinit.cpp | 17 ++++++++--------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/blitter/factory.hpp b/src/blitter/factory.hpp index 5889cca4f2..4daa4c42cd 100644 --- a/src/blitter/factory.hpp +++ b/src/blitter/factory.hpp @@ -93,7 +93,7 @@ public: * @param name the blitter to select. * @post Sets the blitter so GetCurrentBlitter() returns it too. */ - static Blitter *SelectBlitter(const std::string &name) + static Blitter *SelectBlitter(const std::string_view name) { BlitterFactory *b = GetBlitterFactory(name); if (b == nullptr) return nullptr; @@ -111,17 +111,17 @@ public: * @param name the blitter factory to select. * @return The blitter factory, or nullptr when there isn't one with the wanted name. */ - static BlitterFactory *GetBlitterFactory(const std::string &name) + static BlitterFactory *GetBlitterFactory(const std::string_view name) { #if defined(DEDICATED) - const char *default_blitter = "null"; + const std::string_view default_blitter = "null"; #elif defined(WITH_COCOA) - const char *default_blitter = "32bpp-anim"; + const std::string_view default_blitter = "32bpp-anim"; #else - const char *default_blitter = "8bpp-optimized"; + const std::string_view default_blitter = "8bpp-optimized"; #endif if (GetBlitters().empty()) return nullptr; - const char *bname = name.empty() ? default_blitter : name.c_str(); + const std::string_view bname = name.empty() ? default_blitter : name; for (auto &it : GetBlitters()) { BlitterFactory *b = it.second; diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index a0aac40fd7..7971222ccf 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.cpp @@ -219,10 +219,10 @@ static void LoadSpriteTables() } -static void RealChangeBlitter(const char *repl_blitter) +static void RealChangeBlitter(const std::string_view repl_blitter) { - const char *cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName(); - if (strcmp(cur_blitter, repl_blitter) == 0) return; + const std::string_view cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName(); + if (cur_blitter == repl_blitter) return; Debug(driver, 1, "Switching blitter from '{}' to '{}'... ", cur_blitter, repl_blitter); Blitter *new_blitter = BlitterFactory::SelectBlitter(repl_blitter); @@ -270,7 +270,7 @@ static bool SwitchNewGRFBlitter() /* Search the best blitter. */ static const struct { - const char *name; + const std::string_view name; uint animation; ///< 0: no support, 1: do support, 2: both uint min_base_depth, max_base_depth, min_grf_depth, max_grf_depth; } replacement_blitters[] = { @@ -290,7 +290,7 @@ static bool SwitchNewGRFBlitter() }; const bool animation_wanted = HasBit(_display_opt, DO_FULL_ANIMATION); - const char *cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName(); + const std::string_view cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName(); for (const auto &replacement_blitter : replacement_blitters) { if (animation_wanted && (replacement_blitter.animation == 0)) continue; @@ -298,15 +298,14 @@ static bool SwitchNewGRFBlitter() if (!IsInsideMM(depth_wanted_by_base, replacement_blitter.min_base_depth, replacement_blitter.max_base_depth + 1)) continue; if (!IsInsideMM(depth_wanted_by_grf, replacement_blitter.min_grf_depth, replacement_blitter.max_grf_depth + 1)) continue; - const char *repl_blitter = replacement_blitter.name; - if (strcmp(repl_blitter, cur_blitter) == 0) { + if (replacement_blitter.name == cur_blitter) { return false; } - if (BlitterFactory::GetBlitterFactory(repl_blitter) == nullptr) continue; + if (BlitterFactory::GetBlitterFactory(replacement_blitter.name) == nullptr) continue; /* Inform the video driver we want to switch blitter as soon as possible. */ - VideoDriver::GetInstance()->QueueOnMainThread(std::bind(&RealChangeBlitter, repl_blitter)); + VideoDriver::GetInstance()->QueueOnMainThread(std::bind(&RealChangeBlitter, replacement_blitter.name)); break; } From eaafc57de679bb2991ef96c0c0f2a473f4cc1e54 Mon Sep 17 00:00:00 2001 From: translators Date: Sat, 6 Apr 2024 04:41:24 +0000 Subject: [PATCH 27/29] Update: Translations from eints swedish: 6 changes by joeax910 norwegian (bokmal): 2 changes by eriksorngard chinese (simplified): 2 changes by WenSimEHRP dutch: 2 changes by Afoklala --- src/lang/dutch.txt | 2 ++ src/lang/norwegian_bokmal.txt | 2 ++ src/lang/simplified_chinese.txt | 2 ++ src/lang/swedish.txt | 12 ++++++------ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 32c7857259..3c24b2d5d0 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -4899,7 +4899,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Verwacht STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Opslaan van spel is nog bezig,{}Wacht tot dit voltooid is! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatisch opslaan mislukt STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan niet lezen van schijf +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Spel opslaan mislukt... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan bestand niet verwijderen +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Spel laden spel mislukt... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interne fout: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Opgeslagen spel beschadigd - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Opgeslagen spel hoort bij een nieuwere versie diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 0096ed5655..3eaf13fca4 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -4901,7 +4901,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Anslått STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Lagring pågår enda,{}vennligst vent til den er klar! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatisk lagring mislyktes STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Kan ikke lese fra disk +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Lagring av spillet mislyktes... STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kan ikke slette fil +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Lasting av spill mislyktes... STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Intern feil: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Ødelagt lagret spill - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spillet er lagret i en nyere versjon diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 366cbcb7cf..9b454332df 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -4899,7 +4899,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}预计 STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}保存仍在继续{}请耐心等待…… STR_ERROR_AUTOSAVE_FAILED :{WHITE}自动保存失败 STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}不能读取驱动器 +STR_ERROR_GAME_SAVE_FAILED :{WHITE}保存游戏失败…… STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}不能删除文件 +STR_ERROR_GAME_LOAD_FAILED :{WHITE}读取游戏失败…… STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :内部错误: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :无法识别的存档 - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :该存档是新版本的。当前版本无法读取。 diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index f7627ee22c..c86a05f7e3 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -2858,14 +2858,14 @@ STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_BRIDGE_NAME_SUSPENSION_STEEL :Hängbro, Stål -STR_BRIDGE_NAME_GIRDER_STEEL :Balkbro, Stål -STR_BRIDGE_NAME_CANTILEVER_STEEL :Konsolbro, Stål -STR_BRIDGE_NAME_SUSPENSION_CONCRETE :Hängbro, Betong +STR_BRIDGE_NAME_SUSPENSION_STEEL :Hängbro, stål +STR_BRIDGE_NAME_GIRDER_STEEL :Balkbro, stål +STR_BRIDGE_NAME_CANTILEVER_STEEL :Konsolbro, stål +STR_BRIDGE_NAME_SUSPENSION_CONCRETE :Hängbro, betong STR_BRIDGE_NAME_WOODEN :Träbro STR_BRIDGE_NAME_CONCRETE :Betongbro -STR_BRIDGE_NAME_TUBULAR_STEEL :Rörbro, Stål -STR_BRIDGE_TUBULAR_SILICON :Rörbro, Kisel +STR_BRIDGE_NAME_TUBULAR_STEEL :Rörbro, stål +STR_BRIDGE_TUBULAR_SILICON :Rörbro, kisel # Road construction toolbar From c544a2be0ab457ad16ed274f597e026016e3fb2e Mon Sep 17 00:00:00 2001 From: Rubidium Date: Fri, 5 Apr 2024 22:34:20 +0200 Subject: [PATCH 28/29] Fix: do not use lengthof() for non C-style arrays --- src/network/network_gui.cpp | 2 +- src/newgrf.cpp | 2 +- src/settings.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index a9f6bd4882..b659f64d21 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -2251,7 +2251,7 @@ struct NetworkCompanyPasswordWindow : public Window { QueryString password_editbox; ///< Password editbox. Dimension warning_size; ///< How much space to use for the warning text - NetworkCompanyPasswordWindow(WindowDesc *desc, Window *parent) : Window(desc), password_editbox(lengthof(_settings_client.network.default_company_pass)) + NetworkCompanyPasswordWindow(WindowDesc *desc, Window *parent) : Window(desc), password_editbox(NETWORK_PASSWORD_LENGTH) { this->InitNested(0); this->UpdateWarningStringSize(); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 021608b843..f3ba26801d 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -9499,7 +9499,7 @@ static void FinaliseIndustriesArray() for (auto &indtsp : _industry_tile_specs) { /* Apply default cargo translation map for unset cargo slots */ - for (uint i = 0; i < lengthof(indtsp.accepts_cargo); ++i) { + for (size_t i = 0; i < indtsp.accepts_cargo.size(); ++i) { if (!IsValidCargoID(indtsp.accepts_cargo[i])) indtsp.accepts_cargo[i] = GetCargoIDByLabel(GetActiveCargoLabel(indtsp.accepts_cargo_label[i])); } } diff --git a/src/settings.cpp b/src/settings.cpp index bb4f0966d6..1dc89ef622 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1031,7 +1031,7 @@ static void GraphicsSetLoadConfig(IniFile &ini) if (const IniItem *item = group->GetItem("extra_params"); item != nullptr && item->value) { auto &extra_params = BaseGraphics::ini_data.extra_params; - extra_params.resize(lengthof(GRFConfig::param)); + extra_params.resize(0x80); // TODO: make ParseIntList work nicely with C++ containers int count = ParseIntList(item->value->c_str(), &extra_params.front(), extra_params.size()); if (count < 0) { SetDParamStr(0, BaseGraphics::ini_data.name); From 97bea563d73ed493ddbe0b72309421f9f1c0aad2 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Fri, 5 Apr 2024 22:34:24 +0200 Subject: [PATCH 29/29] Codechange: let lengthof fail when anything that isn't a C-style array is passed --- src/stdafx.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/stdafx.h b/src/stdafx.h index 850d18adba..7f598de39e 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -273,6 +273,9 @@ static_assert(SIZE_MAX >= UINT32_MAX); #define M_PI 3.14159265358979323846 #endif /* M_PI_2 */ +template +char (&ArraySizeHelper(T (&array)[N]))[N]; + /** * Return the length of an fixed size array. * Unlike sizeof this function returns the number of elements @@ -281,7 +284,7 @@ static_assert(SIZE_MAX >= UINT32_MAX); * @param x The pointer to the first element of the array * @return The number of elements */ -#define lengthof(x) (sizeof(x) / sizeof(x[0])) +#define lengthof(array) (sizeof(ArraySizeHelper(array))) /** * Get the end element of an fixed size array.