mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
20 Commits
088db62dba
...
f06b3e9846
Author | SHA1 | Date |
---|---|---|
|
f06b3e9846 | |
|
4c24334fda | |
|
fd6f1e844a | |
|
429a6f58e7 | |
|
90351578a6 | |
|
e4f94747f3 | |
|
bc8e26f4e7 | |
|
69e20e79ab | |
|
17ba9d8c96 | |
|
233aac567b | |
|
ec1cf96b62 | |
|
8bd06807e4 | |
|
1fecbeff76 | |
|
c47a0e1578 | |
|
6ce7195ef1 | |
|
54b1a067eb | |
|
d3c5ae2648 | |
|
0c85ce29ea | |
|
3961318974 | |
|
bb6fa9bf3b |
|
@ -241,7 +241,7 @@ class BuildAirportWindow : public PickerWindowBase {
|
|||
DropDownList list;
|
||||
|
||||
for (uint i = 0; i < AirportClass::GetClassCount(); i++) {
|
||||
list.emplace_back(new DropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(AirportClass::Get((AirportClassID)i)->name, i, false));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
|
|
@ -568,8 +568,8 @@ public:
|
|||
|
||||
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: {
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListStringItem(STR_REPLACE_ENGINES, 1, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_REPLACE_WAGONS, 0, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_ENGINES, 1, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_WAGONS, 0, false));
|
||||
ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ struct BaseSet {
|
|||
return Tnum_files - this->valid_files;
|
||||
}
|
||||
|
||||
bool FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename = true);
|
||||
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename = true);
|
||||
|
||||
/**
|
||||
* Get the description for the given ISO code.
|
||||
|
@ -244,7 +244,7 @@ struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, true> {
|
|||
PaletteType palette; ///< Palette of this graphics set
|
||||
BlitterType blitter; ///< Blitter of this graphics set
|
||||
|
||||
bool FillSetDetails(struct IniFile *ini, const std::string &path, const std::string &full_filename);
|
||||
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename);
|
||||
|
||||
static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir);
|
||||
};
|
||||
|
@ -301,7 +301,7 @@ struct MusicSet : BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false> {
|
|||
/** Number of valid songs in set. */
|
||||
byte num_available;
|
||||
|
||||
bool FillSetDetails(struct IniFile *ini, const std::string &path, const std::string &full_filename);
|
||||
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename);
|
||||
};
|
||||
|
||||
/** All data/functions related with replacing the base music */
|
||||
|
|
|
@ -39,10 +39,15 @@ extern void CheckExternalFiles();
|
|||
* @return true if loading was successful.
|
||||
*/
|
||||
template <class T, size_t Tnum_files, bool Tsearch_in_tars>
|
||||
bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename)
|
||||
bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename)
|
||||
{
|
||||
IniGroup *metadata = ini->GetGroup("metadata");
|
||||
IniItem *item;
|
||||
const IniGroup *metadata = ini.GetGroup("metadata");
|
||||
if (metadata == nullptr) {
|
||||
Debug(grf, 0, "Base " SET_TYPE "set detail loading: metadata missing.");
|
||||
Debug(grf, 0, " Is {} readable for the user running OpenTTD?", full_filename);
|
||||
return false;
|
||||
}
|
||||
const IniItem *item;
|
||||
|
||||
fetch_metadata("name");
|
||||
this->name = *item->value;
|
||||
|
@ -51,10 +56,10 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
|||
this->description[std::string{}] = *item->value;
|
||||
|
||||
/* Add the translations of the descriptions too. */
|
||||
for (item = metadata->item; item != nullptr; item = item->next) {
|
||||
if (item->name.compare(0, 12, "description.") != 0) continue;
|
||||
for (const IniItem &titem : metadata->items) {
|
||||
if (titem.name.compare(0, 12, "description.") != 0) continue;
|
||||
|
||||
this->description[item->name.substr(12)] = item->value.value_or("");
|
||||
this->description[titem.name.substr(12)] = titem.value.value_or("");
|
||||
}
|
||||
|
||||
fetch_metadata("shortname");
|
||||
|
@ -69,13 +74,13 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
|||
this->fallback = (item != nullptr && item->value && *item->value != "0" && *item->value != "false");
|
||||
|
||||
/* For each of the file types we want to find the file, MD5 checksums and warning messages. */
|
||||
IniGroup *files = ini->GetGroup("files");
|
||||
IniGroup *md5s = ini->GetGroup("md5s");
|
||||
IniGroup *origin = ini->GetGroup("origin");
|
||||
const IniGroup *files = ini.GetGroup("files");
|
||||
const IniGroup *md5s = ini.GetGroup("md5s");
|
||||
const IniGroup *origin = ini.GetGroup("origin");
|
||||
for (uint i = 0; i < Tnum_files; i++) {
|
||||
MD5File *file = &this->files[i];
|
||||
/* Find the filename first. */
|
||||
item = files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i]);
|
||||
item = files != nullptr ? files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i]) : nullptr;
|
||||
if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) {
|
||||
Debug(grf, 0, "No " SET_TYPE " file for: {} (in {})", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
|
||||
return false;
|
||||
|
@ -93,7 +98,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
|||
file->filename = path + filename;
|
||||
|
||||
/* Then find the MD5 checksum */
|
||||
item = md5s->GetItem(filename);
|
||||
item = md5s != nullptr ? md5s->GetItem(filename) : nullptr;
|
||||
if (item == nullptr || !item->value.has_value()) {
|
||||
Debug(grf, 0, "No MD5 checksum specified for: {} (in {})", filename, full_filename);
|
||||
return false;
|
||||
|
@ -119,8 +124,8 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
|||
}
|
||||
|
||||
/* Then find the warning message when the file's missing */
|
||||
item = origin->GetItem(filename);
|
||||
if (item == nullptr) item = origin->GetItem("default");
|
||||
item = origin != nullptr ? origin->GetItem(filename) : nullptr;
|
||||
if (item == nullptr) item = origin != nullptr ? origin->GetItem("default") : nullptr;
|
||||
if (item == nullptr || !item->value.has_value()) {
|
||||
Debug(grf, 1, "No origin warning message specified for: {}", filename);
|
||||
file->missing_warning.clear();
|
||||
|
@ -159,9 +164,9 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
|
|||
Debug(grf, 1, "Checking {} for base " SET_TYPE " set", filename);
|
||||
|
||||
Tbase_set *set = new Tbase_set();
|
||||
IniFile *ini = new IniFile();
|
||||
IniFile ini{};
|
||||
std::string path{ filename, basepath_length };
|
||||
ini->LoadFromDisk(path, BASESET_DIR);
|
||||
ini.LoadFromDisk(path, BASESET_DIR);
|
||||
|
||||
auto psep = path.rfind(PATHSEPCHAR);
|
||||
if (psep != std::string::npos) {
|
||||
|
@ -218,7 +223,6 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
|
|||
delete set;
|
||||
}
|
||||
|
||||
delete ini;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -574,11 +574,12 @@ static uint GetCargoWeight(const CargoArray &cap, VehicleType vtype)
|
|||
|
||||
static int DrawCargoCapacityInfo(int left, int right, int y, TestedEngineDetails &te, bool refittable)
|
||||
{
|
||||
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||
if (te.all_capacities[c] == 0) continue;
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
CargoID cid = cs->Index();
|
||||
if (te.all_capacities[cid] == 0) continue;
|
||||
|
||||
SetDParam(0, c);
|
||||
SetDParam(1, te.all_capacities[c]);
|
||||
SetDParam(0, cid);
|
||||
SetDParam(1, te.all_capacities[cid]);
|
||||
SetDParam(2, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY);
|
||||
DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY);
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
|
|
|
@ -204,4 +204,9 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc)
|
|||
|
||||
using SetCargoBitIterator = SetBitIterator<CargoID, CargoTypes>;
|
||||
|
||||
/** Comparator to sort CargoID by according to desired order. */
|
||||
struct CargoIDComparator {
|
||||
bool operator() (const CargoID &lhs, const CargoID &rhs) const { return _sorted_cargo_types[lhs] < _sorted_cargo_types[rhs]; }
|
||||
};
|
||||
|
||||
#endif /* CARGOTYPE_H */
|
||||
|
|
|
@ -675,10 +675,10 @@ private:
|
|||
if (default_livery != nullptr) {
|
||||
/* Add COLOUR_END to put the colour out of range, but also allow us to show what the default is */
|
||||
default_col = (primary ? default_livery->colour1 : default_livery->colour2) + COLOUR_END;
|
||||
list.emplace_back(new DropDownListColourItem(default_col, false));
|
||||
list.push_back(std::make_unique<DropDownListColourItem>(default_col, false));
|
||||
}
|
||||
for (uint i = 0; i < lengthof(_colour_dropdown); i++) {
|
||||
list.emplace_back(new DropDownListColourItem(i, HasBit(used_colours, i)));
|
||||
list.push_back(std::make_unique<DropDownListColourItem>(i, HasBit(used_colours, i)));
|
||||
}
|
||||
|
||||
byte sel = (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col;
|
||||
|
|
|
@ -75,14 +75,14 @@ struct SetDateWindow : Window {
|
|||
|
||||
case WID_SD_DAY:
|
||||
for (uint i = 0; i < 31; i++) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_DAY_NUMBER_1ST + i, i + 1, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_DAY_NUMBER_1ST + i, i + 1, false));
|
||||
}
|
||||
selected = this->date.day;
|
||||
break;
|
||||
|
||||
case WID_SD_MONTH:
|
||||
for (uint i = 0; i < 12; i++) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_MONTH_JAN + i, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MONTH_JAN + i, i, false));
|
||||
}
|
||||
selected = this->date.month;
|
||||
break;
|
||||
|
@ -90,7 +90,7 @@ struct SetDateWindow : Window {
|
|||
case WID_SD_YEAR:
|
||||
for (TimerGameCalendar::Year i = this->min_year; i <= this->max_year; i++) {
|
||||
SetDParam(0, i);
|
||||
list.emplace_back(new DropDownListStringItem(STR_JUST_INT, static_cast<int32_t>(i), false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_JUST_INT, static_cast<int32_t>(i), false));
|
||||
}
|
||||
selected = static_cast<int32_t>(this->date.year);
|
||||
break;
|
||||
|
|
|
@ -876,7 +876,8 @@ struct DepotWindow : Window {
|
|||
static std::string details;
|
||||
details.clear();
|
||||
|
||||
for (CargoID cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
CargoID cargo_type = cs->Index();
|
||||
if (capacity[cargo_type] == 0) continue;
|
||||
|
||||
SetDParam(0, cargo_type); // {CARGO} #1
|
||||
|
|
|
@ -311,7 +311,7 @@ struct GSConfigWindow : public Window {
|
|||
|
||||
DropDownList list;
|
||||
for (int i = config_item.min_value; i <= config_item.max_value; i++) {
|
||||
list.emplace_back(new DropDownListStringItem(config_item.labels.find(i)->second, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(config_item.labels.find(i)->second, i, false));
|
||||
}
|
||||
|
||||
ShowDropDownListAt(this, std::move(list), old_val, WID_GSC_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);
|
||||
|
|
|
@ -356,7 +356,7 @@ static DropDownList BuildMapsizeDropDown()
|
|||
|
||||
for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) {
|
||||
SetDParam(0, 1LL << i);
|
||||
list.emplace_back(new DropDownListStringItem(STR_JUST_INT, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_JUST_INT, i, false));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -369,20 +369,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.emplace_back(new DropDownListStringItem(grf_names[i], BUILTIN_TOWNNAME_GENERATOR_COUNT + i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(grf_names[i], BUILTIN_TOWNNAME_GENERATOR_COUNT + i, false));
|
||||
}
|
||||
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.emplace_back(new DropDownListItem(-1, false)); // separator line
|
||||
list.push_back(std::make_unique<DropDownListItem>(-1, false)); // separator line
|
||||
newgrf_size++;
|
||||
}
|
||||
|
||||
/* Add and sort original townnames generators */
|
||||
for (uint i = 0; i < BUILTIN_TOWNNAME_GENERATOR_COUNT; i++) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + i, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + i, i, false));
|
||||
}
|
||||
std::sort(list.begin() + newgrf_size, list.end(), DropDownListStringItem::NatSortFunc);
|
||||
|
||||
|
|
|
@ -347,12 +347,13 @@ void GfxLoadSprites()
|
|||
UpdateCursorSize();
|
||||
}
|
||||
|
||||
bool GraphicsSet::FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename)
|
||||
bool GraphicsSet::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename)
|
||||
{
|
||||
bool ret = this->BaseSet<GraphicsSet, MAX_GFT, true>::FillSetDetails(ini, path, full_filename, false);
|
||||
if (ret) {
|
||||
IniGroup *metadata = ini->GetGroup("metadata");
|
||||
IniItem *item;
|
||||
const IniGroup *metadata = ini.GetGroup("metadata");
|
||||
assert(metadata != nullptr); /* ret can't be true if metadata isn't present. */
|
||||
const IniItem *item;
|
||||
|
||||
fetch_metadata("palette");
|
||||
this->palette = ((*item->value)[0] == 'D' || (*item->value)[0] == 'd') ? PAL_DOS : PAL_WINDOWS;
|
||||
|
|
|
@ -274,11 +274,12 @@ HotkeyList::~HotkeyList()
|
|||
* Load HotkeyList from IniFile.
|
||||
* @param ini IniFile to load from.
|
||||
*/
|
||||
void HotkeyList::Load(IniFile *ini)
|
||||
void HotkeyList::Load(const IniFile &ini)
|
||||
{
|
||||
IniGroup *group = ini->GetGroup(this->ini_group);
|
||||
const IniGroup *group = ini.GetGroup(this->ini_group);
|
||||
if (group == nullptr) return;
|
||||
for (Hotkey &hotkey : this->items) {
|
||||
IniItem *item = group->GetItem(hotkey.name);
|
||||
const IniItem *item = group->GetItem(hotkey.name);
|
||||
if (item != nullptr) {
|
||||
hotkey.keycodes.clear();
|
||||
if (item->value.has_value()) ParseHotkeys(hotkey, item->value->c_str());
|
||||
|
@ -290,11 +291,11 @@ void HotkeyList::Load(IniFile *ini)
|
|||
* Save HotkeyList to IniFile.
|
||||
* @param ini IniFile to save to.
|
||||
*/
|
||||
void HotkeyList::Save(IniFile *ini) const
|
||||
void HotkeyList::Save(IniFile &ini) const
|
||||
{
|
||||
IniGroup *group = ini->GetGroup(this->ini_group);
|
||||
IniGroup &group = ini.GetOrCreateGroup(this->ini_group);
|
||||
for (const Hotkey &hotkey : this->items) {
|
||||
IniItem &item = group->GetOrCreateItem(hotkey.name);
|
||||
IniItem &item = group.GetOrCreateItem(hotkey.name);
|
||||
item.SetValue(SaveKeycodes(hotkey));
|
||||
}
|
||||
}
|
||||
|
@ -320,8 +321,8 @@ int HotkeyList::CheckMatch(uint16_t keycode, bool global_only) const
|
|||
|
||||
static void SaveLoadHotkeys(bool save)
|
||||
{
|
||||
IniFile *ini = new IniFile();
|
||||
ini->LoadFromDisk(_hotkeys_file, NO_DIRECTORY);
|
||||
IniFile ini{};
|
||||
ini.LoadFromDisk(_hotkeys_file, NO_DIRECTORY);
|
||||
|
||||
for (HotkeyList *list : *_hotkey_lists) {
|
||||
if (save) {
|
||||
|
@ -331,8 +332,7 @@ static void SaveLoadHotkeys(bool save)
|
|||
}
|
||||
}
|
||||
|
||||
if (save) ini->SaveToDisk(_hotkeys_file);
|
||||
delete ini;
|
||||
if (save) ini.SaveToDisk(_hotkeys_file);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@ struct HotkeyList {
|
|||
HotkeyList(const std::string &ini_group, const std::vector<Hotkey> &items, GlobalHotkeyHandlerFunc global_hotkey_handler = nullptr);
|
||||
~HotkeyList();
|
||||
|
||||
void Load(IniFile *ini);
|
||||
void Save(IniFile *ini) const;
|
||||
void Load(const IniFile &ini);
|
||||
void Save(IniFile &ini) const;
|
||||
|
||||
int CheckMatch(uint16_t keycode, bool global_only = false) const;
|
||||
|
||||
|
|
|
@ -1920,11 +1920,6 @@ enum CargoesFieldType {
|
|||
|
||||
static const uint MAX_CARGOES = 16; ///< Maximum number of cargoes carried in a #CFT_CARGO field in #CargoesField.
|
||||
|
||||
static bool CargoIDSorter(const CargoID &a, const CargoID &b)
|
||||
{
|
||||
return _sorted_cargo_types[a] < _sorted_cargo_types[b];
|
||||
}
|
||||
|
||||
/** Data about a single field in the #IndustryCargoesWindow panel. */
|
||||
struct CargoesField {
|
||||
static int vert_inter_industry_space;
|
||||
|
@ -2054,7 +2049,8 @@ struct CargoesField {
|
|||
}
|
||||
}
|
||||
this->u.cargo.num_cargoes = (count < 0) ? static_cast<uint8_t>(insert - std::begin(this->u.cargo.vertical_cargoes)) : count;
|
||||
std::sort(std::begin(this->u.cargo.vertical_cargoes), insert, &CargoIDSorter);
|
||||
CargoIDComparator comparator;
|
||||
std::sort(std::begin(this->u.cargo.vertical_cargoes), insert, comparator);
|
||||
std::fill(insert, std::end(this->u.cargo.vertical_cargoes), CT_INVALID);
|
||||
this->u.cargo.top_end = top_end;
|
||||
this->u.cargo.bottom_end = bottom_end;
|
||||
|
@ -3067,7 +3063,7 @@ struct IndustryCargoesWindow : public Window {
|
|||
case WID_IC_CARGO_DROPDOWN: {
|
||||
DropDownList lst;
|
||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||
lst.emplace_back(new DropDownListStringItem(cs->name, cs->Index(), false));
|
||||
lst.push_back(std::make_unique<DropDownListStringItem>(cs->name, cs->Index(), false));
|
||||
}
|
||||
if (!lst.empty()) {
|
||||
int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1;
|
||||
|
@ -3081,7 +3077,7 @@ struct IndustryCargoesWindow : public Window {
|
|||
for (IndustryType ind : _sorted_industry_types) {
|
||||
const IndustrySpec *indsp = GetIndustrySpec(ind);
|
||||
if (!indsp->enabled) continue;
|
||||
lst.emplace_back(new DropDownListStringItem(indsp->name, ind, false));
|
||||
lst.push_back(std::make_unique<DropDownListStringItem>(indsp->name, ind, false));
|
||||
}
|
||||
if (!lst.empty()) {
|
||||
int selected = (this->ind_cargo < NUM_INDUSTRYTYPES) ? (int)this->ind_cargo : -1;
|
||||
|
|
22
src/ini.cpp
22
src/ini.cpp
|
@ -32,9 +32,9 @@
|
|||
|
||||
/**
|
||||
* Create a new ini file with given group names.
|
||||
* @param list_group_names A \c nullptr terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST
|
||||
* @param list_group_names A list with group names that should be loaded as lists instead of variables. @see IGT_LIST
|
||||
*/
|
||||
IniFile::IniFile(const char * const *list_group_names) : IniLoadFile(list_group_names)
|
||||
IniFile::IniFile(const IniGroupNameList &list_group_names) : IniLoadFile(list_group_names)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -56,20 +56,20 @@ bool IniFile::SaveToDisk(const std::string &filename)
|
|||
std::ofstream os(OTTD2FS(file_new).c_str());
|
||||
if (os.fail()) return false;
|
||||
|
||||
for (const IniGroup *group = this->group; group != nullptr; group = group->next) {
|
||||
os << group->comment << "[" << group->name << "]\n";
|
||||
for (const IniItem *item = group->item; item != nullptr; item = item->next) {
|
||||
os << item->comment;
|
||||
for (const IniGroup &group : this->groups) {
|
||||
os << group.comment << "[" << group.name << "]\n";
|
||||
for (const IniItem &item : group.items) {
|
||||
os << item.comment;
|
||||
|
||||
/* protect item->name with quotes if needed */
|
||||
if (item->name.find(' ') != std::string::npos ||
|
||||
item->name[0] == '[') {
|
||||
os << "\"" << item->name << "\"";
|
||||
if (item.name.find(' ') != std::string::npos ||
|
||||
item.name[0] == '[') {
|
||||
os << "\"" << item.name << "\"";
|
||||
} else {
|
||||
os << item->name;
|
||||
os << item.name;
|
||||
}
|
||||
|
||||
os << " = " << item->value.value_or("") << "\n";
|
||||
os << " = " << item.value.value_or("") << "\n";
|
||||
}
|
||||
}
|
||||
os << this->comment;
|
||||
|
|
202
src/ini_load.cpp
202
src/ini_load.cpp
|
@ -20,18 +20,9 @@
|
|||
* @param parent the group we belong to
|
||||
* @param name the name of the item
|
||||
*/
|
||||
IniItem::IniItem(IniGroup *parent, const std::string &name) : next(nullptr)
|
||||
IniItem::IniItem(const std::string &name)
|
||||
{
|
||||
this->name = StrMakeValid(name);
|
||||
|
||||
*parent->last_item = this;
|
||||
parent->last_item = &this->next;
|
||||
}
|
||||
|
||||
/** Free everything we loaded. */
|
||||
IniItem::~IniItem()
|
||||
{
|
||||
delete this->next;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,37 +39,9 @@ void IniItem::SetValue(const std::string_view value)
|
|||
* @param parent the file we belong to
|
||||
* @param name the name of the group
|
||||
*/
|
||||
IniGroup::IniGroup(IniLoadFile *parent, const std::string &name) : next(nullptr), type(IGT_VARIABLES), item(nullptr)
|
||||
IniGroup::IniGroup(const std::string &name, IniGroupType type) : type(type)
|
||||
{
|
||||
this->name = StrMakeValid(name);
|
||||
|
||||
this->last_item = &this->item;
|
||||
*parent->last_group = this;
|
||||
parent->last_group = &this->next;
|
||||
|
||||
if (parent->list_group_names != nullptr) {
|
||||
for (uint i = 0; parent->list_group_names[i] != nullptr; i++) {
|
||||
if (this->name == parent->list_group_names[i]) {
|
||||
this->type = IGT_LIST;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent->seq_group_names != nullptr) {
|
||||
for (uint i = 0; parent->seq_group_names[i] != nullptr; i++) {
|
||||
if (this->name == parent->seq_group_names[i]) {
|
||||
this->type = IGT_SEQUENCE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Free everything we loaded. */
|
||||
IniGroup::~IniGroup()
|
||||
{
|
||||
delete this->item;
|
||||
delete this->next;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,10 +49,10 @@ IniGroup::~IniGroup()
|
|||
* @param name name of the item to find.
|
||||
* @return the requested item or nullptr if not found.
|
||||
*/
|
||||
IniItem *IniGroup::GetItem(const std::string &name) const
|
||||
const IniItem *IniGroup::GetItem(const std::string &name) const
|
||||
{
|
||||
for (IniItem *item = this->item; item != nullptr; item = item->next) {
|
||||
if (item->name == name) return item;
|
||||
for (const IniItem &item : this->items) {
|
||||
if (item.name == name) return &item;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -102,12 +65,22 @@ IniItem *IniGroup::GetItem(const std::string &name) const
|
|||
*/
|
||||
IniItem &IniGroup::GetOrCreateItem(const std::string &name)
|
||||
{
|
||||
for (IniItem *item = this->item; item != nullptr; item = item->next) {
|
||||
if (item->name == name) return *item;
|
||||
for (IniItem &item : this->items) {
|
||||
if (item.name == name) return item;
|
||||
}
|
||||
|
||||
/* Item doesn't exist, make a new one. */
|
||||
return *(new IniItem(this, name));
|
||||
return this->CreateItem(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an item with the given name. This does not reuse an existing item of the same name.
|
||||
* @param name name of the item to create.
|
||||
* @return the created item.
|
||||
*/
|
||||
IniItem &IniGroup::CreateItem(const std::string &name)
|
||||
{
|
||||
return this->items.emplace_back(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,22 +89,7 @@ IniItem &IniGroup::GetOrCreateItem(const std::string &name)
|
|||
*/
|
||||
void IniGroup::RemoveItem(const std::string &name)
|
||||
{
|
||||
IniItem **prev = &this->item;
|
||||
|
||||
for (IniItem *item = this->item; item != nullptr; prev = &item->next, item = item->next) {
|
||||
if (item->name != name) continue;
|
||||
|
||||
*prev = item->next;
|
||||
/* "last_item" is a pointer to the "real-last-item"->next. */
|
||||
if (this->last_item == &item->next) {
|
||||
this->last_item = prev;
|
||||
}
|
||||
|
||||
item->next = nullptr;
|
||||
delete item;
|
||||
|
||||
return;
|
||||
}
|
||||
this->items.remove_if([&name](const IniItem &item) { return item.name == name; });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,81 +97,85 @@ void IniGroup::RemoveItem(const std::string &name)
|
|||
*/
|
||||
void IniGroup::Clear()
|
||||
{
|
||||
delete this->item;
|
||||
this->item = nullptr;
|
||||
this->last_item = &this->item;
|
||||
this->items.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new in-memory Ini file representation.
|
||||
* @param list_group_names A \c nullptr terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST
|
||||
* @param seq_group_names A \c nullptr terminated list with group names that should be loaded as lists of names. @see IGT_SEQUENCE
|
||||
* @param list_group_names A list with group names that should be loaded as lists instead of variables. @see IGT_LIST
|
||||
* @param seq_group_names A list with group names that should be loaded as lists of names. @see IGT_SEQUENCE
|
||||
*/
|
||||
IniLoadFile::IniLoadFile(const char * const *list_group_names, const char * const *seq_group_names) :
|
||||
group(nullptr),
|
||||
IniLoadFile::IniLoadFile(const IniGroupNameList &list_group_names, const IniGroupNameList &seq_group_names) :
|
||||
list_group_names(list_group_names),
|
||||
seq_group_names(seq_group_names)
|
||||
{
|
||||
this->last_group = &this->group;
|
||||
}
|
||||
|
||||
/** Free everything we loaded. */
|
||||
IniLoadFile::~IniLoadFile()
|
||||
{
|
||||
delete this->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the group with the given name. If it doesn't exist
|
||||
* and \a create_new is \c true create a new group.
|
||||
* Get the group with the given name.
|
||||
* @param name name of the group to find.
|
||||
* @param create_new Allow creation of group if it does not exist.
|
||||
* @return The requested group if it exists or was created, else \c nullptr.
|
||||
* @return The requested group or \c nullptr if not found.
|
||||
*/
|
||||
IniGroup *IniLoadFile::GetGroup(const std::string &name, bool create_new)
|
||||
const IniGroup *IniLoadFile::GetGroup(const std::string &name) const
|
||||
{
|
||||
/* does it exist already? */
|
||||
for (IniGroup *group = this->group; group != nullptr; group = group->next) {
|
||||
if (group->name == name) return group;
|
||||
for (const IniGroup &group : this->groups) {
|
||||
if (group.name == name) return &group;
|
||||
}
|
||||
|
||||
if (!create_new) return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* otherwise make a new one */
|
||||
IniGroup *group = new IniGroup(this, name);
|
||||
group->comment = "\n";
|
||||
return group;
|
||||
/**
|
||||
* Get the group with the given name.
|
||||
* @param name name of the group to find.
|
||||
* @return The requested group or \c nullptr if not found.
|
||||
*/
|
||||
IniGroup *IniLoadFile::GetGroup(const std::string &name)
|
||||
{
|
||||
for (IniGroup &group : this->groups) {
|
||||
if (group.name == name) return &group;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the group with the given name, and if it doesn't exist create a new group.
|
||||
* @param name name of the group to find.
|
||||
* @return the requested group.
|
||||
*/
|
||||
IniGroup &IniLoadFile::GetOrCreateGroup(const std::string &name)
|
||||
{
|
||||
for (IniGroup &group : this->groups) {
|
||||
if (group.name == name) return group;
|
||||
}
|
||||
|
||||
/* Group doesn't exist, make a new one. */
|
||||
return this->CreateGroup(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an group with the given name. This does not reuse an existing group of the same name.
|
||||
* @param name name of the group to create.
|
||||
* @return the created group.
|
||||
*/
|
||||
IniGroup &IniLoadFile::CreateGroup(const std::string &name)
|
||||
{
|
||||
IniGroupType type = IGT_VARIABLES;
|
||||
if (std::find(this->list_group_names.begin(), this->list_group_names.end(), name) != this->list_group_names.end()) type = IGT_LIST;
|
||||
if (std::find(this->seq_group_names.begin(), this->seq_group_names.end(), name) != this->seq_group_names.end()) type = IGT_SEQUENCE;
|
||||
|
||||
return this->groups.emplace_back(name, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the group with the given name.
|
||||
* @param name name of the group to remove.
|
||||
*/
|
||||
void IniLoadFile::RemoveGroup(const char *name)
|
||||
void IniLoadFile::RemoveGroup(const std::string &name)
|
||||
{
|
||||
size_t len = strlen(name);
|
||||
IniGroup *prev = nullptr;
|
||||
IniGroup *group;
|
||||
|
||||
/* does it exist already? */
|
||||
for (group = this->group; group != nullptr; prev = group, group = group->next) {
|
||||
if (group->name.compare(0, len, name) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (group == nullptr) return;
|
||||
|
||||
if (prev != nullptr) {
|
||||
prev->next = prev->next->next;
|
||||
if (this->last_group == &group->next) this->last_group = &prev->next;
|
||||
} else {
|
||||
this->group = this->group->next;
|
||||
if (this->last_group == &group->next) this->last_group = &this->group;
|
||||
}
|
||||
|
||||
group->next = nullptr;
|
||||
delete group;
|
||||
size_t len = name.length();
|
||||
this->groups.remove_if([&name, &len](const IniGroup &group) { return group.name.compare(0, len, name) == 0; });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,7 +186,7 @@ void IniLoadFile::RemoveGroup(const char *name)
|
|||
*/
|
||||
void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir)
|
||||
{
|
||||
assert(this->last_group == &this->group);
|
||||
assert(this->groups.empty());
|
||||
|
||||
char buffer[1024];
|
||||
IniGroup *group = nullptr;
|
||||
|
@ -275,7 +237,7 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir)
|
|||
e--;
|
||||
}
|
||||
s++; // skip [
|
||||
group = new IniGroup(this, std::string(s, e - s));
|
||||
group = &this->CreateGroup(std::string(s, e - s));
|
||||
if (comment_size != 0) {
|
||||
group->comment.assign(comment, comment_size);
|
||||
comment_size = 0;
|
||||
|
@ -283,9 +245,9 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir)
|
|||
} else if (group != nullptr) {
|
||||
if (group->type == IGT_SEQUENCE) {
|
||||
/* A sequence group, use the line as item name without further interpretation. */
|
||||
IniItem *item = new IniItem(group, std::string(buffer, e - buffer));
|
||||
IniItem &item = group->CreateItem(std::string(buffer, e - buffer));
|
||||
if (comment_size) {
|
||||
item->comment.assign(comment, comment_size);
|
||||
item.comment.assign(comment, comment_size);
|
||||
comment_size = 0;
|
||||
}
|
||||
continue;
|
||||
|
@ -301,9 +263,9 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir)
|
|||
}
|
||||
|
||||
/* it's an item in an existing group */
|
||||
IniItem *item = new IniItem(group, std::string(s, t - s));
|
||||
IniItem &item = group->CreateItem(std::string(s, t - s));
|
||||
if (comment_size != 0) {
|
||||
item->comment.assign(comment, comment_size);
|
||||
item.comment.assign(comment, comment_size);
|
||||
comment_size = 0;
|
||||
}
|
||||
|
||||
|
@ -320,9 +282,9 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir)
|
|||
|
||||
/* If the value was not quoted and empty, it must be nullptr */
|
||||
if (!quoted && e == t) {
|
||||
item->value.reset();
|
||||
item.value.reset();
|
||||
} else {
|
||||
item->value = StrMakeValid(std::string(t));
|
||||
item.value = StrMakeValid(std::string(t));
|
||||
}
|
||||
} else {
|
||||
/* it's an orphan item */
|
||||
|
|
|
@ -21,48 +21,48 @@ enum IniGroupType {
|
|||
|
||||
/** A single "line" in an ini file. */
|
||||
struct IniItem {
|
||||
IniItem *next; ///< The next item in this group
|
||||
std::string name; ///< The name of this item
|
||||
std::optional<std::string> value; ///< The value of this item
|
||||
std::string comment; ///< The comment associated with this item
|
||||
|
||||
IniItem(struct IniGroup *parent, const std::string &name);
|
||||
~IniItem();
|
||||
IniItem(const std::string &name);
|
||||
|
||||
void SetValue(const std::string_view value);
|
||||
};
|
||||
|
||||
/** A group within an ini file. */
|
||||
struct IniGroup {
|
||||
IniGroup *next; ///< the next group within this file
|
||||
std::list<IniItem> items; ///< all items in the group
|
||||
IniGroupType type; ///< type of group
|
||||
IniItem *item; ///< the first item in the group
|
||||
IniItem **last_item; ///< the last item in the group
|
||||
std::string name; ///< name of group
|
||||
std::string comment; ///< comment for group
|
||||
|
||||
IniGroup(struct IniLoadFile *parent, const std::string &name);
|
||||
~IniGroup();
|
||||
IniGroup(const std::string &name, IniGroupType type);
|
||||
|
||||
IniItem *GetItem(const std::string &name) const;
|
||||
const IniItem *GetItem(const std::string &name) const;
|
||||
IniItem &GetOrCreateItem(const std::string &name);
|
||||
IniItem &CreateItem(const std::string &name);
|
||||
void RemoveItem(const std::string &name);
|
||||
void Clear();
|
||||
};
|
||||
|
||||
/** Ini file that only supports loading. */
|
||||
struct IniLoadFile {
|
||||
IniGroup *group; ///< the first group in the ini
|
||||
IniGroup **last_group; ///< the last group in the ini
|
||||
using IniGroupNameList = std::initializer_list<std::string_view>;
|
||||
|
||||
std::list<IniGroup> groups; ///< all groups in the ini
|
||||
std::string comment; ///< last comment in file
|
||||
const char * const *list_group_names; ///< nullptr terminated list with group names that are lists
|
||||
const char * const *seq_group_names; ///< nullptr terminated list with group names that are sequences.
|
||||
const IniGroupNameList list_group_names; ///< list of group names that are lists
|
||||
const IniGroupNameList seq_group_names; ///< list of group names that are sequences.
|
||||
|
||||
IniLoadFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr);
|
||||
virtual ~IniLoadFile();
|
||||
IniLoadFile(const IniGroupNameList &list_group_names = {}, const IniGroupNameList &seq_group_names = {});
|
||||
virtual ~IniLoadFile() { }
|
||||
|
||||
IniGroup *GetGroup(const std::string &name, bool create_new = true);
|
||||
void RemoveGroup(const char *name);
|
||||
const IniGroup *GetGroup(const std::string &name) const;
|
||||
IniGroup *GetGroup(const std::string &name);
|
||||
IniGroup &GetOrCreateGroup(const std::string &name);
|
||||
IniGroup &CreateGroup(const std::string &name);
|
||||
void RemoveGroup(const std::string &name);
|
||||
|
||||
void LoadFromDisk(const std::string &filename, Subdirectory subdir);
|
||||
|
||||
|
@ -86,7 +86,7 @@ struct IniLoadFile {
|
|||
|
||||
/** Ini file that supports both loading and saving. */
|
||||
struct IniFile : IniLoadFile {
|
||||
IniFile(const char * const *list_group_names = nullptr);
|
||||
IniFile(const IniGroupNameList &list_group_names = {});
|
||||
|
||||
bool SaveToDisk(const std::string &filename);
|
||||
|
||||
|
|
|
@ -4422,7 +4422,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... te n
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... te naby aan 'n ander dorp
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... te veel dorpe
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... daar is nie meer spasie oor op die kaart nie
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE} Die dorp sal nie paaie bou nie. Jy kan dit verander deur die bou van paaie via Stellings-> Omgewings-> Dorpe te aktiveer
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Pad werke in verloop
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan nie die dorp verwyder nie...{}'n Stasie of depot verwys na die dorp of die blok wat deur die dorp besit word kan nie verwyder word nie.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... daar is geen plek vir 'n standbeeld in die middel van die dorp
|
||||
|
|
|
@ -4137,7 +4137,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... قر
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... قريبة جدا من مدينة أخرى
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... المدن كثيرة جدا
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... لا يوجد فراغ في الخريطة
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}لن تبني البلدية طرق جديدة. بإمكانك تمكين بناء الطرق الجديدة عن طريق الاعدادات --> البيئة--> المدن
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}اعمال الطرق قيد التنفيذ
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}لا يمكن ازالة هذه المدينة{}محطة او ورشة مرتبطة بالمدينة او هناك مربع مملوك للمدينة لا يمكن لزالته
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... لا يوجد مكان مناسب للمجسم بداخل هذة المدينة/البلدة
|
||||
|
|
|
@ -4171,7 +4171,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... mapa
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... beste herritik hurbilegi
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... herri gehiegi
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ez dago leku gehiagorik mapan
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Herriak ez du errepiderik eraikiko. Herriek errepideak eraiki ahal izateko Ezarpen Aurreratuak->Ekonomia->Herriak
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Errepide lanak egiten
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Geltoki edo gordailu bat herriari lotua dago edo ezin izan da herriaren jabegoa den lauki bat ezabatu
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ez dago leku egokirik estatua batentzat hiri honen erdian
|
||||
|
|
|
@ -4778,7 +4778,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... за
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... занадта блізка да іншага горада
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... занадта шмат гарадоў
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... няма месца на мапе
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Гарады ня будуць будаваць дарогі самі. Вы можаце ўключыць будаўніцтва дарог у раздзеле «Наладкі -> Навак.{NBSP}асяроддзе -> Гарады».
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Ідуць дарожныя работы...
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Немагчыма зьнішчыць горад:{}да яго адносіцца станцыя або дэпо, альбо немагчыма ачысьціць адну з занятых ім клетак.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... у цэнтры горада няма месца для статуі
|
||||
|
|
|
@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... muit
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... muito perto de outra cidade
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... cidades demais
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... não há mais espaço no mapa
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}A cidade não irá construir estradas. Você pode ativar a construção através de Configurações->Ambiente->Cidades
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Recapeamento rodoviário em progresso
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Impossível remover cidade...{}Uma estação ou depósito referente à essa cidade não pode ser removido
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... não há local para uma estátua no centro dessa cidade
|
||||
|
|
|
@ -4251,7 +4251,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... пр
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... прекалено близо до друг град
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... прекалено много градове
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... няма повече място на картата
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Градът няма да изгражда пътища. Можете да активирате строенето на пътища чрез Настройки за напреднали->Икономика->Градове.
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Пътни ремонти в процес
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Градът не може да бъде премахнат...{}Станция или депо има връзка с града, или плочка, собственост на града, не може да бъде отстранена
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... няма подходящо място за статуя в центъра на града
|
||||
|
|
|
@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... mass
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... massa prop d'una altra població
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... massa poblacions
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}...no queda espai al mapa.
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}La població no construirà carrers. Pots activar la construcció de carrers via Configuració->Interacció amb l'entorn->Poblacions
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obres en progrés
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}No es pot eliminar aquesta població...{}Hi ha una estació, un dipòsit o una cel·la pertanyent a la població que no pot ser eliminada
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... no hi ha un lloc adequat per situar l'estàtua al centre d'aquesta població
|
||||
|
|
|
@ -4609,7 +4609,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... preb
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... preblizu drugome gradu
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... previše gradova
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nema više mjesta na karti
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Grad neće graditi ceste. Možete uključiti gradnju cesta putem Postavki->Okolina->Gradovi
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Cestovni radovi u tijeku
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nije moguće izbrisati ovaj grad...{}Postaja ili spremište se pozivaju na grad ili polja u vlasništvu grada nije moguće ukloniti
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nema odgovarajućeg mjesta za kip u središtu ovog grada
|
||||
|
|
|
@ -4878,7 +4878,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... moc
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... moc blízko k jinému městu
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... příliš mnoho měst
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... na mapě už není místo
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Město nebude stavět silnice. Můžete to změnit přes Pokročilé nastavení->Ekonomika->Města
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Silnice je v rekonstrukci
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nelze vybourat město...{}Buď k němu patří stanice nebo depo, anebo se nedá odklidit políčko městem vlastněné
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... v tomto městě není žádné místo vhodné pro umístění sochy
|
||||
|
|
|
@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... for
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... for tæt på en anden by
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... for mange byer
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... der er ikke mere plads på kortet
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Byen vil ikke kunne bygge veje. Du kan tillade byer at bygge veje via Avancerede indstillinger->Økonomi->Byer.
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vejarbejde i gang
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan ikke slette denne by...{}En station eller et depot refererer til byen, eller en brik der er ejet a byen kan ikke fjernes
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... Der er ingen egnede steder at placere en statue
|
||||
|
|
|
@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... te d
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... te dicht bij een andere plaats
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... te veel plaatsen
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... er is geen ruimte meer op de kaart
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}De stad bouwt geen wegen. Het bouwen van wegen kan aangezet worden via Instellingen->Omgeving->Steden
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Wegwerkzaamheden in uitvoering
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan deze stad niet verwijderen...{}Een station of depot verwijst naar deze plaats of een door de stad beheerde tegel kan niet worden verwijderd
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... er is geen geschikte plaats voor een standbeeld in het centrum van dit dorp
|
||||
|
|
|
@ -924,10 +924,8 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}New {STR
|
|||
|
||||
STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}Open the group window focused on the vehicle's group
|
||||
|
||||
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} no longer accepts {STRING}
|
||||
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} no longer accepts {STRING} or {STRING}
|
||||
STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} now accepts {STRING}
|
||||
STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO :{WHITE}{STATION} now accepts {STRING} and {STRING}
|
||||
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_LIST :{WHITE}{STATION} no longer accepts: {CARGO_LIST}
|
||||
STR_NEWS_STATION_NOW_ACCEPTS_CARGO_LIST :{WHITE}{STATION} now accepts: {CARGO_LIST}
|
||||
|
||||
STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED :{BIG_FONT}{BLACK}Offer of subsidy expired:{}{}{STRING} from {STRING2} to {STRING2} will now not attract a subsidy
|
||||
STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLACK}Subsidy withdrawn:{}{}{STRING} service from {STRING2} to {STRING2} is no longer subsidised
|
||||
|
|
|
@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... too
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... too close to another town
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... too many towns
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... there is no more space on the map
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}The town will not build roads. You can enable building of roads via Advanced Settings->Environment->Towns
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Road works in progress
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Can't delete this town...{}A station or depot is referring to the town or a town owned tile can't be removed
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... there is no suitable place for a statue in the centre of this town
|
||||
|
|
|
@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... too
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... too close to another town
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... too many towns
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... there is no more space on the map
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}The town will not build roads. You can enable building of roads via Settings->Environment->Towns
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Road work in progress
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Can't delete this town...{}A station or depot is referring to the town or a town owned tile can't be removed
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... there is no suitable place for a statue in the center of this town
|
||||
|
|
|
@ -4768,7 +4768,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... tro
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... tro proksime al alia urbo
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... tro da urboj
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... spaco mankas sur la mapo
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}La urbo ne konstruos stratojn. Vi povas ebligi stratkonstruadon per Avancitaj Agordoj->Ekonomio->Urboj
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Aktivas vojprilaborado
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Ne eblas forviŝi ĉi tiun urbon...{}Stacidomo aŭ garaĝo havas referencon al la urbo, aŭ ne eblas forviŝi kahelon posedatan de la urbo
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ne jen estas konvenan lokon por statuo en la centro de ĉi tiu urbo
|
||||
|
|
|
@ -4820,7 +4820,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... liig
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... liiga lähedal teisele asulale
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... liiga palju asulaid
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... pole enam ruumi kaardil
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Asula ei ehita teid. Teedeehituse lubamiseks Põhjalik seadistus->Majandus->Asulad
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Teede ehitamine
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Seda asulat ei saa kõrvaldada...{}Jaam või depoo viitab asulale, või asulale kuuluvat ruutu ei saa kõrvaldada
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... asula keskuses ei leidu kujule sobivat kohta
|
||||
|
|
|
@ -3826,7 +3826,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ov t
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ov tætt við eina aðra bygd
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... ov nógvar bygdir
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... tað er einki pláss eftir á kortinum
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Bygdin byggir ikki vegir. Tú kanst tendra vega byggjing í Víðkaðir Innstillingar->Búðskapur->Bygdir
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Veg arbeiði í gongd
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kann ikki strika hesa bygdina...{}Ein støð ella goymsla vísur til bygdina, ella ein puntur ið er ogn hjá bygdini kann ikki beinast burtur
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... einki hóskandi stað til eina standmynd í miðjuni av hesi bygdini
|
||||
|
|
|
@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... liia
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... liian lähellä toista kuntaa
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... liian monta kuntaa
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... kartalla ei ole enää tilaa
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Kunta ei rakenna teitä. Voit sallia teiden rakentamisen valikosta Asetukset->Ympäristö->Kunnat
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Tietyöt ovat käynnissä.
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kuntaa ei voida poistaa...{}Asema tai varikko viittaa kuntaan tai kunnan omistamaa ruutua ei voida poistaa
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... tämän kunnan keskustassa ei ole sopivaa paikkaa patsaalle
|
||||
|
|
|
@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... trop
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... trop près d'une autre ville
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... trop de villes
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... il n'y a plus d'emplacement sur la carte
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}La ville ne construira pas de routes. Vous pouvez activer la construction des routes sous Paramètres->Environnement->Villes
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Route en travaux
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Impossible de supprimer cette ville...{}Une station ou un dépôt fait référence à cette ville ou une propriété municipale ne peut pas être supprimée.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... aucun emplacement convenable disponible pour une statue dans ce centre-ville
|
||||
|
|
|
@ -4565,7 +4565,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ro f
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ro fhaisg air baile eile
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... tha cus bhailtean ann
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... chan eil rum air fhàgail air a' mhapa
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Cha tog am baile rathad sam bith. ’S urrainn dhut togail rathaidean a chur an comas le Roghainnean->Àrainneachd->Bailtean
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Rathad ga ath-thogail
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Cha ghabh am baile seo sguabadh às...{}Tha stèisean no port no garaids no trèan-lann no cala no hangar a' toirt iomradh air a' bhaile no tha leac ann a tha leis a' bhaile is nach gabh toirt air falbh
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... chan eil ionad freagarrach airson ìomhaigh ann am meadhan a' bhaile seo
|
||||
|
|
|
@ -4812,7 +4812,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... dema
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... demasiado preto doutra cidade
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... hai demasiadas cidades
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... non queda máis espazo no mapa
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}O pobo non construirá estradas. Podes activar a función de construción de estradas en Opcións Avanzadas->Economía->Pobos
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obras na estrada en curso
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Non se pode borrar esta vila...{}Unha estación ou depósito está relacionado coa vila ou un cadro propiedade da vila non pode ser eliminado
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... non hai ningún sitio adecuado para unha estatua no centro desta vila
|
||||
|
|
|
@ -4843,7 +4843,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... zu d
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... zu dicht an einer anderen Stadt
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... zu viele Städte
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... es ist kein Platz mehr auf dem Spielfeld
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Städte bauen im Moment keine Straßen. Städtischer Straßenbau kann mittels Einstellungen->Umgebung->Städte eingestellt werden
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Straßenarbeiten sind im Gange
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Stadt kann nicht gelöscht werden ...{}Eine Station oder ein Depot bezieht sich auf diese Stadt oder ein Feld im städtischen Besitz kann nicht entfernt werden.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... es gibt keinen geeigneten Standort für die Statue im Zentrum dieser Stadt
|
||||
|
|
|
@ -4865,7 +4865,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... πο
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... πολύ κοντά σε άλλη πόλη
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... πάρα πολλές πόλεις
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... δεν υπάρχει άλλος χώρος στον χάρτη
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Η πόλη δεν θα οικοδομεί δρόμους. Μπορείτε να ενεργοποιήσετε την κατασκευή οδών μέσω τις Προχωρημένες Επιλογές->Οικονομία->Πόλεις
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Έργα οδοποιίας σε εξέλιξη
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Δεν γίνεται να διαγραφεί η πόλη...{}Ένας σταθμός ή ένα αμαξοστάσιο που αναφέρεται στην πόλη ή ένα τετραγωνίδιο της πόλης δεν μπορεί να αφαιρεθεί
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... δεν υπάρχει κατάλληλο μέρος για άγαλμα στο κέντρο αυτής της πόλης
|
||||
|
|
|
@ -4468,7 +4468,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... קר
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... קרוב מידי לעיר אחרת
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... יותר מידי ערים
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... אין יותר מקום על המפה
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}העיר לא תבנה כבישים. באפשרותך לאפשר בניית כבישים בעזרת תפריט הגדרות מתקמדות->כלכלה->ערים
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}עבודות כביש בפעולה
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}לא ניתן למחוק עיר זו...{}תחנה או מוסך מקושר לעיר או שמשבצת בבעלות העיר לא ניתנת להסרה
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... אין אף מיקום מתאים לפסל במרכז עיירה זו
|
||||
|
|
|
@ -4909,7 +4909,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... túl
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... túl közel van egy másik településhez
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... túl sok a település
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nincs több hely a térképen
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}A település nem fog utakat építeni. Az útépítést a Haladó beállítások->Környezet->Települések menüben engedélyezheted
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Útkarbantartás folyamatban
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nem törölheted ezt a várost...{}Egy állomás vagy járműtelep hivatkozik a városra, vagy egy városi tulajdonú mező nem eltávolítható
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nincs megfelelő hely egy szobornak a város központjában
|
||||
|
|
|
@ -4059,7 +4059,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... of n
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... of nálægt öðrum bæ
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... of margir bæir
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... það er ekkert laust svæði á kortinu
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Bærinn getur ekki lagt vegi. Því er hægt að breyta í Ítarlegar stillingar->Efnahagur->Bæir.
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vegaframkvæmdir standa yfir
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Ekki hægt að eyða bæ...{}Stöð eða skýli vísar í þennan bæ eða ekki hægt að fjarlægja reit í eigu bæjarins.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... það er enginn ákjósanlegur staður fyrir styttu í miðju þessa bæjar
|
||||
|
|
|
@ -4813,7 +4813,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... terl
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... terlalu dekat dengan kota lain
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... terlalu banyak kota
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... tidak ada lagi ruang tersisa dalam peta
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Kota tidak akan membangun jalan. Anda dapat mengaktifkan pembangunan jalan pada menu Pengaturan Lanjutan->Ekonomi->Kota
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Jalan sedang dikerjakan
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Tidak dapat menghancurkan kota ini...{}Suatu stasiun atau depo tergantung pada kota ini atau kotak milik kota tidak dapat dihapus
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... tidak ada tempat yang cocok untuk patung di tengah kota ini
|
||||
|
|
|
@ -4670,7 +4670,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... rogh
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... roghearr do bhaile eile
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... an iomarca bailte
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... níl a thuilleadh spáis ar an léarscáil
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Ní thógfaidh an baile seo bóithre. Is féidir leat tógáil bóithre a chumasú in Ardsocruithe->Geilleagar->Bailte.
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Tá oibreacha bóthair ar bun
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Ní féidir an baile seo a scriosadh...{}Ní féidir stáisiún nó iosta atá ag tagairt don bhaile nó do thíle atá faoi úinéireacht an bhaile a bhaint
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... níl aon suíomh oiriúnach do dhealbh i lár an bhaile seo
|
||||
|
|
|
@ -4907,7 +4907,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... trop
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... troppo vicino ad un'altra città
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... troppe città
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... non c'è altro spazio sulla mappa
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Alla città non è permesso costruire strade. È possibile abilitare la costruzione di strade in Impostazioni -> Ambiente -> Città
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Lavori stradali in corso
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Impossibile eliminare la città...{}Una stazione o un deposito fa ancora riferimento alla città o una casella di proprietà della città non può essere rimossa
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... non ci sono spazi adeguati per una statua nel centro di questa città
|
||||
|
|
|
@ -4791,7 +4791,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}マッ
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}他の街に近すぎます
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}街数の制限を超えています
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}マップに空きスペースがありません
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}この街は自動では道路を敷設しません。「設定→環境→街」から道路の敷設を許可できます
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}道路補修工事中です
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}街を削除できません{}この街名を参照する停留施設・車庫か、街が所有するタイルが除去できません
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}街の中心部に像を建てるのに適した場所がありません
|
||||
|
|
|
@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... 지
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... 다른 도시와 너무 가깝습니다
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... 도시가 너무 많습니다
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... 지도에 더 이상 공간이 없습니다
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}도시가 도로를 짓지 않을 것입니다. [설정→환경→도시]에서 도로를 지을 수 있도록 설정을 변경하실 수 있습니다.
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}도로 작업이 진행 중입니다
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}이 도시를 삭제할 수 없습니다...{}도시나 도시 소유의 땅에 역, 정류장, 항구, 공항 또는 차량기지, 차고지, 정박소 등이 존재하면 도시를 삭제할 수 없습니다.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... 이 도시의 중심에 동상을 세우기 적합한 장소가 없습니다
|
||||
|
|
|
@ -4558,7 +4558,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... nimi
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... nimis prope aliud oppidum
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... nimis oppida adsunt
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... plus spatium tabulae deest
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Oppidum non vias struet. Potes hanc optionem mutare in Electionibus->Circumiecta->Oppida
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Constructio viaria agitur
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Non licet oppidum delere...{}Statio receptaculumve est oppido sive non licet tegulam oppidi removere
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... non est locus effigiei idoneus in medio oppidi
|
||||
|
|
|
@ -4769,7 +4769,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... pār
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... pārāk tuvu citai pilsētai
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... pārāk daudz pilsētu
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... uz kartes nav vairāk vietas
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Pilsēta ceļus nebūvēs. Jūs varat ieslēgt ceļu būvi caur Papildu iestatījumi->Ekonomika->Pilsētas
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Notiek ceļa remonts
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Šo pilsētu nevar dzēst...{}Kāda stacija vai depo attiecas uz pilsētu. Vai pilsētai pieder nenoņemams lauciņš
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... šās pilsētas centrā statujai nav piemērotas vietas
|
||||
|
|
|
@ -4964,7 +4964,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... per
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... per arti kito miesto
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... per daug miestų
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... daugiau nera vietos zemelapyje
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Miestas nestatys kelių. Jūs galite įjungti kelių statybą per „Išplėstinės nuostatos>Aplinka>Miestai“.
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vyksta kelio darbai
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Negalima panaikinti šio miesto...{}Mieste yra stotelė arba depas, arba miestui priklausantis vienas iš laukelių negali būti pašalintas
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nėra tinkamos vietos statulai šio miesto centre
|
||||
|
|
|
@ -4762,7 +4762,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ze n
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ze no un enger anerer Stad
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... ze vill Stied
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... et ass keng Plaz méi op der Kaart
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Stied bauen keng Stroossen. Du kanns de Bau iwwert Astellungen->Economie->Stied aschalten
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Stroossenarbeschten amgaangen
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kann des Stad net läschen...{}Eng Statioun oder Schapp huet den Numm vun dëser Stad oder en Stéck dat der Stad gehéiert kann net ewechgeholl ginn
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... et gëtt keng gëeegent Plaz fir eng Statu am Stadzentrum
|
||||
|
|
|
@ -3965,7 +3965,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... terl
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... terlalu hampir ke bandar lain
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... bandar terlalu banyak
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ruang tidak mencukupi di dalam peta
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Bandar ini tidak akan membina jalan. Anda boleh membenarkan pembinaan jalan melalui Tetapan Lanjutan->Ekonomi->Bandar
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Kerja-kerja jalanraya sedang berjalan
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Tidak boleh padam bandar ini...{}Tidak boleh dipadamkan kerana terdapat sebuah stesen atau depoh yang dipunyai bandar atau petak bandar
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... tiada lokasi sesuai untuk arca di tengah bandar
|
||||
|
|
|
@ -4692,7 +4692,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}...{NBSP
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...{NBSP}for nær en annen by
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}...{NBSP}for mange byer
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... det er ikke mer plass på kartet
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Byen kommer ikke til å bygge veier. Du kan aktivere bygging av veier via Innstillinger->Miljø->Byer
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Veiarbeid i gang
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan ikke fjerne denne byen...{}En stasjon eller garasje/stall/hangar/dokk henviser til byen eller en by-eid rute som ikke kan fjernes
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... det er ingen passende steder for en statue i sentrum av denne byen
|
||||
|
|
|
@ -4194,7 +4194,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... for
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... for nær ein annan by
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... for mange byar
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... det er ikkje meir plass på kartet
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Byen byggjer ikkje vegar. Du kan tillete veg-bygging i Avanserte innstillingar -> Økonomi -> Byar
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vegarbeid pågår
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan ikkje fjerne denne byen...{}Ein stasjon eller garasje/stall/hangar/dokk refererar til byen eller ei by-egd rute som ikkje kan fjernast
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... det er ingen passande plass til statue i sentrum av denne byen
|
||||
|
|
|
@ -5252,7 +5252,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... zbyt
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... zbyt blisko innego miasta
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... zbyt wiele miast
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nie ma więcej miejsca na mapie
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Miasto nie będzie budować dróg. Możesz zezwolić na budowę dróg poprzez Ustawienia->Środowisko->Miasta
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Trwają roboty drogowe
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nie można usunąć tego miasta...{}Stacja lub zajezdnia przynależy do tego miasta lub obszar miasta nie może być usunięty
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... w centrum tego miasta nie ma odpowiedniego miejsca na pomnik
|
||||
|
|
|
@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... muit
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... muito perto de outra localidade
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... demasiadas localidades
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... não existe mais espaço no mapa
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}A localidade não construirá estradas. Pode-se permitir a construção de estradas por Opções Avançadas->Economia->Localidades
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Trabalhos na estrada em curso
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Não é possível eliminar esta localidade...{}Uma estação ou depósito refere-se à localidade ou não é possível remover terreno pertencente à mesma
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... não há um sítio adequado para uma estátua no centro desta localidade
|
||||
|
|
|
@ -4865,7 +4865,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... prea
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... prea aproape de alt oraş
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... prea multe oraşe
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nu mai este loc pe hartă
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Orașul nu va construi drumuri. Poți activa construirea drumurilor din Setări avansate -> Economie -> Orașe
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Lucrari la drum in curs de desfasurare
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Acest oraș nu poate fi șters...{}O stație sau un depou face referire la acest oraș, sau o parcelă deținută de oraș nu poate fi eliminată
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nu există niciun loc potrivit pentru o statuie în centrul acestui oraș
|
||||
|
|
|
@ -5053,7 +5053,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... сл
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... слишком близко к другому городу
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... слишком много городов
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... нет места на карте
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Города не будут строить дороги сами. Вы можете включить строительство дорог в разделе «Настройки -> Окр.{NBSP}среда -> Города».
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Идут дорожные работы...
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Невозможно уничтожить город:{}к нему относится станция или депо, либо невозможно очистить одну из занимаемых им клеток.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... в центре города нет места для статуи
|
||||
|
|
|
@ -4963,7 +4963,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... prev
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... drugo naselje je previše blizu
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... ima previše naselja
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... više ne postoji slobodnog prostora na terenu
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Naselje neće graditi kolovoze. Možete uključiti gradnju kolovoza preko Napredna Podešavanja->Okruženje->Naselja
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Putni radovi u toku
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nije moguće obrisati naselje...{}Stanica ili depo na zemljištvu naselja se ne može ukloniti
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ne postoji odgovarajuće mesto za spomenik u centru ovog naselja
|
||||
|
|
|
@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}太靠
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}太靠近另一个城镇了
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}城镇太多了
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}地图上没有多余的地方了
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}城镇不会修建道路{}您可以在“设置->环境->城镇”选项下开启建设道路的功能
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}正在进行道路工程
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}无法删除城镇...{}城镇范围内还有车站、车库或无法移除的区块
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... 城市中心没有合适的地方放置公司塑像
|
||||
|
|
|
@ -4880,7 +4880,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... prí
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... príliš blízko iného mesta
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... príliš veľa miest
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nie je miesto na mape
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Mesto nebude stavať cesty. Môžete povoliť budovanie ciest cez Pokročilé nasvavenia->Ekonomika->Mestá.
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Prebiehajú cestné práce
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Toto mesto nie je možné odstrániť...{}Stanica alebo depo sa odvoláva na mesto, alebo parcela vo vlastníctve mesta nemôže byť odstránená
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... v centre mesta sa nenachádza žiadne vhodné miesto pre sochu
|
||||
|
|
|
@ -4447,7 +4447,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... preb
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... preblizu drugemu mestu
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... preveliko število mest
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ni več prostora na zemljevidu
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Mesta ne bodo gradila cest. Lahko omogočiš gradnjo cest v Napredne nastavitve->Ekonomija->Mesta
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Cestna dela napredujejo
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Ni mogoče zbrisati mesta...{}Postaja ali garaža se nanaša na to mesto ali pa področje v lastnini mesta ne more biti odstranjeno
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ni primernega mesta za kip v centru tega mesta
|
||||
|
|
|
@ -4759,7 +4759,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... dema
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... demasiado cerca de otro municipio
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... demasiados municipios
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... no hay más espacio en el mapa
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}El municipio no construirá carreteras. Puedes activar la función de construcción de carreteras en Configuración->Ambiente->Municipios
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obras de carretera en progreso
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}No se puede borrar este municipio...{}Quedan estaciones o depósitos relacionados con él, o una propiedad suya no puede ser retirada
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... no existe un lugar apropiado para una estatua en el centro de este municipio
|
||||
|
|
|
@ -4760,7 +4760,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... dema
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... demasiado cerca de otra localidad
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... demasiadas localidades
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ya no hay espacio en el mapa
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}La localidad no construirá carreteras. Se puede activar esta función en Configuración->Entorno->Localidades
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obras de carretera en progreso
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}No se puede eliminar esta localidad...{}Aún tiene una estación o depósito, o una de sus casillas no se puede quitar
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... no hay lugar apto para una estatua en el centro de esta localidad
|
||||
|
|
|
@ -4845,7 +4845,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... för
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... för nära en annan stad
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... för många städer
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... det finns ingen plats kvar på kartan
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Staden kommer inte bygga vägar. Du kan tillåta att staden bygger vägar via Inställningar->Miljö->Städer
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vägarbete pågår
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan inte ta bort den här staden...{}En station eller depå refererar till staden eller så kan inte en stadsägd ruta tas bort.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... det finns ingen lämplig plats för en staty i stadens centrum
|
||||
|
|
|
@ -4278,7 +4278,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ப
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... மற்றொரு நகரத்திற்கு மிகவும் அருகாமையில் உள்ளது
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... மிகவும் அதிகமான நகரங்கள்
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... படத்தில் வேறு வெற்றுஇடம் இல்லை
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}நகராட்சி சாலைகளை அமைக்காது. இந்த அமைப்பினை மாற்ற செல்க சிறப்பு அமைப்புகள் -> பொருளாதாரம் -> நகரங்கள்
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}சாலைப் பணிகள் நடந்துக் கொண்டிருக்கின்றன
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}இந்த நகரத்தினை நீக்க இயலாது ...{} ஒரு நிலையமோ அல்லது பணிமனையோ நகரத்தின் பெயரில் உள்ளது மற்றும் நகரத்திற்குச் சொந்தமான கட்டங்களை நீக்க முடியாது.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... நகரத்தின் நடுவில் சிலையினை அமைக்க தகுந்த இடமில்லை
|
||||
|
|
|
@ -4411,7 +4411,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ต
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ใกล้กับเมืองอื่นมากเกินไป
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... มีเมืองมากเกินไป
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... มีพื้นที่บนแผนที่ไม่มากพอ
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}เมืองจะไม่สามารถสร้างถนนได้ในอนาคต. คุณสามารถเปิดใช้งานสร้างถนนของเมือง ใน Advanced Settings->Economy->Towns
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}กำลังอยู่ระหว่างการปรับปรุงถนน
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}ไม่สามารถทำลายเมืองได้{}สถานีหรือโรงเก็บนี้เป็นทรัพย์สินของเมืองไม่สามารถทำลายหรือเคลื่อนย้ายได้
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ที่นี่ไม่มีสถานที่เหมาะสมในการสร้างอนุเสาวรีย์ในใจกลางเมือง
|
||||
|
|
|
@ -4839,7 +4839,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... 太
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... 太接近另一個市鎮
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... 已有太多市鎮
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... 地圖沒有足夠空間
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}市鎮不會自動興建道路。你可以在 [設定] -> [環境] -> [市鎮] 啟用市鎮自行興建道路的功能。
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}道路施工中
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}無法刪除此市鎮...{}市鎮範圍內還有車站或機廠或無法移除的區塊
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... 市中心沒有適合的空間建造雕像
|
||||
|
|
|
@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... hari
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... başka bir şehire çok yakın
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... çok fazla şehir var
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... haritada boş yer yok
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Kasaba yol yapmayacak. Yol yapımını Gelişmiş Ayarlar->Ekonomi->Şehirler'den etkinleştirebilirsiniz
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Yol çalışmaları
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Bu kasaba silinemiyor...{}Bir istasyon veya garaj kasabaya atıfta bulunuyor ya da bir kasaba karesi kaldırılamıyor
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... bu şehrin merkezinde heykel için uygun bir yer yok
|
||||
|
|
|
@ -4924,7 +4924,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... на
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... надто близько до іншого міста
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... забагато міст
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... на карті немає вільного місця
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Місто не будуватиме дороги. Ви можете дозволити будівництво доріг через налаштування->Довкілля->Міста
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Дорога ремонтується
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Не можна видалити це місто...{}Станція або депо, що відносяться до міста або знаходяться на землі у власності міста, не можуть бути видалені
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... немає придатного місця для статуї в центрі цього міста
|
||||
|
|
|
@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... quá
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... quá gần đô thị khác
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... quá nhiều đô thị
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... không còn khoảng trống nào trên bản đồ
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Đô thị sẽ không xây dựng đường phố. Bạn có thể bật tính năng này ở menu Thiết lập mở rộng->Môi trường->Đô thị
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Xây dựng cầu đường đang tiến hành
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Không thể xoá đo thị này...{}Có một ga, bến hoặc xưởng thuộc đô thị hoặc là 1 ô đất của đô thị không thể xoá được.
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... không có nơi nào hợp lý để dựng tượng đài ở trung tâm đô thị này
|
||||
|
|
|
@ -4443,7 +4443,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... rhy
|
|||
STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... rhy agos i dref arall
|
||||
STR_ERROR_TOO_MANY_TOWNS :{WHITE}... gormod o drefi
|
||||
STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nid oes mwy o le ar y map
|
||||
STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Ni fydd y dref yn adeiladu ffyrdd. Gallwch alluogi adeiladu ffyrdd yn Gosodiadau->Amgylchedd->Trefi
|
||||
STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Mae gwaith yn cael ei wneud ar y ffordd
|
||||
STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Methu dileu'r dref...{}Mae gorsaf neu depo sy'n cyfeirio i'r dref neu deil ym mherchnogaeth y dref na ellir ei ddileu
|
||||
STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nid oes man addas i'r cerflun yn nghanol y ddinas yma
|
||||
|
|
|
@ -306,19 +306,20 @@ public:
|
|||
line << GetString(STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED);
|
||||
|
||||
bool found = false;
|
||||
for (CargoID i = 0; i < NUM_CARGO; ++i) {
|
||||
if (acceptance[i] > 0) {
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
CargoID cid = cs->Index();
|
||||
if (acceptance[cid] > 0) {
|
||||
/* Add a comma between each item. */
|
||||
if (found) line << ", ";
|
||||
found = true;
|
||||
|
||||
/* If the accepted value is less than 8, show it in 1/8:ths */
|
||||
if (acceptance[i] < 8) {
|
||||
SetDParam(0, acceptance[i]);
|
||||
SetDParam(1, CargoSpec::Get(i)->name);
|
||||
if (acceptance[cid] < 8) {
|
||||
SetDParam(0, acceptance[cid]);
|
||||
SetDParam(1, cs->name);
|
||||
line << GetString(STR_LAND_AREA_INFORMATION_CARGO_EIGHTS);
|
||||
} else {
|
||||
line << GetString(CargoSpec::Get(i)->name);
|
||||
line << GetString(cs->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,14 +116,14 @@ template <class Tbase_set>
|
|||
return BaseMedia<Tbase_set>::used_set != nullptr;
|
||||
}
|
||||
|
||||
bool MusicSet::FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename)
|
||||
bool MusicSet::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename)
|
||||
{
|
||||
bool ret = this->BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false>::FillSetDetails(ini, path, full_filename);
|
||||
if (ret) {
|
||||
this->num_available = 0;
|
||||
IniGroup *names = ini->GetGroup("names");
|
||||
IniGroup *catindex = ini->GetGroup("catindex");
|
||||
IniGroup *timingtrim = ini->GetGroup("timingtrim");
|
||||
const IniGroup *names = ini.GetGroup("names");
|
||||
const IniGroup *catindex = ini.GetGroup("catindex");
|
||||
const IniGroup *timingtrim = ini.GetGroup("timingtrim");
|
||||
uint tracknr = 1;
|
||||
for (uint i = 0; i < lengthof(this->songinfo); i++) {
|
||||
const std::string &filename = this->files[i].filename;
|
||||
|
@ -133,7 +133,7 @@ bool MusicSet::FillSetDetails(IniFile *ini, const std::string &path, const std::
|
|||
|
||||
this->songinfo[i].filename = filename; // non-owned pointer
|
||||
|
||||
IniItem *item = catindex->GetItem(_music_file_names[i]);
|
||||
const IniItem *item = catindex != nullptr ? catindex->GetItem(_music_file_names[i]) : nullptr;
|
||||
if (item != nullptr && item->value.has_value() && !item->value->empty()) {
|
||||
/* Song has a CAT file index, assume it's MPS MIDI format */
|
||||
this->songinfo[i].filetype = MTT_MPSMIDI;
|
||||
|
@ -158,7 +158,7 @@ bool MusicSet::FillSetDetails(IniFile *ini, const std::string &path, const std::
|
|||
* the beginning, so we don't start reading e.g. root. */
|
||||
while (*trimmed_filename == PATHSEPCHAR) trimmed_filename++;
|
||||
|
||||
item = names->GetItem(trimmed_filename);
|
||||
item = names != nullptr ? names->GetItem(trimmed_filename) : nullptr;
|
||||
if (item != nullptr && item->value.has_value() && !item->value->empty()) break;
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ bool MusicSet::FillSetDetails(IniFile *ini, const std::string &path, const std::
|
|||
this->songinfo[i].tracknr = tracknr++;
|
||||
}
|
||||
|
||||
item = trimmed_filename != nullptr ? timingtrim->GetItem(trimmed_filename) : nullptr;
|
||||
item = trimmed_filename != nullptr && timingtrim != nullptr ? timingtrim->GetItem(trimmed_filename) : nullptr;
|
||||
if (item != nullptr && item->value.has_value() && !item->value->empty()) {
|
||||
auto endpos = item->value->find(':');
|
||||
if (endpos != std::string::npos) {
|
||||
|
|
|
@ -72,9 +72,9 @@ static DropDownList BuildVisibilityDropDownList()
|
|||
{
|
||||
DropDownList list;
|
||||
|
||||
list.emplace_back(new DropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_LOCAL, SERVER_GAME_TYPE_LOCAL, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY, SERVER_GAME_TYPE_INVITE_ONLY, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_PUBLIC, SERVER_GAME_TYPE_PUBLIC, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NETWORK_SERVER_VISIBILITY_LOCAL, SERVER_GAME_TYPE_LOCAL, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY, SERVER_GAME_TYPE_INVITE_ONLY, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NETWORK_SERVER_VISIBILITY_PUBLIC, SERVER_GAME_TYPE_PUBLIC, false));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
@ -1544,8 +1544,8 @@ private:
|
|||
static void OnClickClientAdmin([[maybe_unused]] NetworkClientListWindow *w, [[maybe_unused]] Point pt, ClientID client_id)
|
||||
{
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK, DD_CLIENT_ADMIN_KICK, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN, DD_CLIENT_ADMIN_BAN, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK, DD_CLIENT_ADMIN_KICK, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN, DD_CLIENT_ADMIN_BAN, false));
|
||||
|
||||
Rect wi_rect;
|
||||
wi_rect.left = pt.x;
|
||||
|
@ -1566,8 +1566,8 @@ private:
|
|||
static void OnClickCompanyAdmin([[maybe_unused]] NetworkClientListWindow *w, [[maybe_unused]] Point pt, CompanyID company_id)
|
||||
{
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, DD_COMPANY_ADMIN_RESET, NetworkCompanyHasClients(company_id)));
|
||||
list.emplace_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK, DD_COMPANY_ADMIN_UNLOCK, !NetworkCompanyIsPassworded(company_id)));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, DD_COMPANY_ADMIN_RESET, NetworkCompanyHasClients(company_id)));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK, DD_COMPANY_ADMIN_UNLOCK, !NetworkCompanyIsPassworded(company_id)));
|
||||
|
||||
Rect wi_rect;
|
||||
wi_rect.left = pt.x;
|
||||
|
@ -1598,9 +1598,9 @@ private:
|
|||
{
|
||||
ButtonCommon *chat_button = new CompanyButton(SPR_CHAT, company_id == COMPANY_SPECTATOR ? STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP : STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyChat);
|
||||
|
||||
if (_network_server) this->buttons[line_count].emplace_back(new CompanyButton(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR));
|
||||
if (_network_server) this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR));
|
||||
this->buttons[line_count].emplace_back(chat_button);
|
||||
if (client_playas != company_id) this->buttons[line_count].emplace_back(new CompanyButton(SPR_JOIN, STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyJoin, company_id != COMPANY_SPECTATOR && Company::Get(company_id)->is_ai));
|
||||
if (client_playas != company_id) this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyJoin, company_id != COMPANY_SPECTATOR && Company::Get(company_id)->is_ai));
|
||||
|
||||
this->line_count += 1;
|
||||
|
||||
|
@ -1609,8 +1609,8 @@ private:
|
|||
if (ci->client_playas != company_id) continue;
|
||||
has_players = true;
|
||||
|
||||
if (_network_server) this->buttons[line_count].emplace_back(new ClientButton(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP, COLOUR_RED, ci->client_id, &NetworkClientListWindow::OnClickClientAdmin, _network_own_client_id == ci->client_id));
|
||||
if (_network_own_client_id != ci->client_id) this->buttons[line_count].emplace_back(new ClientButton(SPR_CHAT, STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP, COLOUR_ORANGE, ci->client_id, &NetworkClientListWindow::OnClickClientChat));
|
||||
if (_network_server) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP, COLOUR_RED, ci->client_id, &NetworkClientListWindow::OnClickClientAdmin, _network_own_client_id == ci->client_id));
|
||||
if (_network_own_client_id != ci->client_id) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_CHAT, STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP, COLOUR_ORANGE, ci->client_id, &NetworkClientListWindow::OnClickClientChat));
|
||||
|
||||
if (ci->client_id == _network_own_client_id) {
|
||||
this->player_self_index = this->line_count;
|
||||
|
@ -1640,7 +1640,7 @@ private:
|
|||
|
||||
/* As spectator, show a line to create a new company. */
|
||||
if (client_playas == COMPANY_SPECTATOR && !NetworkMaxCompaniesReached()) {
|
||||
this->buttons[line_count].emplace_back(new CompanyButton(SPR_JOIN, STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP, COLOUR_ORANGE, COMPANY_SPECTATOR, &NetworkClientListWindow::OnClickCompanyNew));
|
||||
this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP, COLOUR_ORANGE, COMPANY_SPECTATOR, &NetworkClientListWindow::OnClickCompanyNew));
|
||||
this->line_count += 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -8850,7 +8850,7 @@ void ResetPersistentNewGRFData()
|
|||
*/
|
||||
static void BuildCargoTranslationMap()
|
||||
{
|
||||
memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
|
||||
_cur.grffile->cargo_map.fill(UINT8_MAX);
|
||||
|
||||
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
||||
if (!cs->IsValid()) continue;
|
||||
|
@ -9067,20 +9067,13 @@ static void CalculateRefitMasks()
|
|||
* cargo type. Finally disable the vehicle, if there is still no cargo. */
|
||||
if (!IsValidCargoID(ei->cargo_type) && ei->refit_mask != 0) {
|
||||
/* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
|
||||
const uint8_t *cargo_map_for_first_refittable = nullptr;
|
||||
{
|
||||
const GRFFile *file = _gted[engine].defaultcargo_grf;
|
||||
if (file == nullptr) file = e->GetGRF();
|
||||
if (file != nullptr && file->grf_version >= 8 && file->cargo_list.size() != 0) {
|
||||
cargo_map_for_first_refittable = file->cargo_map;
|
||||
}
|
||||
}
|
||||
|
||||
if (cargo_map_for_first_refittable != nullptr) {
|
||||
const GRFFile *file = _gted[engine].defaultcargo_grf;
|
||||
if (file == nullptr) file = e->GetGRF();
|
||||
if (file != nullptr && file->grf_version >= 8 && file->cargo_list.size() != 0) {
|
||||
/* Use first refittable cargo from cargo translation table */
|
||||
byte best_local_slot = 0xFF;
|
||||
byte best_local_slot = UINT8_MAX;
|
||||
for (CargoID cargo_type : SetCargoBitIterator(ei->refit_mask)) {
|
||||
byte local_slot = cargo_map_for_first_refittable[cargo_type];
|
||||
byte local_slot = file->cargo_map[cargo_type];
|
||||
if (local_slot < best_local_slot) {
|
||||
best_local_slot = local_slot;
|
||||
ei->cargo_type = cargo_type;
|
||||
|
|
|
@ -127,7 +127,7 @@ struct GRFFile : ZeroedMemoryAllocator {
|
|||
std::vector<GRFLabel> labels; ///< List of labels
|
||||
|
||||
std::vector<CargoLabel> cargo_list; ///< Cargo translation table (local ID -> label)
|
||||
uint8_t cargo_map[NUM_CARGO]; ///< Inverse cargo translation table (CargoID -> local ID)
|
||||
std::array<uint8_t, NUM_CARGO> cargo_map{}; ///< Inverse cargo translation table (CargoID -> local ID)
|
||||
|
||||
std::vector<RailTypeLabel> railtype_list; ///< Railtype translation table
|
||||
RailType railtype_map[RAILTYPE_END];
|
||||
|
|
|
@ -435,19 +435,11 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
|
||||
case 0x42: { // Consist cargo information
|
||||
if (!HasBit(v->grf_cache.cache_valid, NCVV_CONSIST_CARGO_INFORMATION)) {
|
||||
const Vehicle *u;
|
||||
std::array<uint8_t, NUM_CARGO> common_cargoes{};
|
||||
byte cargo_classes = 0;
|
||||
uint8_t common_cargoes[NUM_CARGO];
|
||||
uint8_t common_subtypes[256];
|
||||
byte user_def_data = 0;
|
||||
CargoID common_cargo_type = CT_INVALID;
|
||||
uint8_t common_subtype = 0xFF; // Return 0xFF if nothing is carried
|
||||
|
||||
/* Reset our arrays */
|
||||
memset(common_cargoes, 0, sizeof(common_cargoes));
|
||||
memset(common_subtypes, 0, sizeof(common_subtypes));
|
||||
|
||||
for (u = v; u != nullptr; u = u->Next()) {
|
||||
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||
if (v->type == VEH_TRAIN) user_def_data |= Train::From(u)->tcache.user_def_data;
|
||||
|
||||
/* Skip empty engines */
|
||||
|
@ -458,16 +450,13 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
}
|
||||
|
||||
/* Pick the most common cargo type */
|
||||
uint common_cargo_best_amount = 0;
|
||||
for (CargoID cargo = 0; cargo < NUM_CARGO; cargo++) {
|
||||
if (common_cargoes[cargo] > common_cargo_best_amount) {
|
||||
common_cargo_best_amount = common_cargoes[cargo];
|
||||
common_cargo_type = cargo;
|
||||
}
|
||||
}
|
||||
auto cargo_it = std::max_element(std::begin(common_cargoes), std::end(common_cargoes));
|
||||
/* Return CT_INVALID if nothing is carried */
|
||||
CargoID common_cargo_type = (*cargo_it == 0) ? (CargoID)CT_INVALID : static_cast<CargoID>(std::distance(std::begin(common_cargoes), cargo_it));
|
||||
|
||||
/* Count subcargo types of common_cargo_type */
|
||||
for (u = v; u != nullptr; u = u->Next()) {
|
||||
std::array<uint8_t, UINT8_MAX + 1> common_subtypes{};
|
||||
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||
/* Skip empty engines and engines not carrying common_cargo_type */
|
||||
if (u->cargo_type != common_cargo_type || !u->GetEngine()->CanCarryCargo()) continue;
|
||||
|
||||
|
@ -475,13 +464,9 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
}
|
||||
|
||||
/* Pick the most common subcargo type*/
|
||||
uint common_subtype_best_amount = 0;
|
||||
for (uint i = 0; i < lengthof(common_subtypes); i++) {
|
||||
if (common_subtypes[i] > common_subtype_best_amount) {
|
||||
common_subtype_best_amount = common_subtypes[i];
|
||||
common_subtype = i;
|
||||
}
|
||||
}
|
||||
auto subtype_it = std::max_element(std::begin(common_subtypes), std::end(common_subtypes));
|
||||
/* Return UINT8_MAX if nothing is carried */
|
||||
uint8_t common_subtype = (*subtype_it == 0) ? UINT8_MAX : static_cast<uint8_t>(std::distance(std::begin(common_subtypes), subtype_it));
|
||||
|
||||
/* Note: We have to store the untranslated cargotype in the cache as the cache can be read by different NewGRFs,
|
||||
* which will need different translations */
|
||||
|
|
|
@ -392,7 +392,7 @@ struct NewGRFParametersWindow : public Window {
|
|||
|
||||
DropDownList list;
|
||||
for (uint32_t i = par_info.min_value; i <= par_info.max_value; i++) {
|
||||
list.emplace_back(new DropDownListStringItem(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i, false));
|
||||
}
|
||||
|
||||
ShowDropDownListAt(this, std::move(list), old_val, WID_NP_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);
|
||||
|
@ -952,10 +952,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
|||
DropDownList list;
|
||||
|
||||
/* Add 'None' option for clearing list */
|
||||
list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NONE, -1, false));
|
||||
|
||||
for (uint i = 0; i < this->grf_presets.size(); i++) {
|
||||
list.emplace_back(new DropDownListStringItem(this->grf_presets[i], i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(this->grf_presets[i], i, false));
|
||||
}
|
||||
|
||||
this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window
|
||||
|
|
|
@ -1299,7 +1299,7 @@ public:
|
|||
case WID_O_COND_VARIABLE: {
|
||||
DropDownList list;
|
||||
for (uint i = 0; i < lengthof(_order_conditional_variable); i++) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i], false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i], false));
|
||||
}
|
||||
ShowDropDownList(this, std::move(list), this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable(), WID_O_COND_VARIABLE);
|
||||
break;
|
||||
|
|
|
@ -2353,7 +2353,7 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
|
|||
DropDownList list;
|
||||
|
||||
if (all_option) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE, false));
|
||||
}
|
||||
|
||||
Dimension d = { 0, 0 };
|
||||
|
@ -2375,18 +2375,18 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
|
|||
SetDParam(0, rti->strings.menu_text);
|
||||
SetDParam(1, rti->max_speed);
|
||||
if (for_replacement) {
|
||||
list.emplace_back(new DropDownListStringItem(rti->strings.replace_text, rt, !HasBit(avail_railtypes, rt)));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(rti->strings.replace_text, rt, !HasBit(avail_railtypes, rt)));
|
||||
} else {
|
||||
StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
|
||||
DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt));
|
||||
auto iconitem = std::make_unique<DropDownListIconItem>(rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt));
|
||||
iconitem->SetDimension(d);
|
||||
list.emplace_back(iconitem);
|
||||
list.push_back(std::move(iconitem));
|
||||
}
|
||||
}
|
||||
|
||||
if (list.size() == 0) {
|
||||
/* Empty dropdowns are not allowed */
|
||||
list.emplace_back(new DropDownListStringItem(STR_NONE, INVALID_RAILTYPE, true));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NONE, INVALID_RAILTYPE, true));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
|
|
@ -1814,7 +1814,7 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b
|
|||
DropDownList list;
|
||||
|
||||
if (all_option) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_REPLACE_ALL_ROADTYPE, INVALID_ROADTYPE, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_ALL_ROADTYPE, INVALID_ROADTYPE, false));
|
||||
}
|
||||
|
||||
Dimension d = { 0, 0 };
|
||||
|
@ -1836,18 +1836,18 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b
|
|||
SetDParam(0, rti->strings.menu_text);
|
||||
SetDParam(1, rti->max_speed / 2);
|
||||
if (for_replacement) {
|
||||
list.emplace_back(new DropDownListStringItem(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt)));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt)));
|
||||
} else {
|
||||
StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
|
||||
DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
|
||||
auto iconitem = std::make_unique<DropDownListIconItem>(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
|
||||
iconitem->SetDimension(d);
|
||||
list.emplace_back(iconitem);
|
||||
list.push_back(std::move(iconitem));
|
||||
}
|
||||
}
|
||||
|
||||
if (list.size() == 0) {
|
||||
/* Empty dropdowns are not allowed */
|
||||
list.emplace_back(new DropDownListStringItem(STR_NONE, INVALID_ROADTYPE, true));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NONE, INVALID_ROADTYPE, true));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -1880,14 +1880,14 @@ 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;
|
||||
DropDownListIconItem *item = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
|
||||
auto item = std::make_unique<DropDownListIconItem>(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
|
||||
item->SetDimension(d);
|
||||
list.emplace_back(item);
|
||||
list.push_back(std::move(item));
|
||||
}
|
||||
|
||||
if (list.size() == 0) {
|
||||
/* Empty dropdowns are not allowed */
|
||||
list.emplace_back(new DropDownListStringItem(STR_NONE, -1, true));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NONE, -1, true));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
|
|
@ -40,9 +40,7 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
|
|||
|
||||
if (v->HasArticulatedPart()) {
|
||||
CargoArray max_cargo{};
|
||||
StringID subtype_text[NUM_CARGO];
|
||||
|
||||
memset(subtype_text, 0, sizeof(subtype_text));
|
||||
std::array<StringID, NUM_CARGO> subtype_text{};
|
||||
|
||||
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||
max_cargo[u->cargo_type] += u->cargo_cap;
|
||||
|
@ -55,16 +53,17 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
|
|||
std::string capacity = GetString(STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY);
|
||||
|
||||
bool first = true;
|
||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||
if (max_cargo[i] > 0) {
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
CargoID cid = cs->Index();
|
||||
if (max_cargo[cid] > 0) {
|
||||
if (!first) capacity += ", ";
|
||||
|
||||
SetDParam(0, i);
|
||||
SetDParam(1, max_cargo[i]);
|
||||
SetDParam(0, cid);
|
||||
SetDParam(1, max_cargo[cid]);
|
||||
capacity += GetString(STR_JUST_CARGO);
|
||||
|
||||
if (subtype_text[i] != 0) {
|
||||
capacity += GetString(subtype_text[i]);
|
||||
if (subtype_text[cid] != STR_NULL) {
|
||||
capacity += GetString(subtype_text[cid]);
|
||||
}
|
||||
|
||||
first = false;
|
||||
|
|
|
@ -469,7 +469,7 @@ struct ScriptSettingsWindow : public Window {
|
|||
|
||||
DropDownList list;
|
||||
for (int i = config_item.min_value; i <= config_item.max_value; i++) {
|
||||
list.emplace_back(new DropDownListStringItem(config_item.labels.find(i)->second, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(config_item.labels.find(i)->second, i, false));
|
||||
}
|
||||
|
||||
ShowDropDownListAt(this, std::move(list), old_val, WID_SCRS_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);
|
||||
|
|
151
src/settings.cpp
151
src/settings.cpp
|
@ -131,12 +131,11 @@ static bool IsSignedVarMemType(VarType vt)
|
|||
*/
|
||||
class ConfigIniFile : public IniFile {
|
||||
private:
|
||||
inline static const char * const list_group_names[] = {
|
||||
inline static const IniGroupNameList list_group_names = {
|
||||
"bans",
|
||||
"newgrf",
|
||||
"servers",
|
||||
"server_bind_addresses",
|
||||
nullptr,
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -587,8 +586,8 @@ const std::string &StringSettingDesc::Read(const void *object) const
|
|||
*/
|
||||
static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, const char *grpname, void *object, bool only_startup)
|
||||
{
|
||||
IniGroup *group;
|
||||
IniGroup *group_def = ini.GetGroup(grpname);
|
||||
const IniGroup *group;
|
||||
const IniGroup *group_def = ini.GetGroup(grpname);
|
||||
|
||||
for (auto &desc : settings_table) {
|
||||
const SettingDesc *sd = GetSettingDesc(desc);
|
||||
|
@ -600,13 +599,15 @@ static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, co
|
|||
auto sc = s.find('.');
|
||||
if (sc != std::string::npos) {
|
||||
group = ini.GetGroup(s.substr(0, sc));
|
||||
if (group == nullptr) group = group_def;
|
||||
s = s.substr(sc + 1);
|
||||
} else {
|
||||
group = group_def;
|
||||
}
|
||||
|
||||
IniItem *item = group->GetItem(s);
|
||||
if (item == nullptr && group != group_def) {
|
||||
const IniItem *item = nullptr;
|
||||
if (group != nullptr) item = group->GetItem(s);
|
||||
if (item == nullptr && group != group_def && group_def != nullptr) {
|
||||
/* For settings.xx.yy load the settings from [settings] yy = ? in case the previous
|
||||
* did not exist (e.g. loading old config files with a [settings] section */
|
||||
item = group_def->GetItem(s);
|
||||
|
@ -615,7 +616,9 @@ static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, co
|
|||
/* For settings.xx.zz.yy load the settings from [zz] yy = ? in case the previous
|
||||
* did not exist (e.g. loading old config files with a [yapf] section */
|
||||
sc = s.find('.');
|
||||
if (sc != std::string::npos) item = ini.GetGroup(s.substr(0, sc))->GetItem(s.substr(sc + 1));
|
||||
if (sc != std::string::npos) {
|
||||
if (group = ini.GetGroup(s.substr(0, sc)); group != nullptr) item = group->GetItem(s.substr(sc + 1));
|
||||
}
|
||||
}
|
||||
|
||||
sd->ParseValue(item, object);
|
||||
|
@ -676,10 +679,10 @@ static void IniSaveSettings(IniFile &ini, const SettingTable &settings_table, co
|
|||
std::string s{ sd->GetName() };
|
||||
auto sc = s.find('.');
|
||||
if (sc != std::string::npos) {
|
||||
group = ini.GetGroup(s.substr(0, sc));
|
||||
group = &ini.GetOrCreateGroup(s.substr(0, sc));
|
||||
s = s.substr(sc + 1);
|
||||
} else {
|
||||
if (group_def == nullptr) group_def = ini.GetGroup(grpname);
|
||||
if (group_def == nullptr) group_def = &ini.GetOrCreateGroup(grpname);
|
||||
group = group_def;
|
||||
}
|
||||
|
||||
|
@ -777,14 +780,14 @@ bool ListSettingDesc::IsDefaultValue(void *) const
|
|||
*/
|
||||
static void IniLoadSettingList(IniFile &ini, const char *grpname, StringList &list)
|
||||
{
|
||||
IniGroup *group = ini.GetGroup(grpname);
|
||||
const IniGroup *group = ini.GetGroup(grpname);
|
||||
|
||||
if (group == nullptr) return;
|
||||
|
||||
list.clear();
|
||||
|
||||
for (const IniItem *item = group->item; item != nullptr; item = item->next) {
|
||||
if (!item->name.empty()) list.push_back(item->name);
|
||||
for (const IniItem &item : group->items) {
|
||||
if (!item.name.empty()) list.push_back(item.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -799,13 +802,11 @@ static void IniLoadSettingList(IniFile &ini, const char *grpname, StringList &li
|
|||
*/
|
||||
static void IniSaveSettingList(IniFile &ini, const char *grpname, StringList &list)
|
||||
{
|
||||
IniGroup *group = ini.GetGroup(grpname);
|
||||
|
||||
if (group == nullptr) return;
|
||||
group->Clear();
|
||||
IniGroup &group = ini.GetOrCreateGroup(grpname);
|
||||
group.Clear();
|
||||
|
||||
for (const auto &iter : list) {
|
||||
group->GetOrCreateItem(iter).SetValue("");
|
||||
group.GetOrCreateItem(iter).SetValue("");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -893,10 +894,9 @@ static void ValidateSettings()
|
|||
}
|
||||
}
|
||||
|
||||
static void AILoadConfig(IniFile &ini, const char *grpname)
|
||||
static void AILoadConfig(const IniFile &ini, const char *grpname)
|
||||
{
|
||||
IniGroup *group = ini.GetGroup(grpname);
|
||||
IniItem *item;
|
||||
const IniGroup *group = ini.GetGroup(grpname);
|
||||
|
||||
/* Clean any configured AI */
|
||||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
|
@ -907,44 +907,44 @@ static void AILoadConfig(IniFile &ini, const char *grpname)
|
|||
if (group == nullptr) return;
|
||||
|
||||
CompanyID c = COMPANY_FIRST;
|
||||
for (item = group->item; c < MAX_COMPANIES && item != nullptr; c++, item = item->next) {
|
||||
for (const IniItem &item : group->items) {
|
||||
AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME);
|
||||
|
||||
config->Change(item->name);
|
||||
config->Change(item.name);
|
||||
if (!config->HasScript()) {
|
||||
if (item->name != "none") {
|
||||
Debug(script, 0, "The AI by the name '{}' was no longer found, and removed from the list.", item->name);
|
||||
if (item.name != "none") {
|
||||
Debug(script, 0, "The AI by the name '{}' was no longer found, and removed from the list.", item.name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (item->value.has_value()) config->StringToSettings(*item->value);
|
||||
if (item.value.has_value()) config->StringToSettings(*item.value);
|
||||
c++;
|
||||
if (c >= MAX_COMPANIES) break;
|
||||
}
|
||||
}
|
||||
|
||||
static void GameLoadConfig(IniFile &ini, const char *grpname)
|
||||
static void GameLoadConfig(const IniFile &ini, const char *grpname)
|
||||
{
|
||||
IniGroup *group = ini.GetGroup(grpname);
|
||||
IniItem *item;
|
||||
const IniGroup *group = ini.GetGroup(grpname);
|
||||
|
||||
/* Clean any configured GameScript */
|
||||
GameConfig::GetConfig(GameConfig::SSS_FORCE_NEWGAME)->Change(std::nullopt);
|
||||
|
||||
/* If no group exists, return */
|
||||
if (group == nullptr) return;
|
||||
if (group == nullptr || group->items.empty()) return;
|
||||
|
||||
item = group->item;
|
||||
if (item == nullptr) return;
|
||||
const IniItem &item = group->items.front();
|
||||
|
||||
GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME);
|
||||
|
||||
config->Change(item->name);
|
||||
config->Change(item.name);
|
||||
if (!config->HasScript()) {
|
||||
if (item->name != "none") {
|
||||
Debug(script, 0, "The GameScript by the name '{}' was no longer found, and removed from the list.", item->name);
|
||||
if (item.name != "none") {
|
||||
Debug(script, 0, "The GameScript by the name '{}' was no longer found, and removed from the list.", item.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (item->value.has_value()) config->StringToSettings(*item->value);
|
||||
if (item.value.has_value()) config->StringToSettings(*item.value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -987,22 +987,21 @@ static bool DecodeHexText(const char *pos, uint8_t *dest, size_t dest_size)
|
|||
* @param grpname Group name containing the configuration of the GRF.
|
||||
* @param is_static GRF is static.
|
||||
*/
|
||||
static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_static)
|
||||
static GRFConfig *GRFLoadConfig(const IniFile &ini, const char *grpname, bool is_static)
|
||||
{
|
||||
IniGroup *group = ini.GetGroup(grpname);
|
||||
IniItem *item;
|
||||
const IniGroup *group = ini.GetGroup(grpname);
|
||||
GRFConfig *first = nullptr;
|
||||
GRFConfig **curr = &first;
|
||||
|
||||
if (group == nullptr) return nullptr;
|
||||
|
||||
uint num_grfs = 0;
|
||||
for (item = group->item; item != nullptr; item = item->next) {
|
||||
for (const IniItem &item : group->items) {
|
||||
GRFConfig *c = nullptr;
|
||||
|
||||
uint8_t grfid_buf[4];
|
||||
MD5Hash md5sum;
|
||||
const char *filename = item->name.c_str();
|
||||
const char *filename = item.name.c_str();
|
||||
bool has_grfid = false;
|
||||
bool has_md5sum = false;
|
||||
|
||||
|
@ -1026,8 +1025,8 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati
|
|||
if (c == nullptr) c = new GRFConfig(filename);
|
||||
|
||||
/* Parse parameters */
|
||||
if (item->value.has_value() && !item->value->empty()) {
|
||||
int count = ParseIntList(item->value->c_str(), c->param.data(), c->param.size());
|
||||
if (item.value.has_value() && !item.value->empty()) {
|
||||
int count = ParseIntList(item.value->c_str(), c->param.data(), c->param.size());
|
||||
if (count < 0) {
|
||||
SetDParamStr(0, filename);
|
||||
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY, WL_CRITICAL);
|
||||
|
@ -1050,7 +1049,7 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati
|
|||
SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN);
|
||||
}
|
||||
|
||||
SetDParamStr(0, StrEmpty(filename) ? item->name.c_str() : filename);
|
||||
SetDParamStr(0, StrEmpty(filename) ? item.name.c_str() : filename);
|
||||
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_GRF, WL_CRITICAL);
|
||||
delete c;
|
||||
continue;
|
||||
|
@ -1089,9 +1088,10 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati
|
|||
return first;
|
||||
}
|
||||
|
||||
static IniFileVersion LoadVersionFromConfig(IniFile &ini)
|
||||
static IniFileVersion LoadVersionFromConfig(const IniFile &ini)
|
||||
{
|
||||
IniGroup *group = ini.GetGroup("version");
|
||||
const IniGroup *group = ini.GetGroup("version");
|
||||
if (group == nullptr) return IFV_0;
|
||||
|
||||
auto version_number = group->GetItem("ini_version");
|
||||
/* Older ini-file versions don't have this key yet. */
|
||||
|
@ -1105,10 +1105,8 @@ static IniFileVersion LoadVersionFromConfig(IniFile &ini)
|
|||
|
||||
static void AISaveConfig(IniFile &ini, const char *grpname)
|
||||
{
|
||||
IniGroup *group = ini.GetGroup(grpname);
|
||||
|
||||
if (group == nullptr) return;
|
||||
group->Clear();
|
||||
IniGroup &group = ini.GetOrCreateGroup(grpname);
|
||||
group.Clear();
|
||||
|
||||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME);
|
||||
|
@ -1121,17 +1119,14 @@ static void AISaveConfig(IniFile &ini, const char *grpname)
|
|||
name = "none";
|
||||
}
|
||||
|
||||
IniItem *item = new IniItem(group, name);
|
||||
item->SetValue(value);
|
||||
group.CreateItem(name).SetValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
static void GameSaveConfig(IniFile &ini, const char *grpname)
|
||||
{
|
||||
IniGroup *group = ini.GetGroup(grpname);
|
||||
|
||||
if (group == nullptr) return;
|
||||
group->Clear();
|
||||
IniGroup &group = ini.GetOrCreateGroup(grpname);
|
||||
group.Clear();
|
||||
|
||||
GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME);
|
||||
std::string name;
|
||||
|
@ -1143,8 +1138,7 @@ static void GameSaveConfig(IniFile &ini, const char *grpname)
|
|||
name = "none";
|
||||
}
|
||||
|
||||
IniItem *item = new IniItem(group, name);
|
||||
item->SetValue(value);
|
||||
group.CreateItem(name).SetValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1153,23 +1147,23 @@ static void GameSaveConfig(IniFile &ini, const char *grpname)
|
|||
*/
|
||||
static void SaveVersionInConfig(IniFile &ini)
|
||||
{
|
||||
IniGroup *group = ini.GetGroup("version");
|
||||
group->GetOrCreateItem("version_string").SetValue(_openttd_revision);
|
||||
group->GetOrCreateItem("version_number").SetValue(fmt::format("{:08X}", _openttd_newgrf_version));
|
||||
group->GetOrCreateItem("ini_version").SetValue(std::to_string(INIFILE_VERSION));
|
||||
IniGroup &group = ini.GetOrCreateGroup("version");
|
||||
group.GetOrCreateItem("version_string").SetValue(_openttd_revision);
|
||||
group.GetOrCreateItem("version_number").SetValue(fmt::format("{:08X}", _openttd_newgrf_version));
|
||||
group.GetOrCreateItem("ini_version").SetValue(std::to_string(INIFILE_VERSION));
|
||||
}
|
||||
|
||||
/* Save a GRF configuration to the given group name */
|
||||
static void GRFSaveConfig(IniFile &ini, const char *grpname, const GRFConfig *list)
|
||||
{
|
||||
ini.RemoveGroup(grpname);
|
||||
IniGroup *group = ini.GetGroup(grpname);
|
||||
IniGroup &group = ini.GetOrCreateGroup(grpname);
|
||||
group.Clear();
|
||||
const GRFConfig *c;
|
||||
|
||||
for (c = list; c != nullptr; c = c->next) {
|
||||
std::string key = fmt::format("{:08X}|{}|{}", BSWAP32(c->ident.grfid),
|
||||
FormatArrayAsHex(c->ident.md5sum), c->filename);
|
||||
group->GetOrCreateItem(key).SetValue(GRFBuildParamList(c));
|
||||
group.GetOrCreateItem(key).SetValue(GRFBuildParamList(c));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1223,6 +1217,7 @@ static void RemoveEntriesFromIni(IniFile &ini, const SettingTable &table)
|
|||
if (sc == std::string::npos) continue;
|
||||
|
||||
IniGroup *group = ini.GetGroup(s.substr(0, sc));
|
||||
if (group == nullptr) continue;
|
||||
s = s.substr(sc + 1);
|
||||
|
||||
group->RemoveItem(s);
|
||||
|
@ -1252,16 +1247,16 @@ static void RemoveEntriesFromIni(IniFile &ini, const SettingTable &table)
|
|||
* @param[out] old_item The old item to base upgrading on.
|
||||
* @return Whether upgrading should happen; if false, old_item is a nullptr.
|
||||
*/
|
||||
bool IsConversionNeeded(ConfigIniFile &ini, std::string group, std::string old_var, std::string new_var, IniItem **old_item)
|
||||
bool IsConversionNeeded(const ConfigIniFile &ini, const std::string &group, const std::string &old_var, const std::string &new_var, const IniItem **old_item)
|
||||
{
|
||||
*old_item = nullptr;
|
||||
|
||||
IniGroup *igroup = ini.GetGroup(group, false);
|
||||
const IniGroup *igroup = ini.GetGroup(group);
|
||||
/* If the group doesn't exist, there is nothing to convert. */
|
||||
if (igroup == nullptr) return false;
|
||||
|
||||
IniItem *tmp_old_item = igroup->GetItem(old_var);
|
||||
IniItem *new_item = igroup->GetItem(new_var);
|
||||
const IniItem *tmp_old_item = igroup->GetItem(old_var);
|
||||
const IniItem *new_item = igroup->GetItem(new_var);
|
||||
|
||||
/* If the old item doesn't exist, there is nothing to convert. */
|
||||
if (tmp_old_item == nullptr) return false;
|
||||
|
@ -1306,9 +1301,9 @@ void LoadFromConfig(bool startup)
|
|||
|
||||
/* Move no_http_content_downloads and use_relay_service from generic_ini to private_ini. */
|
||||
if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) {
|
||||
IniGroup *network = generic_ini.GetGroup("network", false);
|
||||
const IniGroup *network = generic_ini.GetGroup("network");
|
||||
if (network != nullptr) {
|
||||
IniItem *no_http_content_downloads = network->GetItem("no_http_content_downloads");
|
||||
const IniItem *no_http_content_downloads = network->GetItem("no_http_content_downloads");
|
||||
if (no_http_content_downloads != nullptr) {
|
||||
if (no_http_content_downloads->value == "true") {
|
||||
_settings_client.network.no_http_content_downloads = true;
|
||||
|
@ -1317,7 +1312,7 @@ void LoadFromConfig(bool startup)
|
|||
}
|
||||
}
|
||||
|
||||
IniItem *use_relay_service = network->GetItem("use_relay_service");
|
||||
const IniItem *use_relay_service = network->GetItem("use_relay_service");
|
||||
if (use_relay_service != nullptr) {
|
||||
if (use_relay_service->value == "never") {
|
||||
_settings_client.network.use_relay_service = UseRelayService::URS_NEVER;
|
||||
|
@ -1330,7 +1325,7 @@ void LoadFromConfig(bool startup)
|
|||
}
|
||||
}
|
||||
|
||||
IniItem *old_item;
|
||||
const IniItem *old_item;
|
||||
|
||||
if (generic_version < IFV_GAME_TYPE && IsConversionNeeded(generic_ini, "network", "server_advertise", "server_game_type", &old_item)) {
|
||||
auto old_value = BoolSettingDesc::ParseSingleValue(old_item->value->c_str());
|
||||
|
@ -1388,8 +1383,8 @@ void SaveToConfig()
|
|||
* just so we can add a comment before it (that is how IniFile works).
|
||||
* This to explain what the file is about. After doing it once, never touch
|
||||
* it again, as otherwise we might be reverting user changes. */
|
||||
if (!private_ini.GetGroup("private", false)) private_ini.GetGroup("private")->comment = "; This file possibly contains private information which can identify you as person.\n";
|
||||
if (!secrets_ini.GetGroup("secrets", false)) secrets_ini.GetGroup("secrets")->comment = "; Do not share this file with others, not even if they claim to be technical support.\n; This file contains saved passwords and other secrets that should remain private to you!\n";
|
||||
if (IniGroup *group = private_ini.GetGroup("private"); group != nullptr) group->comment = "; This file possibly contains private information which can identify you as person.\n";
|
||||
if (IniGroup *group = secrets_ini.GetGroup("secrets"); group != nullptr) group->comment = "; Do not share this file with others, not even if they claim to be technical support.\n; This file contains saved passwords and other secrets that should remain private to you!\n";
|
||||
|
||||
if (generic_version == IFV_0) {
|
||||
/* Remove some obsolete groups. These have all been loaded into other groups. */
|
||||
|
@ -1413,7 +1408,7 @@ void SaveToConfig()
|
|||
|
||||
/* These variables are migrated from generic ini to private ini now. */
|
||||
if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) {
|
||||
IniGroup *network = generic_ini.GetGroup("network", false);
|
||||
IniGroup *network = generic_ini.GetGroup("network");
|
||||
if (network != nullptr) {
|
||||
network->RemoveItem("no_http_content_downloads");
|
||||
network->RemoveItem("use_relay_service");
|
||||
|
@ -1444,9 +1439,9 @@ StringList GetGRFPresetList()
|
|||
StringList list;
|
||||
|
||||
ConfigIniFile ini(_config_file);
|
||||
for (IniGroup *group = ini.group; group != nullptr; group = group->next) {
|
||||
if (group->name.compare(0, 7, "preset-") == 0) {
|
||||
list.push_back(group->name.substr(7));
|
||||
for (const IniGroup &group : ini.groups) {
|
||||
if (group.name.compare(0, 7, "preset-") == 0) {
|
||||
list.push_back(group.name.substr(7));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,18 +213,18 @@ struct GameOptionsWindow : Window {
|
|||
int i = ¤cy - _currency_specs;
|
||||
if (i == CURRENCY_CUSTOM) continue;
|
||||
if (currency.code.empty()) {
|
||||
list.emplace_back(new DropDownListStringItem(currency.name, i, HasBit(disabled, i)));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(currency.name, i, HasBit(disabled, i)));
|
||||
} else {
|
||||
SetDParam(0, currency.name);
|
||||
SetDParamStr(1, currency.code);
|
||||
list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CODE, i, HasBit(disabled, i)));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GAME_OPTIONS_CURRENCY_CODE, i, HasBit(disabled, i)));
|
||||
}
|
||||
}
|
||||
std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
|
||||
|
||||
/* Append custom currency at the end */
|
||||
list.emplace_back(new DropDownListItem(-1, false)); // separator line
|
||||
list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM)));
|
||||
list.push_back(std::make_unique<DropDownListItem>(-1, false)); // separator line
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM)));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ struct GameOptionsWindow : Window {
|
|||
|
||||
const StringID *items = _autosave_dropdown;
|
||||
for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) {
|
||||
list.emplace_back(new DropDownListStringItem(*items, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(*items, i, false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ struct GameOptionsWindow : Window {
|
|||
SetDParamStr(0, _languages[i].name);
|
||||
}
|
||||
SetDParam(1, (LANGUAGE_TOTAL_STRINGS - _languages[i].missing) * 100 / LANGUAGE_TOTAL_STRINGS);
|
||||
list.emplace_back(new DropDownListStringItem(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i, false));
|
||||
}
|
||||
std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
|
||||
break;
|
||||
|
@ -273,7 +273,7 @@ struct GameOptionsWindow : Window {
|
|||
for (uint i = 0; i < _resolutions.size(); i++) {
|
||||
SetDParam(0, _resolutions[i].width);
|
||||
SetDParam(1, _resolutions[i].height);
|
||||
list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_RESOLUTION_ITEM, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GAME_OPTIONS_RESOLUTION_ITEM, i, false));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -282,7 +282,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.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i, false));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2219,15 +2219,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.emplace_back(new DropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(_game_settings_restrict_dropdown[mode], mode, disabled));
|
||||
}
|
||||
break;
|
||||
|
||||
case WID_GS_TYPE_DROPDOWN:
|
||||
list.emplace_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false));
|
||||
list.emplace_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME, false));
|
||||
list.emplace_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(_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<DropDownListStringItem>(_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<DropDownListStringItem>(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false));
|
||||
break;
|
||||
}
|
||||
return list;
|
||||
|
@ -2391,7 +2391,7 @@ struct GameSettingsWindow : Window {
|
|||
|
||||
DropDownList list;
|
||||
for (int i = sd->min; i <= (int)sd->max; i++) {
|
||||
list.emplace_back(new DropDownListStringItem(sd->str_val + i - sd->min, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(sd->str_val + i - sd->min, i, false));
|
||||
}
|
||||
|
||||
ShowDropDownListAt(this, std::move(list), value, WID_GS_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);
|
||||
|
|
|
@ -29,7 +29,7 @@ DropDownList BuildSetDropDownList(int *selected_index)
|
|||
*selected_index = T::GetIndexOfUsedSet();
|
||||
DropDownList list;
|
||||
for (int i = 0; i < n; i++) {
|
||||
list.emplace_back(new DropDownListStringItem(T::GetSet(i)->name, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(T::GetSet(i)->name, i, false));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
|
|
@ -151,10 +151,10 @@ private:
|
|||
struct SettingsIniFile : IniLoadFile {
|
||||
/**
|
||||
* Construct a new ini loader.
|
||||
* @param list_group_names A \c nullptr terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST
|
||||
* @param seq_group_names A \c nullptr terminated list with group names that should be loaded as lists of names. @see IGT_SEQUENCE
|
||||
* @param list_group_names A list with group names that should be loaded as lists instead of variables. @see IGT_LIST
|
||||
* @param seq_group_names A list with group names that should be loaded as lists of names. @see IGT_SEQUENCE
|
||||
*/
|
||||
SettingsIniFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr) :
|
||||
SettingsIniFile(const IniGroupNameList &list_group_names = {}, const IniGroupNameList &seq_group_names = {}) :
|
||||
IniLoadFile(list_group_names, seq_group_names)
|
||||
{
|
||||
}
|
||||
|
@ -188,32 +188,18 @@ static const char *TEMPLATES_GROUP_NAME = "templates"; ///< Name of the group co
|
|||
static const char *VALIDATION_GROUP_NAME = "validation"; ///< Name of the group containing the validation statements.
|
||||
static const char *DEFAULTS_GROUP_NAME = "defaults"; ///< Name of the group containing default values for the template variables.
|
||||
|
||||
/**
|
||||
* Load the INI file.
|
||||
* @param filename Name of the file to load.
|
||||
* @return Loaded INI data.
|
||||
*/
|
||||
static IniLoadFile *LoadIniFile(const char *filename)
|
||||
{
|
||||
static const char * const seq_groups[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, nullptr};
|
||||
|
||||
IniLoadFile *ini = new SettingsIniFile(nullptr, seq_groups);
|
||||
ini->LoadFromDisk(filename, NO_DIRECTORY);
|
||||
return ini;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump a #IGT_SEQUENCE group into #_stored_output.
|
||||
* @param ifile Loaded INI data.
|
||||
* @param group_name Name of the group to copy.
|
||||
*/
|
||||
static void DumpGroup(IniLoadFile *ifile, const char * const group_name)
|
||||
static void DumpGroup(const IniLoadFile &ifile, const char * const group_name)
|
||||
{
|
||||
IniGroup *grp = ifile->GetGroup(group_name, false);
|
||||
const IniGroup *grp = ifile.GetGroup(group_name);
|
||||
if (grp != nullptr && grp->type == IGT_SEQUENCE) {
|
||||
for (IniItem *item = grp->item; item != nullptr; item = item->next) {
|
||||
if (!item->name.empty()) {
|
||||
_stored_output.Add(item->name.c_str());
|
||||
for (const IniItem &item : grp->items) {
|
||||
if (!item.name.empty()) {
|
||||
_stored_output.Add(item.name.c_str());
|
||||
_stored_output.Add("\n", 1);
|
||||
}
|
||||
}
|
||||
|
@ -227,9 +213,9 @@ static void DumpGroup(IniLoadFile *ifile, const char * const group_name)
|
|||
* @param defaults Fallback group to search, \c nullptr skips the search.
|
||||
* @return Text of the item if found, else \c nullptr.
|
||||
*/
|
||||
static const char *FindItemValue(const char *name, IniGroup *grp, IniGroup *defaults)
|
||||
static const char *FindItemValue(const char *name, const IniGroup *grp, const IniGroup *defaults)
|
||||
{
|
||||
IniItem *item = grp->GetItem(name);
|
||||
const IniItem *item = grp->GetItem(name);
|
||||
if (item == nullptr && defaults != nullptr) item = defaults->GetItem(name);
|
||||
if (item == nullptr || !item->value.has_value()) return nullptr;
|
||||
return item->value->c_str();
|
||||
|
@ -242,18 +228,18 @@ static const char *FindItemValue(const char *name, IniGroup *grp, IniGroup *defa
|
|||
* @param default_grp Default values for items not set in @grp.
|
||||
* @param output Output to use for result.
|
||||
*/
|
||||
static void DumpLine(IniItem *item, IniGroup *grp, IniGroup *default_grp, OutputStore &output)
|
||||
static void DumpLine(const IniItem *item, const IniGroup *grp, const IniGroup *default_grp, OutputStore &output)
|
||||
{
|
||||
static const int MAX_VAR_LENGTH = 64;
|
||||
|
||||
/* Prefix with #if/#ifdef/#ifndef */
|
||||
static const char * const pp_lines[] = {"if", "ifdef", "ifndef", nullptr};
|
||||
static const auto pp_lines = {"if", "ifdef", "ifndef"};
|
||||
int count = 0;
|
||||
for (const char * const *name = pp_lines; *name != nullptr; name++) {
|
||||
const char *condition = FindItemValue(*name, grp, default_grp);
|
||||
for (const auto &name : pp_lines) {
|
||||
const char *condition = FindItemValue(name, grp, default_grp);
|
||||
if (condition != nullptr) {
|
||||
output.Add("#", 1);
|
||||
output.Add(*name);
|
||||
output.Add(name);
|
||||
output.Add(" ", 1);
|
||||
output.Add(condition);
|
||||
output.Add("\n", 1);
|
||||
|
@ -306,31 +292,30 @@ static void DumpLine(IniItem *item, IniGroup *grp, IniGroup *default_grp, Output
|
|||
* Output all non-special sections through the template / template variable expansion system.
|
||||
* @param ifile Loaded INI data.
|
||||
*/
|
||||
static void DumpSections(IniLoadFile *ifile)
|
||||
static void DumpSections(const IniLoadFile &ifile)
|
||||
{
|
||||
static const char * const special_group_names[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, DEFAULTS_GROUP_NAME, TEMPLATES_GROUP_NAME, VALIDATION_GROUP_NAME, nullptr};
|
||||
static const auto special_group_names = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, DEFAULTS_GROUP_NAME, TEMPLATES_GROUP_NAME, VALIDATION_GROUP_NAME};
|
||||
|
||||
IniGroup *default_grp = ifile->GetGroup(DEFAULTS_GROUP_NAME, false);
|
||||
IniGroup *templates_grp = ifile->GetGroup(TEMPLATES_GROUP_NAME, false);
|
||||
IniGroup *validation_grp = ifile->GetGroup(VALIDATION_GROUP_NAME, false);
|
||||
const IniGroup *default_grp = ifile.GetGroup(DEFAULTS_GROUP_NAME);
|
||||
const IniGroup *templates_grp = ifile.GetGroup(TEMPLATES_GROUP_NAME);
|
||||
const IniGroup *validation_grp = ifile.GetGroup(VALIDATION_GROUP_NAME);
|
||||
if (templates_grp == nullptr) return;
|
||||
|
||||
/* Output every group, using its name as template name. */
|
||||
for (IniGroup *grp = ifile->group; grp != nullptr; grp = grp->next) {
|
||||
const char * const *sgn;
|
||||
for (sgn = special_group_names; *sgn != nullptr; sgn++) if (grp->name == *sgn) break;
|
||||
if (*sgn != nullptr) continue;
|
||||
for (const IniGroup &grp : ifile.groups) {
|
||||
/* Exclude special group names. */
|
||||
if (std::find(std::begin(special_group_names), std::end(special_group_names), grp.name) != std::end(special_group_names)) continue;
|
||||
|
||||
IniItem *template_item = templates_grp->GetItem(grp->name); // Find template value.
|
||||
const IniItem *template_item = templates_grp->GetItem(grp.name); // Find template value.
|
||||
if (template_item == nullptr || !template_item->value.has_value()) {
|
||||
FatalError("Cannot find template {}", grp->name);
|
||||
FatalError("Cannot find template {}", grp.name);
|
||||
}
|
||||
DumpLine(template_item, grp, default_grp, _stored_output);
|
||||
DumpLine(template_item, &grp, default_grp, _stored_output);
|
||||
|
||||
if (validation_grp != nullptr) {
|
||||
IniItem *validation_item = validation_grp->GetItem(grp->name); // Find template value.
|
||||
const IniItem *validation_item = validation_grp->GetItem(grp.name); // Find template value.
|
||||
if (validation_item != nullptr && validation_item->value.has_value()) {
|
||||
DumpLine(validation_item, grp, default_grp, _post_amble_output);
|
||||
DumpLine(validation_item, &grp, default_grp, _post_amble_output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -430,11 +415,14 @@ static const OptionData _opts[] = {
|
|||
*/
|
||||
static void ProcessIniFile(const char *fname)
|
||||
{
|
||||
IniLoadFile *ini_data = LoadIniFile(fname);
|
||||
DumpGroup(ini_data, PREAMBLE_GROUP_NAME);
|
||||
DumpSections(ini_data);
|
||||
DumpGroup(ini_data, POSTAMBLE_GROUP_NAME);
|
||||
delete ini_data;
|
||||
static const IniLoadFile::IniGroupNameList seq_groups = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME};
|
||||
|
||||
SettingsIniFile ini{{}, seq_groups};
|
||||
ini.LoadFromDisk(fname, NO_DIRECTORY);
|
||||
|
||||
DumpGroup(ini, PREAMBLE_GROUP_NAME);
|
||||
DumpSections(ini);
|
||||
DumpGroup(ini, POSTAMBLE_GROUP_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -98,7 +98,7 @@ SpriteFile &OpenCachedSpriteFile(const std::string &filename, Subdirectory subdi
|
|||
{
|
||||
SpriteFile *file = GetCachedSpriteFileByName(filename);
|
||||
if (file == nullptr) {
|
||||
file = _sprite_files.emplace_back(new SpriteFile(filename, subdir, palette_remap)).get();
|
||||
file = _sprite_files.insert(std::end(_sprite_files), std::make_unique<SpriteFile>(filename, subdir, palette_remap))->get();
|
||||
} else {
|
||||
file->SeekToBegin();
|
||||
}
|
||||
|
|
|
@ -518,16 +518,16 @@ CargoTypes GetEmptyMask(const Station *st)
|
|||
}
|
||||
|
||||
/**
|
||||
* Items contains the two cargo names that are to be accepted or rejected.
|
||||
* msg is the string id of the message to display.
|
||||
* Add news item for when a station changes which cargoes it accepts.
|
||||
* @param st Station of cargo change.
|
||||
* @param cargoes Bit mask of cargo types to list.
|
||||
* @param reject True iff the station rejects the cargo types.
|
||||
*/
|
||||
static void ShowRejectOrAcceptNews(const Station *st, uint num_items, CargoID *cargo, StringID msg)
|
||||
static void ShowRejectOrAcceptNews(const Station *st, CargoTypes cargoes, bool reject)
|
||||
{
|
||||
for (uint i = 0; i < num_items; i++) {
|
||||
SetDParam(i + 1, CargoSpec::Get(cargo[i])->name);
|
||||
}
|
||||
|
||||
SetDParam(0, st->index);
|
||||
SetDParam(1, cargoes);
|
||||
StringID msg = reject ? STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_LIST : STR_NEWS_STATION_NOW_ACCEPTS_CARGO_LIST;
|
||||
AddNewsItem(msg, NT_ACCEPTANCE, NF_INCOLOUR | NF_SMALL, NR_STATION, st->index);
|
||||
}
|
||||
|
||||
|
@ -651,41 +651,13 @@ void UpdateStationAcceptance(Station *st, bool show_msg)
|
|||
|
||||
/* show a message to report that the acceptance was changed? */
|
||||
if (show_msg && st->owner == _local_company && st->IsInUse()) {
|
||||
/* List of accept and reject strings for different number of
|
||||
* cargo types */
|
||||
static const StringID accept_msg[] = {
|
||||
STR_NEWS_STATION_NOW_ACCEPTS_CARGO,
|
||||
STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO,
|
||||
};
|
||||
static const StringID reject_msg[] = {
|
||||
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO,
|
||||
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO,
|
||||
};
|
||||
|
||||
/* Array of accepted and rejected cargo types */
|
||||
CargoID accepts[2] = { CT_INVALID, CT_INVALID };
|
||||
CargoID rejects[2] = { CT_INVALID, CT_INVALID };
|
||||
uint num_acc = 0;
|
||||
uint num_rej = 0;
|
||||
|
||||
/* Test each cargo type to see if its acceptance has changed */
|
||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||
if (HasBit(new_acc, i)) {
|
||||
if (!HasBit(old_acc, i) && num_acc < lengthof(accepts)) {
|
||||
/* New cargo is accepted */
|
||||
accepts[num_acc++] = i;
|
||||
}
|
||||
} else {
|
||||
if (HasBit(old_acc, i) && num_rej < lengthof(rejects)) {
|
||||
/* Old cargo is no longer accepted */
|
||||
rejects[num_rej++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Combine old and new masks to get changes */
|
||||
CargoTypes accepts = new_acc & ~old_acc;
|
||||
CargoTypes rejects = ~new_acc & old_acc;
|
||||
|
||||
/* Show news message if there are any changes */
|
||||
if (num_acc > 0) ShowRejectOrAcceptNews(st, num_acc, accepts, accept_msg[num_acc - 1]);
|
||||
if (num_rej > 0) ShowRejectOrAcceptNews(st, num_rej, rejects, reject_msg[num_rej - 1]);
|
||||
if (accepts != 0) ShowRejectOrAcceptNews(st, accepts, false);
|
||||
if (rejects != 0) ShowRejectOrAcceptNews(st, rejects, true);
|
||||
}
|
||||
|
||||
/* redraw the station view since acceptance changed */
|
||||
|
|
|
@ -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.emplace_back(new DropDownListStringItem(p->title, p->index, current_page));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(p->title, p->index, current_page));
|
||||
} else {
|
||||
/* No custom title => use a generic page title with page number. */
|
||||
SetDParam(0, page_num);
|
||||
list.emplace_back(new DropDownListStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page));
|
||||
}
|
||||
page_num++;
|
||||
}
|
||||
|
|
|
@ -528,8 +528,7 @@ void TextfileWindow::AfterLoadMarkdown()
|
|||
DropDownList list;
|
||||
for (size_t line : this->jumplist) {
|
||||
SetDParamStr(0, this->lines[line].text);
|
||||
DropDownListStringItem *item = new DropDownListStringItem(STR_TEXTFILE_JUMPLIST_ITEM, (int)line, false);
|
||||
list.emplace_back(item);
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_TEXTFILE_JUMPLIST_ITEM, (int)line, false));
|
||||
}
|
||||
ShowDropDownList(this, std::move(list), -1, widget);
|
||||
break;
|
||||
|
|
|
@ -207,7 +207,7 @@ static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count
|
|||
{
|
||||
DropDownList list;
|
||||
for (int i = 0; i < count; i++) {
|
||||
list.emplace_back(new DropDownListStringItem(string + i, i, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(string + i, i, false));
|
||||
}
|
||||
PopupMainToolbMenu(w, widget, std::move(list), 0);
|
||||
}
|
||||
|
@ -232,24 +232,24 @@ static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0)
|
|||
if (!_networking) break;
|
||||
|
||||
/* Add the client list button for the companies menu */
|
||||
list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false));
|
||||
|
||||
if (_local_company != COMPANY_SPECTATOR) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, false));
|
||||
}
|
||||
break;
|
||||
case WID_TN_STORY:
|
||||
list.emplace_back(new DropDownListStringItem(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR, false));
|
||||
break;
|
||||
|
||||
case WID_TN_GOAL:
|
||||
list.emplace_back(new DropDownListStringItem(STR_GOALS_SPECTATOR, CTMN_SPECTATOR, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GOALS_SPECTATOR, CTMN_SPECTATOR, false));
|
||||
break;
|
||||
}
|
||||
|
||||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
if (!Company::IsValidID(c)) continue;
|
||||
list.emplace_back(new DropDownListCompanyItem(c, false, HasBit(grey, c)));
|
||||
list.push_back(std::make_unique<DropDownListCompanyItem>(c, false, HasBit(grey, c)));
|
||||
}
|
||||
|
||||
PopupMainToolbMenu(w, widget, std::move(list), _local_company == COMPANY_SPECTATOR ? (widget == WID_TN_COMPANIES ? CTMN_CLIENT_LIST : CTMN_SPECTATOR) : (int)_local_company);
|
||||
|
@ -325,27 +325,27 @@ enum OptionMenuEntries {
|
|||
static CallBackFunction ToolbarOptionsClick(Window *w)
|
||||
{
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS, false));
|
||||
/* 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.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_AI_SETTINGS, OME_AI_SETTINGS, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS, OME_GAMESCRIPT_SETTINGS, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_SETTINGS_MENU_AI_SETTINGS, OME_AI_SETTINGS, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS, OME_GAMESCRIPT_SETTINGS, false));
|
||||
}
|
||||
list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false));
|
||||
list.emplace_back(new DropDownListItem(-1, false));
|
||||
list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)));
|
||||
list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)));
|
||||
list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)));
|
||||
list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)));
|
||||
list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS)));
|
||||
list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)));
|
||||
list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)));
|
||||
list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)));
|
||||
list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false));
|
||||
list.push_back(std::make_unique<DropDownListItem>(-1, false));
|
||||
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)));
|
||||
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)));
|
||||
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)));
|
||||
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)));
|
||||
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS)));
|
||||
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)));
|
||||
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)));
|
||||
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)));
|
||||
list.push_back(std::make_unique<DropDownListCheckedItem>(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)));
|
||||
|
||||
ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, true);
|
||||
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
|
||||
|
@ -475,10 +475,10 @@ enum MapMenuEntries {
|
|||
static CallBackFunction ToolbarMapClick(Window *w)
|
||||
{
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false));
|
||||
PopupMainToolbMenu(w, WID_TN_SMALL_MAP, std::move(list), 0);
|
||||
return CBF_NONE;
|
||||
}
|
||||
|
@ -486,11 +486,11 @@ static CallBackFunction ToolbarMapClick(Window *w)
|
|||
static CallBackFunction ToolbarScenMapTownDir(Window *w)
|
||||
{
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY, false));
|
||||
PopupMainToolbMenu(w, WID_TE_SMALL_MAP, std::move(list), 0);
|
||||
return CBF_NONE;
|
||||
}
|
||||
|
@ -693,13 +693,13 @@ static const int LTMN_HIGHSCORE = -9; ///< Show highscrore table
|
|||
static void AddDropDownLeagueTableOptions(DropDownList &list) {
|
||||
if (LeagueTable::GetNumItems() > 0) {
|
||||
for (LeagueTable *lt : LeagueTable::Iterate()) {
|
||||
list.emplace_back(new DropDownListStringItem(lt->title, lt->index, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(lt->title, lt->index, false));
|
||||
}
|
||||
} else {
|
||||
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING, LTMN_PERFORMANCE_RATING, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING, LTMN_PERFORMANCE_RATING, false));
|
||||
if (!_networking) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_HIGHSCORE, LTMN_HIGHSCORE, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GRAPH_MENU_HIGHSCORE, LTMN_HIGHSCORE, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -708,12 +708,12 @@ static CallBackFunction ToolbarGraphsClick(Window *w)
|
|||
{
|
||||
DropDownList list;
|
||||
|
||||
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, GRMN_OPERATING_PROFIT_GRAPH, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_INCOME_GRAPH, GRMN_INCOME_GRAPH, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH, GRMN_DELIVERED_CARGO_GRAPH, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH, GRMN_PERFORMANCE_HISTORY_GRAPH, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_COMPANY_VALUE_GRAPH, GRMN_COMPANY_VALUE_GRAPH, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_CARGO_PAYMENT_RATES, GRMN_CARGO_PAYMENT_RATES, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, GRMN_OPERATING_PROFIT_GRAPH, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GRAPH_MENU_INCOME_GRAPH, GRMN_INCOME_GRAPH, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH, GRMN_DELIVERED_CARGO_GRAPH, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH, GRMN_PERFORMANCE_HISTORY_GRAPH, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GRAPH_MENU_COMPANY_VALUE_GRAPH, GRMN_COMPANY_VALUE_GRAPH, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GRAPH_MENU_CARGO_PAYMENT_RATES, GRMN_CARGO_PAYMENT_RATES, false));
|
||||
|
||||
if (_toolbar_mode != TB_NORMAL) AddDropDownLeagueTableOptions(list);
|
||||
|
||||
|
@ -974,7 +974,7 @@ static CallBackFunction MenuClickBuildTram(int index)
|
|||
static CallBackFunction ToolbarBuildWaterClick(Window *w)
|
||||
{
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListIconItem(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0, false));
|
||||
list.push_back(std::make_unique<DropDownListIconItem>(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0, false));
|
||||
ShowDropDownList(w, std::move(list), 0, WID_TN_WATER, 140, true);
|
||||
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
|
||||
return CBF_NONE;
|
||||
|
@ -996,7 +996,7 @@ static CallBackFunction MenuClickBuildWater(int)
|
|||
static CallBackFunction ToolbarBuildAirClick(Window *w)
|
||||
{
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListIconItem(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0, false));
|
||||
list.push_back(std::make_unique<DropDownListIconItem>(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0, false));
|
||||
ShowDropDownList(w, std::move(list), 0, WID_TN_AIR, 140, true);
|
||||
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
|
||||
return CBF_NONE;
|
||||
|
@ -1018,9 +1018,9 @@ static CallBackFunction MenuClickBuildAir(int)
|
|||
static CallBackFunction ToolbarForestClick(Window *w)
|
||||
{
|
||||
DropDownList list;
|
||||
list.emplace_back(new DropDownListIconItem(SPR_IMG_LANDSCAPING, PAL_NONE, STR_LANDSCAPING_MENU_LANDSCAPING, 0, false));
|
||||
list.emplace_back(new DropDownListIconItem(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1, false));
|
||||
list.emplace_back(new DropDownListIconItem(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2, false));
|
||||
list.push_back(std::make_unique<DropDownListIconItem>(SPR_IMG_LANDSCAPING, PAL_NONE, STR_LANDSCAPING_MENU_LANDSCAPING, 0, false));
|
||||
list.push_back(std::make_unique<DropDownListIconItem>(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1, false));
|
||||
list.push_back(std::make_unique<DropDownListIconItem>(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2, false));
|
||||
ShowDropDownList(w, std::move(list), 0, WID_TN_LANDSCAPE, 100, true);
|
||||
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
|
||||
return CBF_NONE;
|
||||
|
|
|
@ -447,14 +447,15 @@ void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t v
|
|||
|
||||
/* Indent the total cargo capacity details */
|
||||
Rect ir = r.Indent(WidgetDimensions::scaled.hsep_indent, rtl);
|
||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||
if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) {
|
||||
SetDParam(0, i); // {CARGO} #1
|
||||
SetDParam(1, act_cargo[i]); // {CARGO} #2
|
||||
SetDParam(2, i); // {SHORTCARGO} #1
|
||||
SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2
|
||||
for (const CargoSpec *cs : _sorted_cargo_specs) {
|
||||
CargoID cid = cs->Index();
|
||||
if (max_cargo[cid] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) {
|
||||
SetDParam(0, cid); // {CARGO} #1
|
||||
SetDParam(1, act_cargo[cid]); // {CARGO} #2
|
||||
SetDParam(2, cid); // {SHORTCARGO} #1
|
||||
SetDParam(3, max_cargo[cid]); // {SHORTCARGO} #2
|
||||
SetDParam(4, _settings_game.vehicle.freight_trains);
|
||||
DrawString(ir.left, ir.right, y + text_y_offset, FreightWagonMult(i) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY);
|
||||
DrawString(ir.left, ir.right, y + text_y_offset, FreightWagonMult(cid) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY);
|
||||
y += line_height;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -399,15 +399,15 @@ DropDownList BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplac
|
|||
{
|
||||
DropDownList list;
|
||||
|
||||
if (show_autoreplace) list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false));
|
||||
list.emplace_back(new DropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false));
|
||||
if (show_autoreplace) list.push_back(std::make_unique<DropDownListStringItem>(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false));
|
||||
|
||||
if (show_group) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false));
|
||||
} else if (show_create) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_CREATE_GROUP, ADI_CREATE_GROUP, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_VEHICLE_LIST_CREATE_GROUP, ADI_CREATE_GROUP, false));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -550,18 +550,18 @@ struct RefitOption {
|
|||
}
|
||||
};
|
||||
|
||||
typedef std::vector<RefitOption> SubtypeList; ///< List of refit subtypes associated to a cargo.
|
||||
using RefitOptions = std::map<CargoID, std::vector<RefitOption>, CargoIDComparator>; ///< Available refit options (subtype and string) associated with each cargo type.
|
||||
|
||||
/**
|
||||
* Draw the list of available refit options for a consist and highlight the selected refit option (if any).
|
||||
* @param list List of subtype options for each (sorted) cargo.
|
||||
* @param sel Selected refit cargo-type in the window
|
||||
* @param refits Available refit options for each (sorted) cargo.
|
||||
* @param sel Selected refit option in the window
|
||||
* @param pos Position of the selected item in caller widow
|
||||
* @param rows Number of rows(capacity) in caller window
|
||||
* @param delta Step height in caller window
|
||||
* @param r Rectangle of the matrix widget.
|
||||
*/
|
||||
static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int sel[2], uint pos, uint rows, uint delta, const Rect &r)
|
||||
static void DrawVehicleRefitWindow(const RefitOptions &refits, const RefitOption *sel, uint pos, uint rows, uint delta, const Rect &r)
|
||||
{
|
||||
Rect ir = r.Shrink(WidgetDimensions::scaled.matrix);
|
||||
uint current = 0;
|
||||
|
@ -578,12 +578,13 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int
|
|||
Rect tr = ir.Indent(iconwidth + WidgetDimensions::scaled.hsep_wide, rtl);
|
||||
|
||||
/* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */
|
||||
for (uint i = 0; current < pos + rows && i < NUM_CARGO; i++) {
|
||||
for (uint j = 0; current < pos + rows && j < list[i].size(); j++) {
|
||||
const RefitOption &refit = list[i][j];
|
||||
for (const auto &pair : refits) {
|
||||
bool has_subtypes = pair.second.size() > 1;
|
||||
for (const RefitOption &refit : pair.second) {
|
||||
if (current >= pos + rows) break;
|
||||
|
||||
/* Hide subtypes if sel[0] does not match */
|
||||
if (sel[0] != (int)i && refit.subtype != 0xFF) continue;
|
||||
/* Hide subtypes if selected cargo type does not match */
|
||||
if ((sel == nullptr || sel->cargo != refit.cargo) && refit.subtype != UINT8_MAX) continue;
|
||||
|
||||
/* Refit options with a position smaller than pos don't have to be drawn. */
|
||||
if (current < pos) {
|
||||
|
@ -591,19 +592,19 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int
|
|||
continue;
|
||||
}
|
||||
|
||||
if (list[i].size() > 1) {
|
||||
if (refit.subtype != 0xFF) {
|
||||
if (has_subtypes) {
|
||||
if (refit.subtype != UINT8_MAX) {
|
||||
/* Draw tree lines */
|
||||
int ycenter = tr.top + FONT_HEIGHT_NORMAL / 2;
|
||||
GfxDrawLine(iconcenter, tr.top - WidgetDimensions::scaled.matrix.top, iconcenter, j == list[i].size() - 1 ? ycenter : tr.top - WidgetDimensions::scaled.matrix.top + delta - 1, linecolour);
|
||||
GfxDrawLine(iconcenter, tr.top - WidgetDimensions::scaled.matrix.top, iconcenter, (&refit == &pair.second.back()) ? ycenter : tr.top - WidgetDimensions::scaled.matrix.top + delta - 1, linecolour);
|
||||
GfxDrawLine(iconcenter, ycenter, iconinner, ycenter, linecolour);
|
||||
} else {
|
||||
/* Draw expand/collapse icon */
|
||||
DrawSprite(sel[0] == (int)i ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, tr.top + (FONT_HEIGHT_NORMAL - iconheight) / 2);
|
||||
DrawSprite((sel != nullptr && sel->cargo == refit.cargo) ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, tr.top + (FONT_HEIGHT_NORMAL - iconheight) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
TextColour colour = (sel[0] == (int)i && (uint)sel[1] == j) ? TC_WHITE : TC_BLACK;
|
||||
TextColour colour = (sel != nullptr && sel->cargo == refit.cargo && sel->subtype == refit.subtype) ? TC_WHITE : TC_BLACK;
|
||||
/* Get the cargo name. */
|
||||
SetDParam(0, CargoSpec::Get(refit.cargo)->name);
|
||||
SetDParam(1, refit.string);
|
||||
|
@ -617,9 +618,8 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int
|
|||
|
||||
/** Refit cargo window. */
|
||||
struct RefitWindow : public Window {
|
||||
int sel[2]; ///< Index in refit options, sel[0] == -1 if nothing is selected.
|
||||
RefitOption *cargo; ///< Refit option selected by #sel.
|
||||
SubtypeList list[NUM_CARGO]; ///< List of refit subtypes available for each sorted cargo.
|
||||
const RefitOption *selected_refit; ///< Selected refit option.
|
||||
RefitOptions refit_list; ///< List of refit subtypes available for each sorted cargo.
|
||||
VehicleOrderID order; ///< If not #INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly).
|
||||
uint information_width; ///< Width required for correctly displaying all cargoes in the information panel.
|
||||
Scrollbar *vscroll; ///< The main scrollbar.
|
||||
|
@ -638,7 +638,12 @@ struct RefitWindow : public Window {
|
|||
*/
|
||||
void BuildRefitList()
|
||||
{
|
||||
for (uint i = 0; i < NUM_CARGO; i++) this->list[i].clear();
|
||||
/* Store the currently selected RefitOption. */
|
||||
std::optional<RefitOption> current_refit_option;
|
||||
if (this->selected_refit != nullptr) current_refit_option = *(this->selected_refit);
|
||||
this->selected_refit = nullptr;
|
||||
|
||||
this->refit_list.clear();
|
||||
Vehicle *v = Vehicle::Get(this->window_number);
|
||||
|
||||
/* Check only the selected vehicles. */
|
||||
|
@ -657,19 +662,16 @@ struct RefitWindow : public Window {
|
|||
if (this->auto_refit && !HasBit(e->info.misc_flags, EF_AUTO_REFIT)) continue;
|
||||
|
||||
/* Loop through all cargoes in the refit mask */
|
||||
int current_index = 0;
|
||||
for (const auto &cs : _sorted_cargo_specs) {
|
||||
CargoID cid = cs->Index();
|
||||
/* Skip cargo type if it's not listed */
|
||||
if (!HasBit(cmask, cid)) {
|
||||
current_index++;
|
||||
continue;
|
||||
}
|
||||
if (!HasBit(cmask, cid)) continue;
|
||||
|
||||
bool first_vehicle = this->list[current_index].size() == 0;
|
||||
auto &list = this->refit_list[cid];
|
||||
bool first_vehicle = list.size() == 0;
|
||||
if (first_vehicle) {
|
||||
/* Keeping the current subtype is always an option. It also serves as the option in case of no subtypes */
|
||||
this->list[current_index].push_back({cid, 0xFF, STR_EMPTY});
|
||||
list.push_back({cid, UINT8_MAX, STR_EMPTY});
|
||||
}
|
||||
|
||||
/* Check the vehicle's callback mask for cargo suffixes.
|
||||
|
@ -701,16 +703,15 @@ struct RefitWindow : public Window {
|
|||
option.cargo = cid;
|
||||
option.subtype = refit_cyc;
|
||||
option.string = subtype;
|
||||
include(this->list[current_index], option);
|
||||
include(list, option);
|
||||
} else {
|
||||
/* Intersect the subtypes of earlier vehicles with the subtypes of this vehicle */
|
||||
if (subtype == STR_EMPTY) {
|
||||
/* No more subtypes for this vehicle, delete all subtypes >= refit_cyc */
|
||||
SubtypeList &l = this->list[current_index];
|
||||
/* 0xFF item is in front, other subtypes are sorted. So just truncate the list in the right spot */
|
||||
for (uint i = 1; i < l.size(); i++) {
|
||||
if (l[i].subtype >= refit_cyc) {
|
||||
l.resize(i);
|
||||
/* UINT8_MAX item is in front, other subtypes are sorted. So just truncate the list in the right spot */
|
||||
for (uint i = 1; i < list.size(); i++) {
|
||||
if (list[i].subtype >= refit_cyc) {
|
||||
list.resize(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -718,11 +719,10 @@ struct RefitWindow : public Window {
|
|||
} else {
|
||||
/* Check whether the subtype matches with the subtype of earlier vehicles. */
|
||||
uint pos = 1;
|
||||
SubtypeList &l = this->list[current_index];
|
||||
while (pos < l.size() && l[pos].subtype != refit_cyc) pos++;
|
||||
if (pos < l.size() && l[pos].string != subtype) {
|
||||
while (pos < list.size() && list[pos].subtype != refit_cyc) pos++;
|
||||
if (pos < list.size() && list[pos].string != subtype) {
|
||||
/* String mismatch, remove item keeping the order */
|
||||
l.erase(l.begin() + pos);
|
||||
list.erase(list.begin() + pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -736,9 +736,23 @@ struct RefitWindow : public Window {
|
|||
v->First()->InvalidateNewGRFCache();
|
||||
v->InvalidateNewGRFCache();
|
||||
}
|
||||
current_index++;
|
||||
}
|
||||
} while (v->IsGroundVehicle() && (v = v->Next()) != nullptr);
|
||||
|
||||
/* Restore the previously selected RefitOption. */
|
||||
if (current_refit_option.has_value()) {
|
||||
for (const auto &pair : this->refit_list) {
|
||||
for (const auto &refit : pair.second) {
|
||||
if (refit.cargo == current_refit_option->cargo && refit.subtype == current_refit_option->subtype) {
|
||||
this->selected_refit = &refit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this->selected_refit != nullptr) break;
|
||||
}
|
||||
}
|
||||
|
||||
this->SetWidgetDisabledState(WID_VR_REFIT, this->selected_refit == nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -746,24 +760,22 @@ struct RefitWindow : public Window {
|
|||
*/
|
||||
void RefreshScrollbar()
|
||||
{
|
||||
uint scroll_row = 0;
|
||||
uint row = 0;
|
||||
size_t scroll_row = 0;
|
||||
size_t rows = 0;
|
||||
CargoID cargo = this->selected_refit == nullptr ? (CargoID)CT_INVALID : this->selected_refit->cargo;
|
||||
|
||||
for (uint i = 0; i < NUM_CARGO; i++) {
|
||||
for (uint j = 0; j < this->list[i].size(); j++) {
|
||||
const RefitOption &refit = this->list[i][j];
|
||||
|
||||
/* Hide subtypes if sel[0] does not match */
|
||||
if (this->sel[0] != (int)i && refit.subtype != 0xFF) continue;
|
||||
|
||||
if (this->sel[0] == (int)i && (uint)this->sel[1] == j) scroll_row = row;
|
||||
|
||||
row++;
|
||||
for (const auto &pair : this->refit_list) {
|
||||
if (pair.first == cargo) {
|
||||
/* selected_refit points to an element in the vector so no need to search for it. */
|
||||
scroll_row = rows + (this->selected_refit - pair.second.data());
|
||||
rows += pair.second.size();
|
||||
} else {
|
||||
rows++; /* Unselected cargo type is collapsed into one row. */
|
||||
}
|
||||
}
|
||||
|
||||
this->vscroll->SetCount(row);
|
||||
if (scroll_row < row) this->vscroll->ScrollTowards(scroll_row);
|
||||
this->vscroll->SetCount(rows);
|
||||
this->vscroll->ScrollTowards(static_cast<int>(scroll_row));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -774,45 +786,24 @@ struct RefitWindow : public Window {
|
|||
{
|
||||
uint row = 0;
|
||||
|
||||
for (uint i = 0; i < NUM_CARGO; i++) {
|
||||
for (uint j = 0; j < this->list[i].size(); j++) {
|
||||
const RefitOption &refit = this->list[i][j];
|
||||
|
||||
/* Hide subtypes if sel[0] does not match */
|
||||
if (this->sel[0] != (int)i && refit.subtype != 0xFF) continue;
|
||||
|
||||
for (const auto &pair : refit_list) {
|
||||
for (const RefitOption &refit : pair.second) {
|
||||
if (row == click_row) {
|
||||
this->sel[0] = i;
|
||||
this->sel[1] = j;
|
||||
this->selected_refit = &refit;
|
||||
return;
|
||||
}
|
||||
|
||||
row++;
|
||||
/* If this cargo type is not already selected then its subtypes are not visible, so skip the rest. */
|
||||
if (this->selected_refit == nullptr || this->selected_refit->cargo != refit.cargo) break;
|
||||
}
|
||||
}
|
||||
|
||||
this->sel[0] = -1;
|
||||
this->sel[1] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the #RefitOption placed in the selected index.
|
||||
* @return Pointer to the #RefitOption currently in use.
|
||||
*/
|
||||
RefitOption *GetRefitOption()
|
||||
{
|
||||
if (this->sel[0] < 0) return nullptr;
|
||||
|
||||
SubtypeList &l = this->list[this->sel[0]];
|
||||
if ((uint)this->sel[1] >= l.size()) return nullptr;
|
||||
|
||||
return &l[this->sel[1]];
|
||||
/* No selection made */
|
||||
this->selected_refit = nullptr;
|
||||
}
|
||||
|
||||
RefitWindow(WindowDesc *desc, const Vehicle *v, VehicleOrderID order, bool auto_refit) : Window(desc)
|
||||
{
|
||||
this->sel[0] = -1;
|
||||
this->sel[1] = 0;
|
||||
this->auto_refit = auto_refit;
|
||||
this->order = order;
|
||||
this->CreateNestedTree();
|
||||
|
@ -830,37 +821,13 @@ struct RefitWindow : public Window {
|
|||
this->FinishInitNested(v->index);
|
||||
this->owner = v->owner;
|
||||
|
||||
this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0);
|
||||
this->SetWidgetDisabledState(WID_VR_REFIT, this->selected_refit == nullptr);
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
if (this->cargo != nullptr) {
|
||||
/* Store the RefitOption currently in use. */
|
||||
RefitOption current_refit_option = *(this->cargo);
|
||||
|
||||
/* Rebuild the refit list */
|
||||
this->BuildRefitList();
|
||||
this->sel[0] = -1;
|
||||
this->sel[1] = 0;
|
||||
this->cargo = nullptr;
|
||||
for (uint i = 0; this->cargo == nullptr && i < NUM_CARGO; i++) {
|
||||
for (uint j = 0; j < list[i].size(); j++) {
|
||||
if (list[i][j] == current_refit_option) {
|
||||
this->sel[0] = i;
|
||||
this->sel[1] = j;
|
||||
this->cargo = &list[i][j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0);
|
||||
this->RefreshScrollbar();
|
||||
} else {
|
||||
/* Rebuild the refit list */
|
||||
this->OnInvalidateData(VIWD_CONSIST_CHANGED);
|
||||
}
|
||||
/* (Re)build the refit list */
|
||||
this->OnInvalidateData(VIWD_CONSIST_CHANGED);
|
||||
}
|
||||
|
||||
void OnPaint() override
|
||||
|
@ -913,14 +880,14 @@ struct RefitWindow : public Window {
|
|||
* @return INVALID_STRING_ID if there is no capacity. StringID to use in any other case.
|
||||
* @post String parameters have been set.
|
||||
*/
|
||||
StringID GetCapacityString(RefitOption *option) const
|
||||
StringID GetCapacityString(const RefitOption &option) const
|
||||
{
|
||||
assert(_current_company == _local_company);
|
||||
auto [cost, refit_capacity, mail_capacity, cargo_capacities] = Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, this->selected_vehicle, option->cargo, option->subtype, this->auto_refit, false, this->num_vehicles);
|
||||
auto [cost, refit_capacity, mail_capacity, cargo_capacities] = Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, this->selected_vehicle, option.cargo, option.subtype, this->auto_refit, false, this->num_vehicles);
|
||||
|
||||
if (cost.Failed()) return INVALID_STRING_ID;
|
||||
|
||||
SetDParam(0, option->cargo);
|
||||
SetDParam(0, option.cargo);
|
||||
SetDParam(1, refit_capacity);
|
||||
|
||||
Money money = cost.GetCost();
|
||||
|
@ -1021,12 +988,12 @@ struct RefitWindow : public Window {
|
|||
}
|
||||
|
||||
case WID_VR_MATRIX:
|
||||
DrawVehicleRefitWindow(this->list, this->sel, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->resize.step_height, r);
|
||||
DrawVehicleRefitWindow(this->refit_list, this->selected_refit, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->resize.step_height, r);
|
||||
break;
|
||||
|
||||
case WID_VR_INFO:
|
||||
if (this->cargo != nullptr) {
|
||||
StringID string = this->GetCapacityString(this->cargo);
|
||||
if (this->selected_refit != nullptr) {
|
||||
StringID string = this->GetCapacityString(*this->selected_refit);
|
||||
if (string != INVALID_STRING_ID) {
|
||||
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), string);
|
||||
}
|
||||
|
@ -1061,9 +1028,9 @@ struct RefitWindow : public Window {
|
|||
uint max_width = 0;
|
||||
|
||||
/* Check the width of all cargo information strings. */
|
||||
for (uint i = 0; i < NUM_CARGO; i++) {
|
||||
for (uint j = 0; j < this->list[i].size(); j++) {
|
||||
StringID string = this->GetCapacityString(&list[i][j]);
|
||||
for (const auto &list : this->refit_list) {
|
||||
for (const RefitOption &refit : list.second) {
|
||||
StringID string = this->GetCapacityString(refit);
|
||||
if (string != INVALID_STRING_ID) {
|
||||
Dimension dim = GetStringBoundingBox(string);
|
||||
max_width = std::max(dim.width, max_width);
|
||||
|
@ -1080,7 +1047,6 @@ struct RefitWindow : public Window {
|
|||
|
||||
case 1: // A new cargo has been selected.
|
||||
if (!gui_scope) break;
|
||||
this->cargo = GetRefitOption();
|
||||
this->RefreshScrollbar();
|
||||
break;
|
||||
}
|
||||
|
@ -1168,7 +1134,7 @@ struct RefitWindow : public Window {
|
|||
|
||||
case WID_VR_MATRIX: { // listbox
|
||||
this->SetSelection(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_VR_MATRIX));
|
||||
this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0);
|
||||
this->SetWidgetDisabledState(WID_VR_REFIT, this->selected_refit == nullptr);
|
||||
this->InvalidateData(1);
|
||||
|
||||
if (click_count == 1) break;
|
||||
|
@ -1176,14 +1142,14 @@ struct RefitWindow : public Window {
|
|||
}
|
||||
|
||||
case WID_VR_REFIT: // refit button
|
||||
if (this->cargo != nullptr) {
|
||||
if (this->selected_refit != nullptr) {
|
||||
const Vehicle *v = Vehicle::Get(this->window_number);
|
||||
|
||||
if (this->order == INVALID_VEH_ORDER_ID) {
|
||||
bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX;
|
||||
if (Command<CMD_REFIT_VEHICLE>::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo, this->cargo->subtype, false, false, this->num_vehicles) && delete_window) this->Close();
|
||||
if (Command<CMD_REFIT_VEHICLE>::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->selected_refit->cargo, this->selected_refit->subtype, false, false, this->num_vehicles) && delete_window) this->Close();
|
||||
} else {
|
||||
if (Command<CMD_ORDER_REFIT>::Post(v->tile, v->index, this->order, this->cargo->cargo)) this->Close();
|
||||
if (Command<CMD_ORDER_REFIT>::Post(v->tile, v->index, this->order, this->selected_refit->cargo)) this->Close();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -464,7 +464,7 @@ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int butt
|
|||
|
||||
for (uint i = 0; strings[i] != INVALID_STRING_ID; i++) {
|
||||
if (!HasBit(hidden_mask, i)) {
|
||||
list.emplace_back(new DropDownListStringItem(strings[i], i, HasBit(disabled_mask, i)));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(strings[i], i, HasBit(disabled_mask, i)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue