From 13789d17037c1a3a2d7a90ee76e36cd9779a1fd8 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 30 May 2023 22:35:00 +0200 Subject: [PATCH 01/11] Codechange: use std::string for FiosIsValidFile --- src/fileio.cpp | 2 +- src/fios.cpp | 4 ++-- src/os/os2/os2.cpp | 8 +++----- src/os/unix/unix.cpp | 15 +++++---------- src/os/windows/win32.cpp | 2 +- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/fileio.cpp b/src/fileio.cpp index 92707b58e4..13b0e26f5b 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -68,7 +68,7 @@ TarFileList _tar_filelist[NUM_SUBDIRS]; typedef std::map TarLinkList; static TarLinkList _tar_linklist[NUM_SUBDIRS]; ///< List of directory links -extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb); +extern bool FiosIsValidFile(const std::string &path, const struct dirent *ent, struct stat *sb); /** * Checks whether the given search path is a valid search path diff --git a/src/fios.cpp b/src/fios.cpp index f5444fdb0b..2f33f40cfc 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -36,7 +36,7 @@ SortingBits _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING; /* OS-specific functions are taken from their respective files (win32/unix/os2 .c) */ extern bool FiosIsRoot(const char *path); -extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb); +extern bool FiosIsValidFile(const std::string &path, const struct dirent *ent, struct stat *sb); extern bool FiosIsHiddenFile(const struct dirent *ent); extern void FiosGetDrives(FileList &file_list); extern bool FiosGetDiskFreeSpace(const char *path, uint64 *tot); @@ -381,7 +381,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c std::string d_name = FS2OTTD(dirent->d_name); /* found file must be directory, but not '.' or '..' */ - if (FiosIsValidFile(_fios_path->c_str(), dirent, &sb) && S_ISDIR(sb.st_mode) && + if (FiosIsValidFile(*_fios_path, dirent, &sb) && S_ISDIR(sb.st_mode) && (!FiosIsHiddenFile(dirent) || StrStartsWithIgnoreCase(PERSONAL_DIR, d_name)) && d_name != "." && d_name != "..") { fios = &file_list.emplace_back(); diff --git a/src/os/os2/os2.cpp b/src/os/os2/os2.cpp index 235478ff27..e3913d7289 100644 --- a/src/os/os2/os2.cpp +++ b/src/os/os2/os2.cpp @@ -120,12 +120,10 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) #endif } -bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb) +bool FiosIsValidFile(const std::string &path, const struct dirent *ent, struct stat *sb) { - char filename[MAX_PATH]; - - snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, ent->d_name); - return stat(filename, sb) == 0; + std::string filename = fmt::format("{}" PATHSEP "{}", path, ent->d_name); + return stat(filename.c_str(), sb) == 0; } bool FiosIsHiddenFile(const struct dirent *ent) diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index 8fa259454b..0f18a977e1 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -86,18 +86,13 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) return true; } -bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb) +bool FiosIsValidFile(const std::string &path, const struct dirent *ent, struct stat *sb) { - char filename[MAX_PATH]; - int res; - assert(path[strlen(path) - 1] == PATHSEPCHAR); - if (strlen(path) > 2) assert(path[strlen(path) - 2] != PATHSEPCHAR); - res = seprintf(filename, lastof(filename), "%s%s", path, ent->d_name); + assert(path.back() == PATHSEPCHAR); + if (path.size() > 2) assert(path[path.size() - 2] != PATHSEPCHAR); + std::string filename = fmt::format("{}{}", path, ent->d_name); - /* Could we fully concatenate the path and filename? */ - if (res >= (int)lengthof(filename) || res < 0) return false; - - return stat(filename, sb) == 0; + return stat(filename.c_str(), sb) == 0; } bool FiosIsHiddenFile(const struct dirent *ent) diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index affa3c9dc9..54bf06249f 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -190,7 +190,7 @@ void FiosGetDrives(FileList &file_list) } } -bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb) +bool FiosIsValidFile(const std::string &path, const struct dirent *ent, struct stat *sb) { /* hectonanoseconds between Windows and POSIX epoch */ static const int64 posix_epoch_hns = 0x019DB1DED53E8000LL; From f2e704b9a7805e201a2a04781f1b1cd0c751ecc0 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 30 May 2023 22:37:33 +0200 Subject: [PATCH 02/11] Codechange: use std::string for FiosIsRoot --- src/fios.cpp | 4 ++-- src/os/os2/os2.cpp | 4 ++-- src/os/unix/unix.cpp | 4 ++-- src/os/windows/win32.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/fios.cpp b/src/fios.cpp index 2f33f40cfc..5a9e30dbb6 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -35,7 +35,7 @@ static std::string *_fios_path = nullptr; SortingBits _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING; /* OS-specific functions are taken from their respective files (win32/unix/os2 .c) */ -extern bool FiosIsRoot(const char *path); +extern bool FiosIsRoot(const std::string &path); extern bool FiosIsValidFile(const std::string &path, const struct dirent *ent, struct stat *sb); extern bool FiosIsHiddenFile(const struct dirent *ent); extern void FiosGetDrives(FileList &file_list); @@ -366,7 +366,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c assert(_fios_path != nullptr); /* A parent directory link exists if we are not in the root directory */ - if (!FiosIsRoot(_fios_path->c_str())) { + if (!FiosIsRoot(*_fios_path)) { fios = &file_list.emplace_back(); fios->type = FIOS_TYPE_PARENT; fios->mtime = 0; diff --git a/src/os/os2/os2.cpp b/src/os/os2/os2.cpp index e3913d7289..bc7ffdca99 100644 --- a/src/os/os2/os2.cpp +++ b/src/os/os2/os2.cpp @@ -36,9 +36,9 @@ # include #endif -bool FiosIsRoot(const char *file) +bool FiosIsRoot(const std::string &file) { - return file[3] == '\0'; + return file.size() == 3; // C:\... } void FiosGetDrives(FileList &file_list) diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index 0f18a977e1..aa3c443e15 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -57,9 +57,9 @@ #include "../../safeguards.h" -bool FiosIsRoot(const char *path) +bool FiosIsRoot(const std::string &path) { - return path[1] == '\0'; + return path == PATHSEP; } void FiosGetDrives(FileList &file_list) diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 54bf06249f..caf968f31e 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -168,9 +168,9 @@ int closedir(DIR *d) return 0; } -bool FiosIsRoot(const char *file) +bool FiosIsRoot(const std::string &file) { - return file[3] == '\0'; // C:\... + return file.size() == 3; // C:\... } void FiosGetDrives(FileList &file_list) From 324c43eeb2654fa689c9e324080d02f62393a142 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 30 May 2023 22:38:55 +0200 Subject: [PATCH 03/11] Codechange: let FiosGetDiskFreeSpace only return disk space and split FiosGetCurrentPath off --- src/console_cmds.cpp | 5 +---- src/fios.cpp | 12 +++--------- src/fios.h | 3 ++- src/fios_gui.cpp | 12 ++++++------ src/os/os2/os2.cpp | 25 +++++++------------------ src/os/unix/unix.cpp | 13 ++++--------- src/os/windows/win32.cpp | 7 ++++--- 7 files changed, 27 insertions(+), 50 deletions(-) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 1df9541384..5cf8b1c958 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -514,8 +514,6 @@ DEF_CONSOLE_CMD(ConChangeDirectory) DEF_CONSOLE_CMD(ConPrintWorkingDirectory) { - const char *path; - if (argc == 0) { IConsolePrint(CC_HELP, "Print out the current working directory. Usage: 'pwd'."); return true; @@ -525,8 +523,7 @@ DEF_CONSOLE_CMD(ConPrintWorkingDirectory) _console_file_list.ValidateFileList(true); _console_file_list.InvalidateFileList(); - FiosGetDescText(&path, nullptr); - IConsolePrint(CC_DEFAULT, path); + IConsolePrint(CC_DEFAULT, FiosGetCurrentPath()); return true; } diff --git a/src/fios.cpp b/src/fios.cpp index 5a9e30dbb6..118c6ed5ed 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -39,7 +39,6 @@ extern bool FiosIsRoot(const std::string &path); extern bool FiosIsValidFile(const std::string &path, const struct dirent *ent, struct stat *sb); extern bool FiosIsHiddenFile(const struct dirent *ent); extern void FiosGetDrives(FileList &file_list); -extern bool FiosGetDiskFreeSpace(const char *path, uint64 *tot); /* get the name of an oldstyle savegame */ extern void GetOldSaveGameName(const std::string &file, char *title, const char *last); @@ -128,16 +127,11 @@ const FiosItem *FileList::FindItem(const std::string_view file) } /** - * Get descriptive texts. Returns the path and free space - * left on the device - * @param path string describing the path - * @param total_free total free space in megabytes, optional (can be nullptr) - * @return StringID describing the path (free space or failure) + * Get the current path/working directory. */ -StringID FiosGetDescText(const char **path, uint64 *total_free) +std::string FiosGetCurrentPath() { - *path = _fios_path->c_str(); - return FiosGetDiskFreeSpace(*path, total_free) ? STR_SAVELOAD_BYTES_FREE : STR_ERROR_UNABLE_TO_READ_DRIVE; + return *_fios_path; } /** diff --git a/src/fios.h b/src/fios.h index 70986135a2..1470ee2fa7 100644 --- a/src/fios.h +++ b/src/fios.h @@ -110,7 +110,8 @@ void FiosGetHeightmapList(SaveLoadOperation fop, FileList &file_list); bool FiosBrowseTo(const FiosItem *item); -StringID FiosGetDescText(const char **path, uint64 *total_free); +std::string FiosGetCurrentPath(); +std::optional FiosGetDiskFreeSpace(const std::string &path); bool FiosDelete(const char *name); std::string FiosMakeHeightmapName(const char *name); std::string FiosMakeSavegameName(const char *name); diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index b23d20b3fa..2cde115cf6 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -420,19 +420,19 @@ public: break; case WID_SL_BACKGROUND: { - static const char *path = nullptr; - static StringID str = STR_ERROR_UNABLE_TO_READ_DRIVE; - static uint64 tot = 0; + static std::string path; + static std::optional free_space = std::nullopt; if (_fios_path_changed) { - str = FiosGetDescText(&path, &tot); + path = FiosGetCurrentPath(); + free_space = FiosGetDiskFreeSpace(path); _fios_path_changed = false; } Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); - if (str != STR_ERROR_UNABLE_TO_READ_DRIVE) SetDParam(0, tot); - DrawString(ir.left, ir.right, ir.top + FONT_HEIGHT_NORMAL, str); + if (free_space.has_value()) SetDParam(0, free_space.value()); + DrawString(ir.left, ir.right, ir.top + FONT_HEIGHT_NORMAL, free_space.has_value() ? STR_SAVELOAD_BYTES_FREE : STR_ERROR_UNABLE_TO_READ_DRIVE); DrawString(ir.left, ir.right, ir.top, path, TC_BLACK); break; } diff --git a/src/os/os2/os2.cpp b/src/os/os2/os2.cpp index bc7ffdca99..3be323e407 100644 --- a/src/os/os2/os2.cpp +++ b/src/os/os2/os2.cpp @@ -92,32 +92,21 @@ void FiosGetDrives(FileList &file_list) #endif } -bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) +std::optional FiosGetDiskFreeSpace(const std::string &path) { #ifndef __INNOTEK_LIBC__ struct diskfree_t free; char drive = path[0] - 'A' + 1; - if (tot != nullptr && _getdiskfree(drive, &free) == 0) { - *tot = free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector; - return true; + if (_getdiskfree(drive, &free) == 0) { + return free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector; } +#elif defined(HAS_STATVFS) + struct statvfs s; - return false; -#else - uint64 free = 0; - -#ifdef HAS_STATVFS - { - struct statvfs s; - - if (statvfs(path, &s) != 0) return false; - free = (uint64)s.f_frsize * s.f_bavail; - } -#endif - if (tot != nullptr) *tot = free; - return true; + if (statvfs(path.c_str(), &s) == 0) return static_cast(s.f_frsize) * s.f_bavail; #endif + return std::nullopt; } bool FiosIsValidFile(const std::string &path, const struct dirent *ent, struct stat *sb) diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index aa3c443e15..2dfce9f21b 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -67,23 +67,18 @@ void FiosGetDrives(FileList &file_list) return; } -bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) +std::optional FiosGetDiskFreeSpace(const std::string &path) { - uint64 free = 0; - #ifdef __APPLE__ struct statfs s; - if (statfs(path, &s) != 0) return false; - free = (uint64)s.f_bsize * s.f_bavail; + if (statfs(path.c_str(), &s) == 0) return static_cast(s.f_bsize) * s.f_bavail; #elif defined(HAS_STATVFS) struct statvfs s; - if (statvfs(path, &s) != 0) return false; - free = (uint64)s.f_frsize * s.f_bavail; + if (statvfs(path.c_str(), &s) == 0) return static_cast(s.f_frsize) * s.f_bavail; #endif - if (tot != nullptr) *tot = free; - return true; + return std::nullopt; } bool FiosIsValidFile(const std::string &path, const struct dirent *ent, struct stat *sb) diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index caf968f31e..a18f693d53 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -213,16 +213,17 @@ bool FiosIsHiddenFile(const struct dirent *ent) return (ent->dir->fd.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) != 0; } -bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) +std::optional FiosGetDiskFreeSpace(const std::string &path) { UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box ULARGE_INTEGER bytes_free; bool retval = GetDiskFreeSpaceEx(OTTD2FS(path).c_str(), &bytes_free, nullptr, nullptr); - if (retval && tot != nullptr) *tot = bytes_free.QuadPart; SetErrorMode(sem); // reset previous setting - return retval; + + if (retval) return bytes_free.QuadPart; + return std::nullopt; } void CreateConsole() From d9f8a4c380983de28c6ddf491e4e137d8a99af9b Mon Sep 17 00:00:00 2001 From: Rubidium Date: Wed, 31 May 2023 17:16:31 +0200 Subject: [PATCH 04/11] Codechange: use std::string GetString variant --- src/network/network_content_gui.cpp | 6 +++--- src/newgrf_debug_gui.cpp | 4 +--- src/newgrf_gui.cpp | 3 +-- src/osk_gui.cpp | 25 ++++++++----------------- src/saveload/saveload.cpp | 6 +++--- 5 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index f82b807c62..3ef613824f 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -345,7 +345,7 @@ class NetworkContentListWindow : public Window, ContentCallback { uint filesize_sum; ///< The sum of all selected file sizes Scrollbar *vscroll; ///< Cache of the vertical scrollbar - static char content_type_strs[CONTENT_TYPE_END][64]; ///< Cached strings for all content types. + static std::string content_type_strs[CONTENT_TYPE_END]; ///< Cached strings for all content types. /** Search external websites for content */ void OpenExternalSearch() @@ -1019,7 +1019,7 @@ NetworkContentListWindow::GUIContentList::FilterFunction * const NetworkContentL &TypeOrSelectedFilter, }; -char NetworkContentListWindow::content_type_strs[CONTENT_TYPE_END][64]; +std::string NetworkContentListWindow::content_type_strs[CONTENT_TYPE_END]; /** * Build array of all strings corresponding to the content types. @@ -1027,7 +1027,7 @@ char NetworkContentListWindow::content_type_strs[CONTENT_TYPE_END][64]; void BuildContentTypeStringList() { for (int i = CONTENT_TYPE_BEGIN; i < CONTENT_TYPE_END; i++) { - GetString(NetworkContentListWindow::content_type_strs[i], STR_CONTENT_TYPE_BASE_GRAPHICS + i - CONTENT_TYPE_BASE_GRAPHICS, lastof(NetworkContentListWindow::content_type_strs[i])); + NetworkContentListWindow::content_type_strs[i] = GetString(STR_CONTENT_TYPE_BASE_GRAPHICS + i - CONTENT_TYPE_BASE_GRAPHICS); } } diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index bccae4f1bd..86f45bfd16 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -510,9 +510,7 @@ struct NewGRFInspectWindow : Window { NOT_REACHED(); } - char buffer[64]; - GetString(buffer, string, lastof(buffer)); - this->DrawString(r, i++, fmt::format(" {:02x}: {} ({})", nip->prop, buffer, nip->name)); + this->DrawString(r, i++, fmt::format(" {:02x}: {} ({})", nip->prop, GetString(string), nip->name)); } } diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 109a958016..cec827f300 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -71,14 +71,13 @@ static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params) { Rect tr = r.Shrink(WidgetDimensions::scaled.frametext); if (c->error != nullptr) { - char message[512]; SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages SetDParamStr(1, c->filename); SetDParamStr(2, c->error->data); for (uint i = 0; i < c->error->param_value.size(); i++) { SetDParam(3 + i, c->error->param_value[i]); } - GetString(message, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message)); + std::string message = GetString(c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING); SetDParamStr(0, message); tr.top = DrawStringMultiLine(tr, c->error->severity); diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp index 307cc4f793..3b8e963bb5 100644 --- a/src/osk_gui.cpp +++ b/src/osk_gui.cpp @@ -347,27 +347,18 @@ static WindowDesc _osk_desc( */ void GetKeyboardLayout() { - char keyboard[2][OSK_KEYBOARD_ENTRIES * 4 + 1]; - char errormark[2][OSK_KEYBOARD_ENTRIES + 1]; // used for marking invalid chars + std::string keyboard[2]; + std::string errormark[2]; // used for marking invalid chars bool has_error = false; // true when an invalid char is detected - if (_keyboard_opt[0].empty()) { - GetString(keyboard[0], STR_OSK_KEYBOARD_LAYOUT, lastof(keyboard[0])); - } else { - strecpy(keyboard[0], _keyboard_opt[0].c_str(), lastof(keyboard[0])); - } - - if (_keyboard_opt[1].empty()) { - GetString(keyboard[1], STR_OSK_KEYBOARD_LAYOUT_CAPS, lastof(keyboard[1])); - } else { - strecpy(keyboard[1], _keyboard_opt[1].c_str(), lastof(keyboard[1])); - } + keyboard[0] = _keyboard_opt[0].empty() ? GetString(STR_OSK_KEYBOARD_LAYOUT) : _keyboard_opt[0]; + keyboard[1] = _keyboard_opt[1].empty() ? GetString(STR_OSK_KEYBOARD_LAYOUT_CAPS) : _keyboard_opt[1]; for (uint j = 0; j < 2; j++) { - const char *kbd = keyboard[j]; + auto kbd = keyboard[j].begin(); bool ended = false; for (uint i = 0; i < OSK_KEYBOARD_ENTRIES; i++) { - _keyboard[j][i] = Utf8Consume(&kbd); + _keyboard[j][i] = Utf8Consume(kbd); /* Be lenient when the last characters are missing (is quite normal) */ if (_keyboard[j][i] == '\0' || ended) { @@ -377,10 +368,10 @@ void GetKeyboardLayout() } if (IsPrintable(_keyboard[j][i])) { - errormark[j][i] = ' '; + errormark[j] += ' '; } else { has_error = true; - errormark[j][i] = '^'; + errormark[j] += '^'; _keyboard[j][i] = ' '; } } diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index abe61ac247..b2b626386f 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -2792,9 +2792,9 @@ const char *GetSaveLoadErrorString() SetDParam(0, _sl.error_str); SetDParamStr(1, _sl.extra_msg); - static char err_str[512]; - GetString(err_str, _sl.action == SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED, lastof(err_str)); - return err_str; + static std::string err_str; + err_str = GetString(_sl.action == SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED); + return err_str.c_str(); } /** Show a gui message when saving has failed */ From f29606fd141d1c3f2afdf49eca8c2314f2e41de5 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Wed, 31 May 2023 18:02:50 +0200 Subject: [PATCH 05/11] Codechange: use std::string to cache engine/group/vehicle names --- src/build_vehicle_gui.cpp | 7 +++---- src/company_gui.cpp | 6 +++--- src/group_gui.cpp | 6 +++--- src/vehicle_gui.cpp | 6 +++--- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index ecda60450b..b22218dbe8 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -145,19 +145,18 @@ static EngineID _last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE }; */ static bool EngineNameSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - static char last_name[2][64] = { "", "" }; + static std::string last_name[2] = { {}, {} }; if (a.engine_id != _last_engine[0]) { _last_engine[0] = a.engine_id; SetDParam(0, PackEngineNameDParam(a.engine_id, EngineNameContext::PurchaseList)); - - GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0])); + last_name[0] = GetString(STR_ENGINE_NAME); } if (b.engine_id != _last_engine[1]) { _last_engine[1] = b.engine_id; SetDParam(0, PackEngineNameDParam(b.engine_id, EngineNameContext::PurchaseList)); - GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1])); + last_name[1] = GetString(STR_ENGINE_NAME); } int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting). diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 23967879fd..6a4d6b457b 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -721,18 +721,18 @@ private: /* Sort the groups by their name */ const Group *last_group[2] = { nullptr, nullptr }; - char last_name[2][64] = { "", "" }; + std::string last_name[2] = { {}, {} }; list.Sort([&](const Group * const &a, const Group * const &b) -> bool { if (a != last_group[0]) { last_group[0] = a; SetDParam(0, a->index); - GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0])); + last_name[0] = GetString(STR_GROUP_NAME); } if (b != last_group[1]) { last_group[1] = b; SetDParam(0, b->index); - GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1])); + last_name[1] = GetString(STR_GROUP_NAME); } int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting). diff --git a/src/group_gui.cpp b/src/group_gui.cpp index d2ddf10b0e..38c719e7e1 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -177,18 +177,18 @@ private: /* Sort the groups by their name */ const Group *last_group[2] = { nullptr, nullptr }; - char last_name[2][64] = { "", "" }; + std::string last_name[2] = { {}, {} }; list.Sort([&](const Group * const &a, const Group * const &b) { if (a != last_group[0]) { last_group[0] = a; SetDParam(0, a->index); - GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0])); + last_name[0] = GetString(STR_GROUP_NAME); } if (b != last_group[1]) { last_group[1] = b; SetDParam(0, b->index); - GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1])); + last_name[1] = GetString(STR_GROUP_NAME); } int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting). diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 240083e211..7e16099f1d 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1332,18 +1332,18 @@ static bool VehicleNumberSorter(const Vehicle * const &a, const Vehicle * const /** Sort vehicles by their name */ static bool VehicleNameSorter(const Vehicle * const &a, const Vehicle * const &b) { - static char last_name[2][64]; + static std::string last_name[2] = { {}, {} }; if (a != _last_vehicle[0]) { _last_vehicle[0] = a; SetDParam(0, a->index); - GetString(last_name[0], STR_VEHICLE_NAME, lastof(last_name[0])); + last_name[0] = GetString(STR_VEHICLE_NAME); } if (b != _last_vehicle[1]) { _last_vehicle[1] = b; SetDParam(0, b->index); - GetString(last_name[1], STR_VEHICLE_NAME, lastof(last_name[1])); + last_name[1] = GetString(STR_VEHICLE_NAME); } int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting). From b5b004e5188590d415ace4b4ea1e36139ed231a4 Mon Sep 17 00:00:00 2001 From: translators Date: Wed, 31 May 2023 18:42:26 +0000 Subject: [PATCH 06/11] Update: Translations from eints ukrainian: 117 changes by alextov --- src/lang/ukrainian.txt | 212 +++++++++++++++++++++++------------------ 1 file changed, 117 insertions(+), 95 deletions(-) diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index a1b95d8ead..9682542fb4 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -320,6 +320,7 @@ STR_UNITS_VELOCITY_IMPERIAL :{DECIMAL}{NBSP} STR_UNITS_VELOCITY_METRIC :{DECIMAL}{NBSP}км/год STR_UNITS_VELOCITY_SI :{DECIMAL}{NBSP}м/с STR_UNITS_VELOCITY_GAMEUNITS :{DECIMAL}{NBSP}клітинок/день +STR_UNITS_VELOCITY_KNOTS :{DECIMAL}{NBSP}вуз{P ол ла лів} STR_UNITS_POWER_IMPERIAL :{DECIMAL}{NBSP}к.с. STR_UNITS_POWER_METRIC :{DECIMAL}{NBSP}к.с. @@ -495,7 +496,7 @@ STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Буду STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Змінити ландшафт STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Налаштувати звук/музику STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Показати останнє повідомлення. Налаштування повідомлень -STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Інформація про земельну ділянку, консоль, налагодження скриптів, знімки екрану, про OpenTTD +STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Інформація про земельну ділянку, знімки екрану, про гру OpenTTD та інструменти для розробки STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Переключити панелі # Extra tooltips for the scenario editor toolbar @@ -530,7 +531,7 @@ STR_SCENEDIT_FILE_MENU_QUIT :Вихід STR_SETTINGS_MENU_GAME_OPTIONS :Налаштування гри STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Налаштування STR_SETTINGS_MENU_AI_SETTINGS :Налаштування ШІ -STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Налаштування сценарію гри +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Налаштування ігрового скрипту STR_SETTINGS_MENU_NEWGRF_SETTINGS :Налаштування NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Налаштування прозорості STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Показувати назви міст @@ -629,7 +630,7 @@ STR_NEWS_MENU_DELETE_ALL_MESSAGES :Видалит STR_ABOUT_MENU_LAND_BLOCK_INFO :Інформація про ділянку STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Вкл./відкл. консоль -STR_ABOUT_MENU_AI_DEBUG :Налагодження АІ / Ігрового Скрипта +STR_ABOUT_MENU_AI_DEBUG :Зневадження ШІ / ігрового скрипту STR_ABOUT_MENU_SCREENSHOT :Знімок екрану STR_ABOUT_MENU_SHOW_FRAMERATE :Швидкість генерації гри STR_ABOUT_MENU_ABOUT_OPENTTD :Про гру 'OpenTTD' @@ -1059,15 +1060,20 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Пере STR_GAME_OPTIONS_CAPTION :{WHITE}Налаштування гри STR_GAME_OPTIONS_TAB_GENERAL :Загальні +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Виберіть загальні налаштування STR_GAME_OPTIONS_TAB_GRAPHICS :Графіка STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Виберіть налаштування графіки STR_GAME_OPTIONS_TAB_SOUND :Звук +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Виберіть налаштування звуку та музики STR_GAME_OPTIONS_VOLUME :Гучність STR_GAME_OPTIONS_SFX_VOLUME :Звукові ефекти +STR_GAME_OPTIONS_MUSIC_VOLUME :Музика +STR_GAME_OPTIONS_VOLUME_0 :0% STR_GAME_OPTIONS_VOLUME_25 :25% STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Грошова одиниця @@ -1123,6 +1129,10 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Вибе # Autosave dropdown ###length 5 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF :вимкнено +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES :Кожні 10 хвилин +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES :Кожні 30 хвилин +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES :Кожні 60 хвилин +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES :Кожні 120 хвилин STR_GAME_OPTIONS_LANGUAGE :{BLACK}Мова STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Виберіть мову інтерфейса користувача @@ -1281,7 +1291,7 @@ STR_CITY_APPROVAL_TOLERANT :терпиме STR_CITY_APPROVAL_HOSTILE :вороже STR_CITY_APPROVAL_PERMISSIVE :допустиме (не впливає на дії компанії) -STR_WARNING_NO_SUITABLE_AI :{WHITE}Немає відповідних AI...{}Ви можете завантажити кілька AI через систему 'Вмісту в Інтернеті' +STR_WARNING_NO_SUITABLE_AI :{WHITE}Немає підходящих модулів ШІ...{}Ви можете завантажити різноманітні модулі ШІ через 'Додатковий контент' # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Налаштування @@ -1356,7 +1366,7 @@ STR_CONFIG_SETTING_RUNNING_COSTS :Експлуа STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Встановіть вартість обслуговування та експлуатаційні витрати на транспорт та інфраструктуру STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Швидкість будівництва: {STRING} -STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Обмеження кількості будівельних дій для AI +STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Обмеження кількості будівельних дій для ШІ STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Поломки транспорту: {STRING} STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :Встановіть частоту поломок недостатньо якісно обслугованого транспорту @@ -1429,7 +1439,7 @@ STR_CONFIG_SETTING_FORBID_90_DEG :Заборон STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :При включенні прямокутні перетини шляхів не будуть вважатися поворотами. Для повороту необходно прокладати шляхи під кутом 45°. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Станції можуть складатися з не суміжних частин: {STRING} -STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Дозволяє об'єднання в одну станцію частин, що не примикають одна до одної. Щоб приєднати нову станцію до існуючої необхідно використовувати Ctrl+Click при будівництві. +STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Дозволяє об'єднання в одну станцію частин, що не примикають одна до одної. Щоб приєднати нову станцію до існуючої, необхідно використовувати Ctrl+клац при будівництві STR_CONFIG_SETTING_INFLATION :Інфляція: {STRING} STR_CONFIG_SETTING_INFLATION_HELPTEXT :Дозволяє інфляцію в економіці. При цьому витрати з часом зростають дещо швидше за прибутки @@ -1547,7 +1557,7 @@ STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :При вклю STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Автозаміна зношених транспортних засобів: {STRING} STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :При включенні транспортні засоби з вичерпаним строком служби автоматично замінюються на нові (при виконанні умов автозаміни). -STR_CONFIG_SETTING_AUTORENEW_MONTHS :Автозаміна транспрорту {STRING} закінчення строку експлуатації +STR_CONFIG_SETTING_AUTORENEW_MONTHS :Автозаміна транспорту {STRING} закінчення строку експлуатації STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT :Момент з якого транспортний засіб підлягає автоматичній заміні. ###length 2 STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_BEFORE :{COMMA} місяц{P ь я ів} до @@ -1578,7 +1588,7 @@ STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Показат STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :При включенні придатний вантаж для транспортних засобів показано нижче у списку транспорту STR_CONFIG_SETTING_LANDSCAPE :Ландшафт: {STRING} -STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Ландшафти визначають базові ігрові сценарії з різними вантажами, необхідними для зростання міст. NewGRF'и й ігрові скрипти дозволяють тонший контроль +STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Ландшафти визначають базові ігрові сценарії з різними вантажами, необхідними для зростання міст. NewGRF-и та ігрові скрипти дозволяють тонший контроль STR_CONFIG_SETTING_LAND_GENERATOR :Генератор ландшафту: {STRING} STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :Стандартний залежить від базового набору графіки і створює стандартні форми ландшафту. TerraGenesis базується на генераторі шумів Перлина з тоншими налаштуваннями управління @@ -1645,7 +1655,7 @@ STR_CONFIG_SETTING_EDGES_NOT_EMPTY :{WHITE}Одна STR_CONFIG_SETTING_EDGES_NOT_WATER :{WHITE}Одна або більше клітинок на одному з країв не є водними STR_CONFIG_SETTING_STATION_SPREAD :Максимальний розмір станцій: {STRING} -STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT :Максимально допустимий лінійний розмір станцій. Зауважте, що занадто високе значення параметру може уповільнити гру. +STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT :Максимально допустимий лінійний розмір станцій. Зауважте, що занадто високе значення параметра може уповільнити гру. STR_CONFIG_SETTING_SERVICEATHELIPAD :Автоматичний техогляд гелікоптерів на площадках: {STRING} STR_CONFIG_SETTING_SERVICEATHELIPAD_HELPTEXT :Проводити техогляд гелікоптерів кожного разу при приземленні, навіть якщо аєропорт не має депо. @@ -1677,7 +1687,7 @@ STR_CONFIG_SETTING_SCROLLMODE_RMB :Переміщ STR_CONFIG_SETTING_SCROLLMODE_LMB :Переміщувати ЛКМ STR_CONFIG_SETTING_SMOOTH_SCROLLING :Плавна прокрутка у вікні: {STRING} -STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Налаштування способу прокрутки основного екрану при клацанні мишою по зменшенній карті, або інших діях, що призводять до переміщення по карті (кнопки "Оглянути", тощо). При включенні опції переміщення карти відбувається плавно. При виключенні - відбувається моментальне переміщення в необхідну точку +STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Налаштування способу прокрутки основного екрану при клацанні мишею по зменшенній карті, або інших діях, що призводять до переміщення по карті (кнопки "Оглянути", тощо). При включенні опції переміщення карти відбувається плавно. При виключенні - відбувається моментальне переміщення в необхідну точку STR_CONFIG_SETTING_MEASURE_TOOLTIP :Показувати підказки про розміри під час будівництва: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Відображати довжини та різниці висот в підказках в процесі будівництва. @@ -1706,9 +1716,9 @@ STR_CONFIG_SETTING_OSK_ACTIVATION :Екранна STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Виберіть спосіб відкриття екранної клавіатури для введення тексту у поля тільки за допомогою вказівного пристрою. Це призначено для невеликих пристроїв без фактичної клавіатури ###length 4 STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :Вимкнено -STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Подвійний клац мишою -STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :Одиночний клац мишою (коли виділено) -STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK :Одиночний клац мишою (негайно) +STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Подвійний клац мишею +STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :Одиночний клац мишею (коли виділено) +STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK :Одиночний клац мишею (негайно) STR_CONFIG_SETTING_USE_RELAY_SERVICE :Використати мережеве реле: {STRING} STR_CONFIG_SETTING_USE_RELAY_SERVICE_HELPTEXT :Якщо не вдалося з'єднатися з сервером, можна скористатися мережевим реле. Якщо обрано "Ніколи" цього не буде, якщо обрано "Питати" буде запитано дозвіл, якщо обрано "Дозволити" буде з'єднуватися без підтвердження. @@ -1720,8 +1730,8 @@ STR_CONFIG_SETTING_USE_RELAY_SERVICE_ALLOW :Дозволи STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU :Емуляція правого клацу миші: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT :Задає спосіб емуляції правого клацу миші ###length 3 -STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Команда+клац мишою -STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+клац мишою +STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+клац мишею +STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+клац мишею STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :не емулювати STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Закрити вікно правою кнопкою миші: {STRING} @@ -1776,7 +1786,7 @@ STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT :Вмикає в STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :Залишати інструменти активними після використання: {STRING} STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Залишати інструменти будівництва активними після використання. -STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :Автоматично прибирати сигнали при будівництві колії.: {STRING} +STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :Автоматично прибирати сигнали при будівництві колії: {STRING} STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT :Автоматично прибирати сигнали на шляху при будівництві колії. Увага: це може спричинити зіткнення потягів! STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT :Обмеження швидкості прискорення: {STRING} @@ -1834,19 +1844,19 @@ STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Заборон STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Забороняє віртуальним гравцям використання водного транспорту. STR_CONFIG_SETTING_AI_PROFILE :Параметри профілю за умовчанням: {STRING} -STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Виберіть, який профіль налаштувань використовувати випадковому ШІ або для початкових значень при додаванні нового ШІ або сценарію гри +STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Виберіть, який профіль налаштувань використовувати випадковому ШІ або для початкових значень при додаванні нового ШІ або скрипту гри ###length 3 STR_CONFIG_SETTING_AI_PROFILE_EASY :Легкий STR_CONFIG_SETTING_AI_PROFILE_MEDIUM :Середній STR_CONFIG_SETTING_AI_PROFILE_HARD :Складний -STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Дозволити AI у колективній грі: {STRING} +STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Дозволити ШІ у колективній грі: {STRING} STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Дозволяє участь віртуальних гравців у колективній грі STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :Максимально допустима кількість #opcodes: {STRING} -STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Максимально допустима кількість розрахунків, що можуть виконати скрипти віртуальних гравців впродовж одного ходу. -STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Максимальне використаня пам'яті скриптом: {STRING} -STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Скільки пам'яті може зайняти один сценарій до примусового припинення. Це може знадобитися збільшити для великих карт. +STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Максимально допустима кількість розрахунків, які може виконати скрипт впродовж одного ходу +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Максимальне використання пам'яті скриптом: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Скільки пам'яті може зайняти один скрипт до примусового припинення. Це може знадобитися збільшити для великих карт. STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Інтервали техогляду вказано у відсотках: {STRING} @@ -1949,13 +1959,13 @@ STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :При прот STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :Налаштування відстані між сигналами при будівництві сигналів протягуванням. STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA} клітин{P ку ки ок} STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :При протягуванні дотримуватись фіксованої дистанціі між сигналами: {STRING} -STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Вибрати спосіб встановлення сигналів при протягуванні мишою з утриманням Ctrl. Якщо опція вимкнена, то сигнали встановлюються навколо мостів та тунелів аби не було великих відрізків шляху без сигналів. Якщо увімкнено, заданий інтервал встановлювання сигналів витримується більш строго - через кожні n клітинок (веде до легшого вирівнювання сигналів на паралельних коліях) +STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Вибрати спосіб встановлення сигналів при протягуванні мишею з утриманням Ctrl. Якщо опція вимкнена, то сигнали встановлюються навколо мостів та тунелів аби не було великих відрізків шляху без сигналів. Якщо увімкнено, заданий інтервал встановлювання сигналів витримується більш строго - через кожні n клітинок (веде до легшого вирівнювання сигналів на паралельних коліях) STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Автоматично будувати семафори до {STRING} року STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Налаштування року впровадження світлофорів замість семафорів. До цього року будуть встановлюватись лише семафори. STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Сигнали, доступні при циклічному переборі: {STRING} -STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Налаштування типу сигналів, що доступні при зміні типу за допомогою Ctrl+клац мишою +STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Налаштування типу сигналів, що доступні при зміні типу за допомогою Ctrl+клац мишею ###length 2 STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :тільки маршрутні STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :всі видимі @@ -2081,7 +2091,8 @@ STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Встанов STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Рівень заповнення коротких маршрутів перед переходом до містких: {STRING} STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Часто між двома заданими станціями є більше, ніж один шлях. Cargodist заповнить спочатку найкоротший маршрут, потім другий після найкоротшого і т. д. Рівень заповнення визначається за допомогою оцінки місткості та запланованого використання. Якщо всі маршрути буде заповнено, а джерело вантажу не вичерпається, алгоритм почне переповнювати маршрути, починаючи з наймісткіших. Ця настройка дозволяє задати рівень заповнення в процентах, якого треба досягнути на першому маршруті перед тим, як перейти до заповнення наступного. Варто встановити цей рівень меншим за 100%, щоб уникнути переповнення станцій в разі переоцінки місткості маршруту. -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Одиниці швидкості: {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Одиниці швидкості (на суші): {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_NAUTICAL :Одиниці швидкості (на воді): {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Показувати швидкості в таких одиницях ###length 5 STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL :Імперські (милі/год) @@ -2167,7 +2178,7 @@ STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Змін STR_CONFIG_ERROR :{WHITE}Помилка у файлі конфігурації... STR_CONFIG_ERROR_ARRAY :{WHITE}... помилка в масиві '{STRING}' STR_CONFIG_ERROR_INVALID_VALUE :{WHITE}... невірне значення '{STRING}' для '{STRING}' -STR_CONFIG_ERROR_TRAILING_CHARACTERS :{WHITE}... лишні символи в кінці параметру '{STRING}' +STR_CONFIG_ERROR_TRAILING_CHARACTERS :{WHITE}... зайві символи в кінці параметра '{STRING}' STR_CONFIG_ERROR_DUPLICATE_GRFID :{WHITE}... ігнорую NewGRF '{STRING}': дублікат GRF ID з '{STRING}' STR_CONFIG_ERROR_INVALID_GRF :{WHITE}... ігнорую невірні NewGRF '{STRING}': {STRING} STR_CONFIG_ERROR_INVALID_GRF_NOT_FOUND :не знайдено @@ -2203,10 +2214,10 @@ STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Нала STR_INTRO_NEWGRF_SETTINGS :{BLACK}Налаштування NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Додатковий контент STR_INTRO_AI_SETTINGS :{BLACK}Налаштування ШІ -STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Налаштування сценарію гри +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Налаштування ігрового скрипту STR_INTRO_QUIT :{BLACK}Вихід -STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Почати нову гру. Ctrl+клац мишою пропускає конфігурацію карти +STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Почати нову гру. Ctrl+клац мишею пропускає конфігурацію карти STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}Продовжити збережену гру STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Почати нову гру з використанням готової карти висот (рельєфу) STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}Почати нову гру з використанням готового сценарію @@ -2224,7 +2235,7 @@ STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Нала STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Показати налаштування NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Перевірити доступний для завантаження додатковий контент STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Показати налаштування ШІ -STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Показати налаштування сценарію гри +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Показати налаштування ігрового скрипту STR_INTRO_TOOLTIP_QUIT :{BLACK}Вийти з OpenTTD STR_INTRO_BASESET :{BLACK}В обраному наборі базової графіки немає {NUM} спрайт{P а ів ів}. Будь ласка, оновіть набір графіки. @@ -2264,9 +2275,9 @@ STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Пока STR_LIVERY_ROAD_VEHICLE_TOOLTIP :{BLACK}Показати фарбування автотранспорта STR_LIVERY_SHIP_TOOLTIP :{BLACK}Показати фарбування кораблів STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Показати фарбування авіації -STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Оберіть основний колір для обраної схеми. Ctrl+клац мишою встановить обраний колір для всіх схем -STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Оберіть другорядний колір для обраної схеми. Ctrl+клац мишою встановить обраний колір для всіх схем -STR_LIVERY_PANEL_TOOLTIP :{BLACK}Оберіть кольорову схему для зміни, чи декілька з Ctrl+клац мишою. Клацніть на прямокутнику, щоб ввімкнути/вимкнути використання схем +STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Оберіть основний колір для обраної схеми. Ctrl+клац мишею встановить обраний колір для всіх схем +STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Оберіть другорядний колір для обраної схеми. Ctrl+клац мишею встановить обраний колір для всіх схем +STR_LIVERY_PANEL_TOOLTIP :{BLACK}Оберіть кольорову схему для зміни, чи декілька з Ctrl+клац мишею. Клацніть на прямокутнику, щоб ввімкнути/вимкнути використання схем ###length 23 STR_LIVERY_DEFAULT :Стандартний колір @@ -2369,7 +2380,7 @@ STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION :{BLACK}Кліє STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION_TOOLTIP :{BLACK}Клієнти в мережі/макс.клієнтів{}Компанії в мережі/макс.компаній STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT :{BLACK}{COMMA}x{COMMA} STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION :{BLACK}Розмір карти -STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION_TOOLTIP :{BLACK}Розмір карти гри{}Клацніть мишою для сортування за районом +STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION_TOOLTIP :{BLACK}Розмір карти гри{}Клацніть мишею для сортування за районом STR_NETWORK_SERVER_LIST_DATE_CAPTION :{BLACK}Дата STR_NETWORK_SERVER_LIST_DATE_CAPTION_TOOLTIP :{BLACK}Поточна дата STR_NETWORK_SERVER_LIST_YEARS_CAPTION :{BLACK}Роки @@ -2641,7 +2652,7 @@ STR_CONTENT_TYPE_CAPTION :{BLACK}Тип STR_CONTENT_TYPE_CAPTION_TOOLTIP :{BLACK}Тип вмісту STR_CONTENT_NAME_CAPTION :{BLACK}Назва STR_CONTENT_NAME_CAPTION_TOOLTIP :{BLACK}Назва вмісту -STR_CONTENT_MATRIX_TOOLTIP :{BLACK}Клацніть мишою на рядку, щоб побачити деталі{}Клацніть позначку, щоб обрати його для завантаження +STR_CONTENT_MATRIX_TOOLTIP :{BLACK}Клацніть мишею на рядку, щоб побачити деталі{}Клацніть позначку, щоб обрати його для завантаження STR_CONTENT_SELECT_ALL_CAPTION :{BLACK}Вибрати всі STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP :{BLACK}Позначити для завантаження весь вміст STR_CONTENT_SELECT_UPDATES_CAPTION :{BLACK}Вибрати оновлення @@ -2684,7 +2695,7 @@ STR_CONTENT_NO_ZLIB_SUB :{WHITE}... не STR_CONTENT_TYPE_BASE_GRAPHICS :Базова графіка STR_CONTENT_TYPE_NEWGRF :NewGRF STR_CONTENT_TYPE_AI :AI -STR_CONTENT_TYPE_AI_LIBRARY :Бібліотека AI +STR_CONTENT_TYPE_AI_LIBRARY :Бібліотека ШІ STR_CONTENT_TYPE_SCENARIO :Сценарій STR_CONTENT_TYPE_HEIGHTMAP :Карта висот STR_CONTENT_TYPE_BASE_SOUNDS :Основні звуки @@ -2811,7 +2822,8 @@ STR_STATION_BUILD_DRAG_DROP_TOOLTIP :{BLACK}Буду STR_STATION_BUILD_STATION_CLASS_TOOLTIP :{BLACK}Виберіть тип станції для відображення STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}Виберіть тип станції для забудови -STR_STATION_CLASS_DFLT :Звичайна станція +STR_STATION_CLASS_DFLT :Звичайна +STR_STATION_CLASS_DFLT_STATION :Звичайна станція STR_STATION_CLASS_WAYP :Пункт # Signal window @@ -2841,6 +2853,7 @@ STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Вибі STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Підвісний сталевий STR_BRIDGE_NAME_GIRDER_STEEL :Балочний сталевий STR_BRIDGE_NAME_CANTILEVER_STEEL :Каркасний сталевий @@ -2941,8 +2954,8 @@ STR_STATION_BUILD_NOISE :{BLACK}Ріве # Landscaping toolbar STR_LANDSCAPING_TOOLBAR :{WHITE}Ландшафт -STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Опустити край ділянки землі. Протягування мишою опускає вибраний край і вирівнює вибрану ділянку до його нової висоти. Утримуйте Ctrl для виділення клітинок по діагоналі, або Shift - для показу очікуваних витрат -STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Підняти край ділянки землі. Протягування мишою піднімає вибраний край і вирівнює вибрану ділянку до його нової висоти. Утримуйте Ctrl для виділення клітинок по діагоналі, або Shift - для показу очікуваних витрат +STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Опустити край ділянки землі. Протягування мишею опускає вибраний край і вирівнює вибрану ділянку до його нової висоти. Утримуйте Ctrl для виділення клітинок по діагоналі, або Shift - для показу очікуваних витрат +STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Підняти край ділянки землі. Протягування мишею піднімає вибраний край і вирівнює вибрану ділянку до його нової висоти. Утримуйте Ctrl для виділення клітинок по діагоналі, або Shift - для показу очікуваних витрат STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Вирівняти ділянку землі до висоти першого обраного краю. Утримуйте Ctrl для виділення клітинок по діагоналі, або Shift - для показу очікуваних витрат STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Купити ділянку для використання у майбутньому. Утримуйте Ctrl для виділення діагональної ділянки. Утримуйте Shift для показу вартості ділянки @@ -3053,7 +3066,7 @@ STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP :{BLACK}Обер # Land area window STR_LAND_AREA_INFORMATION_CAPTION :{WHITE}Інформація про ділянку -STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Показати місце у центрі екрану. Ctrl+клац мишою відкриє нове вікно з видом на місце +STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Показати місце у центрі екрану. Ctrl+клац мишею відкриє нове вікно з видом на місце STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A :{BLACK}Вартість очистки: {LTBLUE}неможливо STR_LAND_AREA_INFORMATION_COST_TO_CLEAR :{BLACK}Вартість очистки: {RED}{CURRENCY_LONG} STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Дохід при очистці: {LTBLUE}{CURRENCY_LONG} @@ -3215,7 +3228,7 @@ STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Дод STR_FRAMERATE_VIDEO :{BLACK}Виведення на екран: STR_FRAMERATE_SOUND :{BLACK}Обробка звуків: STR_FRAMERATE_ALLSCRIPTS :{BLACK} Виконання скриптів: -STR_FRAMERATE_GAMESCRIPT :{BLACK} Ігровий Скрипт: +STR_FRAMERATE_GAMESCRIPT :{BLACK} Ігровий скрипт: STR_FRAMERATE_AI :{BLACK} ШІ {NUM} {STRING} ###length 15 @@ -3297,8 +3310,8 @@ STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Нала STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Показати налаштування NewGRF STR_MAPGEN_AI_SETTINGS :{BLACK}Налаштування ШІ STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Показати усі налаштування -STR_MAPGEN_GS_SETTINGS :{BLACK}Налаштування сценарію гри -STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Показати налаштування сценарію гри +STR_MAPGEN_GS_SETTINGS :{BLACK}Налаштування скрипту гри +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Показати налаштування ігрового скрипту ###length 21 STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Англійські (оригінальні) @@ -3568,7 +3581,7 @@ STR_SIGN_LIST_MATCH_CASE_TOOLTIP :{BLACK}Пере # Sign window STR_EDIT_SIGN_CAPTION :{WHITE}Редагування напису -STR_EDIT_SIGN_LOCATION_TOOLTIP :{BLACK}Показати позначку в центрі екрану. Ctrl+клац мишою відкриє нове вікно у місці розташування позначки +STR_EDIT_SIGN_LOCATION_TOOLTIP :{BLACK}Показати позначку в центрі екрану. Ctrl+клац мишею відкриє нове вікно у місці розташування позначки STR_EDIT_SIGN_NEXT_SIGN_TOOLTIP :{BLACK}Наступне позначення STR_EDIT_SIGN_PREVIOUS_SIGN_TOOLTIP :{BLACK}Попереднє позначення @@ -3652,7 +3665,7 @@ STR_GOALS_TEXT :{ORANGE}{STRING STR_GOALS_NONE :{ORANGE}- нема - STR_GOALS_PROGRESS :{ORANGE}{STRING} STR_GOALS_PROGRESS_COMPLETE :{GREEN}{STRING} -STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Клац мишою на цілі (меті) відобразить по центру виробництва/місто/клітинку у головному вікні. Ctrl+клац мишою відкриє міні-вікно +STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Клац мишею на цілі (меті) відобразить по центру виробництва/місто/клітинку у головному вікні. Ctrl+клац мишею відкриє міні-вікно # Goal question window STR_GOAL_QUESTION_CAPTION_QUESTION :{BLACK}Питання @@ -3779,9 +3792,9 @@ STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}Забо # Waypoint/buoy view window STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} -STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Показати точку маршруту в центрі екрану. Ctrl+клац мишою відкриє нове вікно у місці розташування точки маршруту +STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Показати точку маршруту в центрі екрану. Ctrl+клац мишею відкриє нове вікно у місці розташування точки маршруту STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Перейменувати точку маршруту -STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Показати буй в центрі екрану. Ctrl+клац мишою відкриє нове вікно у місці розташування буя +STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Показати буй в центрі екрану. Ctrl+клац мишею відкриє нове вікно у місці розташування буя STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Перейменувати буй STR_EDIT_WAYPOINT_NAME :{WHITE}Перейменуйте точку маршруту @@ -3824,9 +3837,9 @@ STR_FINANCES_MAX_LOAN :{WHITE}Макс STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Позичити {CURRENCY_LONG} -STR_FINANCES_BORROW_TOOLTIP :{BLACK}Збільшити розмір позики. Ctrl+клац мишою позичає якнайбільше +STR_FINANCES_BORROW_TOOLTIP :{BLACK}Збільшити розмір позики. Ctrl+клац мишею позичає якнайбільше STR_FINANCES_REPAY_BUTTON :{BLACK}Повернути {CURRENCY_LONG} -STR_FINANCES_REPAY_TOOLTIP :{BLACK}Повернути частину позики. Ctrl+клац мишою повертає якнайбільше +STR_FINANCES_REPAY_TOOLTIP :{BLACK}Повернути частину позики. Ctrl+клац мишею повертає якнайбільше STR_FINANCES_INFRASTRUCTURE_BUTTON :{BLACK}Інфраструктура # Company view @@ -3898,7 +3911,7 @@ STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUST STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} і {NUM} ще... -STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Назви підприємств - клацніть мишою на назву, щоб показати підприємство у центрі екрану. Ctrl+клац мишою відкриває нове вікно з видом на підприємство +STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Назви підприємств - клацніть мишею на назву, щоб показати підприємство у центрі екрану. Ctrl+клац мишею відкриває нове вікно з видом на підприємство STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Приймається вантаж: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Виробництво: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Усі вантажі @@ -3908,7 +3921,7 @@ STR_INDUSTRY_DIRECTORY_FILTER_NONE :Нема STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Вироблено за місяць: STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% перевезено) -STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Показати підприємство у центрі екрану. Ctrl+клац мишою відкриє нове вікно з видом на підприємство +STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Показати підприємство у центрі екрану. Ctrl+клац мишею відкриє нове вікно з видом на підприємство STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Обсяг виробництва: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Підприємство оголосило про близьке закриття! @@ -3976,12 +3989,12 @@ STR_GROUP_DEFAULT_AIRCRAFTS :Незгруп STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) -STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Групи - клацніть мишою на групі, щоб побачити список транспорту цієї групи. Перетягуйте групи, щоб змінити ієрархію. -STR_GROUP_CREATE_TOOLTIP :{BLACK}Клацніть мишою, щоб створити групу +STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Групи - клацніть мишею на групі, щоб побачити список транспорту цієї групи. Перетягуйте групи, щоб змінити ієрархію. +STR_GROUP_CREATE_TOOLTIP :{BLACK}Клацніть мишею, щоб створити групу STR_GROUP_DELETE_TOOLTIP :{BLACK}Стерти вибрану групу STR_GROUP_RENAME_TOOLTIP :{BLACK}Перейменувати вибрану групу STR_GROUP_LIVERY_TOOLTIP :{BLACK}Змінити колір вибраної групи -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Клацніть мишою, щоб захистити групу від глобальної автозаміни. Ctrl + клац також діє на підгрупи. +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Клацніть мишею, щоб захистити групу від глобальної автозаміни. Ctrl+клац також діє на підгрупи. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Видалити групу STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Ви впевнені, що хочете видалити цю групу та всі вкладені групи? @@ -4046,10 +4059,10 @@ STR_CARGO_TYPE_FILTER_FREIGHT :Вантаж STR_CARGO_TYPE_FILTER_NONE :нема ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Список поїздів. Клацніть на поїзд для інформації. Ctrl+клац мишою вимикає показ типу транспорту -STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Список автомобілів. Клацніть на авто для отримання інформації. Ctrl+клац мишою вимикає показ типу транспорту -STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Список кораблів. Клацніть на корабель для отримання інформації. Ctrl+клац мишою вимикає показ типу транспорту -STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Список літальних апаратів. Клацніть на літальному апараті для отримання інформації. Ctrl+клац мишою вимикає показ типу транспорту +STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Список поїздів. Клацніть на поїзд для інформації. Ctrl+клац мишею вимикає показ типу транспорту +STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Список автомобілів. Клацніть на авто для отримання інформації. Ctrl+клац мишею вимикає показ типу транспорту +STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Список кораблів. Клацніть на корабель для отримання інформації. Ctrl+клац мишею вимикає показ типу транспорту +STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Список літальних апаратів. Клацніть на літальному апараті для отримання інформації. Ctrl+клац мишею вимикає показ типу транспорту ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Купити @@ -4070,10 +4083,10 @@ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Купи STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Купити вибраний літак. Утримуйте Shift для показу витрат на придбання ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте виділений поїзд. Shift + Click показує орієнтовну вартість без покупки -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте авто. Shift + Click показує орієнтовну вартість без покупки -STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте виділене судно. Shift + Click показує орієнтовну вартість без покупки -STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте виділені літаки. Shift + Click показує орієнтовну вартість без покупки +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте виділений поїзд. Shift+клац показує орієнтовну вартість без покупки +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте авто. Shift+клац показує орієнтовну вартість без покупки +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте виділене судно. Shift+клац показує орієнтовну вартість без покупки +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте виділені літаки. Shift+клац показує орієнтовну вартість без покупки ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Назва @@ -4165,16 +4178,16 @@ STR_DEPOT_CLONE_SHIP :{BLACK}Клон STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Клонувати ###length VEHICLE_TYPES -STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Купити копію поїзда, включно з усіма автомобілями. Натисніть на цю кнопку, а потім на поїзд в депо або ззовні. Ctrl+клац мишою дозволить поділитися спільними завданнями. Shift+клац мишою покаже орієнтовні витрати на придбання +STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Купити копію поїзда, включно з усіма автомобілями. Натисніть на цю кнопку, а потім на поїзд в депо або ззовні. Ctrl+клац мишею дозволить поділитися спільними завданнями. Shift+клац мишею покаже орієнтовні витрати на придбання STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Купити копію авто. Натисніть на цю кнопку і потім на авто в депо або ззовні. Утримуйте Ctrl для спільного завдання. Утримуйте Shift для показу витрат на придбання STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Купити копію корабля. Натисніть на цю кнопку, і потім на корабель в депо або ззовні. Утримуйте Ctrl для спільного завдання. Утримуйте Shift для показу витрат на придбання STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Купити копію літака. Натисніть на цю кнопку і потім на літак в ангарі або ззовні. Утримуйте Ctrl для спільного завдання. Утримуйте Shift для показу витрат на придбання ###length VEHICLE_TYPES -STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Показати залізничне депо у центрі екрану. Ctrl+клац мишою відкриє нове вікно з видом на залізничне депо -STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Показати гараж у центрі екрану. Ctrl+клац мишою вікдриває нове вікно з видом на гараж -STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}Показати док у центрі екрану. Ctrl+клац мишою відкриє нове вікно з видом на док -STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Показати ангар в центрі екрану. Ctrl+клац мишою відкриє нове вікно з видом на ангар +STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Показати залізничне депо у центрі екрану. Ctrl+клац мишею відкриє нове вікно з видом на залізничне депо +STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Показати гараж у центрі екрану. Ctrl+клац мишею відкриє нове вікно з видом на гараж +STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}Показати док у центрі екрану. Ctrl+клац мишею відкриє нове вікно з видом на док +STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Показати ангар в центрі екрану. Ctrl+клац мишею відкриє нове вікно з видом на ангар ###length VEHICLE_TYPES STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}Отримати список усіх поїздів, що заходять до цього депо @@ -4275,7 +4288,7 @@ STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP :{BLACK}Показати місце розташування потяга в центрі екрану. Подвійний клац для показу потяга в центрі екрану.Ctrl+клац мишою відкриє нове вікно у місці розташування потяга +STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP :{BLACK}Показати місце розташування потяга в центрі екрану. Подвійний клац для показу потяга в центрі екрану.Ctrl+клац мишею відкриє нове вікно у місці розташування потяга STR_VEHICLE_VIEW_ROAD_VEHICLE_CENTER_TOOLTIP :{BLACK}Показати транспорт у вікні. Подвійний клац для показу транспорту в центрі екрану. Ctrl+клац мишою для руху за транспортом. STR_VEHICLE_VIEW_SHIP_CENTER_TOOLTIP :{BLACK}Показати місце розташування корабля в центрі екрану. Подвійний клац для показу корабля в центрі екрану.Ctrl+клац мишою відкриє нове вікно у місці розташування корабля STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}Показати авіатранспорт у вікні. Подвійний клац для показу авіатранспорту в центрі екрану. Ctrl+клац мишою для руху за авіатранспортом. @@ -4304,10 +4317,10 @@ STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Пере STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Переобладнати літак для перевезення іншого виду вантажу ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP :{BLACK}Показати маршрут поїзда. Ctrl+Click показує розклад поїзда -STR_VEHICLE_VIEW_ROAD_VEHICLE_ORDERS_TOOLTIP :{BLACK}Показати накази авто. Ctrl+Click показує розклад авто -STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Показати накази корабля. Ctrl+Click показує розклад корабля -STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Показати накази літака. Ctrl+Click показує розклад літака +STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP :{BLACK}Показати маршрут поїзда. Ctrl+клац показує розклад поїзда +STR_VEHICLE_VIEW_ROAD_VEHICLE_ORDERS_TOOLTIP :{BLACK}Показати накази авто. Ctrl+клац показує розклад авто +STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Показати накази корабля. Ctrl+клац показує розклад корабля +STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Показати накази літака. Ctrl+клац показує розклад літака ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Показати детальну інформацію @@ -4682,13 +4695,13 @@ STR_DATE_YEAR_TOOLTIP :{BLACK}Обер # AI debug window -STR_AI_DEBUG :{WHITE}Налагодження АІ / Ігрового Скрипта +STR_AI_DEBUG :{WHITE}Зневадження ШІ / ігрового скрипту STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} (v{NUM}) -STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}Назва скрипта +STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}Назва скрипту STR_AI_DEBUG_SETTINGS :{BLACK}Налаштування STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}Змінити налаштування скрипту -STR_AI_DEBUG_RELOAD :{BLACK}Перезавантажити AI -STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}Знищити AI, перезавантажити скрипт, та рестартувати AI +STR_AI_DEBUG_RELOAD :{BLACK}Перезавантажити ШІ +STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}Зупинити ШІ, перезавантажити скрипт та перезапустити ШІ STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}Увімкнути/вимкнути паузу при появі сигнального рядку в журналі АІ STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}Рядок: STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}Рядок @@ -4696,47 +4709,47 @@ STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}У ра STR_AI_DEBUG_MATCH_CASE :{BLACK}Регістр STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}Перемкнути перевірку регістру при порівнянні рядків журналу АІ з сигнальним рядком STR_AI_DEBUG_CONTINUE :{BLACK}Продовжити -STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Зняти з паузи і продовжити AI -STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Відобразити результати дебагу цього АІ -STR_AI_GAME_SCRIPT :{BLACK}Ігровий Скрипт -STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Перевірити журнал Ігрового Скрипта +STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Зняти з паузи і продовжити ШІ +STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Відобразити результати зневадження цього ШІ +STR_AI_GAME_SCRIPT :{BLACK}Ігровий скрипт +STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Перевірити журнал ігрового скрипту -STR_ERROR_AI_NO_AI_FOUND :Не знайдено відповідних AI для завантаження.{}Цей AI тимчасовий і нічого не робить.{}Ви можете завантажити кілька AI через систему 'Вмісту в Інтернет' -STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Один із запущених скриптів перестав працювати. Будь ласка, повідомте про це автору скрипта (разом зі знімком вікна налагодження АІ/Ігрового Скрипта) -STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Вікно налагодження АІ / Ігрового Скрипта доступне тільки серверу +STR_ERROR_AI_NO_AI_FOUND :Не знайдено підходящих модулів ШІ.{}Це модуль-заглушка, він нічого не робить.{}Ви можете завантажити різноманітні модулі ШІ через 'Додатковий контент' +STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Один із запущених скриптів перестав працювати. Будь ласка, повідомте про це автора скрипту, разом зі знімком вікна зневадження ШІ / ігрового скрипту +STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Вікно зневадження ШІ / ігрового скрипту доступне тільки серверу # AI configuration window STR_AI_CONFIG_CAPTION_AI :{WHITE}Налаштування ШІ -STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Налаштування ігрового скрипта -STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Ігровий Скрипт, який буде завантажено в наступній грі +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Налаштування ігрового скрипту +STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Ігровий скрипт, який буде завантажено в наступній грі STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}АІ, які будуть завантажені в наступній грі STR_AI_CONFIG_HUMAN_PLAYER :Гравець-людина -STR_AI_CONFIG_RANDOM_AI :Випадковий AI +STR_AI_CONFIG_RANDOM_AI :Випадковий ШІ STR_AI_CONFIG_NONE :(нема) STR_AI_CONFIG_NAME_VERSION :{STRING} {YELLOW}v{NUM} STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Кількість конкурентів: {ORANGE}{COMMA} STR_AI_CONFIG_COMPETITORS_INTERVAL :{LTBLUE}Проміжок між вступом конкурентів у гру: {ORANGE}{COMMA} хвилин{P а и ""} STR_AI_CONFIG_MOVE_UP :{BLACK}Перемістити вище -STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Перемістити обраний AI вверх по списку +STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Перемістити обраний ШІ вверх по списку STR_AI_CONFIG_MOVE_DOWN :{BLACK}Перемістити нижче -STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Перемістити обраний AI вниз по списку +STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Перемістити обраний ШІ вниз по списку -STR_AI_CONFIG_GAMESCRIPT :{SILVER}Ігровий Скрипт +STR_AI_CONFIG_GAMESCRIPT :{SILVER}Ігровий скрипт STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Параметри -STR_AI_CONFIG_AI :{SILVER}АІ +STR_AI_CONFIG_AI :{SILVER}ШІ STR_AI_CONFIG_CHANGE_AI :{BLACK}Обрати ШІ STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Обрати ігровий скрипт -STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Завантажити інший скрипт. Ctrl+Click показує всі наявні версії +STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Завантажити інший скрипт. Ctrl+клац показує всі наявні версії STR_AI_CONFIG_CONFIGURE :{BLACK}Настроїти STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Настроїти параметри скрипту # Available AIs window STR_AI_LIST_CAPTION :{WHITE}Доступні {STRING} -STR_AI_LIST_CAPTION_AI :Модулі АІ -STR_AI_LIST_CAPTION_GAMESCRIPT :Ігрові Скрипти -STR_AI_LIST_TOOLTIP :{BLACK}Клацніть мишою, щоб вибрати скрипт +STR_AI_LIST_CAPTION_AI :Модулі ШІ +STR_AI_LIST_CAPTION_GAMESCRIPT :Ігрові скрипти +STR_AI_LIST_TOOLTIP :{BLACK}Клацніть мишею, щоб вибрати скрипт STR_AI_LIST_AUTHOR :{LTBLUE}Автор: {ORANGE}{STRING} STR_AI_LIST_VERSION :{LTBLUE}Версія: {ORANGE}{NUM} @@ -4757,8 +4770,8 @@ STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Знят # Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Налаштування -STR_AI_SETTINGS_CAPTION_AI :{WHITE}Параметри ШІ -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Ігровий Скрипт +STR_AI_SETTINGS_CAPTION_AI :ШІ +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Ігровий скрипт STR_AI_SETTINGS_CLOSE :{BLACK}Закрити STR_AI_SETTINGS_RESET :{BLACK}Скидання STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4819,7 +4832,7 @@ STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}Гра # Map generation messages STR_ERROR_COULD_NOT_CREATE_TOWN :{WHITE}Генерація карти перервана...{}... немає де розташувати міста -STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... у цьому сценарію немає міст +STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... у цьому сценарії немає міст STR_ERROR_PNGMAP :{WHITE}Неможливо завантажити ландшафт з PNG... STR_ERROR_PNGMAP_FILE_NOT_FOUND :{WHITE}... файл не знайдено @@ -5213,13 +5226,22 @@ STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... за STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... літак не може летіти так далеко # Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Немає залізничної станції +STR_ERROR_NO_BUS_STATION :{WHITE}Немає автобусної станції STR_ERROR_NO_TRUCK_STATION :{WHITE}Немає вантажної станції +STR_ERROR_NO_DOCK :{WHITE}Немає порту +STR_ERROR_NO_AIRPORT :{WHITE}Немає аеропорту або геліпорту +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Немає зупинок із сумісним типом трамвайної колії +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Цей літак не може приземлятися у цьому геліпорті STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Цей гелікоптер не може приземлятися у цьому аеропорту +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Немає точки залізничного маршруту +STR_ERROR_NO_BUOY :{WHITE}Немая буя # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Не можна встановити розклад для транспорту... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Транспорт може чекати тільки на станціях STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}Цей транспорт не зупиняється на цій станції. +STR_ERROR_TIMETABLE_INCOMPLETE :{WHITE}... розклад незавершений # Sign related errors STR_ERROR_TOO_MANY_SIGNS :{WHITE}... дуже багато позначень From 9eda419f9b8f48637645b12a373da195c2d18307 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 1 Jun 2023 14:21:33 +0200 Subject: [PATCH 07/11] Fix 646a7e62: recalc_time was not scaled properly (#10901) This caused "runtime" to underflow or, if you are lucky, hit an assert in ScaleToMonthly when it hits zero. But mostly underflow. --- src/linkgraph/flowmapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linkgraph/flowmapper.cpp b/src/linkgraph/flowmapper.cpp index 7ddbafc788..497aacb62b 100644 --- a/src/linkgraph/flowmapper.cpp +++ b/src/linkgraph/flowmapper.cpp @@ -50,7 +50,7 @@ void FlowMapper::Run(LinkGraphJob &job) const /* Scale by time the graph has been running without being compressed. Add 1 to avoid * division by 0 if spawn date == last compression date. This matches * LinkGraph::Monthly(). */ - uint runtime = job.JoinDate() - job.Settings().recalc_time - job.LastCompression() + 1; + uint runtime = job.JoinDate() - job.Settings().recalc_time / SECONDS_PER_DAY - job.LastCompression() + 1; for (auto &it : flows) { it.second.ScaleToMonthly(runtime); } From cdb3a6288b929c9acfa7557725a4e6d10e2c4fed Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Thu, 1 Jun 2023 17:40:24 +0100 Subject: [PATCH 08/11] Codechange: Remove unused CapacitiesMap typedef from struct Vehicle --- src/vehicle_base.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vehicle_base.h b/src/vehicle_base.h index f725784d0c..0be02bb71d 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -240,7 +240,6 @@ struct ClosestDepot { struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist { private: typedef std::list RefitList; - typedef std::map CapacitiesMap; Vehicle *next; ///< pointer to the next vehicle in the chain Vehicle *previous; ///< NOSAVE: pointer to the previous vehicle in the chain From 0b663f709d60fd95254ec6549cf08763c841787f Mon Sep 17 00:00:00 2001 From: PeterN Date: Fri, 2 Jun 2023 09:25:13 +0100 Subject: [PATCH 09/11] Codechange: Sprite mapping for objects doesn't involve cargo types. (#10905) Objects have a default sprite group and an optional purchase list sprite group. There is no need to pretend that these are cargo IDs. --- src/newgrf.cpp | 24 +++++++++--------------- src/newgrf_object.cpp | 4 ++-- src/newgrf_object.h | 4 ++-- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 9d4d14e072..2f311c8bd5 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -5504,15 +5504,6 @@ static void NewSpriteGroup(ByteReader *buf) static CargoID TranslateCargo(uint8 feature, uint8 ctype) { - if (feature == GSF_OBJECTS) { - switch (ctype) { - case 0: return 0; - case 0xFF: return CT_PURCHASE_OBJECT; - default: - GrfMsg(1, "TranslateCargo: Invalid cargo bitnum {} for objects, skipping.", ctype); - return CT_INVALID; - } - } /* Special cargo types for purchase list and stations */ if ((feature == GSF_STATIONS || feature == GSF_ROADSTOPS) && ctype == 0xFE) return CT_DEFAULT_NA; if (ctype == 0xFF) return CT_PURCHASE; @@ -5878,8 +5869,11 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue; - ctype = TranslateCargo(GSF_OBJECTS, ctype); - if (!IsValidCargoID(ctype)) continue; + /* The only valid option here is purchase list sprite groups. */ + if (ctype != 0xFF) { + GrfMsg(1, "ObjectMapSpriteGroup: Invalid cargo bitnum {} for objects, skipping.", ctype); + continue; + } for (auto &object : objects) { ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object].get(); @@ -5889,7 +5883,7 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) continue; } - spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid]; + spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_PURCHASE] = _cur.spritegroups[groupid]; } } @@ -5909,9 +5903,9 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) continue; } - spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid]; - spec->grf_prop.grffile = _cur.grffile; - spec->grf_prop.local_id = object; + spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_DEFAULT] = _cur.spritegroups[groupid]; + spec->grf_prop.grffile = _cur.grffile; + spec->grf_prop.local_id = object; } } diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index 60c0684303..cc418df29b 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -378,8 +378,8 @@ ObjectResolverObject::ObjectResolverObject(const ObjectSpec *spec, Object *obj, : ResolverObject(spec->grf_prop.grffile, callback, param1, param2), object_scope(*this, obj, spec, tile, view) { this->town_scope = nullptr; - this->root_spritegroup = (obj == nullptr && spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT] != nullptr) ? - spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT] : spec->grf_prop.spritegroup[0]; + this->root_spritegroup = (obj == nullptr && spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_PURCHASE] != nullptr) ? + spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_PURCHASE] : spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_DEFAULT]; } ObjectResolverObject::~ObjectResolverObject() diff --git a/src/newgrf_object.h b/src/newgrf_object.h index ad0ebd3702..e82f916cb8 100644 --- a/src/newgrf_object.h +++ b/src/newgrf_object.h @@ -166,8 +166,8 @@ private: /** Struct containing information relating to object classes. */ typedef NewGRFClass ObjectClass; -/** Mapping of purchase for objects. */ -static const CargoID CT_PURCHASE_OBJECT = 1; +static const size_t OBJECT_SPRITE_GROUP_DEFAULT = 0; +static const size_t OBJECT_SPRITE_GROUP_PURCHASE = 1; uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, const ObjectSpec *spec, Object *o, TileIndex tile, uint8 view = 0); From fa0d865edd44ef4b0d1bd0d9caa781adeccdcb87 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 29 Apr 2023 22:38:40 +0200 Subject: [PATCH 10/11] Change: set macOS deployment target to 10.15 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f0f5ff1dce..614fd4c230 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ if (EMSCRIPTEN) endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13) +set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15) # Use GNUInstallDirs to allow customisation # but set our own default data and bin dir From 6eb51666bcde381874857e992b6ed1cbcfb92763 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 29 Apr 2023 21:40:06 +0200 Subject: [PATCH 11/11] Codechange: use C++ file APIs for writing language files --- src/strgen/strgen.cpp | 234 +++++++++++++----------------------------- 1 file changed, 71 insertions(+), 163 deletions(-) diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp index 1be7f6ea7b..804d091e6b 100644 --- a/src/strgen/strgen.cpp +++ b/src/strgen/strgen.cpp @@ -15,18 +15,12 @@ #include "../strings_type.h" #include "../misc/getoptdata.h" #include "../table/control_codes.h" +#include "../3rdparty/fmt/std.h" #include "strgen.h" - -#if !defined(_WIN32) || defined(__CYGWIN__) -#include -#include -#endif - -#if defined(_WIN32) || defined(__WATCOMC__) -#include -#endif /* _WIN32 || __WATCOMC__ */ +#include +#include #include "../table/strgen_tables.h" @@ -75,7 +69,7 @@ void NORETURN FatalErrorI(const std::string &msg) /** A reader that simply reads using fopen. */ struct FileStringReader : StringReader { - FILE *fh; ///< The file we are reading. + std::ifstream input_stream; /** * Create the reader. @@ -84,22 +78,15 @@ struct FileStringReader : StringReader { * @param master Are we reading the master file? * @param translation Are we reading a translation? */ - FileStringReader(StringData &data, const char *file, bool master, bool translation) : - StringReader(data, file, master, translation) + FileStringReader(StringData &data, const std::filesystem::path &file, bool master, bool translation) : + StringReader(data, file.generic_string().c_str(), master, translation) { - this->fh = fopen(file, "rb"); - if (this->fh == nullptr) FatalError("Could not open {}", file); - } - - /** Free/close the file. */ - virtual ~FileStringReader() - { - fclose(this->fh); + this->input_stream.open(file, std::ifstream::binary); } char *ReadLine(char *buffer, const char *last) override { - return fgets(buffer, ClampTo(last - buffer + 1), this->fh); + return this->input_stream.getline(buffer, last - buffer) ? buffer : nullptr; } void HandlePragma(char *str) override; @@ -184,103 +171,75 @@ void FileStringReader::HandlePragma(char *str) } } -bool CompareFiles(const char *n1, const char *n2) +bool CompareFiles(const std::filesystem::path &path1, const std::filesystem::path &path2) { - FILE *f2 = fopen(n2, "rb"); - if (f2 == nullptr) return false; - - FILE *f1 = fopen(n1, "rb"); - if (f1 == nullptr) { - fclose(f2); - FatalError("can't open {}", n1); - } + /* Check for equal size, but ignore the error code for cases when a file does not exist. */ + std::error_code error_code; + if (std::filesystem::file_size(path1, error_code) != std::filesystem::file_size(path2, error_code)) return false; - size_t l1, l2; - do { - char b1[4096]; - char b2[4096]; - l1 = fread(b1, 1, sizeof(b1), f1); - l2 = fread(b2, 1, sizeof(b2), f2); - - if (l1 != l2 || memcmp(b1, b2, l1)) { - fclose(f2); - fclose(f1); - return false; - } - } while (l1 != 0); + std::ifstream stream1(path1, std::ifstream::binary); + std::ifstream stream2(path2, std::ifstream::binary); - fclose(f2); - fclose(f1); - return true; + return std::equal(std::istreambuf_iterator(stream1.rdbuf()), + std::istreambuf_iterator(), + std::istreambuf_iterator(stream2.rdbuf())); } /** Base class for writing data to disk. */ struct FileWriter { - FILE *fh; ///< The file handle we're writing to. - const char *filename; ///< The file name we're writing to. + std::ofstream output_stream; ///< The stream to write all the output to. + const std::filesystem::path path; ///< The file name we're writing to. /** * Open a file to write to. - * @param filename The file to open. + * @param path The path to the file to open. + * @param openmode The openmode flags for opening the file. */ - FileWriter(const char *filename) + FileWriter(const std::filesystem::path &path, std::ios_base::openmode openmode) : path(path) { - this->filename = stredup(filename); - this->fh = fopen(this->filename, "wb"); - - if (this->fh == nullptr) { - FatalError("Could not open {}", this->filename); - } + this->output_stream.open(path, openmode); } /** Finalise the writing. */ void Finalise() { - fclose(this->fh); - this->fh = nullptr; + this->output_stream.close(); } /** Make sure the file is closed. */ virtual ~FileWriter() { /* If we weren't closed an exception was thrown, so remove the temporary file. */ - if (fh != nullptr) { - fclose(this->fh); - unlink(this->filename); + if (this->output_stream.is_open()) { + this->output_stream.close(); + std::filesystem::remove(this->path); } - free(this->filename); } }; struct HeaderFileWriter : HeaderWriter, FileWriter { - /** The real file name we eventually want to write to. */ - const char *real_filename; + /** The real path we eventually want to write to. */ + const std::filesystem::path real_path; /** The previous string ID that was printed. */ int prev; uint total_strings; /** * Open a file to write to. - * @param filename The file to open. + * @param path The path to the file to open. */ - HeaderFileWriter(const char *filename) : FileWriter("tmp.xxx"), - real_filename(stredup(filename)), prev(0), total_strings(0) - { - fmt::print(this->fh, "/* This file is automatically generated. Do not modify */\n\n"); - fmt::print(this->fh, "#ifndef TABLE_STRINGS_H\n"); - fmt::print(this->fh, "#define TABLE_STRINGS_H\n"); - } - - /** Free the filename. */ - ~HeaderFileWriter() + HeaderFileWriter(const std::filesystem::path &path) : FileWriter("tmp.xxx", std::ofstream::out), + real_path(path), prev(0), total_strings(0) { - free(real_filename); + this->output_stream << "/* This file is automatically generated. Do not modify */\n\n"; + this->output_stream << "#ifndef TABLE_STRINGS_H\n"; + this->output_stream << "#define TABLE_STRINGS_H\n"; } void WriteStringID(const char *name, int stringid) { - if (prev + 1 != stringid) fmt::print(this->fh, "\n"); - fmt::print(this->fh, "static const StringID {} = 0x{:X};\n", name, stringid); + if (prev + 1 != stringid) this->output_stream << "\n"; + fmt::print(this->output_stream, "static const StringID {} = 0x{:X};\n", name, stringid); prev = stringid; total_strings++; } @@ -293,7 +252,7 @@ struct HeaderFileWriter : HeaderWriter, FileWriter { max_plural_forms = std::max(max_plural_forms, _plural_forms[i].plural_count); } - fmt::print(this->fh, + fmt::print(this->output_stream, "\n" "static const uint LANGUAGE_PACK_VERSION = 0x{:X};\n" "static const uint LANGUAGE_MAX_PLURAL = {};\n" @@ -303,19 +262,21 @@ struct HeaderFileWriter : HeaderWriter, FileWriter { data.Version(), lengthof(_plural_forms), max_plural_forms, total_strings ); - fmt::print(this->fh, "#endif /* TABLE_STRINGS_H */\n"); + this->output_stream << "#endif /* TABLE_STRINGS_H */\n"; this->FileWriter::Finalise(); - if (CompareFiles(this->filename, this->real_filename)) { + std::error_code error_code; + if (CompareFiles(this->path, this->real_path)) { /* files are equal. tmp.xxx is not needed */ - unlink(this->filename); + std::filesystem::remove(this->path, error_code); // Just ignore the error } else { /* else rename tmp.xxx into filename */ # if defined(_WIN32) - unlink(this->real_filename); + std::filesystem::remove(this->real_path, error_code); // Just ignore the error, file probably doesn't exist # endif - if (rename(this->filename, this->real_filename) == -1) FatalError("rename() failed"); + std::filesystem::rename(this->path, this->real_path, error_code); + if (error_code) FatalError("rename({}, {}) failed: {}", this->path, this->real_path, error_code.message()); } } }; @@ -324,9 +285,9 @@ struct HeaderFileWriter : HeaderWriter, FileWriter { struct LanguageFileWriter : LanguageWriter, FileWriter { /** * Open a file to write to. - * @param filename The file to open. + * @param path The path to the file to open. */ - LanguageFileWriter(const char *filename) : FileWriter(filename) + LanguageFileWriter(const std::filesystem::path &path) : FileWriter(path, std::ofstream::binary | std::ofstream::out) { } @@ -337,64 +298,16 @@ struct LanguageFileWriter : LanguageWriter, FileWriter { void Finalise() { - if (fputc(0, this->fh) == EOF) { - FatalError("Could not write to {}", this->filename); - } + this->output_stream.put(0); this->FileWriter::Finalise(); } void Write(const byte *buffer, size_t length) { - if (fwrite(buffer, sizeof(*buffer), length, this->fh) != length) { - FatalError("Could not write to {}", this->filename); - } + this->output_stream.write((const char *)buffer, length); } }; -/** Multi-OS mkdirectory function */ -static inline void ottd_mkdir(const char *directory) -{ - /* Ignore directory creation errors; they'll surface later on, and most - * of the time they are 'directory already exists' errors anyhow. */ -#if defined(_WIN32) || defined(__WATCOMC__) - mkdir(directory); -#else - mkdir(directory, 0755); -#endif -} - -/** - * Create a path consisting of an already existing path, a possible - * path separator and the filename. The separator is only appended if the path - * does not already end with a separator - */ -static inline char *mkpath(char *buf, const char *last, const char *path, const char *file) -{ - strecpy(buf, path, last); // copy directory into buffer - - char *p = strchr(buf, '\0'); // add path separator if necessary - if (p[-1] != PATHSEPCHAR && p != last) *p++ = PATHSEPCHAR; - strecpy(p, file, last); // concatenate filename at end of buffer - return buf; -} - -#if defined(_WIN32) -/** - * On MingW, it is common that both / as \ are accepted in the - * params. To go with those flow, we rewrite all incoming / - * simply to \, so internally we can safely assume \, and do - * this for all Windows machines to keep identical behaviour, - * no matter what your compiler was. - */ -static inline char *replace_pathsep(char *s) -{ - for (char *c = s; *c != '\0'; c++) if (*c == '/') *c = '\\'; - return s; -} -#else -static inline char *replace_pathsep(char *s) { return s; } -#endif - /** Options of strgen. */ static const OptionData _opts[] = { GETOPT_GENERAL('C', '\0', "-export-commands", ODF_NO_VALUE), @@ -411,9 +324,8 @@ static const OptionData _opts[] = { int CDECL main(int argc, char *argv[]) { - char pathbuf[MAX_PATH]; - const char *src_dir = "."; - const char *dest_dir = nullptr; + std::filesystem::path src_dir("."); + std::filesystem::path dest_dir; GetOptData mgo(argc - 1, argv + 1, _opts); for (;;) { @@ -479,11 +391,11 @@ int CDECL main(int argc, char *argv[]) return 0; case 's': - src_dir = replace_pathsep(mgo.opt); + src_dir = mgo.opt; break; case 'd': - dest_dir = replace_pathsep(mgo.opt); + dest_dir = mgo.opt; break; case -2: @@ -492,7 +404,7 @@ int CDECL main(int argc, char *argv[]) } } - if (dest_dir == nullptr) dest_dir = src_dir; // if dest_dir is not specified, it equals src_dir + if (dest_dir.empty()) dest_dir = src_dir; // if dest_dir is not specified, it equals src_dir try { /* strgen has two modes of operation. If no (free) arguments are passed @@ -500,57 +412,53 @@ int CDECL main(int argc, char *argv[]) * with a (free) parameter the program will translate that language to destination * directory. As input english.txt is parsed from the source directory */ if (mgo.numleft == 0) { - mkpath(pathbuf, lastof(pathbuf), src_dir, "english.txt"); + std::filesystem::path input_path = src_dir; + input_path /= "english.txt"; /* parse master file */ StringData data(TEXT_TAB_END); - FileStringReader master_reader(data, pathbuf, true, false); + FileStringReader master_reader(data, input_path, true, false); master_reader.ParseFile(); if (_errors != 0) return 1; /* write strings.h */ - ottd_mkdir(dest_dir); - mkpath(pathbuf, lastof(pathbuf), dest_dir, "strings.h"); + std::filesystem::path output_path = dest_dir; + std::filesystem::create_directories(dest_dir); + output_path /= "strings.h"; - HeaderFileWriter writer(pathbuf); + HeaderFileWriter writer(output_path); writer.WriteHeader(data); writer.Finalise(data); if (_errors != 0) return 1; } else if (mgo.numleft >= 1) { - char *r; - - mkpath(pathbuf, lastof(pathbuf), src_dir, "english.txt"); + std::filesystem::path input_path = src_dir; + input_path /= "english.txt"; StringData data(TEXT_TAB_END); /* parse master file and check if target file is correct */ - FileStringReader master_reader(data, pathbuf, true, false); + FileStringReader master_reader(data, input_path, true, false); master_reader.ParseFile(); for (int i = 0; i < mgo.numleft; i++) { data.FreeTranslation(); - const char *translation = replace_pathsep(mgo.argv[i]); - const char *file = strrchr(translation, PATHSEPCHAR); - FileStringReader translation_reader(data, translation, false, file == nullptr || strcmp(file + 1, "english.txt") != 0); + std::filesystem::path lang_file = mgo.argv[i]; + FileStringReader translation_reader(data, lang_file, false, lang_file.filename() != "english.txt"); translation_reader.ParseFile(); // target file if (_errors != 0) return 1; /* get the targetfile, strip any directories and append to destination path */ - r = strrchr(mgo.argv[i], PATHSEPCHAR); - mkpath(pathbuf, lastof(pathbuf), dest_dir, (r != nullptr) ? &r[1] : mgo.argv[i]); - - /* rename the .txt (input-extension) to .lng */ - r = strrchr(pathbuf, '.'); - if (r == nullptr || strcmp(r, ".txt") != 0) r = strchr(pathbuf, '\0'); - strecpy(r, ".lng", lastof(pathbuf)); + std::filesystem::path output_file = dest_dir; + output_file /= lang_file.filename(); + output_file.replace_extension("lng"); - LanguageFileWriter writer(pathbuf); + LanguageFileWriter writer(output_file); writer.WriteLang(data); writer.Finalise(); /* if showing warnings, print a summary of the language */ if ((_show_todo & 2) != 0) { - fmt::print("{} warnings and {} errors for {}\n", _warnings, _errors, pathbuf); + fmt::print("{} warnings and {} errors for {}\n", _warnings, _errors, output_file); } } }