diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 3139d92e9c..1b45c22fb2 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -325,34 +325,8 @@ jobs: if: always() && github.event_name == 'pull_request' - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - name: Get check suite ID - id: check_suite_id - uses: octokit/request-action@v2.x - with: - route: GET /repos/{repository}/actions/runs/{run_id} - repository: ${{ github.repository }} - run_id: ${{ github.run_id }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Get check runs - id: check_runs - uses: octokit/request-action@v2.x - with: - route: GET /repos/{repository}/check-suites/{check_suite_id}/check-runs - repository: ${{ github.repository }} - check_suite_id: ${{ fromJson(steps.check_suite_id.outputs.data).check_suite_id }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Check annotations - shell: bash - run: | - echo '[ - ${{ toJson(fromJson(steps.check_runs.outputs.data).check_runs.*.output.title) }}, ${{ toJson(fromJson(steps.check_runs.outputs.data).check_runs.*.output.summary) }} - ]' | jq '.[0] as $t | .[1] as $s | reduce range(.[0] | length) as $i ([]; . + [if $t[$i] then $t[$i] + ": " + $s[$i] else empty end]) | .[]' - - exit $(echo '${{ toJson(fromJson(steps.check_runs.outputs.data).check_runs.*.output.annotations_count) }}' | jq 'add') + uses: OpenTTD/actions/annotation-check@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b7301abd0f..886e4e0877 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -750,6 +750,21 @@ jobs: with: arch: ${{ matrix.host }} + - name: Import code signing certificate + shell: powershell + # If this is run on a fork, there may not be a certificate set up - continue in this case + continue-on-error: true + run: | + $tempFile = [System.IO.Path]::GetTempFileName() + $bytes = [System.Convert]::FromBase64String($env:WINDOWS_CERTIFICATE_P12) + [IO.File]::WriteAllBytes($tempFile, $bytes) + $pwd = ConvertTo-SecureString $env:WINDOWS_CERTIFICATE_PASSWORD -AsPlainText -Force + Import-PfxCertificate -FilePath $tempFile -CertStoreLocation Cert:\CurrentUser\My -Password $pwd + Remove-Item $tempFile + env: + WINDOWS_CERTIFICATE_P12: ${{ secrets.WINDOWS_CERTIFICATE_P12 }} + WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} + - name: Build (with installer) if: needs.source.outputs.is_tag == 'true' shell: bash @@ -765,12 +780,15 @@ jobs: -DOPTION_USE_NSIS=ON \ -DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DWINDOWS_CERTIFICATE_COMMON_NAME="${WINDOWS_CERTIFICATE_COMMON_NAME}" \ # EOF echo "::endgroup::" echo "::group::Build" cmake --build . echo "::endgroup::" + env: + WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }} - name: Build (without installer) if: needs.source.outputs.is_tag != 'true' @@ -786,12 +804,15 @@ jobs: -DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \ -DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DWINDOWS_CERTIFICATE_COMMON_NAME="${WINDOWS_CERTIFICATE_COMMON_NAME}" \ # EOF echo "::endgroup::" echo "::group::Build" cmake --build . echo "::endgroup::" + env: + WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }} - name: Create bundles shell: bash @@ -813,6 +834,17 @@ jobs: rm -f bundles/*.sha256 echo "::endgroup::" + - name: Sign installer + if: needs.source.outputs.is_tag == 'true' + shell: bash + # If this is run on a fork, there may not be a certificate set up - continue in this case + continue-on-error: true + run: | + cd ${GITHUB_WORKSPACE}/build/bundles + ../../os/windows/sign.bat *.exe "${WINDOWS_CERTIFICATE_COMMON_NAME}" + env: + WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }} + - name: Store bundles uses: actions/upload-artifact@v2 with: diff --git a/CMakeLists.txt b/CMakeLists.txt index 17c5ac238a..5b0150d3d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,6 +311,10 @@ target_link_libraries(openttd Threads::Threads ) +if(HAIKU) + target_link_libraries(openttd "be" "network" "midi") +endif() + if(IPO_FOUND) set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE True) set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL True) diff --git a/changelog.txt b/changelog.txt index 703f434afa..bf75edde4f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2186,7 +2186,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: [NewGRF] Additional text in fund industry window is NewGRF supplied and thus should have a default colour (r22631) - Fix: Also initialise _old_vds with newgame settings; TTD savegames do not contain these settings [FS#4622] (r22626) - Fix: Do not zero the orders of disaster vehicles when converting savegames [FS#4642] (r22625) -- Fix: When closing an AI company the local player cheated to, we need to cheat him to another company [FS#4654] (r22624, r22623) +- Fix: When closing an AI company the local player cheated to, we need to cheat them to another company [FS#4654] (r22624, r22623) - Fix: When closing down companies their shares in other companies must be sold even if share trading is disabled at that point of time (r22622) - Fix: When asking the user to confirm an unsafe unpausing, there is no need to execute a command if 'no' is chosen. This also prevents crashing when clicking unpause while the confirm window is shown (r22621) - Fix: Enforce refit orders to be 'always go to depot' orders; service-only and stop-in-depot orders make no sense with refitting [FS#4651] (r22620) @@ -2908,7 +2908,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Chat message caused glitch when rejoining a network game [FS#3757] (r19629) - Fix: Desync when a command is received and in the queue while a client starts joining, i.e. save the game state. This can happen in two ways: with frame_freq > 1 a command received in a previous frame might not be executed yet or when a command is received in the same frame as the join but before the savegame is made. In both cases the joining client would not get all commands to get in-sync with the server (and the other clients) (r19620) - Fix: Company related graphs were not updated correctly after changing the company colour [FS#3763] (r19615) -- Fix: Possible invalid read when server moves client to spectators before he finishes joining [FS#3755] (r19613) +- Fix: Possible invalid read when server moves client to spectators before they finish joining [FS#3755] (r19613) - Fix: Crash when opening a savegame with a waypoint from around 0.4.0 [FS#3756] (r19612) - Fix: Improve joining behaviour; kicking clients when entering passwords that was just cleared, 'connection lost' for people failing the password, access restriction circumvention [CVE-2010-0401] [FS#3754] (r19610, r19609, r19608, r19607, r19606) - Fix: Desync debugging; false positives in the cache validity checks and saving/loading the command stream (r19619, r19617, r19602, r19601, r19600, r19596, r19593, r19592, r19589, r19587, r19586) @@ -3263,7 +3263,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Do not account for path reservation costs when entering a signal block via a 'block' signal. This way you will not get double penalties, both red signals and reservation costs, for the block signalled tracks [FS#2722] (r18535) - Fix: [NewGRF] An industry NewGRF that defined a too small size for action0 prop 0A could cause a crash (r18527) - Fix: Allegro does not like to work with extmidi, so warn the user about that [FS#3272] (r18520) -- Fix: When you pass a signal at danger, in a PBS controlled area, do not try to do the 'safe' thing and stop, but continue going; the user wanted the train to pass the signal at danger so (s)he has to suffer the consequences. Of course one can always stop the train manually [FS#2891] (r18515) +- Fix: When you pass a signal at danger, in a PBS controlled area, do not try to do the 'safe' thing and stop, but continue going; the user wanted the train to pass the signal at danger so they have to suffer the consequences. Of course one can always stop the train manually [FS#2891] (r18515) - Fix: No error message was created for the first fatal NewGRF error [FS#3368] (r18506) - Fix: Improve airport movement on several airports [FS#3169] (r18505) - Fix: Autoreplace and autorenew always reset their cargo sub type to 0. Now find a sub cargo type with the exact same name and use that, otherwise fallback to 0. So cargo sub types can be maintained via autoreplace *if* the new vehicle supports the same cargo sub type [FS#3159] (r18499) @@ -3746,7 +3746,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Make the join/spectate command require to be connected to a network game; in SP it could lead to crashes (r15514) - Fix: Generating a map with the original map generator with freeform edges on resulted in a crash [FS#2641] (r15511) - Fix: Pre-0.5 OpenTTD stored new_nonstop and full_load_any in a different way, savegame conversion was not working for them (r15500) -- Fix: Crash when opening the game options when the currently loaded base graphics pack has less than 2 valid graphics files. For example when someone replaces all his/her original base graphics with custom work (but keeps the name) or renames the dos ones to windows or vice versa [FS#2630] (r15476) +- Fix: Crash when opening the game options when the currently loaded base graphics pack has less than 2 valid graphics files. For example when someone replaces all their original base graphics with custom work (but keeps the name) or renames the dos ones to windows or vice versa [FS#2630] (r15476) 0.7.0-beta1 (2009-02-16) @@ -4508,7 +4508,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Switching players (using the cheat) crashed on Big Endian machines [FS#1150] (r11023) - Fix: The canal border determination did not take oil rigs into consideration (r11022) - Fix: Do not display income/expenses when they do not belong to a 'valid' tile, like the money cheat/giving money [FS#1175] (r11021) -- Fix: One could not give money when (s)he had too much money or rather: when casting the amount of money to an int32 becomes negative [FS#1174] (r11020) +- Fix: One could not give money when they had too much money or rather: when casting the amount of money to an int32 becomes negative [FS#1174] (r11020) - Fix: When determining the gender of a string, do not assume that the gender is in the front of the string when there can be case switching code at that location [FS#1104] (r10792) - Fix: Determining whether there is a tunnel going under the lowered area is only needed in two directions instead of all four, so take the directions (one for each axis) to the nearest border (along the given axis) [FS#1058] (r10686) - Fix: Graphical glitches when the 'link landscape toolbar' patch is turned on when opening one of the construction toolbars [FS#1076] (r10685) @@ -4569,7 +4569,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Do not unconditionally assume that a tile has a depot (r11027) - Fix: Give a more correct error when building some things on tile 0 [FS#1173] (r11024) - Fix: Do not display income/expenses when they do not belong to a 'valid' tile, like the money cheat and giving money [FS#1175] (r11021) -- Fix: One could not give money when (s)he had too much money [FS#1174] (r11020) +- Fix: One could not give money when they had too much money [FS#1174] (r11020) - Fix: Disallow buying/selling shares in your own company or a bankrupt company [FS#1169] (r11018) - Fix: Crash when quitting the game in one of the end score windows [FS#1218] (r11071) @@ -5529,7 +5529,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Vehicles slow down under bridge if the track is on a foundation - Fix: You can no longer change name of waypoints whom are owned by somebody else - Fix: Shares are now also sold when a company goes bankrupt [SF#1090313] -- Fix: It is no longer possible to crash trains of other companies by building a depot close to a station; trains do no longer enter tiles that do not belong to his owner [SF#1087701] +- Fix: It is no longer possible to crash trains of other companies by building a depot close to a station; trains do no longer enter tiles that do not belong to their owner [SF#1087701] - Fix: Crashed trains are not reported to have too few orders any more [SF#1087403] - Fix: Backup-order-list was not closed with an OT_NOTHING, [SF#1086375] - Fix: Docks now have a button to display the catchment area [SF#1085255] diff --git a/cmake/CompileFlags.cmake b/cmake/CompileFlags.cmake index d709f6a343..4297447e4b 100644 --- a/cmake/CompileFlags.cmake +++ b/cmake/CompileFlags.cmake @@ -167,7 +167,7 @@ macro(compile_flags) message(FATAL_ERROR "No warning flags are set for this compiler yet; please consider creating a Pull Request to add support for this compiler.") endif() - if(NOT WIN32) + if(NOT WIN32 AND NOT HAIKU) # rdynamic is used to get useful stack traces from crash reports. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic") endif() diff --git a/cmake/InstallAndPackage.cmake b/cmake/InstallAndPackage.cmake index 08c34226d1..e0a91f72f4 100644 --- a/cmake/InstallAndPackage.cmake +++ b/cmake/InstallAndPackage.cmake @@ -139,6 +139,13 @@ elseif(WIN32) endif() set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-windows-${CPACK_SYSTEM_NAME}") + + if(WINDOWS_CERTIFICATE_COMMON_NAME) + add_custom_command(TARGET openttd + POST_BUILD + COMMAND "${CMAKE_SOURCE_DIR}/os/windows/sign.bat" "$" "${WINDOWS_CERTIFICATE_COMMON_NAME}" + ) + endif() elseif(UNIX) # With FHS, we can create deb/rpm/... Without it, they would be horribly broken # and not work. The other way around is also true; with FHS they are not diff --git a/os/emscripten/cmake/FindLibLZMA.cmake b/os/emscripten/cmake/FindLibLZMA.cmake index 99d1ca640a..e8a024c4ee 100644 --- a/os/emscripten/cmake/FindLibLZMA.cmake +++ b/os/emscripten/cmake/FindLibLZMA.cmake @@ -1,5 +1,5 @@ # LibLZMA is a recent addition to the emscripten SDK, so it is possible -# someone hasn't updated his SDK yet. Test out if the SDK supports LibLZMA. +# someone hasn't updated their SDK yet. Test out if the SDK supports LibLZMA. include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_FLAGS "-sUSE_LIBLZMA=1") diff --git a/os/windows/sign.bat b/os/windows/sign.bat new file mode 100644 index 0000000000..0e4291f9b8 --- /dev/null +++ b/os/windows/sign.bat @@ -0,0 +1,18 @@ +@echo off +REM Signing script +REM Arguments: sign.bat exe_to_sign certificate_subject_name + +REM This is a loose wrapper around the Microsoft signtool application (included in the Windows SDK). +REM See https://docs.microsoft.com/en-us/dotnet/framework/tools/signtool-exe for more details. + +REM Path to signtool.exe +IF NOT DEFINED SIGNTOOL_PATH (SET SIGNTOOL_PATH=signtool) + +REM URL of the timestamp server +IF NOT DEFINED SIGNTOOL_TIMESTAMP_URL (SET SIGNTOOL_TIMESTAMP_URL=http://timestamp.digicert.com) + +REM Sign with SHA-1 for Windows 7 and below +"%SIGNTOOL_PATH%" sign -v -n %2 -t %SIGNTOOL_TIMESTAMP_URL% %1 + +REM Sign with SHA-256 for Windows 8 and above +"%SIGNTOOL_PATH%" sign -v -n %2 -tr %SIGNTOOL_TIMESTAMP_URL% -fd sha256 -td sha256 -as %1 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8022223ed3..b7a29bde3e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -514,6 +514,7 @@ add_files( viewport_type.h void_cmd.cpp void_map.h + walltime_func.h water.h water_cmd.cpp water_map.h diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index f0167ae0d2..00716a34b0 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1044,7 +1044,7 @@ static bool AircraftController(Aircraft *v) if (count == 0) return false; /* If the plane will be a few subpixels away from the destination after - * this movement loop, start nudging him towards the exact position for + * this movement loop, start nudging it towards the exact position for * the whole loop. Otherwise, heavily depending on the speed of the plane, * it is possible we totally overshoot the target, causing the plane to * make a loop, and trying again, and again, and again .. */ diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index e04eba302a..a4d7bcb7d4 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -379,11 +379,14 @@ public: const Group *g = Group::GetIfValid(this->sel_group); if (g != nullptr) { remove_wagon = HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL); + SetDParam(0, STR_GROUP_NAME); + SetDParam(1, sel_group); } else { const Company *c = Company::Get(_local_company); remove_wagon = c->settings.renew_keep_length; + SetDParam(0, STR_GROUP_DEFAULT_TRAINS + this->window_number); } - SetDParam(0, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF); + SetDParam(2, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF); break; } @@ -642,6 +645,20 @@ public: } } + bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override + { + if (widget != WID_RV_TRAIN_WAGONREMOVE_TOGGLE) return false; + + if (Group::IsValidID(this->sel_group)) { + uint64 params[1]; + params[0] = STR_REPLACE_REMOVE_WAGON_HELP; + GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_GROUP_HELP, 1, params, close_cond); + } else { + GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_HELP, 0, nullptr, close_cond); + } + return true; + } + void OnResize() override { this->vscroll[0]->SetCapacityFromWidget(this, WID_RV_LEFT_MATRIX); diff --git a/src/blitter/32bpp_anim_sse4.cpp b/src/blitter/32bpp_anim_sse4.cpp index 5701d0c13d..779cc99543 100644 --- a/src/blitter/32bpp_anim_sse4.cpp +++ b/src/blitter/32bpp_anim_sse4.cpp @@ -155,6 +155,7 @@ bmno_full_transparency: if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) { if (src->a == 0) { + /* Complete transparency. */ } else if (src->a == 255) { *anim = *(const uint16*) src_mv; *dst = (src_mv->m >= PALETTE_ANIM_START) ? AdjustBrightneSSE(LookupColourInPalette(src_mv->m), src_mv->v) : *src; diff --git a/src/blitter/common.hpp b/src/blitter/common.hpp index aaf63cd6a9..cd3b6276a4 100644 --- a/src/blitter/common.hpp +++ b/src/blitter/common.hpp @@ -16,14 +16,14 @@ #include template -void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel) +void Blitter::DrawLineGeneric(int x1, int y1, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel) { int dy; int dx; int stepx; int stepy; - dy = (y2 - y) * 2; + dy = (y2 - y1) * 2; if (dy < 0) { dy = -dy; stepy = -1; @@ -31,7 +31,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in stepy = 1; } - dx = (x2 - x) * 2; + dx = (x2 - x1) * 2; if (dx < 0) { dx = -dx; stepx = -1; @@ -41,7 +41,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in if (dx == 0 && dy == 0) { /* The algorithm below cannot handle this special case; make it work at least for line width 1 */ - if (x >= 0 && x < screen_width && y >= 0 && y < screen_height) set_pixel(x, y); + if (x1 >= 0 && x1 < screen_width && y1 >= 0 && y1 < screen_height) set_pixel(x1, y1); return; } @@ -67,14 +67,14 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in int dash_count = 0; if (dx > dy) { if (stepx < 0) { - std::swap(x, x2); - std::swap(y, y2); + std::swap(x1, x2); + std::swap(y1, y2); stepy = -stepy; } - if (x2 < 0 || x >= screen_width) return; + if (x2 < 0 || x1 >= screen_width) return; - int y_low = y; - int y_high = y; + int y_low = y1; + int y_high = y1; int frac_low = dy - frac_diff / 2; int frac_high = dy + frac_diff / 2; @@ -87,10 +87,10 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in y_high += stepy; } - if (x < 0) { - dash_count = (-x) % (dash + gap); + if (x1 < 0) { + dash_count = (-x1) % (dash + gap); auto adjust_frac = [&](int64 frac, int &y_bound) -> int { - frac -= ((int64) dy) * ((int64) x); + frac -= ((int64) dy) * ((int64) x1); if (frac >= 0) { int quotient = frac / dx; int remainder = frac % dx; @@ -101,17 +101,17 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in }; frac_low = adjust_frac(frac_low, y_low); frac_high = adjust_frac(frac_high, y_high); - x = 0; + x1 = 0; } x2++; if (x2 > screen_width) { x2 = screen_width; } - while (x != x2) { + while (x1 != x2) { if (dash_count < dash) { for (int y = y_low; y != y_high; y += stepy) { - if (y >= 0 && y < screen_height) set_pixel(x, y); + if (y >= 0 && y < screen_height) set_pixel(x1, y); } } if (frac_low >= 0) { @@ -122,21 +122,21 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in y_high += stepy; frac_high -= dx; } - x++; + x1++; frac_low += dy; frac_high += dy; if (++dash_count >= dash + gap) dash_count = 0; } } else { if (stepy < 0) { - std::swap(x, x2); - std::swap(y, y2); + std::swap(x1, x2); + std::swap(y1, y2); stepx = -stepx; } - if (y2 < 0 || y >= screen_height) return; + if (y2 < 0 || y1 >= screen_height) return; - int x_low = x; - int x_high = x; + int x_low = x1; + int x_high = x1; int frac_low = dx - frac_diff / 2; int frac_high = dx + frac_diff / 2; @@ -149,10 +149,10 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in x_high += stepx; } - if (y < 0) { - dash_count = (-y) % (dash + gap); + if (y1 < 0) { + dash_count = (-y1) % (dash + gap); auto adjust_frac = [&](int64 frac, int &x_bound) -> int { - frac -= ((int64) dx) * ((int64) y); + frac -= ((int64) dx) * ((int64) y1); if (frac >= 0) { int quotient = frac / dy; int remainder = frac % dy; @@ -163,17 +163,17 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in }; frac_low = adjust_frac(frac_low, x_low); frac_high = adjust_frac(frac_high, x_high); - y = 0; + y1 = 0; } y2++; if (y2 > screen_height) { y2 = screen_height; } - while (y != y2) { + while (y1 != y2) { if (dash_count < dash) { for (int x = x_low; x != x_high; x += stepx) { - if (x >= 0 && x < screen_width) set_pixel(x, y); + if (x >= 0 && x < screen_width) set_pixel(x, y1); } } if (frac_low >= 0) { @@ -184,7 +184,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in x_high += stepx; frac_high -= dy; } - y++; + y1++; frac_low += dx; frac_high += dx; if (++dash_count >= dash + gap) dash_count = 0; diff --git a/src/blitter/factory.hpp b/src/blitter/factory.hpp index 94f3f99988..322b11c953 100644 --- a/src/blitter/factory.hpp +++ b/src/blitter/factory.hpp @@ -91,7 +91,7 @@ public: } /** - * Find the requested blitter and return his class. + * Find the requested blitter and return its class. * @param name the blitter to select. * @post Sets the blitter so GetCurrentBlitter() returns it too. */ diff --git a/src/cargo_type.h b/src/cargo_type.h index 89e6f13808..83af40a83a 100644 --- a/src/cargo_type.h +++ b/src/cargo_type.h @@ -61,6 +61,7 @@ enum CargoType { CT_PLASTIC = 10, CT_FIZZY_DRINKS = 11, + NUM_ORIGINAL_CARGO = 12, NUM_CARGO = 64, ///< Maximal number of cargo types in a game. CT_AUTO_REFIT = 0xFD, ///< Automatically choose cargo type when doing auto refitting. diff --git a/src/cargotype.cpp b/src/cargotype.cpp index bf9561dda8..a6ea680d80 100644 --- a/src/cargotype.cpp +++ b/src/cargotype.cpp @@ -77,6 +77,28 @@ void SetupCargoForClimate(LandscapeID l) } } +/** + * Get the cargo ID of a default cargo, if present. + * @param l Landscape + * @param ct Default cargo type. + * @return ID number if the cargo exists, else #CT_INVALID + */ +CargoID GetDefaultCargoID(LandscapeID l, CargoType ct) +{ + assert(l < lengthof(_default_climate_cargo)); + + if (ct == CT_INVALID) return CT_INVALID; + + assert(ct < lengthof(_default_climate_cargo[0])); + CargoLabel cl = _default_climate_cargo[l][ct]; + /* Bzzt: check if cl is just an index into the cargo table */ + if (cl < lengthof(_default_cargo)) { + cl = _default_cargo[cl].label; + } + + return GetCargoIDByLabel(cl); +} + /** * Get the cargo ID by cargo label. * @param cl Cargo type to get. diff --git a/src/cargotype.h b/src/cargotype.h index 86b1887c93..34f5e53a21 100644 --- a/src/cargotype.h +++ b/src/cargotype.h @@ -186,6 +186,7 @@ extern CargoTypes _standard_cargo_mask; void SetupCargoForClimate(LandscapeID l); CargoID GetCargoIDByLabel(CargoLabel cl); CargoID GetCargoIDByBitnum(uint8 bitnum); +CargoID GetDefaultCargoID(LandscapeID l, CargoType ct); void InitializeSortedCargoSpecs(); extern std::vector _sorted_cargo_specs; diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 876b3132f6..8d570bb403 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -407,10 +407,10 @@ struct CheatWindow : Window { SetDParam(0, val * 1000 >> 16); SetDParam(1, 3); StringID str = (btn == CHT_INFLATION_COST) ? STR_CHEAT_INFLATION_COST_QUERY_CAPT : STR_CHEAT_INFLATION_INCOME_QUERY_CAPT; - char *saved = _settings_game.locale.digit_group_separator; - _settings_game.locale.digit_group_separator = const_cast(""); + std::string saved = std::move(_settings_game.locale.digit_group_separator); + _settings_game.locale.digit_group_separator = ""; ShowQueryString(STR_JUST_DECIMAL, str, 12, this, CS_NUMERAL_DECIMAL, QSF_ACCEPT_UNCHANGED); - _settings_game.locale.digit_group_separator = saved; + _settings_game.locale.digit_group_separator = std::move(saved); return; } diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 51bc4f95cf..801c6d45b2 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -862,7 +862,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (client_id == _network_own_client_id) { assert(_local_company == COMPANY_SPECTATOR); SetLocalCompany(c->index); - if (!StrEmpty(_settings_client.network.default_company_pass)) { + if (!_settings_client.network.default_company_pass.empty()) { NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass); } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index bac4d59a3d..303b58ee44 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -838,11 +838,11 @@ public: case WID_SCL_PRI_COL_DROPDOWN: { this->square = GetSpriteSize(SPR_SQUARE); - int padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10; + int string_padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10; for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) { - size->width = std::max(size->width, GetStringBoundingBox(*id).width + padding); + size->width = std::max(size->width, GetStringBoundingBox(*id).width + string_padding); } - size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + padding); + size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + string_padding); break; } } diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 11a1c72864..688c33bb7f 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -54,6 +54,7 @@ #include "linkgraph/linkgraphjob.h" #include "base_media_base.h" #include "debug_settings.h" +#include "walltime_func.h" #include #include "safeguards.h" @@ -793,14 +794,14 @@ DEF_CONSOLE_CMD(ConClientNickChange) return true; } - char *client_name = argv[2]; + std::string client_name(argv[2]); StrTrimInPlace(client_name); if (!NetworkIsValidClientName(client_name)) { IConsoleError("Cannot give a client an empty name"); return true; } - if (!NetworkServerChangeClientName(client_id, client_name)) { + if (!NetworkServerChangeClientName(client_id, client_name.c_str())) { IConsoleError("Cannot give a client a duplicate name"); } @@ -969,13 +970,13 @@ DEF_CONSOLE_CMD(ConNetworkReconnect) break; } - if (StrEmpty(_settings_client.network.last_joined)) { + if (_settings_client.network.last_joined.empty()) { IConsolePrint(CC_DEFAULT, "No server for reconnecting."); return true; } /* Don't resolve the address first, just print it directly as it comes from the config file. */ - IConsolePrintF(CC_DEFAULT, "Reconnecting to %s ...", _settings_client.network.last_joined); + IConsolePrintF(CC_DEFAULT, "Reconnecting to %s ...", _settings_client.network.last_joined.c_str()); return NetworkClientConnectGame(_settings_client.network.last_joined, playas); } @@ -1437,10 +1438,9 @@ DEF_CONSOLE_CMD(ConGetSysDate) return true; } - time_t t; - time(&t); - auto timeinfo = localtime(&t); - IConsolePrintF(CC_DEFAULT, "System Date: %04d-%02d-%02d %02d:%02d:%02d", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + char buffer[lengthof("2000-01-02 03:04:05")]; + LocalTime::Format(buffer, lastof(buffer), "%Y-%m-%d %H:%M:%S"); + IConsolePrintF(CC_DEFAULT, "System Date: %s", buffer); return true; } @@ -1738,7 +1738,7 @@ DEF_CONSOLE_CMD(ConCompanies) if (c->is_ai) { password_state = "AI"; } else if (_network_server) { - password_state = StrEmpty(_network_company_states[c->index].password) ? "unprotected" : "protected"; + password_state = _network_company_states[c->index].password.empty() ? "unprotected" : "protected"; } char colour[512]; @@ -1840,7 +1840,7 @@ DEF_CONSOLE_CMD(ConCompanyPassword) } CompanyID company_id; - const char *password; + std::string password; const char *errormsg; if (argc == 2) { @@ -1862,10 +1862,10 @@ DEF_CONSOLE_CMD(ConCompanyPassword) password = NetworkChangeCompanyPassword(company_id, password); - if (StrEmpty(password)) { + if (password.empty()) { IConsolePrintF(CC_WARNING, "Company password cleared"); } else { - IConsolePrintF(CC_WARNING, "Company password changed to: %s", password); + IConsolePrintF(CC_WARNING, "Company password changed to: %s", password.c_str()); } return true; @@ -1918,7 +1918,7 @@ DEF_CONSOLE_CMD(ConCompanyPasswordHashes) char colour[512]; GetString(colour, STR_COLOUR_DARK_BLUE + _company_colours[c->index], lastof(colour)); IConsolePrintF(CC_INFO, "#:%d(%s) Company Name: '%s' Hash: '%s'", - c->index + 1, colour, company_name, _network_company_states[c->index].password); + c->index + 1, colour, company_name, _network_company_states[c->index].password.c_str()); } return true; diff --git a/src/console_internal.h b/src/console_internal.h index 9ac4e12759..43081c0e31 100644 --- a/src/console_internal.h +++ b/src/console_internal.h @@ -29,7 +29,7 @@ enum ConsoleHookResult { * effect they produce are carried out. The arguments to the commands * are given to them, each input word separated by a double-quote (") is an argument * If you want to handle multiple words as one, enclose them in double-quotes - * eg. 'say "hello sexy boy"' + * eg. 'say "hello everybody"' */ typedef bool IConsoleCmdProc(byte argc, char *argv[]); typedef ConsoleHookResult IConsoleHook(bool echo); diff --git a/src/core/kdtree.hpp b/src/core/kdtree.hpp index 392e31b8ec..cb864e04d7 100644 --- a/src/core/kdtree.hpp +++ b/src/core/kdtree.hpp @@ -274,7 +274,7 @@ class Kdtree { } template - void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, Outputter outputter) const + void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, const Outputter &outputter) const { /* Dimension index of current level */ int dim = level % 2; @@ -458,7 +458,7 @@ public: * @param outputter Callback used to return values from the search. */ template - void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, Outputter outputter) const + void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, const Outputter &outputter) const { assert(x1 < x2); assert(y1 < y2); diff --git a/src/crashlog.cpp b/src/crashlog.cpp index 16ae1245e5..5c0cfbdd6c 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -36,8 +36,7 @@ #include "game/game_info.hpp" #include "company_base.h" #include "company_func.h" - -#include +#include "walltime_func.h" #ifdef WITH_ALLEGRO # include @@ -420,7 +419,6 @@ char *CrashLog::LogCommandLog(char *buffer, const char *last) const */ char *CrashLog::FillCrashLog(char *buffer, const char *last) const { - time_t cur_time = time(nullptr); buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n"); if (GamelogTestEmergency()) { @@ -430,7 +428,7 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last) const buffer += seprintf(buffer, last, "-=-=- As you loaded a savegame for which you do not have the required NewGRFs no crash information would ordinarily be generated. -=-=-\n\n"); } - buffer += seprintf(buffer, last, "Crash at: %s", asctime(gmtime(&cur_time))); + buffer += UTCTime::Format(buffer, last, "Crash at: %Y-%m-%d %H:%M:%S (UTC)\n"); buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i, %i) (DL: %u)\n", _cur_date_ymd.year, _cur_date_ymd.month + 1, _cur_date_ymd.day, _date_fract, _tick_skip_counter, _settings_game.economy.day_length_factor); if (_game_load_time != 0) { diff --git a/src/currency.h b/src/currency.h index e97fc6cb84..10caa59d3a 100644 --- a/src/currency.h +++ b/src/currency.h @@ -70,11 +70,11 @@ enum Currencies { /** Specification of a currency. */ struct CurrencySpec { - uint16 rate; - char separator[8]; - Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO. - char prefix[16]; - char suffix[16]; + uint16 rate; ///< The conversion rate compared to the base currency. + std::string separator; ///< The thousands separator for this currency. + Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO. + std::string prefix; ///< Prefix to apply when formatting money in this currency. + std::string suffix; ///< Suffix to apply when formatting money in this currency. /** * The currency symbol is represented by two possible values, prefix and suffix * Usage of one or the other is determined by #symbol_pos. @@ -89,11 +89,9 @@ struct CurrencySpec { CurrencySpec() = default; - CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) : rate(rate), to_euro(to_euro), symbol_pos(symbol_pos), name(name) + CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) : + rate(rate), separator(separator), to_euro(to_euro), prefix(prefix), suffix(suffix), symbol_pos(symbol_pos), name(name) { - strecpy(this->separator, separator, lastof(this->separator)); - strecpy(this->prefix, prefix, lastof(this->prefix)); - strecpy(this->suffix, suffix, lastof(this->suffix)); } }; diff --git a/src/debug.cpp b/src/debug.cpp index 8bb3332052..5f099adf67 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -26,7 +26,7 @@ #include "os/windows/win32.h" #endif -#include +#include "walltime_func.h" #include "network/network_admin.h" SOCKET _debug_socket = INVALID_SOCKET; @@ -329,8 +329,7 @@ const char *GetLogPrefix() { static char _log_prefix[24]; if (_settings_client.gui.show_date_in_logs) { - time_t cur_time = time(nullptr); - strftime(_log_prefix, sizeof(_log_prefix), "[%Y-%m-%d %H:%M:%S] ", localtime(&cur_time)); + LocalTime::Format(_log_prefix, lastof(_log_prefix), "[%Y-%m-%d %H:%M:%S] "); } else { *_log_prefix = '\0'; } diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 5be78f465b..5dad2c9126 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -398,11 +398,11 @@ struct DepotWindow : Window { uint16 rows_in_display = wid->current_y / wid->resize_y; - uint16 num = this->vscroll->GetPosition() * this->num_columns; + uint num = this->vscroll->GetPosition() * this->num_columns; uint maxval = static_cast(std::min(this->vehicle_list.size(), num + (rows_in_display * this->num_columns))); int y; for (y = r.top + 1; num < maxval; y += this->resize.step_height) { // Draw the rows - for (byte i = 0; i < this->num_columns && num < maxval; i++, num++) { + for (uint i = 0; i < this->num_columns && num < maxval; i++, num++) { /* Draw all vehicles in the current row */ const Vehicle *v = this->vehicle_list[num]; if (this->num_columns == 1) { diff --git a/src/economy.cpp b/src/economy.cpp index f8c6a0afe6..8c3b7edf13 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -320,7 +320,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) for (const Company *c : Company::Iterate()) { for (i = 0; i < 4; i++) { if (c->share_owners[i] == old_owner) { - /* Sell his shares */ + /* Sell its shares */ CommandCost res = DoCommand(0, c->index, 0, DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY); /* Because we are in a DoCommand, we can't just execute another one and * expect the money to be removed. We need to do it ourself! */ @@ -351,7 +351,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } /* Temporarily increase the company's money, to be sure that - * removing his/her property doesn't fail because of lack of money. + * removing their property doesn't fail because of lack of money. * Not too drastically though, because it could overflow */ if (new_owner == INVALID_OWNER) { Company::Get(old_owner)->money = UINT64_MAX >> 2; // jackpot ;p diff --git a/src/error.h b/src/error.h index a8a9223a7d..5519013be1 100644 --- a/src/error.h +++ b/src/error.h @@ -45,6 +45,9 @@ public: ~ErrorMessageData(); ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration = 0, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = nullptr, uint textref_stack_size = 0, const uint32 *textref_stack = nullptr, StringID extra_msg = INVALID_STRING_ID); + /* Remove the copy assignment, as the default implementation will not do the right thing. */ + ErrorMessageData &operator=(ErrorMessageData &rhs) = delete; + /** Check whether error window shall display a company manager face */ bool HasFace() const { return face != INVALID_COMPANY; } diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 0e80ba60ff..0fb55fcb33 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -53,7 +53,7 @@ void LoadCheckData::Clear() this->map_size_x = this->map_size_y = 256; // Default for old savegames which do not store mapsize. this->current_date = 0; - memset(&this->settings, 0, sizeof(this->settings)); + this->settings = {}; for (auto &pair : this->companies) { delete pair.second; diff --git a/src/fontcache.cpp b/src/fontcache.cpp index c60d088aec..50ad07973b 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -489,7 +489,7 @@ static void LoadFreeTypeFont(FontSize fs) case FS_MONO: settings = &_freetype.mono; break; } - if (StrEmpty(settings->font)) return; + if (settings->font.empty()) return; if (_library == nullptr) { if (FT_Init_FreeType(&_library) != FT_Err_Ok) { @@ -500,19 +500,20 @@ static void LoadFreeTypeFont(FontSize fs) DEBUG(freetype, 2, "Initialized"); } + const char *font_name = settings->font.c_str(); FT_Face face = nullptr; /* If font is an absolute path to a ttf, try loading that first. */ - FT_Error error = FT_New_Face(_library, settings->font, 0, &face); + FT_Error error = FT_New_Face(_library, font_name, 0, &face); #if defined(WITH_COCOA) extern void MacOSRegisterExternalFont(const char *file_path); - if (error == FT_Err_Ok) MacOSRegisterExternalFont(settings->font); + if (error == FT_Err_Ok) MacOSRegisterExternalFont(font_name); #endif if (error != FT_Err_Ok) { /* Check if font is a relative filename in one of our search-paths. */ - std::string full_font = FioFindFullPath(BASE_DIR, settings->font); + std::string full_font = FioFindFullPath(BASE_DIR, font_name); if (!full_font.empty()) { error = FT_New_Face(_library, full_font.c_str(), 0, &face); #if defined(WITH_COCOA) @@ -522,10 +523,10 @@ static void LoadFreeTypeFont(FontSize fs) } /* Try loading based on font face name (OS-wide fonts). */ - if (error != FT_Err_Ok) error = GetFontByFaceName(settings->font, &face); + if (error != FT_Err_Ok) error = GetFontByFaceName(font_name, &face); if (error == FT_Err_Ok) { - DEBUG(freetype, 2, "Requested '%s', using '%s %s'", settings->font, face->family_name, face->style_name); + DEBUG(freetype, 2, "Requested '%s', using '%s %s'", font_name, face->family_name, face->style_name); /* Attempt to select the unicode character map */ error = FT_Select_Charmap(face, ft_encoding_unicode); @@ -555,7 +556,7 @@ static void LoadFreeTypeFont(FontSize fs) FT_Done_Face(face); static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" }; - ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", settings->font, SIZE_TO_NAME[fs], error); + ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", font_name, SIZE_TO_NAME[fs], error); return; found_face: diff --git a/src/fontcache.h b/src/fontcache.h index d12015def1..a78d89675f 100644 --- a/src/fontcache.h +++ b/src/fontcache.h @@ -218,9 +218,9 @@ static inline bool GetDrawGlyphShadow(FontSize size) /** Settings for a single freetype font. */ struct FreeTypeSubSetting { - char font[MAX_PATH]; ///< The name of the font, or path to the font. - uint size; ///< The (requested) size of the font. - bool aa; ///< Whether to do anti aliasing or not. + std::string font; ///< The name of the font, or path to the font. + uint size; ///< The (requested) size of the font. + bool aa; ///< Whether to do anti aliasing or not. const void *os_handle = nullptr; ///< Optional native OS font info. Only valid during font search. }; diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 56506672db..4e945be1d7 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -1471,7 +1471,7 @@ struct PerformanceRatingDetailWindow : Window { int64 needed = _score_info[score_type].needed; int score = _score_info[score_type].score; - /* SCORE_TOTAL has his own rules ;) */ + /* SCORE_TOTAL has its own rules ;) */ if (score_type == SCORE_TOTAL) { for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) score += _score_info[i].score; needed = SCORE_MAX; diff --git a/src/heightmap.cpp b/src/heightmap.cpp index 7b070f4405..458b0c910a 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -480,7 +480,7 @@ bool GetHeightmapDimensions(DetailedFileType dft, const char *filename, uint *x, } /** - * Load a heightmap from file and change the map in his current dimensions + * Load a heightmap from file and change the map in its current dimensions * to a landscape representing the heightmap. * It converts pixels to height. The brighter, the higher. * @param dft Type of image file. diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 53e514f1b0..245124f3ed 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -357,7 +357,7 @@ class BuildIndustryWindow : public Window { int numcargo = 0; int firstcargo = -1; - for (byte j = 0; j < cargolistlen; j++) { + for (int j = 0; j < cargolistlen; j++) { if (cargolist[j] == CT_INVALID) continue; numcargo++; if (firstcargo < 0) { @@ -419,7 +419,7 @@ public: switch (widget) { case WID_DPI_MATRIX_WIDGET: { Dimension d = GetStringBoundingBox(STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES); - for (byte i = 0; i < this->count; i++) { + for (uint16 i = 0; i < this->count; i++) { if (this->index[i] == INVALID_INDUSTRYTYPE) continue; d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(this->index[i])->name)); } @@ -438,7 +438,7 @@ public: uint extra_lines_newgrf = 0; uint max_minwidth = FONT_HEIGHT_NORMAL * MAX_MINWIDTH_LINEHEIGHTS; Dimension d = {0, 0}; - for (byte i = 0; i < this->count; i++) { + for (uint16 i = 0; i < this->count; i++) { if (this->index[i] == INVALID_INDUSTRYTYPE) continue; const IndustrySpec *indsp = GetIndustrySpec(this->index[i]); @@ -528,7 +528,7 @@ public: int icon_bottom = icon_top + this->legend.height; int y = r.top; - for (byte i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++) { + for (uint16 i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++) { bool selected = this->selected_index == i + this->vscroll->GetPosition(); if (this->index[i + this->vscroll->GetPosition()] == INVALID_INDUSTRYTYPE) { @@ -2707,14 +2707,14 @@ struct IndustryCargoesWindow : public Window { /** * Compute what and where to display for industry type \a it. - * @param it Industry type to display. + * @param displayed_it Industry type to display. */ - void ComputeIndustryDisplay(IndustryType it) + void ComputeIndustryDisplay(IndustryType displayed_it) { this->GetWidget(WID_IC_CAPTION)->widget_data = STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION; - this->ind_cargo = it; + this->ind_cargo = displayed_it; _displayed_industries.reset(); - _displayed_industries.set(it); + _displayed_industries.set(displayed_it); this->fields.clear(); CargoesRow &row = this->fields.emplace_back(); @@ -2724,7 +2724,7 @@ struct IndustryCargoesWindow : public Window { row.columns[3].MakeEmpty(CFT_SMALL_EMPTY); row.columns[4].MakeHeader(STR_INDUSTRY_CARGOES_CUSTOMERS); - const IndustrySpec *central_sp = GetIndustrySpec(it); + const IndustrySpec *central_sp = GetIndustrySpec(displayed_it); bool houses_supply = HousesCanSupply(central_sp->accepts_cargo, lengthof(central_sp->accepts_cargo)); bool houses_accept = HousesCanAccept(central_sp->produced_cargo, lengthof(central_sp->produced_cargo)); /* Make a field consisting of two cargo columns. */ @@ -2741,7 +2741,7 @@ struct IndustryCargoesWindow : public Window { } /* Add central industry. */ int central_row = 1 + num_indrows / 2; - this->fields[central_row].columns[2].MakeIndustry(it); + this->fields[central_row].columns[2].MakeIndustry(displayed_it); this->fields[central_row].ConnectIndustryProduced(2); this->fields[central_row].ConnectIndustryAccepted(2); diff --git a/src/ini_load.cpp b/src/ini_load.cpp index 86cc8d5d5d..2b3f89bb26 100644 --- a/src/ini_load.cpp +++ b/src/ini_load.cpp @@ -38,13 +38,9 @@ IniItem::~IniItem() * Replace the current value with another value. * @param value the value to replace with. */ -void IniItem::SetValue(const char *value) +void IniItem::SetValue(const std::string_view value) { - if (value == nullptr) { - this->value.reset(); - } else { - this->value.emplace(value); - } + this->value.emplace(value); } /** diff --git a/src/ini_type.h b/src/ini_type.h index 9edf8a8dc9..84cb19bf19 100644 --- a/src/ini_type.h +++ b/src/ini_type.h @@ -33,7 +33,7 @@ struct IniItem { IniItem(struct IniGroup *parent, const std::string &name); ~IniItem(); - void SetValue(const char *value); + void SetValue(const std::string_view value); }; /** A group within an ini file. */ diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index 59b00090c0..58c32349e4 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -3629,7 +3629,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglev Voertuie STR_REPLACE_ROAD_VEHICLES :Padvoertuie STR_REPLACE_TRAM_VEHICLES :Tremweg voertuie -STR_REPLACE_REMOVE_WAGON :{BLACK}Wa verwydering: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Maak autovervanging die lengte van 'n trein dieselfde hou deur verwydering waens (deur voor te begin), indien die enjin vervanging die trein langer sal maak # Vehicle view diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 76de82a592..cd94260db0 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -3155,7 +3155,6 @@ STR_REPLACE_MAGLEV_VEHICLES :مركبات م STR_REPLACE_TRAM_VEHICLES :مركبات الترام -STR_REPLACE_REMOVE_WAGON :{BLACK} إزالة العربات: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK} المحافظة على طول القطار بازالة عربات ابتداء من المقدمة عند التبديل - عندما يكون التبدل ينتج قطارا اطول. # Vehicle view diff --git a/src/lang/basque.txt b/src/lang/basque.txt index f43d98b922..c0abe68fa4 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -3384,7 +3384,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Tren magnetikoa STR_REPLACE_TRAM_VEHICLES :Tranbia ibilgailuak -STR_REPLACE_REMOVE_WAGON :{BLACK}Bagoiak ezabatu: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ordezkatze automatikoari agindu trenaren luzera errespetatzea, bagoiak ezabatuz luzera handitzen badute (trenaren hasierako bagoietik hasita) # Vehicle view diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index b8d3a2dd2b..47517676be 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -3957,7 +3957,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Маґнітн STR_REPLACE_ROAD_VEHICLES :Аўтатранспарт STR_REPLACE_TRAM_VEHICLES :Трамваі -STR_REPLACE_REMOVE_WAGON :{BLACK}Выдаленьне ваґонаў: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Дазволіць пры аўтазамене захоўваць даўжыню цягнікоў шляхам выдаленьня ваґонаў (пачынаючы з галавы цягніка), калі пры аўтазамене лякаматыва павялічыцца даўжыня цягніка. # Vehicle view diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index cd5098ccc5..0609747f77 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -3823,7 +3823,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglevs STR_REPLACE_ROAD_VEHICLES :Veículos terrestres STR_REPLACE_TRAM_VEHICLES :Bondes -STR_REPLACE_REMOVE_WAGON :{BLACK}Remoção de vagões: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Faz autosubstituição manter o tamanho do trem removendo vagões (começando pela frente), se ao substituir a locomotiva o trem ficar maior # Vehicle view diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 4950dffb92..79dc4ffc2a 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -3455,7 +3455,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Монорел STR_REPLACE_MAGLEV_VEHICLES :Маглев влакове -STR_REPLACE_REMOVE_WAGON :{BLACK}Премахване на вагон: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Автоматичната замяна ще запази дължината на влака като премахне вагони (започвайки от предните), ако замяната довежда до по-дълъг влак. # Vehicle view diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 05040eb15f..a01984aa43 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -3823,7 +3823,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Trens maglev STR_REPLACE_ROAD_VEHICLES :Automòbils STR_REPLACE_TRAM_VEHICLES :Tramvies -STR_REPLACE_REMOVE_WAGON :{BLACK}Treure vagons: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Fer que la substitució automàtica mantingui la llargada del tren eliminant vagons (començant pel front), si substituint la màquina el tren es fa més llarg # Vehicle view diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index d1afe801f1..99582b0447 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -3760,7 +3760,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Željeznička v STR_REPLACE_ROAD_VEHICLES :Cestovna vozila STR_REPLACE_TRAM_VEHICLES :Tramvaji -STR_REPLACE_REMOVE_WAGON :{BLACK}Uklanjanje vagona: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Automatska zamjena zadržava istu dužinu vlaka tako da ukloni suvišne vagone (počevši od naprijed), ako bi zamjena lokomotive učinila vlak dužim # Vehicle view diff --git a/src/lang/czech.txt b/src/lang/czech.txt index c81a176759..aad6355ab8 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -4398,7 +4398,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Lokomotivy Magl STR_REPLACE_ROAD_VEHICLES :Silniční vozidla STR_REPLACE_TRAM_VEHICLES :Tramvaje -STR_REPLACE_REMOVE_WAGON :{BLACK}Odebírání vagonů: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Funkce automatického vylepšování vlaků může udržovat stejnou délku vlaku odstraňovaním vagonů (od začátku vlaku), pokud by změna mašiny vlak prodloužila # Vehicle view diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 3c857b32cd..2274c5a7c7 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -3672,7 +3672,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Magnetskinnetog STR_REPLACE_ROAD_VEHICLES :Vejkøretøjer STR_REPLACE_TRAM_VEHICLES :Sporvogne -STR_REPLACE_REMOVE_WAGON :{BLACK}Fjern vogn: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Få autoudskift til at bevare længden af tog ved at fjerne vogne (startende fra fronten), hvis autoudskiftningen gør toget længere. # Vehicle view diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 56848ce941..82ea46b1e0 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -3822,7 +3822,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Magneetzweefspo STR_REPLACE_ROAD_VEHICLES :Wegvoertuigen STR_REPLACE_TRAM_VEHICLES :Trams -STR_REPLACE_REMOVE_WAGON :{BLACK}Wagons verwijderen: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}De te vervangen trein behoudt zijn lengte door wagons weg te halen (startend aan de voorkant), als het vervangen de trein langer zou maken # Vehicle view diff --git a/src/lang/english.txt b/src/lang/english.txt index 092789135f..665573de49 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4835,8 +4835,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglev Vehicles STR_REPLACE_ROAD_VEHICLES :Road Vehicles STR_REPLACE_TRAM_VEHICLES :Tramway Vehicles -STR_REPLACE_REMOVE_WAGON :{BLACK}Wagon removal: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Wagon removal ({STRING1}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Make autoreplace keep the length of a train the same by removing wagons (starting at the front), if replacing the engine would make the train longer +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+Click to also apply to sub-groups # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 94ee65a512..9d2b5fcd29 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -3461,7 +3461,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Monorail Vehicl STR_REPLACE_MAGLEV_VEHICLES :Maglev Vehicles -STR_REPLACE_REMOVE_WAGON :{BLACK}Wagon removal: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Make autoreplace keep the length of a train the same by removing wagons (starting at the front), if replacing the engine would make the train longer # Vehicle view diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 6ab8b323c1..9d8fffd77e 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -3846,7 +3846,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglev Vehicles STR_REPLACE_ROAD_VEHICLES :Road Vehicles STR_REPLACE_TRAM_VEHICLES :Streetcars -STR_REPLACE_REMOVE_WAGON :{BLACK}Car removal: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Make autoreplace keep the length of a train the same by removing cars (starting at the front), if replacing the engine would make the train longer # Vehicle view diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index 6115b29c7e..b5a2ba6563 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -2924,7 +2924,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Unurelaj Veturi STR_REPLACE_MAGLEV_VEHICLES :Maglevaj Veturiloj -STR_REPLACE_REMOVE_WAGON :{BLACK}Vagonforigo: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ĉe aŭtomata anstataŭigo tenu saman longecon de la trajno per forigo de vagonoj (defronte), se per nova maŝino la trajno plilongiĝas # Vehicle view diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index cc57922010..5490bde49d 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -2334,7 +2334,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} li STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} liitus vaatlejatega STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} alustas uue ettevõtte (nr {2:NUM}) STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} lahkus mängust ({2:STRING}) -STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} uus nimi on {STRING} +STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} on muutnud oma nimeks {STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} saatis {2:CURRENCY_LONG} ettevõttele {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server sulges sessiooni STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server restardib...{}Palun oota... @@ -3880,7 +3880,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Magnethõljukve STR_REPLACE_ROAD_VEHICLES :Maanteesõidukid STR_REPLACE_TRAM_VEHICLES :Trammid -STR_REPLACE_REMOVE_WAGON :{BLACK}Vagunite kõrvaldamine: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Automaatne asendamine hoiab rongi pikkuse samana, vajadusel kõrvaldab vaguneid (alates esiotsast), kui muidu rongikoosseis suureneks # Vehicle view diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 63a1715143..2d37ab5af3 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -3107,7 +3107,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Einsporaði jar STR_REPLACE_MAGLEV_VEHICLES :Maglev flutningstól -STR_REPLACE_REMOVE_WAGON :{BLACK}Vogn burturrudding: {ORANGE}{STRING} # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 1dbfe400b8..9cd97d9da7 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -3569,7 +3569,7 @@ STR_GROUP_CREATE_TOOLTIP :{BLACK}Luo ryhm STR_GROUP_DELETE_TOOLTIP :{BLACK}Poista valittu ryhmä STR_GROUP_RENAME_TOOLTIP :{BLACK}Nimeä valittu ryhmä STR_GROUP_LIVERY_TOOLTIP :{BLACK}Muuta valitun ryhmän väritystä -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Poista ryhmä automaattisesti korvattavien joukosta +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Napsauta suojataksesi tämä ryhmä yleiseltä automaattikorvaukselta. Ctrl+napsautus suojaa myös aliryhmät. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Poista ryhmä STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Haluatko varmasti poistaa tämän ryhmän ja sen alaryhmät? @@ -3822,8 +3822,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglev-junat STR_REPLACE_ROAD_VEHICLES :Ajoneuvot STR_REPLACE_TRAM_VEHICLES :Raitiovaunut -STR_REPLACE_REMOVE_WAGON :{BLACK}Vaunun poisto: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Vaunun poisto ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Automaattikorvauksessa junapituus pidetään samana poistamalla vaunuja (edestä) jos veturi pidentäisi junaa +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+napsautus kohdistaaksesi myös aliryhmiin. # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/french.txt b/src/lang/french.txt index 629bb573fd..8490aaa61d 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -2225,6 +2225,7 @@ STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Votre or STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Votre ordinateur a mis trop de temps pour télécharger la carte STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Votre ordinateur a mis trop de temps pour rejoindre le serveur STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Votre nom n'est pas valide +STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}Le serveur interrogé est trop ancien pour ce client ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :erreur générale @@ -2838,7 +2839,7 @@ STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COM STR_FRAMERATE_GAMELOOP :{BLACK}Total de la boucle de jeu{NBSP}: STR_FRAMERATE_GL_ECONOMY :{BLACK} Traitement des marchandises{NBSP}: STR_FRAMERATE_GL_TRAINS :{BLACK} Ticks des trains{NBSP}: -STR_FRAMERATE_GL_ROADVEHS :{WHITE} Ticks des véhicules routiers{NBSP}: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Ticks des véhicules routiers{NBSP}: STR_FRAMERATE_GL_SHIPS :{BLACK} Ticks des navires{NBSP}: STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Ticks des aéroplanes{NBSP}: STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Ticks du monde{NBSP}: @@ -3569,7 +3570,7 @@ STR_GROUP_CREATE_TOOLTIP :{BLACK}Créer u STR_GROUP_DELETE_TOOLTIP :{BLACK}Supprimer le groupe sélectionné STR_GROUP_RENAME_TOOLTIP :{BLACK}Renommer le groupe sélectionné STR_GROUP_LIVERY_TOOLTIP :{BLACK}Changer la couleur du groupe sélectionné -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Cliquer pour protéger ce groupe contre l'auto-remplacement global +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Cliquer pour protéger ce groupe contre l'auto-remplacement global. Ctrl-clic pour protéger aussi les sous-groupes. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Supprimer un groupe STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Êtes-vous sûr de vouloir supprimer ce groupe et ses descendants{NBSP}? @@ -3822,8 +3823,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Véhicules Magl STR_REPLACE_ROAD_VEHICLES :Véhicules routiers STR_REPLACE_TRAM_VEHICLES :Tramways -STR_REPLACE_REMOVE_WAGON :{BLACK}Retrait de wagon{NBSP}: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Retrait de wagon ({STRING}){NBSP}: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Si l'autoremplacement de la locomotive provoque un accroissement de la longueur du train, alors sa longueur initiale sera retrouvée en retirant automatiquement des wagons (d'abord par la tête) +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl-clic pour appliquer aussi aux sous-groupes # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index 08b4e1747e..d0ba1b7a8a 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -3773,7 +3773,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Carbadan aona-r STR_REPLACE_MAGLEV_VEHICLES :Carbadan magnaiteach -STR_REPLACE_REMOVE_WAGON :{BLACK}A' toirt air falbh carbad: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Glèidh faide aig trèan nuair a thèid fhèin-leasachadh le toirt air falbh nan carbadan (bho thoiseach na trèan a-mach) ma dh'fhàsas an trèan nas fhaide le einnsean ùr # Vehicle view diff --git a/src/lang/galician.txt b/src/lang/galician.txt index 1ea620338b..d07bbfafcd 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -3652,7 +3652,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Vehículos magl STR_REPLACE_ROAD_VEHICLES :Vehículos de estrada STR_REPLACE_TRAM_VEHICLES :Tranvías -STR_REPLACE_REMOVE_WAGON :{BLACK}Eliminar os vagóns: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Facer que a autosubstitución manteña a lonxitude do tren quitando vagóns (empezando pola cabeza), se ao substituír a locomotora o tren se fixera máis longo. # Vehicle view diff --git a/src/lang/german.txt b/src/lang/german.txt index 6aa92bf91c..dab780307d 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -4408,7 +4408,7 @@ STR_GROUP_RENAME_TOOLTIP :{BLACK}Ausgewä STR_GROUP_LIVERY_TOOLTIP :{BLACK}Farbschema der ausgewählten Gruppe ändern STR_GROUP_EXPAND_ALL :{BLACK}Alles ausklappen STR_GROUP_COLLAPSE_ALL :{BLACK}Alles einklappen -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Diese Gruppe von der automatischen Fahrzeugersetzung ausschließen +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klicken, um diese Gruppe vor der globalen Autoersetzung zu schützen. Strg+Klick, um außerdem Untergruppen zu schützen STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Gruppe löschen STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Sicher, dass diese Gruppe inklusive aller Untergruppen gelöscht werden soll? @@ -4681,8 +4681,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Magnetschwebeba STR_REPLACE_ROAD_VEHICLES :Straßenfahrzeuge STR_REPLACE_TRAM_VEHICLES :Straßenbahnfahrzeuge -STR_REPLACE_REMOVE_WAGON :{BLACK}Waggon-Entfernung: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Waggon-Entfernung ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ursprüngliche Länge des Zugs beibehalten, indem (vorne beginnend) Waggons entfernt werden, falls das Ersetzen der Lokomotive den Zug verlängern würde +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Strg+Klick, um auch an Untergruppen anzuwenden # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 561bc315a9..75a20a1438 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -3782,7 +3782,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Οχήματα STR_REPLACE_TRAM_VEHICLES :Οχήματα τροχιοδρόμου -STR_REPLACE_REMOVE_WAGON :{BLACK}Αφαίρεση βαγονιού: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Υποχρεώνει την αυτόματη αντικατάσταση να διατηρεί σταθερό το μήκος του τρένου αφαιρώντας βαγόνια (ξεκινώντας από μπροστά), όταν η αντικατάσταση της μηχανής κάνει το τρένο μεγαλύτερο # Vehicle view diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index c10b17acf3..f7b523ecb2 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -3551,7 +3551,6 @@ STR_REPLACE_MONORAIL_VEHICLES :רכבות חד STR_REPLACE_MAGLEV_VEHICLES :רכבות פס-מגנטי -STR_REPLACE_REMOVE_WAGON :{ORANGE}{STRING}{BLACK} : הסרת קרונות STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}שמור על האורך המקורי של הרכבת בעת שימוש בהחלפה אוטומטית, במידה והקטר מאריך את הרכבת הסר קרונות מתחילת הרכבת # Vehicle view diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index a780368cad..973312538e 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -3886,7 +3886,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglev Járműv STR_REPLACE_ROAD_VEHICLES :Közúti járművek STR_REPLACE_TRAM_VEHICLES :Villamosok -STR_REPLACE_REMOVE_WAGON :{BLACK}Vagon törlés: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Az automatikus cserénél a szerelvény hosszának a megtartása vagonok eltávolításával (mozdony utántól kezdve), ha a csere után a szerelvény hosszabb lenne # Vehicle view diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index 469a91ffb2..cf44be2859 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -3266,7 +3266,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Einteinungsvagn STR_REPLACE_MAGLEV_VEHICLES :Segulsvifvagnar -STR_REPLACE_REMOVE_WAGON :{BLACK}Selja lestarvagna: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Heldur lengd lestar með því að fjarlægja vagna (framan frá), ef útskipting dráttarvagna myndi lengja hana # Vehicle view diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index 334e9e7070..b741da3b3d 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -55,7 +55,7 @@ STR_CARGO_PLURAL_BUBBLES :Gelembung STR_CARGO_PLURAL_TOFFEE :Gula-gula STR_CARGO_PLURAL_BATTERIES :Baterai STR_CARGO_PLURAL_PLASTIC :Plastik -STR_CARGO_PLURAL_FIZZY_DRINKS :Minuman Berdesis +STR_CARGO_PLURAL_FIZZY_DRINKS :Minuman Ringan # Singular cargo name STR_CARGO_SINGULAR_NOTHING : @@ -89,7 +89,7 @@ STR_CARGO_SINGULAR_BUBBLE :Gelembung STR_CARGO_SINGULAR_TOFFEE :Gula-gula STR_CARGO_SINGULAR_BATTERY :Baterai STR_CARGO_SINGULAR_PLASTIC :Plastik -STR_CARGO_SINGULAR_FIZZY_DRINK :Minuman Berdesis +STR_CARGO_SINGULAR_FIZZY_DRINK :Minuman Ringan # Quantity of cargo STR_QUANTITY_NOTHING : @@ -123,7 +123,7 @@ STR_QUANTITY_BUBBLES :{COMMA} gelembu STR_QUANTITY_TOFFEE :{WEIGHT_LONG} gula-gula STR_QUANTITY_BATTERIES :{COMMA} baterai STR_QUANTITY_PLASTIC :{VOLUME_LONG} plastik -STR_QUANTITY_FIZZY_DRINKS :{COMMA} minuman berdesis +STR_QUANTITY_FIZZY_DRINKS :{COMMA} minuman ringan STR_QUANTITY_N_A :N/A # Two letter abbreviation of cargo name @@ -158,7 +158,7 @@ STR_ABBREV_BUBBLES :{TINY_FONT}GL STR_ABBREV_TOFFEE :{TINY_FONT}GG STR_ABBREV_BATTERIES :{TINY_FONT}BA STR_ABBREV_PLASTIC :{TINY_FONT}PL -STR_ABBREV_FIZZY_DRINKS :{TINY_FONT}MB +STR_ABBREV_FIZZY_DRINKS :{TINY_FONT}MR STR_ABBREV_NONE :{TINY_FONT}TANPA STR_ABBREV_ALL :{TINY_FONT}SMA @@ -180,7 +180,7 @@ STR_COLOUR_LIGHT_BLUE :Biru terang STR_COLOUR_GREEN :Hijau STR_COLOUR_DARK_GREEN :Hijau tua STR_COLOUR_BLUE :Biru -STR_COLOUR_CREAM :Cream +STR_COLOUR_CREAM :Krim STR_COLOUR_MAUVE :Lembayung muda STR_COLOUR_PURPLE :Ungu STR_COLOUR_ORANGE :Oranye @@ -217,8 +217,8 @@ STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}{NBSP}ga STR_UNITS_VOLUME_SHORT_METRIC :{COMMA}{NBSP}l STR_UNITS_VOLUME_SHORT_SI :{COMMA}{NBSP}m³ -STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA}{NBSP}gallon -STR_UNITS_VOLUME_LONG_METRIC :{COMMA}{NBSP}litre +STR_UNITS_VOLUME_LONG_IMPERIAL :{COMMA}{NBSP}galon +STR_UNITS_VOLUME_LONG_METRIC :{COMMA}{NBSP}liter STR_UNITS_VOLUME_LONG_SI :{COMMA}{NBSP}m³ STR_UNITS_FORCE_IMPERIAL :{COMMA}{NBSP}lbf @@ -952,13 +952,14 @@ STR_GAME_OPTIONS_CURRENCY_NTD :Dollar Taiwan B STR_GAME_OPTIONS_CURRENCY_CNY :Renminbi Cina (CNY) STR_GAME_OPTIONS_CURRENCY_HKD :Dollar Hong Kong (HKD) STR_GAME_OPTIONS_CURRENCY_INR :India Rupee (INR) +STR_GAME_OPTIONS_CURRENCY_IDR :Rupiah Indonesia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaysia (MYR) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Berkendara di lajur kiri STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Berkendara di lajur kanan -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nama kota +STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nama kota: STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Pilih model nama kota ############ start of townname region @@ -998,6 +999,7 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :Setiap 12 bulan STR_GAME_OPTIONS_LANGUAGE :{BLACK}Bahasa STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Pilih antar muka bahasa yang akan dipergunakan +STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% selesai) STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Layar Penuh STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Klik cek box ini untuk memainkan OpenTTD dalam layar penuh @@ -1005,10 +1007,14 @@ STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Klik cek STR_GAME_OPTIONS_RESOLUTION :{BLACK}Resolusi Layar STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Pilih resolusi layar yang diinginkan STR_GAME_OPTIONS_RESOLUTION_OTHER :lainnya +STR_GAME_OPTIONS_RESOLUTION_ITEM :{NUM}x{NUM} STR_GAME_OPTIONS_VIDEO_ACCELERATION :{BLACK}Akselerasi perangkat keras +STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK} Centang kotak ini untuk mengizinkan OpenTTD mencoba menggunakan akselerasi perangkat keras. Pengaturan yang diubah hanya akan diterapkan saat game dimulai ulang. STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Pengaturan hanya akan berlaku setelah game dimulai ulang +STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync +STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Centang kotak ini untuk melakukan sinkronisasi layar (v-sync). Pengaturan yang diubah hanya akan diterapkan saat game dimulai ulang. Hanya berfungsi dengan akselerasi perangkat keras diaktifkan. STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Ukuran antarmuka STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Pilih ukuran elemen antarmuka yang akan digunakan @@ -1029,6 +1035,9 @@ STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :4 kali STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafik STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}Menampilkan kecepatan refresh +STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :{BLACK}Pilih laju penyegaran layar yang akan digunakan +STR_GAME_OPTIONS_REFRESH_RATE_OTHER :lain +STR_GAME_OPTIONS_REFRESH_RATE_ITEM :{NUM}Hz STR_GAME_OPTIONS_REFRESH_RATE_WARNING :{WHITE}Kecepatan refresh yang lebih tinggi dari 60Hz dapat memengaruhi kinerja. STR_GAME_OPTIONS_BASE_GRF :{BLACK}Set Grafik Dasar @@ -1139,6 +1148,7 @@ STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Pengatur STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Penyaring kata: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Perluas semua STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Persempit semua +STR_CONFIG_SETTING_RESET_ALL :{BLACK}Atur ulang semua pengaturan STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(penjelasan belum tersedia) STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}Nilai standar: {ORANGE}{STRING} STR_CONFIG_SETTING_TYPE :{LTBLUE}Tipe setting: {ORANGE}{STRING} @@ -1147,6 +1157,8 @@ STR_CONFIG_SETTING_TYPE_GAME_MENU :Setting permain STR_CONFIG_SETTING_TYPE_GAME_INGAME :Pengaturan permainan (disimpan dalam penyimpanan; hanya mempengaruhi permainan saat ini) STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Setting perusahaan (disimpan dalam penyimpanan; hanya mempengaruhi permainan baru) STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Setting perusahaan (disimpan dalam penyimpanan; hanya mempengaruhi permainan saat ini) +STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION :{WHITE}Peringatan! +STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT :{WHITE}Tindakan ini akan mengembalikan semua pengaturan gim ke nilai awalnya.{} Anda yakin ingin melanjutkan? STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Kategori: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Jenis: @@ -1210,7 +1222,9 @@ STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Pilih seberapa STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Ketinggian peta maksimum: {STRING} STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT :Tetapkan ketinggian maksimum medan peta. Dengan "(otomatis)" nilai yang baik akan diambil setelah pembuatan medan -STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}Kamu tidak bisa mengubah ketinggian peta maksimum di angka itu. Setidaknya ada satu gunung di peta yang lebih tinggi +STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_VALUE :{NUM} +STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_AUTO :(automatis) +STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}Anda tidak dapat menyetel batas ketinggian peta ke nilai ini. Setidaknya harus ada satu gunung di peta yang lebih tinggi STR_CONFIG_SETTING_AUTOSLOPE :Ijinkan pembentukan slop dibawah bangunan, rel, dsb.: {STRING} STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Ijinkan pembentukan tanah dibawah bangunan dan trek tanpa merusaknya STR_CONFIG_SETTING_CATCHMENT :Ijinkan ukuran jangkauan wilayah lebih realistik: {STRING} @@ -1354,7 +1368,10 @@ STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Mengatur berapa STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Jarak maksimal kilang minyak dari batas: {STRING} STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Kilang minyak hanya dibangun pada tepi peta atau pantai STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Tinggi garis salju: {STRING} -STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Mengatur ketinggian di mana salju akan muncul. Salju juga akan mempengaruhi pengembangan industri dan persyaratan untuk pertumbuhan kota +STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Mengontrol di ketinggian mana salju dimulai pada lanskap sub-arktik. Salju juga berpengaruh pada generasi industri dan syarat pertumbuhan kota. Hanya dapat dimodifikasi melalui Editor Skenario atau dihitung melalui "cakupan salju" +STR_CONFIG_SETTING_SNOW_COVERAGE :Cakupan salju: {STRING} +STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Mengontrol perkiraan jumlah salju di lanskap sub-arktik. Salju juga berpengaruh pada generasi industri dan syarat pertumbuhan kota. Hanya digunakan selama pembuatan peta. Tanah yang berada tepat di atas permukaan laut selalu tanpa salju +STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE :{NUM}% STR_CONFIG_SETTING_DESERT_COVERAGE :Cakupan gurun: {STRING} STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT :Kontrol perkiraan jumlah gurun di lanskap tropis. Gurun juga mempengaruhi generasi industri. Hanya digunakan selama pembuatan peta STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE :{NUM}% @@ -1473,6 +1490,10 @@ STR_CONFIG_SETTING_EXPENSES_LAYOUT :Kelompokkan pen STR_CONFIG_SETTING_EXPENSES_LAYOUT_HELPTEXT :Mendefinisikan tata ruang untuk tetingkap biaya perusahaan STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :Secara otomatis menghapus sinyal selama konstruksi rel: {STRING} STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT :Menghapus sinyal secara otomatis selama konstruksi rel jika sinyal menghalangi. Perhatikan bahwa hal ini berpotensi menyebabkan kecelakaan kereta api. +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT :Batas kecepatan maju cepat: {STRING} +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_HELPTEXT :Batasi secepat apa permainan melaju saat maju cepat diaktifkan. 0 = tanpa batas (secepat yang bisa diatasi komputermu). Nilai di bawah 100% memperlambat gim. Batas maksimal tergantung pada spesifikasi komputer dan dapat bervariasi tergantung pada gim. +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_VAL :{NUM}% kecepatan normal +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_ZERO :Tanpa batas (secepat komputer Anda memungkinkan) STR_CONFIG_SETTING_SOUND_TICKER :Ticker berita: {STRING} STR_CONFIG_SETTING_SOUND_TICKER_HELPTEXT :Mainkan suara untuk pesanan berita yang diringkas @@ -1664,12 +1685,14 @@ STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :Perbesaran view STR_CONFIG_SETTING_ZOOM_MAX :Tingkat zoom out Maksimal: {STRING} STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT :Pengecilan maksimum untuk viewport. Semakin kecil semakin tidak jelas STR_CONFIG_SETTING_SPRITE_ZOOM_MIN :Sprite resolusi tertinggi untuk digunakan: {STRING} +STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT :Batas resolusi maksimum yang digunakan sprite. Membatasi resolusi sprite akan menghindari penggunaan grafik resolusi tinggi meskipun tersedia. Ini dapat membantu menjaga tampilan gim tetap menyatu saat menggunakan campuran file GRF dengan atau tanpa grafik resolusi tinggi. STR_CONFIG_SETTING_ZOOM_LVL_MIN :4x STR_CONFIG_SETTING_ZOOM_LVL_IN_2X :2x STR_CONFIG_SETTING_ZOOM_LVL_NORMAL :Normal STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X :2x STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X :4x STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8x +STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN :4x STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_IN_2X :2x STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_NORMAL :1x STR_CONFIG_SETTING_TOWN_GROWTH :Kecepatan pertumbuhan kota: {STRING} @@ -1806,6 +1829,7 @@ STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Kehabisa STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}Mengalokasikan {BYTES} 'spritecache' gagal. 'Spritecache' dikurangi ke {BYTES}. Ini akan kurangi kinerja OpenTTD. Untuk kurangi kebutuhan memori anda bisa coba matikan grafik 32bpp dan/atau tingkat pembesaran # Video initalization errors +STR_VIDEO_DRIVER_ERROR :{WHITE}Kesalahan dengan pengaturan video... STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... tidak ditemukan GPU yang kompatibel. Akselerasi perangkat keras dinonaktifkan # Intro window @@ -1973,6 +1997,8 @@ STR_FACE_TIE :Dasi: STR_FACE_EARRING :Anting-anting: STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Ubah dasi atau anting-anting +STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privat +STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Umum # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Bermain bersama @@ -2036,6 +2062,8 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Nama per STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Atur kata sandi STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Lindungi permainan ini dengan kata kunci jika anda tidak ingin membiarkannya terbuka untuk umum +STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Visibilitas +STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}Orang lain bisa melihat server Anda di daftar umum STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} klien STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Maksimum jumlah klien: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Pilih jumlah klien maksimal. Tidak semua slot harus diisi @@ -2099,12 +2127,45 @@ STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server t STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Perusahaan terkunci, masukkan kata kunci # Network company list added strings -STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Daftar klien +STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Pemain Dalam Jaringan STR_NETWORK_COMPANY_LIST_SPECTATE :Menonton # Network client list - - +STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Multipemain +STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}Server +STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Nama +STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}Nama server tempat Anda bermain +STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Mengubah nama server Anda +STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Nama server +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Visibilitas +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Apakah orang lain dapat melihat server Anda di daftar publik +STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Pemain +STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Nama +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Nama pemain Anda +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}Mengubah nama pemain Anda +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Nama pemain +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Tindakan administratif yang harus dilakukan untuk klien ini +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Tindakan administratif yang harus dilakukan untuk perusahaan ini +STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Gabung perusahaan ini +STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Kirim pesan ke pemain ini +STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Kirim pesan ke semua pemain di perusahaan ini +STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Kirim pesan ke semua penonton +STR_NETWORK_CLIENT_LIST_SPECTATORS :Penonton +STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Perusahaan baru) +STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Ciptakan perusahaan baru dan bergabung +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Ini adalah Anda +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Ini adalah hos permainan + +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Diusir +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Melarang +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Hapus +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Buka pakai kata sandi + +STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Tindakan Admin +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Anda yakin ingin diusir pemain '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Apakah Anda yakin ingin mencekal pemain '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Anda yakin ingin menghapus perusahaan '{COMPANY}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Anda yakin ingin menyetel ulang sandi perusahaan '{COMPANY}'? STR_NETWORK_SERVER :Server STR_NETWORK_CLIENT :Klien @@ -2149,6 +2210,7 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}Tak dapa STR_NETWORK_ERROR_CLIENT_START :{WHITE}Tak dapat tersambung STR_NETWORK_ERROR_TIMEOUT :{WHITE}Waktu Koneksi #{NUM} telah habis STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Kesalahan protokol, koneksi ditutup +STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Nama permainan belum disetel. Nama bisa diatur di bagian atas jendela Multiplayer STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Revisi pada klien tidak sama dengan revisi pada server STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Kata kunci salah STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Server penuh @@ -2161,6 +2223,8 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Jangan t STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Komputer anda terlalu lambat dalam mengikuti server STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Komputer anda terlalu lama untuk mengunduh peta STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Komputer anda terlalu lama untuk bisa bergabung dengan server +STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Nama pemain Anda tidak valid +STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}Server yang diminta terlalu usang untuk klien ini ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :Kesalahan umum @@ -2183,6 +2247,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :tidak menerima STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :waktu koneksi habis STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :pengunduhan peta memakan banyak waktu STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :pengolahan peta memakan banyak waktu +STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :nama yang dihubungi tidak valid ############ End of leave-in-this-order STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Koneksi mungkin terputus @@ -2291,6 +2356,7 @@ STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}Ya, down STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}Tidak, tutup OpenTTD STR_MISSING_GRAPHICS_ERROR_TITLE :{WHITE}Gagal Mendownload +STR_MISSING_GRAPHICS_ERROR :{BLACK}Gagal mengunduh grafik.{}Silakan unduh grafik secara manual. STR_MISSING_GRAPHICS_ERROR_QUIT :{BLACK}Keluar OpenTTD # Transparency settings window @@ -2471,7 +2537,7 @@ STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Bangun p STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Tempatkan pelampung yang dapat digunakan sebagai petunjuk arah. Shift untuk menampilkan perkiraan biaya STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Membangun jembatan air. Shift untuk menampilkan perkiraan biaya STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Membuat area perairan .{}Membuat kanal, kecuali jika CTRL ditekan pada level yang sejajar dengan laut, maka air akan memenuhi permukaan -STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Membuat sungai +STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Membuat sungai. Ctrl untuk memilh area secara diagonal # Ship depot construction window STR_DEPOT_BUILD_SHIP_CAPTION :{WHITE}Orientasi Galangan @@ -2842,9 +2908,17 @@ STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Jumlah Kota: STR_MAPGEN_DATE :{BLACK}Tgl: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Jumlah industri: +STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Puncak tertinggi: +STR_MAPGEN_HEIGHTMAP_HEIGHT_UP :{BLACK}Menambah satu ketinggian maksimum puncak tertinggi di peta STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN :{BLACK}Kurangi satu ketinggian maksimum puncak tertinggi di peta +STR_MAPGEN_SNOW_COVERAGE :{BLACK}Cakupan salju: +STR_MAPGEN_SNOW_COVERAGE_UP :{BLACK}Meningkatkan cakupan salju sepuluh persen STR_MAPGEN_SNOW_COVERAGE_DOWN :{BLACK}Kurangi cakupan salju hingga sepuluh persen +STR_MAPGEN_SNOW_COVERAGE_TEXT :{BLACK}{NUM}% STR_MAPGEN_DESERT_COVERAGE :{BLACK}Cakupan gurun: +STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Meningkatkan cakupan gurun sepuluh persen +STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Kurangi cakupan gurun pasir sebesar sepuluh persen +STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% STR_MAPGEN_SNOW_LINE_HEIGHT :{BLACK}Tinggi garis salju: STR_MAPGEN_SNOW_LINE_UP :{BLACK}Naikkan ketinggian garis salju satu angka STR_MAPGEN_SNOW_LINE_DOWN :{BLACK}Turunkan ketinggian garis salju satu angka @@ -2873,8 +2947,11 @@ STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nama Pet STR_MAPGEN_HEIGHTMAP_SIZE_LABEL :{BLACK}Luas: STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM} x {NUM} +STR_MAPGEN_TERRAIN_TYPE_QUERY_CAPT :{WHITE}Target ketinggian puncak +STR_MAPGEN_HEIGHTMAP_HEIGHT_QUERY_CAPT :{WHITE}Puncak tertinggi STR_MAPGEN_SNOW_COVERAGE_QUERY_CAPT :{WHITE}Cakupan salju (dalam %) STR_MAPGEN_SNOW_LINE_QUERY_CAPT :{WHITE}Ubah ketinggian garis salju +STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT :{WHITE}Cakupan gurun (dalam %) STR_MAPGEN_START_DATE_QUERY_CAPT :{WHITE}Ganti Tahun Permulaan # SE Map generation @@ -3014,6 +3091,7 @@ STR_NEWGRF_ERROR_MSG_WARNING :{RED}Peringatan STR_NEWGRF_ERROR_MSG_ERROR :{RED}Kesalahan: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{STRING} STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Kesalahan fatal NewGRF telah terjadi:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}Terjadi galat pada NewGRF:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} tidak akan bekerja dengan versi TTDPatch yang telah dilaporkan oleh OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} untuk TTD versi {STRING} STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} didesain untuk digunakan dengan {STRING} @@ -3152,13 +3230,13 @@ STR_LOCAL_AUTHORITY_ACTION_NEW_BUILDINGS :Danai pembangun STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Beli hak transportasi eksklusif STR_LOCAL_AUTHORITY_ACTION_BRIBE :Suap pemkot setempat -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Prakarsai kampanye iklan kecil, agar penumpang dan kargo lebih mengutamakan jasa perusahaan transportasi anda.{}Biaya:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Prakarsai kampanye iklan sedang, agar penumpang dan kargo lebih mengutamakan jasa perusahaan transportasi anda.{}Biaya:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Prakarsai kampanye iklan besar, agar penumpang dan kargo lebih mengutamakan jasa perusahaan transportasi anda.{}Biaya: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Danai perbaikan jalan. Akan menyebabkan kemacetan arus lalu lintas hingga 6 bulan.{}Biaya: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Bangun patung sebagai kebanggaan perusahaan anda.{}Biaya: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Biayai pembangunan gedung komersil di kota.{}Biaya: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Beli hak monopoli transportasi di kota ini untuk 1 tahun. Penumpang dan kargo di kota ini hanya akan menggunakan stasiun milik perusahaan anda.{} Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Prakarsai kampanye iklan kecil, agar penumpang dan kargo lebih mengutamakan jasa perusahaan transportasi anda.{}Memberikan penggalak sementara pada peringkat stasiun dalam radius kecil di sekitar pusat kota.{}Biaya:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Prakarsai kampanye iklan sedang, agar penumpang dan kargo lebih mengutamakan jasa perusahaan transportasi anda.{}Memberikan penggalak sementara pada peringkat stasiun dalam radius sedang di sekitar pusat kota.{}Biaya:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Prakarsai kampanye iklan besar, agar penumpang dan kargo lebih mengutamakan jasa perusahaan transportasi anda.{}Memberikan penggalak sementara pada peringkat stasiun dalam radius besar di sekitar pusat kota.{}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Danai perbaikan jalanan perkotaan.{}Akan menyebabkan kemacetan arus lalu lintas hingga 6 bulan.{}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Bangun patung sebagai kebanggaan perusahaan anda.{}Memberikan penggalak permanen pada peringkat stasiun di kota ini.{}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Biayai pembangunan gedung baru di kota.{}Memberikan penggalak sementara pada pertumbuhan kota di kota ini,{}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Beli hak monopoli transportasi di kota ini untuk 1 tahun.{}Pemerintah kota tidak akan mengizinkan penumpang dan kargo untuk memakai stasiun pesaing Anda.{} Biaya: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Kolusi dengan pemkot agar naik peringkat, beresiko terkena hukuman jika tertangkap.{}Biaya: {CURRENCY_LONG} # Goal window @@ -3166,6 +3244,9 @@ STR_GOALS_CAPTION :{WHITE}{COMPANY STR_GOALS_SPECTATOR_CAPTION :{WHITE}Target Global STR_GOALS_SPECTATOR :Target Global STR_GOALS_GLOBAL_BUTTON :{BLACK}Global +STR_GOALS_GLOBAL_BUTTON_HELPTEXT :{BLACK}Tunjukkan target global +STR_GOALS_COMPANY_BUTTON :{BLACK}Perusahaan +STR_GOALS_COMPANY_BUTTON_HELPTEXT :{BLACK}Tunjukkan target perusahaan STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- Tidak ada - STR_GOALS_PROGRESS :{ORANGE}{STRING} @@ -3741,7 +3822,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Kereta Maglev STR_REPLACE_ROAD_VEHICLES :Kendaraan Jalan Raya STR_REPLACE_TRAM_VEHICLES :Kendaraan Jalan Trem -STR_REPLACE_REMOVE_WAGON :{BLACK}Membuang gerbong: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Membuat panjang kereta tetap sama saat penggantian secara otomatis dengan cara membuang gerbong(dihitung dari bagian depan), jika penggantian lokomotif membuat kereta lebih panjang # Vehicle view @@ -4288,6 +4368,7 @@ STR_WARNING_FALLBACK_SOUNDSET :{WHITE}Hanya ef STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}Tangkapan layar besar STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}Resolusi tangkapan layar {COMMA} x {COMMA} piksel. Membuat tangkapan layar akan memakan waktu. Anda ingin melanjutkan? +STR_MESSAGE_HEIGHTMAP_SUCCESSFULLY :{WHITE}Peta ketinggian sudah disimpan sebagai '{STRING}'. Puncak tertinggi adalah {NUM} STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}Pengambilan gambar telah berhasil disimpan sebagai '{STRING}' STR_ERROR_SCREENSHOT_FAILED :{WHITE}Pengambilan gambar gagal @@ -4746,7 +4827,7 @@ STR_INDUSTRY_NAME_COLA_WELLS :Sumur Cola STR_INDUSTRY_NAME_TOY_SHOP :Toko Mainan STR_INDUSTRY_NAME_TOY_FACTORY :Pabrik Mainan STR_INDUSTRY_NAME_PLASTIC_FOUNTAINS :Sumber Mata Air Plastik -STR_INDUSTRY_NAME_FIZZY_DRINK_FACTORY :Pabrik Minuman berdesis +STR_INDUSTRY_NAME_FIZZY_DRINK_FACTORY :Pabrik Minuman Ringan STR_INDUSTRY_NAME_BUBBLE_GENERATOR :Pembangkit Gelembung STR_INDUSTRY_NAME_TOFFEE_QUARRY :Tambang gula-gula STR_INDUSTRY_NAME_SUGAR_MINE :Tambang Gula @@ -4845,7 +4926,7 @@ STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COLA_TANKER :Gerbong Tangki STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_CANDY_VAN :Gerbong Manisan STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOY_VAN :Gerbong Mainan STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_BATTERY_TRUCK :Gerbong Baterai -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FIZZY_DRINK_TRUCK :Gerbong Minuman berdesis +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FIZZY_DRINK_TRUCK :Gerbong Minuman Ringan STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PLASTIC_TRUCK :Gerbong Plastik STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_X2001_ELECTRIC :'X2001' (Listrik) STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Listrik) @@ -4875,7 +4956,7 @@ STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COLA_TANKER :Gerbong Cola STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_CANDY_VAN :Gerbong Manisan STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :Gerbong Mainan STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BATTERY_TRUCK :Gerbong Baterai -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :Gerbong Minuman berdesis +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :Gerbong Minuman Ringan STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PLASTIC_TRUCK :Gerbong Plastik STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Listrik) STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Listrik) @@ -4907,7 +4988,7 @@ STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COLA_TANKER :Gerbong Cola STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_CANDY_VAN :Gerbong Manisan STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_TOY_VAN :Gerbong Mainan STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BATTERY_TRUCK :Gerbong Baterai -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FIZZY_DRINK_TRUCK :Gerbong Minuman berdesis +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FIZZY_DRINK_TRUCK :Gerbong Minuman Ringan STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PLASTIC_TRUCK :Gerbong Plastik STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_REGAL_BUS :Bus MPS Regal STR_VEHICLE_NAME_ROAD_VEHICLE_HEREFORD_LEOPARD_BUS :Bus Hereford Leopard @@ -4988,9 +5069,9 @@ STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_CANDY_TRUCK :Truk Manisan Wi STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_BATTERY_TRUCK :Truk Baterai MightyMover STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_BATTERY_TRUCK :Truk Baterai Powernaught STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_BATTERY_TRUCK :Truk Baterai Wizzowow -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_FIZZY_DRINK :Truk Minuman berdesis MightyMover -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_FIZZY_DRINK :Truk Minuman berdesis Powernaught -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_FIZZY_DRINK_TRUCK :Truk Minuman berdesis Wizzowow +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_FIZZY_DRINK :Truk Minuman Ringan MightyMover +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_FIZZY_DRINK :Truk Minuman Ringan Powernaught +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_FIZZY_DRINK_TRUCK :Truk Minuman Ringan Wizzowow STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_PLASTIC_TRUCK :Truk Plastik MightyMover STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_PLASTIC_TRUCK :Truk Plastik Powernaught STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_PLASTIC_TRUCK :Truk Plastik Wizzowow diff --git a/src/lang/irish.txt b/src/lang/irish.txt index ac6d8e5fd3..984f32daf9 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -3480,7 +3480,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Feithiclí Aonr STR_REPLACE_MAGLEV_VEHICLES :Feithiclí Maglev -STR_REPLACE_REMOVE_WAGON :{BLACK}Vaigíní a bhaint: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ceangail ar uath-athsholáthar fad na traenach a choinneáil mar an gcéanna trí vaigíní a bhaint (ag tosú ag an tosach), má tharlaíonn sé go mbeadh an traein níos faide tar éis an t-inneall a athsholáthar. # Vehicle view diff --git a/src/lang/italian.txt b/src/lang/italian.txt index b748dc2ae4..a3be4a01ec 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -3792,7 +3792,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Veicoli maglev STR_REPLACE_ROAD_VEHICLES :Veicoli stradali STR_REPLACE_TRAM_VEHICLES :Veicoli tranviari -STR_REPLACE_REMOVE_WAGON :{BLACK}Rimozione vagoni: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Fa sì che il rimpiazzamento automatico mantenga costante la lunghezza dei treni rimuovendo vagoni (iniziando dalla testa) nel caso in cui la sostituzione della locomotiva rendesse il treno più lungo # Vehicle view diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index e2f5bba03c..23ec16372c 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -188,11 +188,13 @@ STR_COLOUR_BROWN :茶 STR_COLOUR_GREY :灰 STR_COLOUR_WHITE :白 STR_COLOUR_RANDOM :ランダム +STR_COLOUR_DEFAULT :デフォルト # Units used in OpenTTD STR_UNITS_VELOCITY_IMPERIAL :{COMMA}mph STR_UNITS_VELOCITY_METRIC :{COMMA}km/h STR_UNITS_VELOCITY_SI :{COMMA}m/s +STR_UNITS_VELOCITY_GAMEUNITS :{DECIMAL}{NBSP}タイル/日 STR_UNIT_NAME_VELOCITY_IMPERIAL :mph STR_UNIT_NAME_VELOCITY_METRIC :km/h @@ -232,7 +234,7 @@ STR_LIST_FILTER_OSKTITLE :{BLACK}フィ STR_LIST_FILTER_TOOLTIP :{BLACK}フィルタリングするキーワードを入力します STR_TOOLTIP_GROUP_ORDER :{BLACK}グループの整列法を選択 -STR_TOOLTIP_SORT_ORDER :{BLACK}並べ替えの順序を選択します。(昇順/降順) +STR_TOOLTIP_SORT_ORDER :{BLACK}並べ替えの順序を選択します (昇順 / 降順) STR_TOOLTIP_SORT_CRITERIA :{BLACK}並べ替えの基準を選択します STR_TOOLTIP_FILTER_CRITERIA :{BLACK}フィルタリングの基準を選択します STR_BUTTON_SORT_BY :{BLACK}並べ替え @@ -250,7 +252,7 @@ STR_TOOLTIP_RESIZE :{BLACK}ドラ STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}ウィンドウの大きさを切り替えます STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST :{BLACK}スクロールバーです。リストを縦にスクロールします STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST :{BLACK}スクロールバーです。リストを横にスクロールします -STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}建物などを範囲指定して撤去します。Ctrlを押すと、範囲が斜めになります。Shiftを押しながら決定すると、費用を見積もります +STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}建物などを範囲指定して撤去します。Ctrlで斜めに選択できます。Shiftを押しながら決定すると、費用を見積もります # Show engines button STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN :{BLACK}非表示を表示 @@ -258,15 +260,16 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE :{BLACK}非表 STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP :{BLACK}非表示を表示 STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT :{BLACK}非表示を表示 -STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP :{BLACK}このボタンを押すと、非表示の列車も全て表示されます -STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE_TOOLTIP :{BLACK}このボタンを押すと、非表示の車両も全て表示されます -STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}このボタンを押すと、非表示の船舶も全て表示されます -STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}このボタンを押すと、非表示の航空機も全て表示されます +STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP :{BLACK}このボタンを押すと、非表示の列車もすべて表示されます +STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE_TOOLTIP :{BLACK}このボタンを押すと、非表示の車両もすべて表示されます +STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}このボタンを押すと、非表示の船舶もすべて表示されます +STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}このボタンを押すと、非表示の航空機もすべて表示されます # Query window STR_BUTTON_DEFAULT :{BLACK}デフォルト STR_BUTTON_CANCEL :{BLACK}キャンセル STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}警告: サーバーの管理者はここに入力された文章をすべて読めます。 # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :{NBSP}1234567890-^\qwertyuiop@[asdfghjkl;:] zxcvbnm,./\ @@ -289,7 +292,7 @@ STR_SORT_BY_TYPE :種類 STR_SORT_BY_TRANSPORTED :搬送済量 STR_SORT_BY_NUMBER :番号 STR_SORT_BY_PROFIT_LAST_YEAR :昨年の損益 -STR_SORT_BY_PROFIT_THIS_YEAR :今年の損益 +STR_SORT_BY_PROFIT_THIS_YEAR :今年の利益 STR_SORT_BY_AGE :使用年数 STR_SORT_BY_RELIABILITY :信頼性 STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :貨物種類別の総容量 @@ -318,14 +321,16 @@ STR_SORT_BY_RATING :レーティン STR_SORT_BY_NUM_VEHICLES :車両数 STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :昨年の総利益 STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR :今年の総利益 -STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :前年度の平均利益 +STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :前年の平均利益 +STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR :今年の平均利益 # Group by options for vehicle list +STR_GROUP_BY_NONE :(なし) STR_GROUP_BY_SHARED_ORDERS :共有注文 # Tooltips for the main toolbar STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}ゲームをポーズします -STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}ゲームスピードを早くします +STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}ゲーム進行速度を早くします STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}ゲームオプションの設定画面を開きます STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}ゲームのセーブ、中断、OpenTTDの終了ができます STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}地図の表示、ビューポートの表示、標識のリストの表示ができます @@ -346,7 +351,8 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}社有 STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}ズームインします STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}ズームアウトします STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}鉄道を建設します -STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}道路を建設します +STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}道路を敷設します +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}軌道を敷設する STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}埠頭を建設します STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}空港を建設します STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}地形のツールバーを開きます。整地や植林などを行うことができます。 @@ -364,10 +370,10 @@ STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD :{BLACK}開始 STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}クリックで開始年を入力できます STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}地図と街の一覧を表示します STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}地形の生成をします -STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}町を生成します +STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}街を生成する STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}産業を生成します -STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}道路を建設します -STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}路面電車建設 +STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}道路を敷設します +STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}軌道敷設 STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}木を植えます。Shiftキーを押しながら決定すると費用を見積もります STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}標識を設置します STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}オブジェクトを設置します。Shiftを押しながら決定すると費用を見積もります @@ -445,15 +451,15 @@ STR_INDUSTRY_MENU_FUND_NEW_INDUSTRY :産業の新設 ############ range ends here ############ range for railway construction menu starts -STR_RAIL_MENU_RAILROAD_CONSTRUCTION :鉄道建設 -STR_RAIL_MENU_ELRAIL_CONSTRUCTION :電気鉄道建設 -STR_RAIL_MENU_MONORAIL_CONSTRUCTION :モノレール建設 -STR_RAIL_MENU_MAGLEV_CONSTRUCTION :マグレブ(リニア)建設 +STR_RAIL_MENU_RAILROAD_CONSTRUCTION :鉄道敷設 +STR_RAIL_MENU_ELRAIL_CONSTRUCTION :電気鉄道の敷設 +STR_RAIL_MENU_MONORAIL_CONSTRUCTION :モノレール敷設 +STR_RAIL_MENU_MAGLEV_CONSTRUCTION :マグレブ(リニア)敷設 ############ range ends here ############ range for road construction menu starts -STR_ROAD_MENU_ROAD_CONSTRUCTION :道路建設 -STR_ROAD_MENU_TRAM_CONSTRUCTION :路面電車建設 +STR_ROAD_MENU_ROAD_CONSTRUCTION :道路敷設 +STR_ROAD_MENU_TRAM_CONSTRUCTION :軌道敷設 ############ range ends here ############ range for waterways construction menu starts @@ -576,6 +582,8 @@ STR_MONTH_DEC :12 # Graph window STR_GRAPH_KEY_BUTTON :{BLACK}凡例 STR_GRAPH_KEY_TOOLTIP :{BLACK}この凡例の表示/非表示を切り替えます +STR_GRAPH_X_LABEL_MONTH :{TINY_FONT}{STRING}月 +STR_GRAPH_X_LABEL_MONTH_YEAR :{TINY_FONT}{STRING}月{}{NUM}年 STR_GRAPH_Y_LABEL :{TINY_FONT}{STRING} STR_GRAPH_Y_LABEL_NUMBER :{TINY_FONT}{COMMA} @@ -588,8 +596,8 @@ STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}総資 STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}運送報酬の相場 STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL :{TINY_FONT}{BLACK}輸送時間(日) STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}貨物を10単位(又は10,000リットル)を20マス運送したときの報酬 -STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}全て表示 -STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}全て非表示 +STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}すべて有効化 +STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}すべて無効化 STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}全貨物の運送報酬相場を表示します STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}全貨物の運送報酬相場を非表示にします STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}この貨物の運送報酬相場の表示/非表示を切り替えます @@ -610,7 +618,7 @@ STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRANSPORT_COORDINATOR :運送調整役 STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ROUTE_SUPERVISOR :経路監督 STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_DIRECTOR :理事 STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_CHIEF_EXECUTIVE :取締役 -STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_CHAIRMAN :座長 +STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_CHAIRMAN :会長役 STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_PRESIDENT :総長 STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TYCOON :巨頭 @@ -684,7 +692,7 @@ STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLA STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}プレイリスト - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}消去 STR_PLAYLIST_CHANGE_SET :{BLACK}セットの変更 -STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}選択したプレイリストの内容を消去します。(カスタム1/2 のみ) +STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}選択したプレイリストの内容を消去します (カスタム1/2 のみ) STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}音楽の選択を別のインストール済みセットに変更する STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}クリックすると、その曲を選択したプレイリストに追加します。(カスタム1/2 のみ) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}クリックすると、その曲を選択したプレイリストから削除します。(カスタム1/2 のみ) @@ -762,8 +770,8 @@ STR_SMALLMAP_INDUSTRY :{TINY_FONT}{STR STR_SMALLMAP_LINKSTATS :{TINY_FONT}{STRING} STR_SMALLMAP_COMPANY :{TINY_FONT}{COMPANY} STR_SMALLMAP_TOWN :{TINY_FONT}{WHITE}{TOWN} -STR_SMALLMAP_DISABLE_ALL :{BLACK}全て非表示 -STR_SMALLMAP_ENABLE_ALL :{BLACK}全て表示 +STR_SMALLMAP_DISABLE_ALL :{BLACK}すべて非表示 +STR_SMALLMAP_ENABLE_ALL :{BLACK}すべて表示 STR_SMALLMAP_SHOW_HEIGHT :{BLACK}標高を表示 STR_SMALLMAP_TOOLTIP_DISABLE_ALL_INDUSTRIES :{BLACK}全産業を非表示にします STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES :{BLACK}全産業を表示します @@ -804,7 +812,7 @@ STR_NEWS_AIRCRAFT_CRASH :{BIG_FONT}{BLAC STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}航空機事故発生!{}燃料切れにより航空機が墜落、搭乗していた{COMMA}名が死亡 STR_NEWS_DISASTER_ZEPPELIN :{BIG_FONT}{BLACK}大惨事! {STATION}で飛行船事故! -STR_NEWS_DISASTER_SMALL_UFO :{BIG_FONT}{BLACK}道路車両がUFOとの衝突により大破! +STR_NEWS_DISASTER_SMALL_UFO :{BIG_FONT}{BLACK}車両がUFOとの衝突により大破! STR_NEWS_DISASTER_AIRPLANE_OIL_REFINERY :{BIG_FONT}{BLACK}その瞬間、一面火の海に! {TOWN}付近の石油精製所が爆発! STR_NEWS_DISASTER_HELICOPTER_FACTORY :{BIG_FONT}{BLACK}{TOWN}の工場が突如倒壊 原因は未だ不明! STR_NEWS_DISASTER_BIG_UFO :{BIG_FONT}{BLACK}{TOWN}付近にUFOが着陸! @@ -823,7 +831,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{} (社長) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{0:STRING}の出資により、新たに{1:TOWN}の開発が始まる! -STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK} {BIG_FONT} {TOWN}という新しい町が建設されました! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK} {BIG_FONT} {TOWN}という名の新しい街が創設されました! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}新たな{STRING}が{TOWN}付近に開設! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}新たな{STRING}が{TOWN}付近に作付け開始! @@ -872,6 +880,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}{STRING}が新登場! - {ENGINE} +STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}車両のグループに焦点を合わせたグループウィンドウを開きます STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION}は今後{STRING}を受入れません STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION}は今後{STRING}と{STRING}を受入れません @@ -905,51 +914,52 @@ STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}通貨 ############ start of currency region STR_GAME_OPTIONS_CURRENCY_GBP :英ポンド(£) STR_GAME_OPTIONS_CURRENCY_USD :米ドル($) -STR_GAME_OPTIONS_CURRENCY_EUR :ユーロ(€) +STR_GAME_OPTIONS_CURRENCY_EUR :欧州連合・ユーロ(€) STR_GAME_OPTIONS_CURRENCY_JPY :日本円(¥) -STR_GAME_OPTIONS_CURRENCY_ATS :オーストリアシリング(ATS) -STR_GAME_OPTIONS_CURRENCY_BEF :ベルギーフランク(BEF) -STR_GAME_OPTIONS_CURRENCY_CHF :スイスフランク(CHF) -STR_GAME_OPTIONS_CURRENCY_CZK :チェココルナ(CZK) -STR_GAME_OPTIONS_CURRENCY_DEM :ドイツマルク(DEM) -STR_GAME_OPTIONS_CURRENCY_DKK :デンマーククローネ(DKK) -STR_GAME_OPTIONS_CURRENCY_ESP :スペインペセタ(₧) -STR_GAME_OPTIONS_CURRENCY_FIM :フィンランドマーカ(FIM) -STR_GAME_OPTIONS_CURRENCY_FRF :フランスフラン(₣) -STR_GAME_OPTIONS_CURRENCY_GRD :ギリシアドラクマ(GRD) -STR_GAME_OPTIONS_CURRENCY_HUF :ハンガリーフォリント(HUF) -STR_GAME_OPTIONS_CURRENCY_ISK :アイスランドクローナ(ISK) -STR_GAME_OPTIONS_CURRENCY_ITL :イタリアリラ(ITL) -STR_GAME_OPTIONS_CURRENCY_NLG :オランダギルダー(NLG) -STR_GAME_OPTIONS_CURRENCY_NOK :ノルウェイクローネ(NOK) -STR_GAME_OPTIONS_CURRENCY_PLN :ポーランドズロティ(PLN) -STR_GAME_OPTIONS_CURRENCY_RON :ルーマニアレイ(RON) -STR_GAME_OPTIONS_CURRENCY_RUR :ロシアルーブル(RUR) -STR_GAME_OPTIONS_CURRENCY_SIT :スロベニアトラール(SIT) -STR_GAME_OPTIONS_CURRENCY_SEK :スウェーデンクローナ(SEK) -STR_GAME_OPTIONS_CURRENCY_TRY :トルコリラ(TL) -STR_GAME_OPTIONS_CURRENCY_SKK :スロバキアコルナ(SKK) -STR_GAME_OPTIONS_CURRENCY_BRL :ブラジルレアル(BRL) -STR_GAME_OPTIONS_CURRENCY_EEK :エストニアクローン(EEK) -STR_GAME_OPTIONS_CURRENCY_LTL :リトアニアリタス (LTL) -STR_GAME_OPTIONS_CURRENCY_KRW :韓国ウォン (KRW) +STR_GAME_OPTIONS_CURRENCY_ATS :オーストリア・シリング(ATS) +STR_GAME_OPTIONS_CURRENCY_BEF :ベルギー・フラン(BEF) +STR_GAME_OPTIONS_CURRENCY_CHF :スイス・フラン(CHF) +STR_GAME_OPTIONS_CURRENCY_CZK :チェコ・コルナ(CZK) +STR_GAME_OPTIONS_CURRENCY_DEM :ドイツ・マルク(DEM) +STR_GAME_OPTIONS_CURRENCY_DKK :デンマーク・クローネ(DKK) +STR_GAME_OPTIONS_CURRENCY_ESP :スペイン・ペセタ(₧) +STR_GAME_OPTIONS_CURRENCY_FIM :フィンランド・マーカ(FIM) +STR_GAME_OPTIONS_CURRENCY_FRF :フランス・フラン(₣) +STR_GAME_OPTIONS_CURRENCY_GRD :ギリシャ・ドラクマ(₯) +STR_GAME_OPTIONS_CURRENCY_HUF :ハンガリー・フォリント(HUF) +STR_GAME_OPTIONS_CURRENCY_ISK :アイスランド・クローナ(ISK) +STR_GAME_OPTIONS_CURRENCY_ITL :イタリア・リラ(ITL) +STR_GAME_OPTIONS_CURRENCY_NLG :オランダ・ギルダー(ƒ) +STR_GAME_OPTIONS_CURRENCY_NOK :ノルウェー・クローネ(NOK) +STR_GAME_OPTIONS_CURRENCY_PLN :ポーランド・ズウォティ(PLN) +STR_GAME_OPTIONS_CURRENCY_RON :ルーマニア・レウ(RON) +STR_GAME_OPTIONS_CURRENCY_RUR :ロシア・ルーブル(₽) +STR_GAME_OPTIONS_CURRENCY_SIT :スロベニア・トラール(SIT) +STR_GAME_OPTIONS_CURRENCY_SEK :スウェーデン・クローナ(SEK) +STR_GAME_OPTIONS_CURRENCY_TRY :トルコ・リラ(₺) +STR_GAME_OPTIONS_CURRENCY_SKK :スロバキア・コルナ(SKK) +STR_GAME_OPTIONS_CURRENCY_BRL :ブラジル・レアル(R$) +STR_GAME_OPTIONS_CURRENCY_EEK :エストニア・クローン(EEK) +STR_GAME_OPTIONS_CURRENCY_LTL :リトアニア・リタス(LTL) +STR_GAME_OPTIONS_CURRENCY_KRW :韓国・ウォン(₩) STR_GAME_OPTIONS_CURRENCY_ZAR :南アフリカランド (ZAR) STR_GAME_OPTIONS_CURRENCY_CUSTOM :カスタム… -STR_GAME_OPTIONS_CURRENCY_GEL :グルジア ラリー(GEL) -STR_GAME_OPTIONS_CURRENCY_IRR :イラン リアル(IRR) +STR_GAME_OPTIONS_CURRENCY_GEL :グルジア・ラリー(GEL) +STR_GAME_OPTIONS_CURRENCY_IRR :イラン・リアル(IRR) STR_GAME_OPTIONS_CURRENCY_RUB :新ロシアルーブル(RUB) -STR_GAME_OPTIONS_CURRENCY_MXN :メキシコペソ(MXN) +STR_GAME_OPTIONS_CURRENCY_MXN :メキシコ・ペソ(MXN) STR_GAME_OPTIONS_CURRENCY_NTD :新台湾ドル(ntd) -STR_GAME_OPTIONS_CURRENCY_CNY :人民元(CNY) +STR_GAME_OPTIONS_CURRENCY_CNY :中国・人民元(CNY) STR_GAME_OPTIONS_CURRENCY_HKD :香港ドル(HKD) STR_GAME_OPTIONS_CURRENCY_INR :インドルピー(INR) -STR_GAME_OPTIONS_CURRENCY_IDR :インドネシアルピア(IDR) +STR_GAME_OPTIONS_CURRENCY_IDR :インドネシア・ルピア(IDR) +STR_GAME_OPTIONS_CURRENCY_MYR :マレーシア・リンギット(MYR) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :左側通行 STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :右側通行 -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}街名 +STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}街の名前: STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}街名のスタイルを選択します ############ start of townname region @@ -989,6 +999,7 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :12ヶ月毎 STR_GAME_OPTIONS_LANGUAGE :{BLACK}言語 STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}ゲームの言語を選択します +STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% 完了) STR_GAME_OPTIONS_FULLSCREEN :{BLACK}フルスクリーン STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}OpenTTD をフルスクリーンでプレイするにはチェックします @@ -999,14 +1010,17 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :その他 STR_GAME_OPTIONS_RESOLUTION_ITEM :{NUM}x{NUM} STR_GAME_OPTIONS_VIDEO_ACCELERATION :{BLACK}ハードウェアアクセラレーション +STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}ここをチェックしてOpenTTDがハードウェアアクセラレーションを利用するようにします。設定はゲームを再起動した後に適用されます。 +STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE} この設定は再起動後に適用されます。 STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK} 垂直同期 +STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}ここをチェックして垂直同期を有効にします。設定はゲームを再起動した後に適用されます。ハードウェアアクセラレーションが有効な環境でしか機能しません。 STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}インターフェイスのサイズ STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}インターフェイス上の単位サイズを指定します STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(自動検出) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :通常 +STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :ノーマル STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :2倍 STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :4倍 @@ -1023,6 +1037,7 @@ STR_GAME_OPTIONS_GRAPHICS :{BLACK}グラ STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}画面リフレッシュレート STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :{BLACK}使用する画面のリフレッシュレートを選択します STR_GAME_OPTIONS_REFRESH_RATE_OTHER :その他 +STR_GAME_OPTIONS_REFRESH_RATE_ITEM :{NUM}Hz STR_GAME_OPTIONS_REFRESH_RATE_WARNING :{WHITE}60Hzを超えるリフレッシュレートはパフォーマンスに影響を与える可能性があります。 STR_GAME_OPTIONS_BASE_GRF :{BLACK}基本グラフィックセット @@ -1075,7 +1090,7 @@ STR_FUNDING_ONLY :出資のみ STR_MINIMAL :最小 STR_NUM_VERY_LOW :特に低い STR_NUM_LOW :低い -STR_NUM_NORMAL :通常 +STR_NUM_NORMAL :普通 STR_NUM_HIGH :高い STR_NUM_CUSTOM :カスタム STR_NUM_CUSTOM_NUMBER :カスタム ({NUM}) @@ -1107,7 +1122,7 @@ STR_RIVERS_LOT :多い STR_DISASTER_NONE :なし STR_DISASTER_REDUCED :軽減 -STR_DISASTER_NORMAL :通常 +STR_DISASTER_NORMAL :普通 STR_SUBSIDY_X1_5 :×1.5 STR_SUBSIDY_X2 :×2 @@ -1131,17 +1146,19 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}適切 # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}設定 STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}フィルター設定: -STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}全てを開く -STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}全てを折りたたむ +STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}すべて開く +STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}すべて折りたたむ +STR_CONFIG_SETTING_RESET_ALL :{BLACK}すべての値をリセット STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(説明がありません) STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}デフォルト設定: {ORANGE}{STRING} STR_CONFIG_SETTING_TYPE :{LTBLUE}設定の種類: {ORANGE}{STRING} -STR_CONFIG_SETTING_TYPE_CLIENT :クライアント設定(セーブされませんが全てのゲームに影響) +STR_CONFIG_SETTING_TYPE_CLIENT :クライアント設定(セーブされませんがすべてのゲームに影響します) STR_CONFIG_SETTING_TYPE_GAME_MENU :ゲーム設定(新規ゲームに影響) STR_CONFIG_SETTING_TYPE_GAME_INGAME :ゲーム設定(現在のゲームにのみ影響) STR_CONFIG_SETTING_TYPE_COMPANY_MENU :会社設定(新規ゲームにのみ影響) STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :会社設定(現在の会社のみに影響) STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION :{WHITE}注意! +STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT :{WHITE}この操作によりゲームのすべての設定が初期値にリセットされます。{}続行してもよろしいでしょうか? STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}カテゴリ: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}種類: @@ -1159,9 +1176,9 @@ STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :ゲーム設定 STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :ゲーム設定(保存ゲーム内に記録・今のゲームにのみ影響) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :会社設定(全保存ゲーム内に記録・ニューゲーム時に影響) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :会社設定(保存ゲーム内に記録・今の会社だけに影響) -STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}設定による検索結果を全て表示{}{SILVER}カテゴリ{BLACK}別{WHITE}{STRING} -STR_CONFIG_SETTING_TYPE_HIDES :{BLACK}設定による検索結果を全て表示{}{SILVER}種類{BLACK}別{WHITE}All setting types -STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}設定による検索結果を全て表示{}{SILVER}カテゴリ{BLACK}別{WHITE}{STRING} {BLACK}and {SILVER}Type {BLACK}to {WHITE}All setting types +STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}設定による検索結果をすべて表示{}{SILVER}カテゴリ{BLACK}別{WHITE}{STRING} +STR_CONFIG_SETTING_TYPE_HIDES :{BLACK}設定による検索結果をすべて表示{}{SILVER}種類{BLACK}別{WHITE}すべての設定タイプ +STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}設定による検索結果をすべて表示{}{SILVER}カテゴリ{BLACK}別{WHITE}{STRING} {BLACK}and {SILVER}Type {BLACK}to {WHITE}All setting types STR_CONFIG_SETTINGS_NONE :{WHITE}- なし - STR_CONFIG_SETTING_OFF :無効 @@ -1195,21 +1212,24 @@ STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :助成金対象 STR_CONFIG_SETTING_CONSTRUCTION_COSTS :建設費: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :建設・購入費用のレベルを設定します STR_CONFIG_SETTING_RECESSIONS :景気後退: {STRING} -STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :設定を有効にすると数年おきに短期間、景気の後退が起こる可能性が出ます。景気後退の間は全ての生産がかなりの落ち込みを見せます (景気後退が終わると元のレベルに戻ります) +STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :設定を有効にすると数年おきに短期間、景気の後退が起こる可能性が出ます。景気後退の間はすべての生産がかなりの落ち込みを見せます (景気後退が終わると元のレベルに戻ります)。 STR_CONFIG_SETTING_TRAIN_REVERSING :列車の転回不可: {STRING} STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :設定を有効にすると路線の末端駅でない限り、転回(折り返し)した方が次の目的地に早く着ける場合であっても転回をしなくなります STR_CONFIG_SETTING_DISASTERS :災害: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :設定を有効にすると時折、乗り物や交通インフラを遮断・破壊する災害が起きるようになります -STR_CONFIG_SETTING_CITY_APPROVAL :地域の再編に対する町の姿勢: {STRING} +STR_CONFIG_SETTING_CITY_APPROVAL :地域の再編に対する街の姿勢: {STRING} STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :会社が街域で引き起こした騒音(主に空港)や環境破壊がどの程度、街での評価や同じ地域での更なる建設行為に影響するかを設定します STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :マップ高さ限界: {STRING} +STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT :マップの地形の最高高度を指定します。"(auto)"で地形生成後に適切な値を設定させるようにします。 +STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_VALUE :{NUM} STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_AUTO :(自動) -STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}マップの最高高さをこの値には設定出来ません。少なくとも1箇所以上この値より高い山があります。 +STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}マップの高度限界をこの値に設定できません。より高高度にある山が一つ以上存在します。 STR_CONFIG_SETTING_AUTOSLOPE :建物/路線の自動地形追従: {STRING} STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :撤去を行わないで建物や路線がある土地の地形を変更することを可能にします。建物/路線は変更された地形に自動で追従します。 STR_CONFIG_SETTING_CATCHMENT :現実的な受入範囲: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :駅や空港の種類の違いによって受入範囲が変動するようになります +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :会社の駅が中立の専用荷役所を持つ産業からサービスを受けられるようにする: {STRING} STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :有効にすると、駅が接続されている産業(石油掘削装置など)にも、近くに建設された会社が所有している駅がサービスを提供する場合があります。無効になっている場合、これらの産業は、接続されているステーションによってのみサービスを受けることができます。近くの会社のステーションはそれらにサービスを提供できず、接続されたステーションは業界以外のものにサービスを提供しません STR_CONFIG_SETTING_EXTRADYNAMITE :街有道路・橋・トンネルの撤去容認: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :街有の交通インフラや建物の撤去をより容易にします @@ -1219,9 +1239,9 @@ STR_CONFIG_SETTING_TILE_LENGTH :{COMMA}タイ STR_CONFIG_SETTING_SMOKE_AMOUNT :煙・火花の量{STRING} STR_CONFIG_SETTING_SMOKE_AMOUNT_HELPTEXT :輸送機器が故障や事故の際に発する煙や火花の量を設定します STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL :列車の加減速モデル: {STRING} -STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT :列車の加減速に対して使用する物理モデルを選択します。「オリジナル」モデルでは勾配でのみ、全ての車両に対し等しく減速がかかります。「リアル」モデルでは勾配とカーブで、編成の様々な要素(編成の長さや機関車の牽引力など)に応じて減速がかかるようになります -STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL :道路車両の加減速モデル: {STRING} -STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT :車両の加減速に対して使用する物理モデルを選択します。「オリジナル」モデルでは勾配で全ての車両に対し等しく減速がかかります。「リアル」モデルでは勾配で様々な要素(馬力など)に応じて減速がかかるようになります +STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT :列車の加減速に対して使用する物理モデルを選択します。「オリジナル」モデルでは勾配でのみ、すべての車両に対し等しく減速がかかります。「リアル」モデルでは勾配とカーブで、編成の様々な要素(編成の長さや機関車の牽引力など)に応じて減速がかかるようになります。 +STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL :車両の加減速モデル: {STRING} +STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT :車両の加減速に対して使用する物理モデルを選択します。「オリジナル」モデルでは勾配ですべての車両に対し等しく減速がかかります。「リアル」モデルでは勾配で様々な要素(馬力など)に応じて減速がかかるようになります。 STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS :線路の勾配率: {STRING} STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :線路1タイルあたりの勾配率を設定します。数値を上げると急勾配になり、列車が坂を上りにくくなります。 STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% @@ -1236,11 +1256,11 @@ STR_CONFIG_SETTING_INFLATION_HELPTEXT :インフレを STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH :橋梁の最大長:{STRING} STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH_HELPTEXT :橋梁の最大長を設定できます STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT :橋梁の高度: {STRING} -STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT_HELPTEXT :橋梁の建設出来る高さを設定出来ます +STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT_HELPTEXT :橋梁の最大高度を設定できます STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH :トンネルの最大長:{STRING} STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :トンネルの最大長を設定できます STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :一次産業の開設法: {STRING} -STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :ゲーム中で一次産業をプレイヤーが開設できるかどうかを決めます。「なし」では開設出来ません。「調査/探鉱」では出資することは可能ですが、どこに建設されるかは分かりませんし、失敗することもあります。「他の産業と同様」では一次産業も二次産業同様、好きなところに作ることが出来ます。 +STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :ゲーム中で一次産業をプレイヤーが開設できるかどうかを決めます。「なし」では開設できません。「調査/探鉱」では出資はできますが、どこに建設されるかは分かりませんし、失敗することもあります。「他の産業と同様」では一次産業も二次産業同様、好きなところに作れます。 STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NONE :なし STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NORMAL :他の産業と同様 STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_PROSPECTING :調査/探鉱 @@ -1256,7 +1276,7 @@ STR_CONFIG_SETTING_SIGNALSIDE_RIGHT :右 STR_CONFIG_SETTING_SHOWFINANCES :年末の財政ウインドウ表示: {STRING} STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :有効にすると、毎年末に財政ウインドウがポップアップするようになります。企業の財務状況を簡単にチェックするのに便利です。 STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :直行運転をデフォルト化: {STRING} -STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :通常、輸送機器は目的地までの経路上に停留施設があれば必ずそこに止まります。この設定を有効にすると、経路上の全ての停留施設を飛ばし目的地まで直行するようになります。注意: この設定は新規の指令にのみ作用します。またこの設定が有効であっても、個別に解除することは可能です。 +STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :通常、輸送機器は目的地までの経路上に停留施設があれば必ずそこに止まります。この設定を有効にすると、経路上のすべての停留施設を飛ばし目的地まで直行するようになります。注意: この設定は新規の指令にのみ作用します。またこの設定が有効であっても、個別に解除することは可能です。 STR_CONFIG_SETTING_STOP_LOCATION :新規列車の停車位置: プラットホームの{STRING} STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :デフォルトで列車がプラットホームのどの位置に止まるかを設定します。「先端」ではホームの進入地点と列車終端、「中間」ではホームと列車の中間地点、「終端」では進入地点逆端と列車先端がそれぞれ一致する位置に止まります。注意: この設定は新規の指令にのみ作用します。またこの設定が有効であっても、個別に停車位置を設定することは可能です。 STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :先端 @@ -1269,13 +1289,13 @@ STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :する (フル STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :する STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :する (ビューポートでも有効) STR_CONFIG_SETTING_BRIBE :議会の買収: {STRING} -STR_CONFIG_SETTING_BRIBE_HELPTEXT :街で議会買収を企てることが可能になります。成功すれば街での評判が良くなりますが、地元当局に事が発覚した場合、罰金を受けた上評判が悪くなり、その街では半年間何もすることができなくなります +STR_CONFIG_SETTING_BRIBE_HELPTEXT :街で議会買収を企てられるようになります。成功すれば街での評判が良くなりますが、地元当局に事が発覚した場合罰金を受けた上評判が悪くなり、その上その街では半年間何もできなくなります STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :独占運送契約の締結: {STRING} -STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :会社と街との間で独占運送契約を結ぶことが可能になります。この契約が締結されると、その街にある全ての競争相手の停留施設は丸一年間、旅客・貨物問わず何も受け入れできなくなります +STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :会社と街との間で独占運送契約を結ぶことが可能になります。この契約が締結されると、その街にあるすべての競争相手の停留施設は丸一年間、旅客・貨物問わず何も受け入れできなくなります STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS :街の開発に出資: {STRING} -STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT :街に新たなビルを建てるための開発資金を提供することが可能になります +STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT :街に新たなビルを建てるための開発資金を提供できるようになります。 STR_CONFIG_SETTING_ALLOW_FUND_ROAD :街路補修に出資: {STRING} -STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT :街の道路補修に資金を提供することが可能になります。半年間街内の不通にして敵を混乱させることはできますが、「街路補修時に道路整理」を有効にしない限り工事自体にメリットはありません +STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT :街の道路補修に資金を提供できるようになります。半年間街内の不通にして敵を混乱させることはできますが、「街路補修時に道路整理」を有効にしない限り工事自体にメリットはありません STR_CONFIG_SETTING_ALLOW_GIVE_MONEY :他社への送金: {STRING} STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT :マルチプレイヤーモードの際に、会社間での資金の受け渡しが可能となります STR_CONFIG_SETTING_FREIGHT_TRAINS :重量乗数: {STRING} @@ -1287,11 +1307,11 @@ STR_CONFIG_SETTING_PLANE_CRASHES :航空事故数 STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :航空機事故の発生率を定めます STR_CONFIG_SETTING_PLANE_CRASHES_NONE :なし STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :軽減 -STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :通常 +STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :普通 STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :街有道路での路側型バス停/荷役所建設: {STRING} -STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :路側型バス停/荷役所を街が所有する道路上に建設することを可能にします +STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :路側型バス停/荷役所を街が所有する道路上に建設できるようにします STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :他社の道路上での路側型バス停/荷役所設置: {STRING} -STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :路側型バス停/荷役所を他社が所有する道路上に建設することを可能にします +STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :路側型バス停/荷役所を他社が所有する道路上に建設できるようにします STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}この設定の変更は既に輸送車両が存在する時には不可能です STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :インフラ補修: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :有効にすると、インフラ設備にも維持費が発生するようになります。維持費はネットワークのサイズに非線形で比例する為、小さい会社よりも大きい会社の方が影響が大きくなります @@ -1333,11 +1353,12 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :街の名前ラ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :グラフ線の太さ: {STRING} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :グラフ画面での折れ線の太さを設定します。細い線では値を精密に読み取りやすくなり、太い線ではグラフ自体が見やすくなり、線色の見分けがつきやすくなります STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :ビルドビークルウィンドウにNewGRFの名前を表示します:{STRING} +STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :購入可能な車両の一覧の詳細部分に由来する NewGRF を表示します 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はパーリンノイズに基づいた地形ジェネレーターで、より細かい地形生成のパラメータを指定できます +STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :オリジナルの地形ジェネレーターは基本グラフィックセットに依存し、ある程度固定された地形しか生成できません。TerraGenesisはパーリンノイズに基づいた地形ジェネレーターで、より細かい地形生成のパラメータを指定できます STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :オリジナル STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis STR_CONFIG_SETTING_TERRAIN_TYPE :地形種類: {STRING} @@ -1347,9 +1368,13 @@ STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :どの程度の STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :石油精製所のマップ端からの距離: {STRING} STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :石油精製所はマップの外周付近にのみ建設されます。つまり、外周が海のマップでは海岸沿いに建設されるということです STR_CONFIG_SETTING_SNOWLINE_HEIGHT :雪線の位置: {STRING} -STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :亜寒帯気候での雪線の高さを設定します。雪は産業と街の成長に影響があります +STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :亜寒帯気候での雪線の高さを設定します。雪線は産業生成と街の発展に影響を及ぼします。シナリオエディタを介して変更するか積雪量により計算されます。 +STR_CONFIG_SETTING_SNOW_COVERAGE :降雪量: {STRING} STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :亜寒帯の風景のおおよその雪の量を制御します。雪はまた、産業の生成と町の成長要件にも影響を及ぼします。マップの生成中にのみ使用されます。海抜のすぐ上の土地は常に雪がありません STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE :{NUM}% +STR_CONFIG_SETTING_DESERT_COVERAGE :砂漠の範囲: {STRING} +STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT :熱帯気候でのおおよその砂漠の量を制御します。砂漠は産業生成に影響を及ぼします。マップ生成時にのみ設定が参照されます。 +STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE :{NUM}% STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :地形の起伏: {STRING} STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT :(TerraGenesisのみ) 地形の起伏度を設定します。なだらかな地形では丘陵の数は減り、裾野が長くなります。起伏が多い地形では丘陵が多くなりますが、似たり寄ったりな地形の繰り返しに見えることがあります STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :特になだらか @@ -1361,11 +1386,11 @@ STR_CONFIG_SETTING_VARIETY_HELPTEXT :(TerraGenesis STR_CONFIG_SETTING_RIVER_AMOUNT :川の数: {STRING} STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT :どの位の川が生成されるかを設定します STR_CONFIG_SETTING_TREE_PLACER :植林アルゴリズム: {STRING} -STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT :マップでの木の分布を設定します。「オリジナル」では全ての樹種がマップ全域に散布するように植えられます。「改良」ではある程度のまとまりで植えられます +STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT :マップでの木の分布を設定します。「オリジナル」ではすべての樹種がマップ全域に散布するように植えられます。「改良」ではある程度のまとまりで植えられます STR_CONFIG_SETTING_TREE_PLACER_NONE :なし STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :オリジナル STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :改良版 -STR_CONFIG_SETTING_ROAD_SIDE :道路車両: {STRING} +STR_CONFIG_SETTING_ROAD_SIDE :車両: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :左側/右側通行を設定します STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :ハイトマップの回転方向: {STRING} STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :反時計回り @@ -1385,16 +1410,18 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :ミニマップ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :緑 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :濃緑 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :青紫 -STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :スクロール時の動き +STR_CONFIG_SETTING_SCROLLMODE :ビューポートのスクロール挙動: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :マップのスクロール挙動 STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :右クリックでビューポートを移動し、マウスの位置をロックします STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :右クリックで地図を移動し、マウスの位置をロックします 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_MEASURE_TOOLTIP :測定ツールチップ表示: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :タイルをまたぐような建設活動の際に、距離や面積、高低差などの情報を表示するようになります STR_CONFIG_SETTING_LIVERIES :輸送機器の個別塗装: {STRING} -STR_CONFIG_SETTING_LIVERIES_HELPTEXT :輸送機器別に特定の塗装色を使うことが可能になります。無効にすると全ての輸送機器は企業色で塗装されます +STR_CONFIG_SETTING_LIVERIES_HELPTEXT :輸送機器別に特定の塗装色を使うことが可能になります。無効にするとすべての輸送機器は企業色で塗装されます STR_CONFIG_SETTING_LIVERIES_NONE :無効 STR_CONFIG_SETTING_LIVERIES_OWN :有効(自社のみ) STR_CONFIG_SETTING_LIVERIES_ALL :有効(全社) @@ -1420,6 +1447,8 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :コマンド+ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+クリック (Win) STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :切 +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :右クリックでウィンドウを閉じる: {STRING} +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :ウィンドウ内で右クリックしてウィンドウを閉じられます。右クリックでツールチップも無効にできます。 STR_CONFIG_SETTING_AUTOSAVE :オートセーブ: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :オートセーブの間隔を設定します @@ -1459,8 +1488,11 @@ STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :建設ツール STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :橋やトンネルなどを建設した後もツールバーを開いたままにします STR_CONFIG_SETTING_EXPENSES_LAYOUT :財政ウィンドウのグループ分け: {STRING} STR_CONFIG_SETTING_EXPENSES_LAYOUT_HELPTEXT :財政ウィンドウのレイアウトを収入部門・支出部門でグループ分けするかどうかを設定します -STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_HELPTEXT :早送りが有効になっている場合のゲームの進行速度を制限します。0 =制限なし(コンピューターが許す限り高速)。100%未満の値は、ゲームの速度を低下させます。上限はコンピュータの仕様によって異なり、ゲームによって異なる場合があります。 -STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_VAL :{NUM}%通常のゲーム速度 +STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :線路の敷設中に自動的に信号を除去します: {STRING} +STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT :信号が経路上に存在する場合線路設置の際にすべて自動的に除去されます。鉄道車両の衝突につながる危険性があります。 +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT :ゲーム進行速度の加速制限: {STRING} +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_HELPTEXT :早送りが有効になっている場合のゲーム進行速度を制限します。0 = 制限なし(コンピュータの許す限り高速にする)。100%より下げると進行速度が遅くなります。制限の上限はコンピュータの仕様によって異なり、ゲームの設定にも依存します。 +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_VAL :通常の {NUM}% まで STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_ZERO :制限なし(コンピューターが許す限り高速) STR_CONFIG_SETTING_SOUND_TICKER :ニュース表示: {STRING} @@ -1478,7 +1510,7 @@ STR_CONFIG_SETTING_SOUND_DISASTER_HELPTEXT :事故や災害 STR_CONFIG_SETTING_SOUND_VEHICLE :輸送機器: {STRING} STR_CONFIG_SETTING_SOUND_VEHICLE_HELPTEXT :輸送機器関係の効果音を鳴らすかどうかを設定します STR_CONFIG_SETTING_SOUND_AMBIENT :環境音: {STRING} -STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :町や産業、自然環境に関する効果音を鳴らすかどうかを設定します +STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :街や産業、自然環境に関する効果音を鳴らすかどうかを設定します STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING :有効なインフラのみ建設可能: {STRING} STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING_HELPTEXT :有効にするとその時点で使用可能な設備のみが建設できます。(例: 電気機関車が購入できないときに電気鉄道は建設不可) @@ -1511,6 +1543,7 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :マルチプレ STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :命令コード処理上限: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :AIやゲームスクリプトが一つの「詰め込み指令」を処理する際に、一度に演算できる命令コード数を設定します。一般に値を小さくした場合、ゲームへの負荷が軽減されます 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} @@ -1530,7 +1563,7 @@ STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :有効にする STR_CONFIG_SETTING_WAGONSPEEDLIMITS :貨車の上限速度: {STRING} STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :有効にすると、上限速度が設定されている貨車を使用した場合、列車はその速度以上出せなくなります STR_CONFIG_SETTING_DISABLE_ELRAILS :電気鉄道を無効化: {STRING} -STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT :この設定を有効にすると電気鉄道を建設できなくなります。ただし電気機関車・電車でも架線のない非電化の線路を走ることができるようになります +STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT :この設定を有効にすると電気鉄道を敷設できなくなります。ただし電気機関車・電車は架線のない非電化の線路を走ることができるようになります STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN :停留施設の開業(自社): {STRING} STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN_HELPTEXT :自社の新しい停留施設に最初の列車が到着したときにニュースを表示するかを設定します @@ -1570,11 +1603,15 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :新聞 STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :カラー新聞の開始年: {STRING} STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :新聞がカラー版になる境目の年を設定します STR_CONFIG_SETTING_STARTING_YEAR :開始年: {STRING} -STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :スコアリングの目的でゲームが終了する年。 今年の終わりには、会社のスコアが記録され、ハイスコア画面が表示されますが、プレーヤーはその後もプレイを続けることができます。{}これが開始年より前の場合、ハイスコア画面は表示されません。 +STR_CONFIG_SETTING_ENDING_YEAR :スコア記録の基準年: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :スコア記録の基準となる基準年。基準年の終わりに会社のスコアがハイスコアに記録・表示されます。プレイヤーはその後もプレイを続けられます。{}基準年が開始年より前の場合、ハイスコア画面は表示されません。 STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :(なし) STR_CONFIG_SETTING_ECONOMY_TYPE :エコノミータイプ:{STRING} +STR_CONFIG_SETTING_ECONOMY_TYPE_HELPTEXT :なだらかな経済は生産量の変動をより頻繁に起こすようにします。固定経済は変動と閉鎖の両方を起こさないようにします。産業が NewGRF により提供される場合この設定は影響を及ぼさない場合があります。 STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL :オリジナル STR_CONFIG_SETTING_ECONOMY_TYPE_SMOOTH :なだらか +STR_CONFIG_SETTING_ECONOMY_TYPE_FROZEN :固定 STR_CONFIG_SETTING_ALLOW_SHARES :他社株の取引許容: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :有効にすると、ライバル会社の株式を取引できるようになります。この設定を有効にしても、目的の社が設立から丸5年経過していない場合は取引できません STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :株式を取引するための最低会社年齢:{STRING} @@ -1599,7 +1636,7 @@ STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :信号種類の STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Ctrl+クリックで信号種類を切り替える際に使う、サイクル種類を決定します STR_CONFIG_SETTING_CYCLE_SIGNAL_NORMAL :閉塞・入口・出口・コンボ STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :パス・一方通行パス -STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :全て +STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :すべて STR_CONFIG_SETTING_TOWN_LAYOUT :街の道路配置: {STRING} STR_CONFIG_SETTING_TOWN_LAYOUT_HELPTEXT :街での道路区画計画を設定します @@ -1609,22 +1646,27 @@ STR_CONFIG_SETTING_TOWN_LAYOUT_2X2_GRID :格子状(2x2 STR_CONFIG_SETTING_TOWN_LAYOUT_3X3_GRID :格子状(3x3) STR_CONFIG_SETTING_TOWN_LAYOUT_RANDOM :ランダム STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :街路の自動構築: {STRING} -STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :街の自治体が街の成長に応じて街路を自動で拡張するようになります。無効にすると勝手な街路拡張は行われなくなりますが、街を成長させるためにはプレイヤーが街路の建設を行う必要が出てきます +STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :街の自治体が街の成長に応じて街路を自動で拡張するようになります。無効にすると勝手な街路の拡張は行われなくなりますが、街を成長させるためにはプレイヤーが街路を敷設しなければなりません。 STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :街路との平面交差を許可: {STRING} -STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :有効にすると、会社が作る道路と街路とが交差することが可能となります +STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :有効にすると、会社が作る道路と街路とが交差できるようになります STR_CONFIG_SETTING_NOISE_LEVEL :空港建設に対する街の騒音レベル規制: {STRING} STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :この設定を無効にすると、街に作れる空港は最大2つまでになります。有効にした場合は、各空港の騒音レベルの総和が街の騒音許容レベル以下になるようにしか建てられません。騒音レベルは空港の大きさ・街からの距離により、騒音許容レベルは街の人口により左右されます STR_CONFIG_SETTING_TOWN_FOUNDING :ゲーム中での街新設: {STRING} -STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :有効にすると、ゲーム中でも新規の街を開設するために出資することが可能になります +STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :有効にすると、ゲーム中でも新しく街を開設するために出資できるようになります。 STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :無効 STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :有効 STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :有効(道路配置も設定可) -STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :町の総人口に対する、町の家によって生産される貨物の量。{}二次成長:2倍の大きさの町は4倍の乗客を生み出します。{}線形成長:2倍の大きさの町は2倍の量を生み出します +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :街の貨物生成: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :街の総人口に対する家屋によって生産される貨物の量。{}二次成長:2倍の大きさの街は4倍の乗客を生み出します。{}線形成長:2倍の大きさの街は2倍の量を生み出します +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :二次的(オリジナル) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :線形 STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :樹木の自然成長: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :ゲーム中、ランダムに生えてくる樹種を設定します。設定によっては樹木の生育に依存する産業に悪影響が生じる可能性があります(「不可」にした場合、亜熱帯地域の伐採所を機能させ続けるためには手動で植林し続ける必要があります) +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD :成長はするが広がらない {RED}(製材所の機能を止めます) STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :成長するが、熱帯雨林にのみ広がる STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_ALL :成長し、どこにでも広がる +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_GROWTH_NO_SPREAD :成長はするが広がらない {RED}(製材所の機能を止めます) STR_CONFIG_SETTING_TOOLBAR_POS :メインツールバーの位置: {STRING} STR_CONFIG_SETTING_TOOLBAR_POS_HELPTEXT :画面上のメインツールバーの位置を決めます @@ -1643,14 +1685,15 @@ STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :ズームイン STR_CONFIG_SETTING_ZOOM_MAX :最大ズームアウトレベル:{STRING} STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT :ズームアウトの最大倍率を設定します。ズームアウトの倍率が大きいと、処理遅延が発生する可能性があります STR_CONFIG_SETTING_SPRITE_ZOOM_MIN :使用する最高解像度のスプライト:{STRING} -STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT :スプライトに使用する最大解像度を制限します。 スプライトの解像度を制限すると、使用可能な場合でも高解像度のグラフィックを使用できなくなります。 これにより、高解像度のグラフィックを使用する場合と使用しない場合のGRFファイルを組み合わせて使用する場合に、ゲームの外観を統一することができます。 +STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT :スプライトに使用する最大解像度を制限します。 スプライトの解像度を制限すると使用可能な場合でも高解像度のグラフィックを使用できなくなります。 これにより、高解像度のグラフィックを使用する場合と使用しない場合のGRFファイルを組み合わせて使用する場合にゲームの外観を統一できます。 STR_CONFIG_SETTING_ZOOM_LVL_MIN :4倍 STR_CONFIG_SETTING_ZOOM_LVL_IN_2X :2倍 -STR_CONFIG_SETTING_ZOOM_LVL_NORMAL :通常 +STR_CONFIG_SETTING_ZOOM_LVL_NORMAL :普通 STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X :2倍 STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X :4倍 STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8倍 STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN :4倍 +STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_IN_2X :2倍 STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_NORMAL :1倍 STR_CONFIG_SETTING_TOWN_GROWTH :街の成長速度: {STRING} STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT :街の成長速度を設定します @@ -1659,12 +1702,12 @@ STR_CONFIG_SETTING_TOWN_GROWTH_SLOW :遅い STR_CONFIG_SETTING_TOWN_GROWTH_NORMAL :普通 STR_CONFIG_SETTING_TOWN_GROWTH_FAST :早い STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :特に早い -STR_CONFIG_SETTING_LARGER_TOWNS :都市になる町の比率: {STRING} -STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :町のうち、成長によってその何分の1が都市になるか(あるいは全くならないか)を設定します。都市になると拡大・成長速度が速くなります +STR_CONFIG_SETTING_LARGER_TOWNS :都市になる街の比率: {STRING} +STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :街のうち、成長によってその何分の1が都市になるか(あるいは全くならないか)を設定します。都市になると拡大・成長速度が速くなります STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :{COMMA}分の1 STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :変化なし STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :初期の都市サイズ乗数: {STRING} -STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :ゲーム開始時に都市が普通の町に比べて平均して何倍の人口規模になるかを設定します +STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :ゲーム開始時に都市が普通の街に比べて平均して何倍の人口規模になるかを設定します STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :分配グラフの更新頻度: {STRING}日 STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :リンクグラフを再計算する時間間隔を設定します。それぞれの再計算では、グラフの単一要素に関わる経路計画だけを計算します。つまり、グラフの一部が更新されるだけで、全体が設定した間隔で更新されるという訳ではありません。この間隔を短くすると再計算のためにCPUへの負荷が大きくなります。長くすると、新たなルートが貨物分配に組み込まれるのに時間がかかるようになります。 @@ -1688,7 +1731,7 @@ STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :0より大き STR_CONFIG_SETTING_DEMAND_SIZE :対称分配での戻り量: {STRING} STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :この値を100%未満に設定すると、対称分配の挙動が非対称分配に近くなります。値が小さいほど受け入れ量に対する送り返し量が小さくなります。0%に設定した場合、対称分配と非対称分配の挙動に違いはなくなります STR_CONFIG_SETTING_SHORT_PATH_SATURATION :高収容力経路より速達経路を優先飽和: {STRING} -STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :二つの停留施設間を結ぶ経路が複数存在することが往々にしてあります。そのような場合、貨物分配アルゴリズムは最初に最短となる経路を飽和するまで使用し、次いで2番目の最短経路を使用するというように埋めていきます。飽和したかどうかは、推定収容力、輸送計画によって判断されます。すべての経路を飽和してもまだ需要を満たせない場合、高容量な経路を優先しつつ、すべての経路に負荷を掛けます。しかしほとんどの場合、アルゴリズムは経路の輸送力を正確に見積もることができません。この設定では、高収容力の路線を使用し始める前にどの程度最短経路を飽和するかを設定します。収容力より需要が上回ると推定される時には、停留施設が混み合うのを避けるために100%未満に設定して下さい。 +STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :二つの停留施設間を結ぶ経路が複数存在することは往々にしてあります。そのような場合、貨物分配アルゴリズムは最初に最短となる経路を飽和するまで使用し、次いで2番目の最短経路を使用するというように埋めていきます。飽和したかどうかは、推定収容力、輸送計画によって判断されます。すべての経路を飽和してもまだ需要を満たせない場合、高容量な経路を優先しつつ、すべての経路に負荷を掛けます。しかしほとんどの場合、アルゴリズムは経路の輸送力を正確に見積もることができません。この設定では、高収容力の路線を使用し始める前にどの程度最短経路を飽和するかを設定します。収容力より需要が上回ると推定される時には、停留施設が混み合うのを避けるために100%未満に設定して下さい。 STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :速度単位: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :ゲーム中の速度をいずれの単位系で表すか決定します @@ -1791,6 +1834,7 @@ STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}スプ # Video initalization errors STR_VIDEO_DRIVER_ERROR :{WHITE}ビデオ設定にエラーがあります... +STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... 対応する GPU が見つかりません。ハードウェアアクセラレーションは無効になります。 # Intro window STR_INTRO_CAPTION :{WHITE}OpenTTD {REV} @@ -1830,10 +1874,12 @@ STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}公式 STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}AI/ゲームスクリプトの設定を行います STR_INTRO_TOOLTIP_QUIT :{BLACK}OpenTTD を終了します +STR_INTRO_BASESET :現在選択されているグラフィックのベースセットは {NUM} つのスプライトが欠けています。ベースセットの更新を確認してみてください。 STR_INTRO_TRANSLATION :{BLACK}この言語セットには{NUM}個の未訳文字列があります。翻訳者としてWeb登録し、OpenTTDをより良くする為にご助力下さい。(詳細はreadme.txtをご覧下さい) # Quit window STR_QUIT_CAPTION :{WHITE}終了 +STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD :{YELLOW}OpenTTD を終了してもよろしいですか? STR_QUIT_YES :{BLACK}はい STR_QUIT_NO :{BLACK}いいえ @@ -1869,14 +1915,14 @@ 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_PRIMARY_TOOLTIP :{BLACK}選択した輸送機器に使用する塗装のメインカラーを選択します。Ctrl+クリックで、このタブの輸送機器すべてのメインカラーをこの色にします +STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}選択した輸送機器に使う、塗装のサブカラーを選択します。Ctrl+クリックで、このタブの輸送機器すべてのサブカラーをこの色にします STR_LIVERY_PANEL_TOOLTIP :{BLACK}塗装を変更する輸送機器を選択します。Ctrl+クリックで複数の輸送機器を選択できます。適用状況を切り替えるにはチェックボックスをクリックします STR_LIVERY_DEFAULT :通常の塗装色 STR_LIVERY_STEAM :機関車 (蒸気) -STR_LIVERY_DIESEL :機関車 (ディーゼル) -STR_LIVERY_ELECTRIC :機関車 (電気) +STR_LIVERY_DIESEL :ディーゼル機関車 +STR_LIVERY_ELECTRIC :電気機関車 STR_LIVERY_MONORAIL :機関車 (モノレール) STR_LIVERY_MAGLEV :機関車 (リニア) STR_LIVERY_DMU :気動車 (動力分散式) @@ -1955,6 +2001,8 @@ STR_FACE_TIE :ネクタイ: STR_FACE_EARRING :イヤリング: STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}ネクタイ/イヤリングを変更します +STR_NETWORK_SERVER_VISIBILITY_PRIVATE :プライベート +STR_NETWORK_SERVER_VISIBILITY_PUBLIC :公開 # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}マルチプレイヤーゲーム @@ -2016,9 +2064,10 @@ STR_NETWORK_START_SERVER_CAPTION :{WHITE}新規 STR_NETWORK_START_SERVER_NEW_GAME_NAME :{BLACK}ゲーム名: STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}ゲーム名を指定します。これはマルチプレイヤーゲームの選択画面に表示される名前になります STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}パスワードを設定 -STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}ゲームをパスワードで保護することができます。一般から公然とアクセスされたくない場合等に設定します +STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}ゲームをパスワードで保護できます。一般から公然とアクセスされたくない場合等に設定します STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}可視性 +STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}他のプレイヤーがあなたのサーバーを公開リストで見られるかどうか STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}接続者数: {NUM} STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}最大接続数: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}接続できるクライアントの最大数を指定します。必ずしも全スロットを埋める必要はありません @@ -2052,7 +2101,7 @@ STR_NETWORK_GAME_LOBBY_STATIONS :{SILVER}停留 STR_NETWORK_GAME_LOBBY_PLAYERS :{SILVER}プレイヤー数: {WHITE}{STRING} STR_NETWORK_GAME_LOBBY_NEW_COMPANY :{BLACK}新規会社 -STR_NETWORK_GAME_LOBBY_NEW_COMPANY_TOOLTIP :{BLACK}新規に会社を設立します +STR_NETWORK_GAME_LOBBY_NEW_COMPANY_TOOLTIP :{BLACK}新しく会社を設立します STR_NETWORK_GAME_LOBBY_SPECTATE_GAME :{BLACK}ゲームを観覧 STR_NETWORK_GAME_LOBBY_SPECTATE_GAME_TOOLTIP :{BLACK}観覧者としてゲームを観戦します STR_NETWORK_GAME_LOBBY_JOIN_COMPANY :{BLACK}経営に参画 @@ -2082,16 +2131,44 @@ STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}この STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}この会社は保護されています。経営に参画するにはパスワードを入力してください # Network company list added strings -STR_NETWORK_COMPANY_LIST_CLIENT_LIST :クライアントリスト +STR_NETWORK_COMPANY_LIST_CLIENT_LIST :オンラインのプレイヤー STR_NETWORK_COMPANY_LIST_SPECTATE :観覧モード # Network client list -STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}他の人があなたのサーバーを公開リストで見ることができるかどうか -STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}すべての観客にメッセージを送る +STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}マルチプレイヤー +STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}サーバー +STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}名前 +STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}あなたがプレイしているサーバー名 +STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}サーバーの名前を編集する +STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :サーバー名 +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}可視性 +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}他のプレイヤーがあなたのサーバーを公開リストで見られるかどうか +STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}プレイヤー +STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}名前 +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}あなたのプレイヤー名 +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}プレイヤー名を変更する +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :あなたのプレイヤー名 +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}このクライアントに対して実行する管理アクション +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}この会社に対して実行する管理アクション +STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}この会社に参画する +STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}このプレイヤーにメッセージを送信する +STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}この会社のすべてのプレイヤーにメッセージを送信する +STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}すべての観客にメッセージを送信する +STR_NETWORK_CLIENT_LIST_SPECTATORS :観覧者 +STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(新規会社) +STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}新しく会社を設立し参画します +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}これはあなたです STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}ゲームのホストです +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :キック +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :BAN +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :削除 +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :パスワードのアンロック +STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}管理者アクション +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}'{STRING}'をキックしてもよろしいですか? STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}プレーヤー「{STRING}」を追放してもよろしいですか? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}会社 '{COMPANY}' を削除してもよろしいですか? STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}会社 '{COMPANY}'のパスワードをリセットしてもよろしいですか? STR_NETWORK_SERVER :サーバー @@ -2137,6 +2214,7 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}サー STR_NETWORK_ERROR_CLIENT_START :{WHITE}接続できませんでした STR_NETWORK_ERROR_TIMEOUT :{WHITE}接続 {NUM} でタイムアウトエラーが発生しました STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}プロトコルエラーによって接続が切断されました +STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}あなたのプレイヤー名は設定されていません。名前はマルチプレイヤーウィンドウの上部から設定できます。 STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}クライアントバージョンがサーバーバージョンと一致していません STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}不正なパスワードです STR_NETWORK_ERROR_SERVER_FULL :{WHITE}サーバが満員です @@ -2150,6 +2228,7 @@ STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}サー STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}マップのダウンロード時間が規定を超過しました STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}タイムアウトによりサーバーへの接続を確立できません STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}プレイヤー名が無効です +STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}サーバーが現在使用中のクライアントに対して古すぎます ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :一般エラー @@ -2172,6 +2251,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :パスワード STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :一般的なタイムアウト STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :マップのダウンロード時間超過 STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :マップの処理時間超過 +STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :不正なクライアント名 ############ End of leave-in-this-order STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}接続切断の可能性 @@ -2201,6 +2281,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} が新会社 (#{2:NUM}) を設立しました STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} が退出しました({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} は名前を {STRING} に変更しました +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} が {1:STRING} に {2:CURRENCY_LONG} を送金してくれました STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}サーバがセッションを終了しました STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}このサーバーは再起動中です…{}しばらくお待ちください… STR_NETWORK_MESSAGE_KICKED :*** {STRING}がキックされました。理由: ({STRING}) @@ -2212,12 +2293,12 @@ STR_CONTENT_TYPE_CAPTION_TOOLTIP :{BLACK}コン STR_CONTENT_NAME_CAPTION :{BLACK}名前 STR_CONTENT_NAME_CAPTION_TOOLTIP :{BLACK}コンテンツ名 STR_CONTENT_MATRIX_TOOLTIP :{BLACK}クリックすると詳細を表示します。{}ダウンロードするにはチェックボックスをオンにします。 -STR_CONTENT_SELECT_ALL_CAPTION :{BLACK}全て選択 -STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP :{BLACK}全項目を選択します +STR_CONTENT_SELECT_ALL_CAPTION :{BLACK}すべて選択 +STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP :{BLACK}すべてのコンテンツをダウンロードする STR_CONTENT_SELECT_UPDATES_CAPTION :{BLACK}アップデートを選択 STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP :{BLACK}既にダウンロードしたコンテンツのアップデートをすべて選択します STR_CONTENT_UNSELECT_ALL_CAPTION :{BLACK}選択を解除 -STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP :{BLACK}全ての選択を解除します +STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP :{BLACK}すべてのコンテンツをダウンロードしない STR_CONTENT_SEARCH_EXTERNAL :{BLACK}外部サイトで検索 STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}OpenTTDコンテンツサービスに掲載されていないものを外部サイトを使用して検索できます。 STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}OpenTTDから離脱 @@ -2233,7 +2314,7 @@ STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED :{SILVER}ダウ STR_CONTENT_DETAIL_SUBTITLE_SELECTED :{SILVER}ダウンロード指定されています STR_CONTENT_DETAIL_SUBTITLE_AUTOSELECTED :{SILVER}他との依存関係によりダウンロード指定されています STR_CONTENT_DETAIL_SUBTITLE_ALREADY_HERE :{SILVER}既にダウンロード済です -STR_CONTENT_DETAIL_SUBTITLE_DOES_NOT_EXIST :{SILVER}ファイルが未知の形式のため、OpenTTDからはダウンロード出来ません +STR_CONTENT_DETAIL_SUBTITLE_DOES_NOT_EXIST :{SILVER}ファイルが未知の形式のため、OpenTTDからはダウンロードできません STR_CONTENT_DETAIL_UPDATE :{SILVER}このコンテンツは既にダウンロードされた{STRING}を置き換えます STR_CONTENT_DETAIL_NAME :{SILVER}コンテンツ名: {WHITE}{STRING} STR_CONTENT_DETAIL_VERSION :{SILVER}バージョン: {WHITE}{STRING} @@ -2245,7 +2326,7 @@ STR_CONTENT_DETAIL_SELECTED_BECAUSE_OF :{SILVER}以下 STR_CONTENT_DETAIL_DEPENDENCIES :{SILVER}依存する他コンテンツ: {WHITE}{STRING} STR_CONTENT_DETAIL_TAGS :{SILVER}タグ: {WHITE}{STRING} STR_CONTENT_NO_ZLIB :{WHITE}OpenTTDは"zlib"をサポートしていません -STR_CONTENT_NO_ZLIB_SUB :{WHITE}ダウンロードすることができません! +STR_CONTENT_NO_ZLIB_SUB :{WHITE}ダウンロードできません! # Order of these is important! STR_CONTENT_TYPE_BASE_GRAPHICS :基本グラフィック @@ -2267,11 +2348,11 @@ STR_CONTENT_DOWNLOAD_COMPLETE :{WHITE}ダウ STR_CONTENT_DOWNLOAD_PROGRESS_SIZE :{WHITE}{BYTES} / {BYTES} ダウンロード済 ({NUM} %) # Content downloading error messages -STR_CONTENT_ERROR_COULD_NOT_CONNECT :{WHITE}サーバーに接続することができませんでした... +STR_CONTENT_ERROR_COULD_NOT_CONNECT :{WHITE}サーバーに接続できませんでした STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD :{WHITE}ダウンロード失敗... STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_CONNECTION_LOST :{WHITE}接続が切断されました STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE :{WHITE}ダウンロード先への書込権限がありません -STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}ダウンロードしたファイルを開展することができませんでした +STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}ダウンロードしたファイルを展開できませんでした STR_MISSING_GRAPHICS_SET_CAPTION :{WHITE}基本グラフィック欠落 STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTDの動作に必要な基本グラフィックが見つかりません。ダウンロードしてインストールしますか? @@ -2297,7 +2378,7 @@ STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}透過 # Linkgraph legend window STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}貨物流通履歴 -STR_LINKGRAPH_LEGEND_ALL :{BLACK}全て +STR_LINKGRAPH_LEGEND_ALL :{BLACK}すべて STR_LINKGRAPH_LEGEND_NONE :{BLACK}なし STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}表示する会社を選択 STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} @@ -2324,28 +2405,29 @@ STR_JOIN_WAYPOINT_CAPTION :{WHITE}通過 STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT :{YELLOW}統合せずに建設 # Generic toolbar +STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE :{BLACK}現在このインフラで運用できる車両がないため無効化されています # Rail construction toolbar -STR_RAIL_TOOLBAR_RAILROAD_CONSTRUCTION_CAPTION :鉄道建設 -STR_RAIL_TOOLBAR_ELRAIL_CONSTRUCTION_CAPTION :電気鉄道建設 -STR_RAIL_TOOLBAR_MONORAIL_CONSTRUCTION_CAPTION :モノレール建設 -STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :マグレブ建設 +STR_RAIL_TOOLBAR_RAILROAD_CONSTRUCTION_CAPTION :鉄道敷設 +STR_RAIL_TOOLBAR_ELRAIL_CONSTRUCTION_CAPTION :電気鉄道の敷設 +STR_RAIL_TOOLBAR_MONORAIL_CONSTRUCTION_CAPTION :モノレール敷設 +STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :マグレブ敷設 -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}線路を建設します。Ctrlで建設/撤去の切り替えができます。Shiftを押しながら決定すると費用の見積が出ます -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}自動線路建設モードで線路を建設します。Ctrlで建設/撤去の切り替えができます。Shiftを押しながら決定すると費用の見積が出ます +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}線路を敷設します。Ctrlで敷設/撤去を切り替えられます。Shiftを押しながら決定すると費用を見積もれます +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}自動的に線路を敷設します。Ctrlで建設/撤去を切り替えられます。Shiftを押しながら決定すると費用を見積もれます STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}列車庫を建設します(列車の購入・整備施設になります)。Shiftを押しながら決定すると費用の見積が出ます STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}線路に通過点を設置します。Ctrlを押しながら決定すると通過点同士を結合できます。Shiftを押しながら決定すると費用の見積が出ます -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}駅を建設します。Ctrlを押しながら決定すると離れた駅等と結合可能です。Shiftを押しながら決定すると費用の見積が出ます +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}駅を建設します。Ctrlを押しながら決定すると離れた駅等と結合できます。Shiftを押しながら決定すると費用を見積もれます STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}鉄道信号を建設します。Ctrlで腕木式と色灯式を切り替えられます。{}ドラックして決定するとその区間に一定間隔で信号が配置されます。このときCtrlを押しておくと、その先分岐か信号に行き着くまで連続配置します。{}Ctrl+クリックで信号種類を選ぶウィンドウが出ます(「信号のGUIを使用」設定オフ時のみ)。Shiftを押しながら決定すると費用の見積が出ます STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}鉄道橋を建設します。Shiftを押しながら決定すると費用の見積が出ます STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}鉄道トンネルを建設します。Shiftを押しながら決定すると費用の見積が出ます STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}線路・信号・駅・中継駅の建設/撤去を切り替えます。{}Ctrlを押したままにすると駅・通過点の撤去時に線路ごと撤去されます -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}既設の線路をこのレール種に変更します。Shiftを押しながら決定すると費用の見積が出ます +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}既設の線路をこのレール種に変更します。Shiftを押しながら決定すると費用を見積もれます。 STR_RAIL_NAME_RAILROAD :鉄道 (非電化) -STR_RAIL_NAME_ELRAIL :鉄道 (電化) +STR_RAIL_NAME_ELRAIL :電気鉄道 STR_RAIL_NAME_MONORAIL :モノレール -STR_RAIL_NAME_MAGLEV :マグレブ +STR_RAIL_NAME_MAGLEV :リニア # Rail depot construction window STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION :{WHITE}列車庫建設 @@ -2378,13 +2460,13 @@ STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}閉塞 STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}入口信号 (腕木式){}この信号の先にある出口信号のうち最低でも1つが緑であれば緑になりますが、そうでなければ赤になります。場内信号に良く使われます STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}出口信号 (腕木式){}動作は普通の閉塞信号と同様ですが、入口/コンボ信号を使用する場合に必要になります。ホームの入り口に良く使われます STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}コンボ信号 (腕木式){}コンボ信号は入口信号と出口信号の機能を併せ持つ信号です。この信号を使うと多数の分岐のあるような場内信号網を作ることができます -STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}パス信号 (腕木式){}パス信号では、互いに衝突しない経路が確保できる場合には1つの閉塞内に複数の列車が入ることを許容します。汎用性は高いですが、一方向式しか使えず信号の背面から進行してくる列車を防護することができません。この信号で列車が停車中に正面から対向列車が来ると問答無用で衝突事故を起こします! +STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}パス信号 (腕木式){}パス信号では、互いに衝突しない経路が確保できる場合には1つの閉塞内に複数の列車が入ることを許容します。汎用性は高いですが、一方向式しか使えず信号の背面から進行してくる列車を防護できません。この信号で列車が停車中に正面から対向列車が来ると問答無用で衝突事故を起こします! STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}一方通行パス信号 (腕木式){}パス信号では、互いに衝突しない経路が確保できる場合には1つの閉塞内に複数の列車が入ることを許容します。このタイプのパス信号は信号の背面から通過することはできません STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}閉塞信号 (色灯式){}最も一般的な信号で、1つの閉塞内(信号同士の間の区間)には1編成のみが進入できます。配置した信号をクリックすると信号の向きを「一方向→一方向(逆)→二方向」の順で変えられます。一方向式の信号は背面から通過できません STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}入口信号 (色灯式){}この信号の先にある出口信号のうち最低でも1つが緑であれば緑になりますが、そうでなければ赤になります。場内信号に良く使われます STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}出口信号 (色灯式){}動作は普通の閉塞信号と同様ですが、入口/コンボ信号を使用する場合に必要になります。ホームの入り口に良く使われます STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}コンボ信号 (色灯式){}コンボ信号は入口信号と出口信号の機能を併せ持つ信号です。この信号を使うと多数の分岐のあるような場内信号網を作ることができます -STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}パス信号 (色灯式){}パス信号では、互いに衝突しない経路が確保できる場合には1つの閉塞内に複数の列車が入ることを許容します。汎用性は高いですが、一方向式しか使えず信号の背面から進行してくる列車を防護することができません。この信号で列車が停車中に正面から対向列車が来ると問答無用で衝突事故を起こします! +STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}パス信号 (色灯式){}パス信号では、互いに衝突しない経路が確保できる場合には1つの閉塞内に複数の列車が入ることを許容します。汎用性は高いですが、一方向式しか使えず信号の背面から進行してくる列車を防護できません。この信号で列車が停車中に正面から対向列車が来ると問答無用で衝突事故を起こします! STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}一方通行パス信号 (色灯式){}パス信号では、互いに衝突しない経路が確保できる場合には1つの閉塞内に複数の列車が入ることを許容します。このタイプのパス信号は信号の背面から通過することはできません STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}信号交換{}既存の信号を今選択している信号に交換します。Ctrl+クリックで種類は替えずに腕木/色灯の形式のみ切り替えます。Shift+クリックで費用を見積もります STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}ドラッグ時の信号設置間隔を指定します @@ -2408,12 +2490,12 @@ STR_BRIDGE_TUBULAR_SILICON :管状橋(シ # Road construction toolbar -STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}道路建設 -STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}軌道建設 -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}道路を建設します。Ctrlで建設/撤去の切り替えができます。Shiftを押しながら決定すると費用の見積が出ます -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}路面電車の軌道を建設します。Ctrlで建設/撤去の切り替えができます。Shiftを押しながら決定すると費用の見積が出ます -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}自動建設モードで道路を建設します。Ctrlで建設/撤去の切り替えができます。Shiftを押しながら決定すると費用の見積が出ます -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}自動建設モードで軌道を建設します。Ctrlで建設/撤去の切り替えができます。Shiftを押しながら決定すると費用の見積が出ます +STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}道路敷設 +STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}軌道敷設 +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}道路を建設します。Ctrlで建設/撤去を切り替えられます。Shiftを押しながら決定すると費用を見積もれます +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}路面電車の軌道を敷設します。Ctrlで敷設/撤去を切り替えられます。Shiftを押しながら決定すると費用を見積もれます +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}自動的に道路を敷設します。Ctrlで建設/撤去を切り替えられます。Shiftを押しながら決定すると費用を見積もれます +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}自動的に軌道を敷設します。Ctrlで建設/撤去を切り替えられます。Shiftを押しながら決定すると費用を見積もれます STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}車庫を建設します(バス・トラックの購入・整備施設になります)。Shift+クリックで費用の見積が出ます STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}路面電車庫を建設します(路面電車の購入・修理施設になります)。Shift+クリックで費用の見積が出ます STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}バス停を建設します。Ctrl+クリックで離れた停留施設と結合可能です。Shift+クリックで費用の見積が出ます @@ -2425,9 +2507,10 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}道路 STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}軌道用橋を建設します。Shiftを押しながら決定すると費用の見積が出ます STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}道路トンネルを建設します。Shiftを押しながら決定すると費用の見積が出ます STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}軌道用トンネルを建設します。Shiftを押しながら決定すると費用の見積が出ます -STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}道路の建設/撤去を切り替えます -STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}軌道の建設/撤去を切り替えます -STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}道路の種類を変更/アップグレードします.Shiftは、コスト見積もりの作成/表示を切り替えます +STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}道路の敷設/撤去を切り替えます +STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}軌道の敷設/撤去を切り替えます +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}道路の種類を変更/アップグレードします。Shift を押しながら決定するとコスト見積もりの作成/表示を切り替えられます +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}軌道の種類を変更・アップグレードします。Shift を押しながら決定するとコスト見積もりの作成/表示を切り替えられます STR_ROAD_NAME_ROAD :道路 STR_ROAD_NAME_TRAM :トラムウェイ @@ -2458,7 +2541,7 @@ STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}埠頭 STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}通過点として使えるブイを設置します。Shift+クリックで費用の見積が出ます STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}水路橋を建設します。Shiftを押しながら決定すると費用の見積が出ます STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}水域を作成します。{}通常操作では運河を建設しますが、海水位にある地域でCtrl+クリックするとその地域を水域にします -STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}川を造ります +STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}川を造成します。Ctrlで斜めに選択できます。 # Ship depot construction window STR_DEPOT_BUILD_SHIP_CAPTION :{WHITE}造船所建設 @@ -2496,9 +2579,9 @@ 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_LEVEL_LAND_TOOLTIP :{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}将来用に土地を購入します。Shiftを押しながら決定すると費用を見積もります # Object construction window @@ -2518,9 +2601,11 @@ STR_TREES_RANDOM_TYPE :{BLACK}ラン STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}ランダムな樹類で植林します。Shift+クリックで費用を見積もります STR_TREES_RANDOM_TREES_BUTTON :{BLACK}ランダムに広域植林 STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}地表全体にランダムに植林します +STR_TREES_MODE_NORMAL_BUTTON :{BLACK}普通 STR_TREES_MODE_NORMAL_TOOLTIP :{BLACK}風景の上をドラッグして、単一の木を植えます。 STR_TREES_MODE_FOREST_SM_BUTTON :{BLACK}グローブ STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}風景をドラッグして小さな森を植えます +STR_TREES_MODE_FOREST_LG_BUTTON :{BLACK}森林 STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}風景の上をドラッグして、大きな森を植えます。 # Land generation window (SE) @@ -2559,7 +2644,7 @@ STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON :{BLACK}大 STR_FOUND_TOWN_SIZE_RANDOM :{BLACK}ランダム STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}街のサイズを選択します STR_FOUND_TOWN_CITY :{BLACK}都市 -STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}都市は町と比べて、より早く拡大します。{}初期設定によりますが、設立の時点でも人口は町より多くなります +STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}都市は街に比べてより早く成長します。{}初期設定によりますが、人口は設立の時点で街よりも多くなります STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}街の道路配置 STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT :{BLACK}この街の道路配置(区画)を決定します @@ -2572,14 +2657,17 @@ STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM :{BLACK}ラン # Fund new industry window STR_FUND_INDUSTRY_CAPTION :{WHITE}新規産業の建設に出資 STR_FUND_INDUSTRY_SELECTION_TOOLTIP :{BLACK}建設したい産業をリストから選択します -STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES :多くのランダムな産業 -STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP :{BLACK}マップ全域にランダムに産業を建設します -STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION :{WHITE}ランダムな産業を作成する -STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_QUERY :{YELLOW}ランダムな産業をたくさん作りたいですか? +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES :{BLACK}ランダムな産業を生成する +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP :{BLACK}マップ全域にランダムに産業を生成します +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION :{WHITE}ランダムに産業を生成する +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_QUERY :{YELLOW}ランダムに多くの産業を生成してもよろしいですか? STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST :{BLACK}費用: {YELLOW}{CURRENCY_LONG} STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK}調査/探鉱 STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY :{BLACK}建設 STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY :{BLACK}出資 +STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES :{BLACK}すべての産業を削除する +STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_TOOLTIP :{BLACK}現在マップに存在するすべての産業を削除する +STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_CAPTION :{WHITE}すべての産業を削除する STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_QUERY :{YELLOW}すべての産業を削除してもよろしいですか? # Industry cargoes window @@ -2623,9 +2711,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}受入れ貨物: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE : {BLACK}線路の種類: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}道路の種類: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}路面軌道の種類: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}線路の制限速度: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}道路の最高速度: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}トラムの制限速度:{LTBLUE} {VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :岩石 @@ -2726,39 +2816,60 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD # Framerate display window STR_FRAMERATE_CAPTION :{WHITE}フレームレート +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}シミュレーションレート: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}一秒あたりに計算されるゲームのティック数。 STR_FRAMERATE_RATE_BLITTER :{BLACK}グラフィックフレームレート:{STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}一秒あたりに描写されるフレームの数。 STR_FRAMERATE_SPEED_FACTOR :{BLACK}現在のゲーム速度:{DECIMAL} x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}通常の速度に比べたゲーム進行速度の加速率 STR_FRAMERATE_CURRENT :{WHITE}現在 STR_FRAMERATE_AVERAGE :{WHITE}平均 STR_FRAMERATE_MEMORYUSE :{WHITE}メモリ +STR_FRAMERATE_DATA_POINTS :{BLACK} {COMMA}測定に基づくデータ STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW} {DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} フレーム/秒 STR_FRAMERATE_FPS_WARN :{YELLOW} {DECIMAL}フレーム/秒 STR_FRAMERATE_FPS_BAD :{RED} {DECIMAL}FPS STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} STR_FRAMERATE_BYTES_WARN :{YELLOW} {BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! STR_FRAMERATE_GAMELOOP :{BLACK}ゲームループの合計: STR_FRAMERATE_GL_ECONOMY :{BLACK}貨物の取り扱い: STR_FRAMERATE_GL_TRAINS :{BLACK} 鉄道車両のティック: STR_FRAMERATE_GL_ROADVEHS :{BLACK} 自動車ティック: +STR_FRAMERATE_GL_SHIPS :{BLACK}船舶のティック数: STR_FRAMERATE_GL_AIRCRAFT :{BLACK}航空機ティック: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK}世界のティック: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} リンクグラフの遅延: STR_FRAMERATE_DRAWING :{BLACK}グラフィックレンダリング: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK}世界のビューポート: STR_FRAMERATE_VIDEO :{BLACK}ビデオ出力: STR_FRAMERATE_SOUND :{BLACK}サウンドミキサー: +STR_FRAMERATE_ALLSCRIPTS :{BLACK} ゲームスクリプト・AIの合計: +STR_FRAMERATE_GAMESCRIPT :{BLACK} ゲームスクリプト: +STR_FRAMERATE_AI :{BLACK} AI {NUM} {STRING} ############ End of leave-in-this-order ############ Leave those lines in this order!! STR_FRAMETIME_CAPTION_GAMELOOP :ゲームループ STR_FRAMETIME_CAPTION_GL_ECONOMY :貨物の取り扱い STR_FRAMETIME_CAPTION_GL_TRAINS :切符 -STR_FRAMETIME_CAPTION_GL_SHIPS :船のティック +STR_FRAMETIME_CAPTION_GL_ROADVEHS :車両のティック数 +STR_FRAMETIME_CAPTION_GL_SHIPS :船舶のティック数 STR_FRAMETIME_CAPTION_GL_AIRCRAFT :航空機ティック STR_FRAMETIME_CAPTION_GL_LANDSCAPE :ワールドティック STR_FRAMETIME_CAPTION_GL_LINKGRAPH :リンクグラフの遅延 STR_FRAMETIME_CAPTION_DRAWING :グラフィックレンダリング STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :ワールドビューポートレンダリング STR_FRAMETIME_CAPTION_VIDEO :ビデオ出力 +STR_FRAMETIME_CAPTION_SOUND :サウンドミキシング +STR_FRAMETIME_CAPTION_ALLSCRIPTS :ゲームスクリプト・AIの合計 +STR_FRAMETIME_CAPTION_GAMESCRIPT :ゲームスクリプト STR_FRAMETIME_CAPTION_AI :AI {NUM} {STRING} ############ End of leave-in-this-order @@ -2788,7 +2899,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: STR_SAVELOAD_FILTER_TITLE :{BLACK}フィルター: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}ファイルを上書きする STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}既存のファイルを上書きしてもよろしいですか? -STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (Parent directory) +STR_SAVELOAD_DIRECTORY :{STRING} (ディレクトリ) +STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (親ディレクトリ) STR_SAVELOAD_OSKTITLE :{BLACK}保存名を入力 @@ -2801,12 +2913,14 @@ STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}街数: STR_MAPGEN_DATE :{BLACK}日付: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}産業数: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}最高峰: -STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN :{BLACK}マップの最高峰の最大の高さを1減らします。 +STR_MAPGEN_HEIGHTMAP_HEIGHT_UP :{BLACK}マップの最高峰の値を1増やします +STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN :{BLACK}マップの最高峰の値を1減らします STR_MAPGEN_SNOW_COVERAGE :{BLACK}降雪量: +STR_MAPGEN_SNOW_COVERAGE_UP :{BLACK}積雪量を10%増やします STR_MAPGEN_SNOW_COVERAGE_DOWN :{BLACK}積雪量を10%減らします STR_MAPGEN_SNOW_COVERAGE_TEXT :{BLACK} {NUM}% STR_MAPGEN_DESERT_COVERAGE :{BLACK}砂漠の範囲: -STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}砂漠の割合を10%増やします +STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}砂漠の範囲を10%増やします STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}砂漠の範囲を10%減らします STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% STR_MAPGEN_SNOW_LINE_HEIGHT :{BLACK}雪線の位置: @@ -2838,8 +2952,9 @@ STR_MAPGEN_HEIGHTMAP_SIZE_LABEL :{BLACK}サイ STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM} × {NUM} STR_MAPGEN_TERRAIN_TYPE_QUERY_CAPT :{WHITE}ターゲットの最高の高さ +STR_MAPGEN_HEIGHTMAP_HEIGHT_QUERY_CAPT :{WHITE}最高峰 STR_MAPGEN_SNOW_COVERAGE_QUERY_CAPT :{WHITE}積雪量(%) -STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT :{WHITE}砂漠領域(%) +STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT :{WHITE}砂漠の範囲(%) STR_MAPGEN_SNOW_LINE_QUERY_CAPT :{WHITE}雪線の位置を変更 STR_MAPGEN_START_DATE_QUERY_CAPT :{WHITE}開始年の変更 @@ -2980,6 +3095,7 @@ STR_NEWGRF_ERROR_MSG_WARNING :{RED}警告: {S STR_NEWGRF_ERROR_MSG_ERROR :{RED}エラー: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}致命的エラー: {SILVER}{STRING} STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRFに致命的なエラーが発生しました:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRFにエラーが発生しました:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING}はOpenTTDのTTDPatchバージョンには対応していません STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING}はTTDのバージョン{STRING}にのみ対応しています STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING}を使用時には{STRING}を有効にしなければなりません @@ -2999,6 +3115,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :疑似スプラ STR_NEWGRF_ERROR_GRM_FAILED :要求されたGRFのリソースは使用できません (スプライト {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING}は{STRING}により無効にされました STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :不正なレイアウト書式です (スプライト {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :プロパティ値リストの要素が多すぎます(スプライト {3:NUM}、プロパティ {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :不正な産業生産コールバック(スプライト {3:NUM}, "{2:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}注意! @@ -3030,6 +3148,7 @@ STR_NEWGRF_BUGGY :{WHITE}NewGRF{0 STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}{1:ENGINE}の貨物/改造情報が購入時とは異なります。自動更新/置換時に改造に失敗する恐れがあります STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}{1:STRING}が生産コールバック内で無限ループを起こしました STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}戻り値{1:HEX}が不明/不正の値{2:HEX}を返しました +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' は {2:HEX} において生産コールバックで不正な貨物タイプを返しました。 # 'User removed essential NewGRFs'-placeholders for stuff without specs STR_NEWGRF_INVALID_CARGO :<無効な貨物> @@ -3054,6 +3173,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_NEXT_SIGN_TOOLTIP :{BLACK}次の標識へ移動 STR_EDIT_SIGN_PREVIOUS_SIGN_TOOLTIP :{BLACK}前の標識へ移動 @@ -3063,12 +3183,13 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}標識 STR_TOWN_DIRECTORY_CAPTION :{WHITE}街一覧 STR_TOWN_DIRECTORY_NONE :{ORANGE}- なし- STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}町名 - メイン画面を町の場所に移動するには町名をクリックします。Ctrl+クリックで新しいビューポートに表示します +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (都市){BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}街の名前 - メイン画面を街の場所に移動するには名前をクリックします。Ctrl+クリックで新しいビューポートに表示します STR_TOWN_POPULATION :{BLACK}地域人口: {COMMA}人 # Town view window STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} -STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN}(市) +STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (都市) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}人口: {ORANGE}{COMMA}人{BLACK} 建物: {ORANGE}{COMMA}戸 STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK} {CARGO_LIST}先月:{ORANGE} {COMMA} {BLACK}最大:{ORANGE} {COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}街の成長に必要な物資: @@ -3113,18 +3234,20 @@ STR_LOCAL_AUTHORITY_ACTION_NEW_BUILDINGS :市街地開発 STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :独占運送契約を締結 STR_LOCAL_AUTHORITY_ACTION_BRIBE :議会を買収 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}旅客と貨物を確保する為に、街で新聞広告を実施します。{} 費用: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}旅客と貨物を確保する為に、街でラジオCMを実施します{} 費用: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}旅客と貨物を確保する為に、街でTV-CMを開始します{} 費用: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}街内の道路補修工事に出資します。{}最高6ヶ月間街中の道路交通が途絶します。{} 費用: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}社を称える彫像を建設します{} 費用: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}市街地の開発に出資します{} 費用: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}旅客と貨物を確保する為に、街で新聞広告を実施します。{}より多くの旅客と貨物が自社の交通網を利用するようになります。{}費用: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}旅客と貨物を確保する為に、街でラジオCMを実施します{}街の中心部から中範囲にある駅の評価が一時的に高まります。{}費用: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}旅客と貨物を確保する為に、街でTV-CMを開始します{}街の中心部の大範囲にある駅の評価が一時的に高まります。{}費用: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}街内の道路補修工事に出資します。最高6ヶ月間街中の道路交通が途絶します。{}費用: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}社を称える彫像を建設します{}この街の駅の評価を恒久的に高めます。{}費用: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}市街地の開発に出資します{}街の成長速度が一時的に早まります。{}費用: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}街と一年間の独占運送契約を締結します。{}乗客や貨物はあなたの会社の運送経路のみを使用するようになります。{} 費用: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}買収を行い、議会内の評判を高めます。注意: 露見した場合は処罰されます{} 費用: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} 目標 STR_GOALS_SPECTATOR_CAPTION :{WHITE}大目標 +STR_GOALS_SPECTATOR :グローバルな目標 +STR_GOALS_GLOBAL_BUTTON :{BLACK}グローバル STR_GOALS_GLOBAL_BUTTON_HELPTEXT :{BLACK}グローバルな目標を表示する STR_GOALS_COMPANY_BUTTON :{BLACK}会社 STR_GOALS_COMPANY_BUTTON_HELPTEXT :{BLACK}会社の目標を見る @@ -3135,10 +3258,10 @@ STR_GOALS_PROGRESS_COMPLETE :{GREEN}{STRING} STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}クリックするとメイン画面を対象となる産業・街・タイルに移動します。Ctrl+クリックで新たなビューポートを開いて対象を表示します # Goal question window -STR_GOAL_QUESTION_CAPTION_QUESTION :質問 -STR_GOAL_QUESTION_CAPTION_INFORMATION :情報 -STR_GOAL_QUESTION_CAPTION_WARNING :警告 -STR_GOAL_QUESTION_CAPTION_ERROR :エラー +STR_GOAL_QUESTION_CAPTION_QUESTION :{BLACK}質問 +STR_GOAL_QUESTION_CAPTION_INFORMATION :{BLACK}情報 +STR_GOAL_QUESTION_CAPTION_WARNING :{BLACK}警告 +STR_GOAL_QUESTION_CAPTION_ERROR :{YELLOW}エラー ############ Start of Goal Question button list STR_GOAL_QUESTION_BUTTON_CANCEL :キャンセル @@ -3406,7 +3529,7 @@ STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}本社 STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}本社ビルを移転します(費用は社の総資産の1%になります)。Shift+クリックで費用を見積もります STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}詳細 STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}インフラ設備の詳細な個数・タイル数を表示します -STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}送金 +STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}お金を渡す STR_COMPANY_VIEW_GIVE_MONEY_TOOLTIP :{BLACK}この会社にお金を渡す STR_COMPANY_VIEW_NEW_FACE_BUTTON :{BLACK}顔の変更 @@ -3447,6 +3570,10 @@ STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}産業 STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- なし - STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% 輸送済み){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +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_ACCEPTED_CARGO_FILTER :{BLACK}受け取った貨物: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}生産された貨物:{SILVER} {STRING} @@ -3462,9 +3589,11 @@ STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}生産 STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}この産業拠点は間もなく閉鎖されます! STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}必要条件:{YELLOW} {STRING} {STRING} +STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}生産: {YELLOW}{STRING}{STRING} STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :、{STRING} {STRING} STR_INDUSTRY_VIEW_REQUIRES : {BLACK}必要物資: +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW} {STRING} {BLACK}:{CARGO_SHORT}待機中{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}生産量を変更 (8の倍数、最大2040) @@ -3490,7 +3619,7 @@ STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT :購入可能な STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP :{BLACK}この輸送機関で利用可能な輸送機器の一覧を表示します STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}リストを管理 -STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}このリスト内のすべての車両にこの指令を送信 +STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}このリスト内のすべての車両に指令を送信する STR_VEHICLE_LIST_REPLACE_VEHICLES :輸送機器更新 STR_VEHICLE_LIST_SEND_FOR_SERVICING :回送して点検 @@ -3515,6 +3644,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :グループ化 STR_GROUP_DEFAULT_SHIPS :グループ化されていない船舶 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}新規のグループを作成します @@ -3524,20 +3654,21 @@ STR_GROUP_LIVERY_TOOLTIP :{BLACK}選択 STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}このグループ内の輸送機器を全体を対象とする自動交換の際も交換されないようにします STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}グループを削除 -STR_GROUP_DELETE_QUERY_TEXT :{WHITE}このグループとそれに所属する全てを削除してもよろしいですか? +STR_GROUP_DELETE_QUERY_TEXT :{WHITE}このグループとそれに属するすべてを削除してもよろしいですか? STR_GROUP_ADD_SHARED_VEHICLE :共有輸送機器を追加 STR_GROUP_REMOVE_ALL_VEHICLES :全輸送機器を削除 STR_GROUP_RENAME_CAPTION :{BLACK}グループ名を変更 -STR_GROUP_PROFIT_THIS_YEAR :今年の利益: +STR_GROUP_PROFIT_THIS_YEAR :今年の利益: STR_GROUP_PROFIT_LAST_YEAR :昨年の利益: STR_GROUP_OCCUPANCY :選択中: +STR_GROUP_OCCUPANCY_VALUE :{NUM}% # Build vehicle window STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :新規機関車(非電化) -STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :新規機関車(電化)/電車 +STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :新規電気機関車・電車 STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :新規モノレール車両 STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :新規リニア車両 @@ -3546,6 +3677,7 @@ STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :新しい路面 ############ range for vehicle availability starts STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :新規列車 +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :新しい車両 STR_BUY_VEHICLE_SHIP_CAPTION :新規船舶 STR_BUY_VEHICLE_AIRCRAFT_CAPTION :新規航空機 ############ range for vehicle availability ends @@ -3588,14 +3720,19 @@ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}船舶 STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}航空機を購入 STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}購入し改造する +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}購入し改造する STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}船の購入と修理 +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}航空機の購入と修理 STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}選択した列車を購入します。Shift+クリックで購入費を見積もります STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}選択した車両を購入します。Shift+クリックで購入費を見積もります STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}選択した船舶を購入します。Shift+クリックで購入費を見積もります STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}選択した航空機を購入します。Shift+クリックで購入費を見積もります +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 +クリックすると、購入なしの推定コストが表示されます STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}名称を変更 STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}名称を変更 @@ -3638,7 +3775,7 @@ STR_DEPOT_VEHICLE_TOOLTIP :{BLACK}{ENGINE} STR_DEPOT_VEHICLE_TOOLTIP_CHAIN :{BLACK}{NUM}台{STRING} STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ({CARGO_SHORT}) -STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}列車 - 情報を見るには列車を右クリックします。編成を変更するには各車両をドラッグします。Ctrlを押したままドラッグするとその車両から後続する全ての車両を一度に移動できます +STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}列車 - 情報を見るには列車を右クリックします。編成を変更するには各車両をドラッグします。Ctrlを押したままドラッグするとその車両に続くすべての車両を一度に移動できます。 STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}車両 - 情報を見るには車両を右クリックします STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}船舶 - 情報を見るには船舶を右クリックします STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}航空機 - 情報を見るには航空機を右クリックします @@ -3671,7 +3808,7 @@ STR_DEPOT_SHIP_NEW_VEHICLES_TOOLTIP :{BLACK}新規 STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}新規航空機を購入します STR_DEPOT_CLONE_TRAIN :{BLACK}列車を複製 -STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}道路車両を複製 +STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}車両を複製 STR_DEPOT_CLONE_SHIP :{BLACK}船舶を複製 STR_DEPOT_CLONE_AIRCRAFT :{BLACK}航空機を複製 @@ -3682,7 +3819,7 @@ STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}航空 STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}メイン画面を列車庫の場所に移動します。Ctrl+クリックで新規のビューポートに表示します STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}メイン画面を車庫の場所に移動します。Ctrl+クリックで新規のビューポートに表示します -STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}メイン画面を造船所の場所に移動します。Ctrl+クリックで新規のビューポートに表示します +STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}メイン画面を造船所の場所に移動します。Ctrl+クリックで造船所の場所に新しくビューポートを開きます STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}メイン画面を格納庫の場所に移動します。Ctrl+クリックで新規のビューポートに表示します STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}選択中の列車庫が指令リストに入っている全列車のリストを表示します @@ -3704,9 +3841,10 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}庫内 # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}製造会社からのメッセージ -STR_ENGINE_PREVIEW_MESSAGE :{GOLD}弊社は新たに{STRING}を設計致しました。{}実地でのパフォーマンスなどを検討する為、貴社に独占モニター権を提供したいと考えておりますがいかがでしょうか? +STR_ENGINE_PREVIEW_MESSAGE :{GOLD}弊社は新たに{STRING}を設計いたしました。{}実地試験を行うにあたって貴社にご協力いただきたく、一年間の独占的使用権を提供したいと考えておりますがいかがでしょうか? STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :列車 +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :電気機関車 STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :モノレール列車 STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :リニア列車 @@ -3716,11 +3854,13 @@ STR_ENGINE_PREVIEW_TRAM_VEHICLE :路面電車車 STR_ENGINE_PREVIEW_AIRCRAFT :航空機 STR_ENGINE_PREVIEW_SHIP :船舶 -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}価格: {CURRENCY_LONG} 重量: {WEIGHT_SHORT}{}最高速度: {VELOCITY}{}出力: {POWER}{}運用費: {CURRENCY_LONG}/年{}収容量: {CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}費用: {CURRENCY_LONG} 重量: {WEIGHT_SHORT}{} 最高速度: {VELOCITY} 出力: {POWER}{} 維持費: {CURRENCY_LONG} /年{} 容量: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}価格: {CURRENCY_LONG} 重量: {WEIGHT_SHORT}{}最高速度: {VELOCITY} 出力: {POWER} 最大牽引力: {6:FORCE}{}運用費: {4:CURRENCY_LONG}/年{}収容量 {5:CARGO_LONG} -STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}価格: {CURRENCY_LONG} 最高速度: {VELOCITY}{}収容量: {CARGO_LONG}{}運用費: {CURRENCY_LONG}/年 -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}コスト:{CURRENCY_LONG}最大。 速度:{VELOCITY}{}航空機の種類:{STRING}範囲:{COMMA}タイル{}容量:{CARGO_LONG}、{CARGO_LONG}{}ランニングコスト:{CURRENCY_LONG} /年 -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}コスト:{CURRENCY_LONG}最大。 速度:{VELOCITY}{}航空機の種類:{STRING}範囲:{COMMA}タイル{}容量:{CARGO_LONG}{}ランニングコスト:{CURRENCY_LONG} /年 +STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}費用: {CURRENCY_LONG} 最高速度: {VELOCITY}{} 容量: {CARGO_LONG}{} 維持費: {CURRENCY_LONG} /年 +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}費用: {CURRENCY_LONG} 最高速度: {VELOCITY}{} 航空機の種類: {STRING}{} 容量: {CARGO_LONG}, {CARGO_LONG}{} 維持費: {CURRENCY_LONG}/yr +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}費用: {CURRENCY_LONG} 最高速度: {VELOCITY}{} 航空機の種類: {STRING}{} 容量: {CARGO_LONG}{} 維持費: {CURRENCY_LONG} /年 +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}費用: {CURRENCY_LONG} 最高速度: {VELOCITY}{} 航空機の種類: {STRING} 範囲: {COMMA}タイル{} 容量: {CARGO_LONG}、{CARGO_LONG}{} 維持費: {CURRENCY_LONG} /年 +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}費用: {CURRENCY_LONG} 最高速度: {VELOCITY}{} 航空機の種類: {STRING} 範囲:{COMMA}タイル{} 容量: {CARGO_LONG}{} 維持費: {CURRENCY_LONG} /年 # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}{STRING}の自動置換 - {STRING} @@ -3750,25 +3890,28 @@ STR_REPLACE_HELP_STOP_BUTTON :{BLACK}クリ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}置換対象を機関車/貨車に切り替えます STR_REPLACE_ENGINES :機関車 STR_REPLACE_WAGONS :貨車 -STR_REPLACE_ALL_RAILTYPE :全ての鉄道車両 +STR_REPLACE_ALL_RAILTYPE :すべての鉄道車両 +STR_REPLACE_ALL_ROADTYPE :すべての車両 STR_REPLACE_HELP_RAILTYPE :{BLACK}置換対象となる線路種類を切り替えます +STR_REPLACE_HELP_ROADTYPE :{BLACK}置換対象となる道路種類を切り替えます STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}左で選択された機関車の置換対象を(あれば)表示します STR_REPLACE_RAIL_VEHICLES :機関車(非電化) -STR_REPLACE_ELRAIL_VEHICLES :機関車(電化)/電車 +STR_REPLACE_ELRAIL_VEHICLES :電気機関車・電車 STR_REPLACE_MONORAIL_VEHICLES :モノレール車両 STR_REPLACE_MAGLEV_VEHICLES :リニア車両 -STR_REPLACE_ROAD_VEHICLES :道路車両 +STR_REPLACE_ROAD_VEHICLES :車両 STR_REPLACE_TRAM_VEHICLES :路面電車の車両 -STR_REPLACE_REMOVE_WAGON :{BLACK}列車の短縮: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}機関車の交換で列車長が長くなる場合、列車長を維持する為に客車/貨車を減らすことができます。外されるのは従属部分の先頭からになります # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} 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 +クリックすると、航空機の位置に新しいビューポートが開きます STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}列車を列車庫へ回送します。Ctrl+クリックすると点検後、再出庫します @@ -3783,10 +3926,10 @@ STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}航空 STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}赤信号を無視して進行させます -STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}現在とは異なる種類の貨物を運送出来るよう列車を改造します -STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}現在とは異なる種類の貨物を運送出来るよう車両を改造します -STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}現在とは異なる種類の貨物を運送出来るよう船舶を改造します -STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}現在とは異なる種類の貨物を運送出来るよう航空機を改造します +STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}現在とは異なる種類の貨物を運送するように列車を改造します +STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}現在とは異なる種類の貨物を運送するように車両を改造します +STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}現在とは異なる種類の貨物を運送するように船舶を改造します +STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}現在とは異なる種類の貨物を運送するように航空機を改造します STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}運転方向を反転させます STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}車両を反転します @@ -3806,6 +3949,7 @@ STR_VEHICLE_VIEW_ROAD_VEHICLE_STATUS_START_STOP_TOOLTIP :{BLACK}現在 STR_VEHICLE_VIEW_SHIP_STATE_STATUS_STOP_TOOLTIP :{BLACK}現在の船のアクション-クリックして船を停止/開始します STR_VEHICLE_VIEW_AIRCRAFT_STATUS_START_STOP_TOOLTIP :{BLACK}現在の航空機のアクション-クリックして航空機を停止/開始します +STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}注文先の中央のメインビュー。Ctrlキーを押しながらクリックすると、注文先の場所に新しいビューポートが開きます # Messages in the start stop button in the vehicle view STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}積み降ろし中 @@ -3906,7 +4050,7 @@ STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}改造 STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}改造後の積載量: {GOLD}{CARGO_LONG}{}{BLACK}改造収益: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}改造後の積載量: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}改造費用: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}改造後の積載量: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}改造収益: {GREEN}{CURRENCY_LONG} -STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}改造を行う貨車(客車)を選択します。ドラッグで複数の貨車を選択できます。空きスペースをクリックすると全貨車が選択されます。Ctrl+クリックでその貨車から後続する貨車を全て選択します +STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}改造を行う貨車(客車)を選択します。ドラッグで複数の貨車を選択できます。空きスペースをクリックすると全貨車が選択されます。Ctrl+クリックでその貨車に続く貨車をすべて選択します STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}この列車が新たに輸送する貨物種類を選択します STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}この車両が新たに輸送する貨物種類を選択します @@ -3918,10 +4062,10 @@ STR_REFIT_ROAD_VEHICLE_REFIT_BUTTON :{BLACK}車両 STR_REFIT_SHIP_REFIT_BUTTON :{BLACK}船舶を改造 STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}航空機を改造 -STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}選択した種類の貨物を運送するために列車を改造します -STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}選択した種類の貨物を運送するために車両を改造します -STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}選択した種類の貨物を運送するために船舶を改造します -STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}選択した種類の貨物を運送するために航空機を改造します +STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}選択した種類の貨物を運送するように列車を改造します +STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}選択した種類の貨物を運送するように車両を改造します +STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}選択した種類の貨物を運送するように船舶を改造します +STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}選択した種類の貨物を運送するように航空機を改造します # Order view STR_ORDERS_CAPTION :{WHITE}{VEHICLE} (指令) @@ -3950,9 +4094,9 @@ STR_ORDER_DROP_FULL_LOAD_ANY :いずれかを STR_ORDER_DROP_NO_LOADING :荷積み無し STR_ORDER_TOOLTIP_FULL_LOAD :{BLACK}選択した指令先での荷積み方式を変更します -STR_ORDER_TOGGLE_UNLOAD :{BLACK}全て降ろす -STR_ORDER_DROP_UNLOAD_IF_ACCEPTED :受入有なら降ろす -STR_ORDER_DROP_UNLOAD :全て降ろす +STR_ORDER_TOGGLE_UNLOAD :{BLACK}すべて荷降ろしする +STR_ORDER_DROP_UNLOAD_IF_ACCEPTED :貨物を納入できるなら荷降ろしする +STR_ORDER_DROP_UNLOAD :すべて荷降ろしする STR_ORDER_DROP_TRANSFER :転送 STR_ORDER_DROP_NO_UNLOADING :荷下ろし無し STR_ORDER_TOOLTIP_UNLOAD :{BLACK}選択した指令先での荷下ろし方式を変更します @@ -3980,6 +4124,7 @@ STR_ORDER_CONDITIONAL_AGE :使用年数( STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :点検要求 STR_ORDER_CONDITIONAL_UNCONDITIONALLY :常に STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :耐用年数までの残期間(年) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :最大信頼度 STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}輸送機器のデータと指定の数値でどのような条件式を組むかを決定します STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :に等しい @@ -3999,7 +4144,7 @@ STR_ORDERS_SKIP_TOOLTIP :{BLACK}現在 STR_ORDERS_DELETE_BUTTON :{BLACK}削除 STR_ORDERS_DELETE_TOOLTIP :{BLACK}選択した指令を削除します -STR_ORDERS_DELETE_ALL_TOOLTIP :{BLACK}指令を全て消去 +STR_ORDERS_DELETE_ALL_TOOLTIP :{BLACK}指令をすべて除去 STR_ORDERS_STOP_SHARING_BUTTON :{BLACK}共有を解除 STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}指令の共有を解除します。Ctrl+クリックで全司令を消去します @@ -4170,7 +4315,7 @@ STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}ゲー STR_ERROR_AI_NO_AI_FOUND :適切なAIが見つかりません。{}このAIはダミーAIで何も行いません。{}AIは「オンラインコンテンツの確認」経由でダウンロード可能です STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}実行中のAIの一つがクラッシュしました。AIの作者にデバッグウインドウのスクリーンショットを付け、ご報告ください -STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/ゲームスクリプトのデバッグウインドウはサーバーでのみ使用することができます +STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/ゲームスクリプトのデバッグウインドウはサーバーでのみ使用できます # AI configuration window STR_AI_CONFIG_CAPTION :{WHITE}AIの設定 @@ -4212,7 +4357,9 @@ STR_AI_LIST_CANCEL :{BLACK}キャ STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}スクリプトを変更しません STR_SCREENSHOT_CAPTION :{WHITE}スクリーンショットを撮る +STR_SCREENSHOT_SCREENSHOT :{BLACK}通常のスクリーンショット STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}スクリーンショットを完全に拡大 +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}デフォルトの拡大率のスクリーンショット STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}地図全体のスクリーンショット STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}ハイトマップスクリーンショット STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}ミニマップのスクリーンショット @@ -4324,6 +4471,7 @@ STR_WARNING_FALLBACK_SOUNDSET :{WHITE}フェ STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}巨大なスクリーンショット STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}このスクリーンショットのサイズは {COMMA}×{COMMA} ピクセルになります。このまま続行してもよろしいですか? +STR_MESSAGE_HEIGHTMAP_SUCCESSFULLY :{WHITE}ハイトマップは正常に '{STRING}' として保存されました。最高峰は {NUM} です。 STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}スクリーンショットを'{STRING}'に正常に保存しました STR_ERROR_SCREENSHOT_FAILED :{WHITE}スクリーンショットの保存に失敗しました! @@ -4339,13 +4487,13 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}平地 STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}土地の傾きが違います STR_ERROR_CAN_T_DO_THIS :{WHITE}それをすることはできません STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}先に建物を撤去しなければなりません -STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}この範囲を撤去することは出来ません +STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}この範囲を撤去することはできません STR_ERROR_SITE_UNSUITABLE :{WHITE}地形が不適当です STR_ERROR_ALREADY_BUILT :{WHITE}既に設置されています STR_ERROR_OWNED_BY :{WHITE}{STRING}の所有設備です STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}この土地は他の会社に所有されています -STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}一度に出来る整地量を越えています -STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}一度に出来る撤去量を越えています +STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}一度にできる整地量を越えています +STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}一度にできる撤去量を越えています STR_ERROR_TREE_PLANT_LIMIT_REACHED :{WHITE}木の本数が多すぎます STR_ERROR_NAME_MUST_BE_UNIQUE :{WHITE}名前は重複してはいけません STR_ERROR_GENERIC_OBJECT_IN_THE_WAY :{WHITE}{1:STRING}があります @@ -4393,7 +4541,7 @@ 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_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}街の中心部に像を建てるのに適した場所がありません @@ -4516,7 +4664,7 @@ STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}道路 STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}このレール種別との平面交差はできません STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}この道路では踏切は作れません STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}ここには信号を設置できません -STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}ここには線路を建設できません +STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}ここには線路を敷設できません STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}ここから線路を撤去できません STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}ここから信号を撤去できません STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE :{WHITE}この信号を交換できません @@ -4528,14 +4676,15 @@ STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}この # Road construction errors STR_ERROR_MUST_REMOVE_ROAD_FIRST :{WHITE}先に道路を撤去しなければなりません STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION :{WHITE}一方通行路は交差できません -STR_ERROR_CAN_T_BUILD_ROAD_HERE :{WHITE}ここには道路を建設できません -STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE :{WHITE}ここには軌道を建設できません +STR_ERROR_CAN_T_BUILD_ROAD_HERE :{WHITE}ここには道路を敷設できません +STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE :{WHITE}ここには軌道を敷設できません STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}ここから道路を撤去できません STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}ここから軌道を撤去できません STR_ERROR_THERE_IS_NO_ROAD :{WHITE}道路がありません STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}軌道がありません -STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}この道路のタイプは変更できません +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}この道路の種類は変更できません STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}ここで路面電車の種類を変更できません... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}適当な道路がありません STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}有効な路面電車がありません STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}軌道に互換性がありません @@ -4590,13 +4739,14 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}グル STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}グループを削除できません STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}グループ名を変更できません STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}親グループを設定できません +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}グループ階層のループは許可されていません STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}グループ内の全車両を移動できません STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}この車両をこのグループに追加できません STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}グループに共有車両を追加できません # Generic vehicle errors STR_ERROR_TRAIN_IN_THE_WAY :{WHITE}列車があります -STR_ERROR_ROAD_VEHICLE_IN_THE_WAY :{WHITE}道路車両があります +STR_ERROR_ROAD_VEHICLE_IN_THE_WAY :{WHITE}経路上に車両があります STR_ERROR_SHIP_IN_THE_WAY :{WHITE}船舶があります STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}航空機があります @@ -4663,7 +4813,7 @@ STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}飛行 STR_ERROR_NO_MORE_SPACE_FOR_ORDERS :{WHITE}これ以上の指令を追加できません STR_ERROR_TOO_MANY_ORDERS :{WHITE}指令が多すぎます STR_ERROR_CAN_T_INSERT_NEW_ORDER :{WHITE}新規指令を挿入できません -STR_ERROR_CAN_T_DELETE_THIS_ORDER :{WHITE}この指令を削除できません +STR_ERROR_CAN_T_DELETE_THIS_ORDER :{WHITE}この指令を除去できません STR_ERROR_CAN_T_MODIFY_THIS_ORDER :{WHITE}この指令を変更できません STR_ERROR_CAN_T_MOVE_THIS_ORDER :{WHITE}この指令を移動できません STR_ERROR_CAN_T_SKIP_ORDER :{WHITE}実行中の指令はスキップできません @@ -4698,10 +4848,11 @@ STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :Transport Tycoo STR_BASEGRAPHICS_WIN_DESCRIPTION :Transport Tycoon Deluxe オリジナル版 グラフィック (Windows) STR_BASESOUNDS_DOS_DESCRIPTION :Transport Tycoon Deluxe オリジナル版 効果音 (DOS) STR_BASESOUNDS_WIN_DESCRIPTION :Transport Tycoon Deluxe オリジナル版 効果音 (Windows) -STR_BASESOUNDS_NONE_DESCRIPTION :空の効果音パック +STR_BASESOUNDS_NONE_DESCRIPTION :音源の含まれない効果音セット STR_BASEMUSIC_WIN_DESCRIPTION :Transport Tycoon Deluxe オリジナル版 音楽 (Windows) +STR_BASEMUSIC_DOS_DESCRIPTION :Transport Tycoon Deluxe オリジナル版 音楽 (DOS) STR_BASEMUSIC_TTO_DESCRIPTION :オリジナルトランスポートタイクーン(オリジナル/ワールドエディター)DOS版の音楽。 -STR_BASEMUSIC_NONE_DESCRIPTION :空の音楽パック +STR_BASEMUSIC_NONE_DESCRIPTION :音源の含まれない音楽セット STR_TRADITIONAL_TRAIN_NAME :列車{COMMA} STR_TRADITIONAL_ROAD_VEHICLE_NAME :車両{COMMA} @@ -4789,10 +4940,10 @@ STR_INDUSTRY_NAME_SUGAR_MINE :砂糖鉱山 ##id 0x6000 STR_SV_EMPTY : STR_SV_UNNAMED :[未命名] -STR_SV_TRAIN_NAME :列車{COMMA} -STR_SV_ROAD_VEHICLE_NAME :車両{COMMA} -STR_SV_SHIP_NAME :船舶{COMMA} -STR_SV_AIRCRAFT_NAME :航空機{COMMA} +STR_SV_TRAIN_NAME :列車 #{COMMA} +STR_SV_ROAD_VEHICLE_NAME :車両 #{COMMA} +STR_SV_SHIP_NAME :船舶 #{COMMA} +STR_SV_AIRCRAFT_NAME :航空機 #{COMMA} STR_SV_STNAME :{STRING} STR_SV_STNAME_NORTH :北{STRING} @@ -4910,10 +5061,10 @@ STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :玩具車 STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BATTERY_TRUCK :電池車 STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :炭酸飲料車 STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PLASTIC_TRUCK :プラスチック貨車 -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :Lev1 Leviathan (電気) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :Lev2 Cyclops (電気) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV3_PEGASUS_ELECTRIC :Lev3 Pegasus (電気) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV4_CHIMAERA_ELECTRIC :Lev4 Chimaera (電気) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :Lev1 リヴァイアサン (リニア) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :Lev2 サイクロプス (リニア) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV3_PEGASUS_ELECTRIC :Lev3 ペガサス (リニア) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV4_CHIMAERA_ELECTRIC :Lev4 キマイラ (リニア) STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_WIZZOWOW_ROCKETEER :ピューピュー社 ロケッター STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PASSENGER_CAR :客車 STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_MAIL_VAN :郵便車 diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 97410eed26..6542e5be31 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -3494,7 +3494,7 @@ STR_LAND_AREA_INFORMATION_CAPTION :{WHITE}이 지 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} +STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}제거하면 회수되는 금액: {LTBLUE}{CURRENCY_LONG} STR_LAND_AREA_INFORMATION_OWNER_N_A :없음 STR_LAND_AREA_INFORMATION_OWNER :{BLACK}소유주: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_ROAD_OWNER :{BLACK}도로 소유주: {LTBLUE}{STRING} @@ -3887,7 +3887,7 @@ STR_NEWGRF_PARAMETERS_NUM_PARAM :{LTBLUE}매개 # NewGRF inspect window STR_NEWGRF_INSPECT_CAPTION :{WHITE}NEWGRF 검사 - {STRING} -STR_NEWGRF_INSPECT_PARENT_BUTTON :{BLACK}상위 단계 +STR_NEWGRF_INSPECT_PARENT_BUTTON :{BLACK}상위 STR_NEWGRF_INSPECT_PARENT_TOOLTIP :{BLACK}상위 단계 범위의 오브젝트를 검사합니다 STR_NEWGRF_INSPECT_REFRESH :{BLACK}R STR_NEWGRF_INSPECT_REFRESH_TOOLTIP :{BLACK}콘텐츠를 매 프레임마다 갱신할지를 설정합니다 @@ -4128,7 +4128,7 @@ STR_SUBSIDIES_CAPTION :{WHITE}보조 STR_SUBSIDIES_OFFERED_TITLE :{BLACK}지급 대기 중인 보조금: STR_SUBSIDIES_OFFERED_FROM_TO :{ORANGE}{1:STRING}에서 {2:STRING}까지 {0:STRING} 수송{YELLOW} ({3:DATE_SHORT}까지) STR_SUBSIDIES_NONE :{ORANGE}없음 -STR_SUBSIDIES_SUBSIDISED_TITLE :{BLACK}이미 지급 중인 보조금: +STR_SUBSIDIES_SUBSIDISED_TITLE :{BLACK}이미 지급된 보조금: STR_SUBSIDIES_SUBSIDISED_FROM_TO :{ORANGE}{1:STRING}에서 {2:STRING}까지 {0:STRING} 수송{YELLOW} ({3:COMPANY}{YELLOW}, {DATE_SHORT}까지) STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}산업시설/도시의 위치로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 산업시설/도시의 위치를 기준으로 새로운 외부 화면을 엽니다 @@ -4560,7 +4560,7 @@ STR_GROUP_RENAME_TOOLTIP :{BLACK}선택 STR_GROUP_LIVERY_TOOLTIP :{BLACK}선택한 그룹의 차량 색상을 변경합니다 STR_GROUP_EXPAND_ALL :{BLACK}모두 펼치기 STR_GROUP_COLLAPSE_ALL :{BLACK}모두 접기 -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}클릭해서 전체 자동 교체로부터 이 그룹을 보호합니다 +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}클릭하면 전체 자동 교체로부터 이 그룹을 보호합니다. CTRL+클릭하면 하위 그룹도 보호합니다. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}그룹 삭제 STR_GROUP_DELETE_QUERY_TEXT :{WHITE}이 그룹과 하위 그룹을 정말 삭제하시겠습니까? @@ -4835,8 +4835,9 @@ STR_REPLACE_MAGLEV_VEHICLES :자기부상 STR_REPLACE_ROAD_VEHICLES :자동차 STR_REPLACE_TRAM_VEHICLES :전차 차량 -STR_REPLACE_REMOVE_WAGON :{BLACK}화물차 제거: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}화물차 제거 ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}자동 교체시 열차의 길이가 교체 전보다 길어지면 객차/화차를 (앞쪽부터) 제거하여 열차의 전체 길이가 달라지지 않도록 합니다 +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. CTRL+클릭하면 하위 그룹에도 적용됩니다 # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/latin.txt b/src/lang/latin.txt index 9d4c67688d..f30cf25217 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -3768,7 +3768,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Vehicula Monoor STR_REPLACE_MAGLEV_VEHICLES :Vehicula Maglev -STR_REPLACE_REMOVE_WAGON :{BLACK}Ablatio curruum: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Facere ut automutatio longitudinem traminis contineat ablatione curruum (primo primorum), si tramen longius fiat mutatione hamaxae # Vehicle view diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 644fda7c7e..cfd1be6bda 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -3733,7 +3733,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Magleva transpo STR_REPLACE_ROAD_VEHICLES :Autotransporta līdzekļi STR_REPLACE_TRAM_VEHICLES :Tramvaji -STR_REPLACE_REMOVE_WAGON :{BLACK}Vagona noņemšana: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Automātiskā aizvietošana saglabās esošo vilciena garumu noņemot vagonus (sākot no priekšgala), ja mainot lokomotīvi tas kļūtu garāks # Vehicle view diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index 9266d3373a..ac49e0f983 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -4031,7 +4031,6 @@ STR_REPLACE_MAGLEV_VEHICLES :„Maglev“ tr STR_REPLACE_ROAD_VEHICLES :Automobilius STR_REPLACE_TRAM_VEHICLES :Tramvajinės transporto priemonės -STR_REPLACE_REMOVE_WAGON :{BLACK}Vagono pašalinimas: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Pakeitimo metu išlaikyti traukinio ilgį atjungiant vagonus (pradedant nuo priekio), jeigu pakeitus garvežį traukinys pailgėtų # Vehicle view diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index b0fe5e1216..79759e1b90 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -3774,7 +3774,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Magnéitbunn Ge STR_REPLACE_ROAD_VEHICLES :Stroossegefierer STR_REPLACE_TRAM_VEHICLES :Tram-Gefierer -STR_REPLACE_REMOVE_WAGON :{BLACK}Waggon raushuelen: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Mécht dass d'automatescht Austauschen d'Längt vum Zuch behält, an dem e Waggonen (vu lénks un) wechhëllt, wann d'Lok den Zuch ze laang mécht # Vehicle view diff --git a/src/lang/malay.txt b/src/lang/malay.txt index e8b200fe14..c1f52e264b 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -3179,7 +3179,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Monorel Kendera STR_REPLACE_MAGLEV_VEHICLES :Kenderaan Maglev -STR_REPLACE_REMOVE_WAGON :{BLACK}Penghapusan wagon: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Membuat penukaran secara automatik menyimpan kepanjangan keretapi yang sama dengan mengeluarkan gerabak (bermula dari bahagian hadapan), sekiranya menyebabkan kereta api lebih panjang # Vehicle view diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 2a6c98b96a..d9387a6d0d 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -2280,7 +2280,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} ha STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} har blitt med som tilskuer STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} har startet et nytt firma (nr. {2:NUM}) STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} har forlatt spillet ({2:STRING}) -STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} har forandret sitt navn til {STRING} +STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} har endret navnet sitt til {STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} ga {2:CURRENCY_LONG} til ditt firma{1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Tjeneren avsluttet spillet STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Tjeneren starter på nytt...{}Vennligst vent... @@ -3826,7 +3826,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglev-kjøret STR_REPLACE_ROAD_VEHICLES :Veikjøretøy STR_REPLACE_TRAM_VEHICLES :Trikkekjøretøy -STR_REPLACE_REMOVE_WAGON :{BLACK}Vognfjerning: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}La autoerstatningen beholde lengen på toget ved å fjerne vogner (fra første vogn), hvis utskiftningen gjør toget lengre. # Vehicle view diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index bb3f008618..af1d9112af 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -3400,7 +3400,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Monorail-køyre STR_REPLACE_MAGLEV_VEHICLES :Maglev-køyretøy -STR_REPLACE_REMOVE_WAGON :{BLACK}Vognfjerning: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Lat den automatiske utskiftinga behalde lengda på toget ved å fjerne vogner (frå første vogn), dersom utskiftinga gjer toget lenger. # Vehicle view diff --git a/src/lang/polish.txt b/src/lang/polish.txt index a64867a468..3711de5ed9 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -4166,7 +4166,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Kolej Maglev STR_REPLACE_ROAD_VEHICLES :Pojazdy drogowe STR_REPLACE_TRAM_VEHICLES :Tramwaje -STR_REPLACE_REMOVE_WAGON :{BLACK}Usunięcie wagonów: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Autowymiana zachowuje długość pociągu poprzez usuwanie wagonów (począwszy od początku), jeśli wymiana lokomotywy spowoduje wydłużenie pociągu # Vehicle view diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 330b6b1c48..94db813c2e 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -3570,7 +3570,7 @@ STR_GROUP_CREATE_TOOLTIP :{BLACK}Clique p STR_GROUP_DELETE_TOOLTIP :{BLACK}Remover o grupo seleccionado STR_GROUP_RENAME_TOOLTIP :{BLACK}Mudar o nome do grupo seleccionado STR_GROUP_LIVERY_TOOLTIP :{BLACK}Alterar a imagem do grupo selecionado -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Clique para proteger este grupo da autosubstituição global +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Clique para proteger este grupo da auto-substituição global. Ctrl+Clique para proteger também sub-grupos. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Apagar Grupo STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Tem a certeza de que quer apagar este grupo e quaisquer descendentes? @@ -3823,8 +3823,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglevs STR_REPLACE_ROAD_VEHICLES :Veículos rodoviários STR_REPLACE_TRAM_VEHICLES :Elétricos -STR_REPLACE_REMOVE_WAGON :{BLACK}Remover vagões: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Remover vagões ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Forçar a substituição automática a manter o comprimento do comboio, removendo vagões (do início), nas situações em que a substituição da locomotiva pode resultar num comboio mais comprido. +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+Clique para aplicar também a sub-grupos # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index bf4f8af114..f7972cbfe8 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -3640,7 +3640,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Vehicule Pernă STR_REPLACE_ROAD_VEHICLES :Autovehicule STR_REPLACE_TRAM_VEHICLES :Tramvaie -STR_REPLACE_REMOVE_WAGON :{BLACK}Retragere vagoane: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Fă optiunea de autoînlocuire să păstreze identică lungimea unui tren prin eliminarea vagoanelor (începând din faţă) dacă înlocuirea locomotivei ar face trenul mai lung # Vehicle view diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 80fdb5bb5d..040158dd91 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -3750,7 +3750,7 @@ 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}Защита транспорта в группе от глобальной автозамены +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Защита транспорта в группе от глобальной автозамены. Ctrl+щелчок - защита также и вложенных групп. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Удаление группы STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Удалить эту и все вложенные группы? @@ -4018,8 +4018,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Магнитн STR_REPLACE_ROAD_VEHICLES :Автотранспорт STR_REPLACE_TRAM_VEHICLES :Трамваи -STR_REPLACE_REMOVE_WAGON :{BLACK}Удаление вагонов: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Удаление вагонов ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Разрешить при автозамене сохранять длину поездов путём удаления вагонов (начиная с головы поезда), если при автозамене локомотива увеличится длина состава. +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}{}Ctrl+щелчок - применить также и к вложенным группам. # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index 980fb28b3a..4803b009ef 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -3985,7 +3985,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Magnetnošinska STR_REPLACE_ROAD_VEHICLES :Drumska vozila STR_REPLACE_TRAM_VEHICLES :Tramvajska vozila -STR_REPLACE_REMOVE_WAGON :{BLACK}Ukanjanje vagona: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ukoliko bi se zamenom kompozicija produžila, automatska obnova će ukloniti vagone (sa početka) kako bi se zadržala dužina kompozicije # Vehicle view diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 673cf4d738..66d1fdda6c 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -3779,7 +3779,6 @@ STR_REPLACE_MAGLEV_VEHICLES :磁悬浮列车 STR_REPLACE_ROAD_VEHICLES :路面交通工具 STR_REPLACE_TRAM_VEHICLES :电车 -STR_REPLACE_REMOVE_WAGON :{BLACK}清理挂车:{ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}当车辆升级可能造成列车变长时{}自动从最前面的挂车去掉若干节以保证列车长度不变 # Vehicle view diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 98760a4565..c43f4e744b 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -2318,7 +2318,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :spracovanie map STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :Neplatný názov klienta ############ End of leave-in-this-order -STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Možná ztráta pripojenia +STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Možná strata pripojenia STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION :{WHITE}Posledných {NUM} sekúnd nedorazili zo servera žiadne dáta # Network related errors @@ -3890,8 +3890,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Lokomotíva pre STR_REPLACE_ROAD_VEHICLES :Automobily STR_REPLACE_TRAM_VEHICLES :Električky -STR_REPLACE_REMOVE_WAGON :{BLACK}Odstránenie vagónu: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Odstránenie vagónu ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Zachovanie pôvodnej dĺžky vlaku, odstránením vagónov (odpredu), keď by funkcia automatickej zmeny rušňa vlak predĺžila +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+klik aplikuje aj na podskupiny # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -4767,7 +4768,7 @@ STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Zatiaľ STR_ERROR_NO_VEHICLES_AVAILABLE_YET_EXPLANATION :{WHITE}Začnite novú hru po {DATE_SHORT} alebo použite NewGRF, ktoré zabezpečí vozidlá v skoršom čase # Specific vehicle errors -STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Nemôžeš nechať vlak prejsť cez návestidlo keď hrozí nebezpečenstvo... +STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Nemožno nechať vlak prejsť návestidlo ak hrozí nebezpečenstvo... STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN :{WHITE}Nemožno otočiť vlak naopak... STR_ERROR_TRAIN_START_NO_POWER :Vlak nemá energiu diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index 8eacfa87e0..e5aae4b5d2 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -3637,7 +3637,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Enotirna vozila STR_REPLACE_MAGLEV_VEHICLES :Magnetna tirna vozila -STR_REPLACE_REMOVE_WAGON :{BLACK}Odstranitev vagonov: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Dovoli samozamenjavi, da z odstranitvijo vagonov, začenši na začetku, ohrani isto dolžino vlaka, če bi ga menjava lokomotive podaljšala # Vehicle view diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index b58e2a55e4..01745e2ec7 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -3570,7 +3570,7 @@ STR_GROUP_CREATE_TOOLTIP :{BLACK}Clica pa STR_GROUP_DELETE_TOOLTIP :{BLACK}Borra el grupo seleccionado STR_GROUP_RENAME_TOOLTIP :{BLACK}Renombra el grupo seleccionado STR_GROUP_LIVERY_TOOLTIP :{BLACK}Cambia el color del grupo seleccionado -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Clic para proteger este grupo del auto reemplazado global +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Clica para proteger este grupo del autorreemplazo global. Ctrl+clic protege también los subgrupos. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Borrar Grupo STR_GROUP_DELETE_QUERY_TEXT :{WHITE}¿Estás seguro de borrar este grupo y todos sus subgrupos? @@ -3823,8 +3823,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Vehículos Magl STR_REPLACE_ROAD_VEHICLES :Vehículos de Carretera STR_REPLACE_TRAM_VEHICLES :Tranvías -STR_REPLACE_REMOVE_WAGON :{BLACK}Retirar vagones: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Retirar vagones ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Fuerza que el reemplazo automático mantenga la longitud del tren, quitando vagones (empezando por la parte delantera) si el reemplazo de vehículos produce un tren más largo +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+clic para aplicar también a subgrupos # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index 656692732e..e0b491c36d 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -3823,7 +3823,7 @@ STR_REPLACE_MAGLEV_VEHICLES :Trenes maglev STR_REPLACE_ROAD_VEHICLES :Vehículos de carretera STR_REPLACE_TRAM_VEHICLES :Vehículos de tranvía -STR_REPLACE_REMOVE_WAGON :{BLACK}Quitar vagón: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Quitar vagó ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Hacer que el reemplazo automático mantenga la longitud del tren quitando vagones (empezando por el frente), si el cambio de locomotora produce un tren más largo # Vehicle view diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 28ecb01153..5fa0ea1d94 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -359,7 +359,7 @@ STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Bygg fly STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Öppna landskapsarkitektursverktygen för att höja/sänka land, plantera träd, etc. STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Visa ljud-/musikfönster STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Visa senaste meddelandet/nyheten, visa meddelandeinställningar -STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Markinformation, konsoll, skript-felsökning, skärmdumpar, om OpenTTD +STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Markinformation, konsol, felsökning av skript, skärmdumpar, om OpenTTD STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Byt verktygsrad # Extra tooltips for the scenario editor toolbar @@ -912,7 +912,7 @@ STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valutaen STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Välj valutaenhet ############ start of currency region -STR_GAME_OPTIONS_CURRENCY_GBP :Brittisk pund (£) +STR_GAME_OPTIONS_CURRENCY_GBP :Brittiskt pund (£) STR_GAME_OPTIONS_CURRENCY_USD :Amerikansk dollar (USD) STR_GAME_OPTIONS_CURRENCY_EUR :Euro (EUR) STR_GAME_OPTIONS_CURRENCY_JPY :Japansk yen (¥) @@ -948,18 +948,18 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Georgisk lari ( STR_GAME_OPTIONS_CURRENCY_IRR :Iransk rial (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Ny rysk rubel (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Mexikansk peso (MXN) -STR_GAME_OPTIONS_CURRENCY_NTD :Nya Taiwanesisk dollar (NTD) -STR_GAME_OPTIONS_CURRENCY_CNY :Kinesisk Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_NTD :Ny taiwanesisk dollar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Kinesisk renminbi (CNY) STR_GAME_OPTIONS_CURRENCY_HKD :Hongkongdollar (HKD) STR_GAME_OPTIONS_CURRENCY_INR :Indisk rupie (INR) -STR_GAME_OPTIONS_CURRENCY_IDR :Indonesisk Rupiah (IDR) -STR_GAME_OPTIONS_CURRENCY_MYR :Malaysisk Ringgit (MYR) +STR_GAME_OPTIONS_CURRENCY_IDR :Indonesisk rupie (IDR) +STR_GAME_OPTIONS_CURRENCY_MYR :Malaysisk ringgit (MYR) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Kör på vänster sida STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Kör på höger sida -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Stadsnamn +STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Stadsnamn: STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Välj typ av stadsnamn ############ start of townname region @@ -999,6 +999,7 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :Var 12:e månad STR_GAME_OPTIONS_LANGUAGE :{BLACK}Språk STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Välj vilket språk som ska användas +STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% färdigt) STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Helskärm STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Kryssa i den här rutan för att spela OpenTTD i helskärmsläge @@ -1060,9 +1061,9 @@ STR_ERROR_FULLSCREEN_FAILED :{WHITE}Fullskä STR_CURRENCY_WINDOW :{WHITE}Egen valuta STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Växlingskurs: {ORANGE}{CURRENCY_LONG} = £ {COMMA} -STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Minska värdet för din valuta med ett Pund (£) -STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Öka värdet för din valuta med ett Pund (£) -STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP :{BLACK}Sätt växelkursen för din valuta mot ett Pund (£) +STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Minska värdet för din valuta med ett pund (£) +STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Öka värdet för din valuta med ett pund (£) +STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP :{BLACK}Sätt växelkursen för din valuta mot ett pund (£) STR_CURRENCY_SEPARATOR :{LTBLUE}Avskiljare: {ORANGE}{STRING} STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP :{BLACK}Sätt separatorn för din valuta @@ -1079,7 +1080,7 @@ STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Byt till STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Byt till euron senare STR_CURRENCY_PREVIEW :{LTBLUE}Förhandsgranska: {ORANGE}{CURRENCY_LONG} -STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pund (£) i din valuta +STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 pund (£) i din valuta STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Ändra valutaparametrar STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Max antal motståndare: {ORANGE}{COMMA} @@ -1322,7 +1323,7 @@ STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Flygplatser bli STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Aktivering av denna inställning gör så att alla flygplatstyper finns kvar i obegränsad tid efter att de blivit tillgängliga STR_CONFIG_SETTING_WARN_LOST_VEHICLE :Varna om fordon är vilse: {STRING} -STR_CONFIG_SETTING_WARN_LOST_VEHICLE_HELPTEXT :Aktiverar meddelanden om fordon som är oförmögna att hitta vägen till deras destination. +STR_CONFIG_SETTING_WARN_LOST_VEHICLE_HELPTEXT :Aktiverar meddelanden om fordon som är oförmögna att hitta vägen till sin destination. STR_CONFIG_SETTING_ORDER_REVIEW :Granska fordonens destinationer: {STRING} STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT :Om det är aktiverat så kontrolleras fordonens order periodiskt och när uppenbara problem identifieras rapporteras detta med ett nyhetsmeddelande STR_CONFIG_SETTING_ORDER_REVIEW_OFF :Nej @@ -1996,6 +1997,8 @@ STR_FACE_TIE :Slips: STR_FACE_EARRING :Örhänge: STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Ändra slips eller örhänge +STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privat +STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Offentlig # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Flera spelare @@ -2055,10 +2058,12 @@ STR_NETWORK_SERVER_LIST_ENTER_IP :{BLACK}IP-adres STR_NETWORK_START_SERVER_CAPTION :{WHITE}Starta ett nytt spel i flerspelarläge STR_NETWORK_START_SERVER_NEW_GAME_NAME :{BLACK}Namn: -STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Namnet på nätverksspelet kommer att synas för andra spelare i multiplayer menyn +STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Namnet på nätverksspelet kommer att synas för andra spelare i flerspelarmenyn STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Bestäm lösenord STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Skydda spelet med ett lösenord så att inte andra än dem som har lösenordet kan gå med i spelet +STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Synlighet +STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}Huruvida andra människor kan se din server i den offentliga listan STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} klient{P "" er} STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Max antal tillåtna klienter: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Välj max antal tillåtna klienter. Alla platser måste inte fyllas. @@ -2122,12 +2127,45 @@ STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Servern STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Företaget är skyddat. Ange lösenord # Network company list added strings -STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Klientlista +STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Spelare online STR_NETWORK_COMPANY_LIST_SPECTATE :Åskåda # Network client list - - +STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Flera spelare +STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}Server +STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Namn +STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}Namnet på servern du spelar på +STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Ändra din servers namn +STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Serverns namn +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Synlighet +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Huruvida andra människor kan se din server i den offentliga listan +STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Spelare +STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Namn +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Ditt spelarnamn +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}Ändra ditt spelarnamn +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Ditt spelarnamn +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Administrativa handlingar att utföra för denna klient +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Administrativa handlingar att utföra för detta företag +STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Gå med i detta företag +STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Skicka ett meddelande till denna spelare +STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Skicka ett meddelande till alla spelare i detta företag +STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Skicka ett meddelande till alla åskådare +STR_NETWORK_CLIENT_LIST_SPECTATORS :Åskådare +STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nytt företag) +STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Skapa ett nytt företag och gå med i det +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Det här är du +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Det här är spelets värd + +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kasta ut +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bannlys +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Ta bort +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Lås upp med lösenord + +STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Administratörshandling +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Är du säker på att du vill kasta ut spelaren '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Är du säker på att du vill bannlysa spelaren '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Är du säker på att du vill ta bort företaget {COMPANY}? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Är du säker på att du vill återställa företaget {COMPANY}s lösenord? STR_NETWORK_SERVER :Server STR_NETWORK_CLIENT :Klient @@ -2172,7 +2210,8 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}Kunde in STR_NETWORK_ERROR_CLIENT_START :{WHITE}Kunde inte ansluta. STR_NETWORK_ERROR_TIMEOUT :{WHITE}Nätverkskoppling #{NUM} timeout STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Ett protokollfel uppstod och anslutningen stängdes. -STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Servern har en annan version än denna klient. +STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Du har inte angivit något spelarnamn. Namninställning kan göras högst upp i flerspelarfönstret +STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Servern har en annan version än denna klient STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Fel lösenord STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Servern är full STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}Du är bannlyst från den här servern @@ -2184,6 +2223,8 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Du tog f STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Din dator tog för lång tid på sig för att ansluta STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Du tog för lång tid på dig att ladda ner kartan STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Du tog för lång tid på dig att ansluta till servern +STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Ditt spelarnamn är inte tillåtet +STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}Servern som fick förfrågan är för gammal för denna klient ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :allmänt fel @@ -2206,6 +2247,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :inget lösenord STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :generell timeout STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :nedladdning av kartan tog för lång tid STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :bearbetning av kartan tog för lång tid +STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :ogiltigt klientnamn ############ End of leave-in-this-order STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Anslutningen har troligtvis försvunnit @@ -2234,7 +2276,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} ha STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} har gått med som åskådare STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} har startat ett nytt företag (#{2:NUM}) STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} har lämnat spelet ({2:STRING}) -STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} har ändrat hans/hennes namn till {STRING} +STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} har ändrat sitt namn till {STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} gav {2:CURRENCY_LONG} till {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Servern avslutade sessionen STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Servern startar om...{}Var vänlig vänta... @@ -2326,8 +2368,8 @@ STR_TRANSPARENT_INDUSTRIES_TOOLTIP :{BLACK}Växla g STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Växla genomskinlighet för byggnader såsom stationer, depåer och riktmärken. Ctrl+klick för att låsa STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Växla genomskinlighet för broar. Ctrl+klick för att låsa STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Växla genomskinlighet för byggnader såsom fyrar och antenner. Ctrl+klick för att låsa -STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Växla genomskinlighet för kontaktledning. CTRL+klick för att låsa -STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Växla genomskinlighet för lastningsindikatörer. CTRL+klick för att låsa +STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Växla genomskinlighet för kontaktledning. Ctrl+klick för att låsa +STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Växla genomskinlighet för lastningsindikatorer. Ctrl+klick för att låsa STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Gör object osynliga istället för genomskinliga # Linkgraph legend window @@ -2494,7 +2536,7 @@ STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Bygg ske STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Bygg hamn. Ctrl aktiverar sammansättning av stationer. Shift växlar mellan att bygga/visa beräknad kostnad STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Placera en boj som kan som kan användas som riktmärke. Shift växlar mellan att bygga/visa beräknad kostnad STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Bygg akvedukt. Shift växlar mellan att bygga/visa beräknad kostnad -STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Definiera vattenyta.{}Skapa en kanal, om inte CTRL är nedhållen vid havsnivå, då den kommer att översvämma närliggande områden istället +STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Definiera vattenyta.{}Skapa en kanal, såvida inte Ctrl är nedtryckt vid havsnivå, då den istället kommer att översvämma närliggande områden STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Placera flod. Ctrl markerar ytan diagonalt # Ship depot construction window @@ -2598,7 +2640,7 @@ STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON :{BLACK}Stor STR_FOUND_TOWN_SIZE_RANDOM :{BLACK}Slumpa STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Välj stadsstorlek STR_FOUND_TOWN_CITY :{BLACK}Stad -STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Stora städer växer snabbare än vanliga städer{}Beroende på inställningarna så är de större när de grundas +STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Storstäder växer snabbare än vanliga städer{}Beroende på inställningarna så är de större när de grundas STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Utformning av stadens vägnät: STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT :{BLACK}Välj vägnätets utformning för denna stad @@ -3048,7 +3090,8 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Varning: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Fel: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatalt: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Ett fatalt NewGRF fel har uppstått:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Ett fatalt NewGRF-fel har uppstått:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}Ett NewGRF-fel har uppstått:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} kommer inte att fungera med den TTDPatchversion som rapporterades av OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} är för {STRING}versionen av TTD STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} är designat för att användas med {STRING} @@ -3369,7 +3412,7 @@ STR_FINANCES_LOAN_TITLE :{WHITE}Lån STR_FINANCES_MAX_LOAN :{WHITE}Maxlån: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Låna {CURRENCY_LONG} -STR_FINANCES_BORROW_TOOLTIP :{BLACK}Öka lånets storlek. Ctrl + Klick lånar så mycket som möjligt +STR_FINANCES_BORROW_TOOLTIP :{BLACK}Öka lånets storlek. Ctrl+klick lånar så mycket som möjligt STR_FINANCES_REPAY_BUTTON :{BLACK}Återbetala {CURRENCY_LONG} STR_FINANCES_REPAY_TOOLTIP :{BLACK}Återbetala en del av lånet. Ctrl+klick återbetalar så mycket som är möjligt STR_FINANCES_INFRASTRUCTURE_BUTTON :{BLACK}Infrastruktur @@ -3526,7 +3569,7 @@ STR_GROUP_CREATE_TOOLTIP :{BLACK}Klicka f STR_GROUP_DELETE_TOOLTIP :{BLACK}Ta bort vald grupp STR_GROUP_RENAME_TOOLTIP :{BLACK}Byt namn på vald grupp STR_GROUP_LIVERY_TOOLTIP :{BLACK}Byt färgschema på vald grupp -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klicka för att skydda denna grupp mot allmän autoreplace +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klicka för att skydda denna grupp mot allmän automatisk förnyelse. Ctrl+klicka för att också skydda undergrupper. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Ta bort grupp STR_GROUP_DELETE_QUERY_TEXT :{WHITE} Är du säker på att du vill ta bort denna grupp och alla efterkommande? @@ -3779,8 +3822,9 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglevfordon STR_REPLACE_ROAD_VEHICLES :Vägfordon STR_REPLACE_TRAM_VEHICLES :Spårvägsfordon -STR_REPLACE_REMOVE_WAGON :{BLACK}Vagnborttagning: {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Vagnborttagning ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Gör så att automatiskt utbyte behåller ett tågs längd genom att ta bort vagnar (med början längst fram) om utbytandet av loket skulle göra tåget längre +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+klicka för att också tillämpa det på undergrupper # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -3788,7 +3832,7 @@ STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP :{BLACK}Centrera huvudvyn på tågets position. Dubbelklicka för att följa tåget i huvudvyn. Ctrl+klicka öppnar ett nytt fönster över tågets position STR_VEHICLE_VIEW_ROAD_VEHICLE_CENTER_TOOLTIP :{BLACK}Centrera huvudvyn på fordonets position. Dubbelklicka för att följa fordonet i huvudvyn. Ctrl+klicka öppnar ett nytt fönster över fordonets position STR_VEHICLE_VIEW_SHIP_CENTER_TOOLTIP :{BLACK}Centrera huvudvyn på fartygets position. Dubbelklicka för att följa fartyget i huvudvyn. Ctrl+klicka öppnar ett nytt fönster över fartygets position -STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}Centrera huvudvyn på flyplanets position. Dubbelklicka för att följa flyplanet i huvudvyn. Ctrl+klicka öppnar ett nytt fönster över flygplanets position +STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}Centrera huvudvyn på flygplanets position. Dubbelklicka för att följa flygplanet i huvudvyn. Ctrl+klicka öppnar ett nytt fönster över flygplanets position STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Skicka tåg till depå. Ctrl+klick skickar tåget enbart på service STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Skicka fordon till depå. Ctrl+klick servar endast @@ -3825,7 +3869,7 @@ STR_VEHICLE_VIEW_ROAD_VEHICLE_STATUS_START_STOP_TOOLTIP :{BLACK}Aktuell STR_VEHICLE_VIEW_SHIP_STATE_STATUS_STOP_TOOLTIP :{BLACK}Aktuell fartygsåtgärd - Tryck för att stoppa/starta fartyg STR_VEHICLE_VIEW_AIRCRAFT_STATUS_START_STOP_TOOLTIP :{BLACK}Aktuell flygplansåtgärd - Tryck för att stoppa/starta flygplanet -STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}Centrera huvudvyn på ordens destination. Ctrl+klick öppnar en ny vy över ordens destination +STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}Centrera huvudvyn på orderns destination. Ctrl+klick öppnar en ny vy över orderns destination # Messages in the start stop button in the vehicle view STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}Lastar / lastar av @@ -3834,7 +3878,7 @@ STR_VEHICLE_STATUS_CRASHED :{RED}Kraschad! STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Motorstopp STR_VEHICLE_STATUS_STOPPED :{RED}Stoppat STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}Stannar, {VELOCITY} -STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}Ingen Kraft +STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}Ingen kraft STR_VEHICLE_STATUS_TRAIN_STUCK :{ORANGE}Väntar på ledig väg STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR :{ORANGE}Nästa destination ligger för långt bort @@ -4016,7 +4060,7 @@ STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}Värde a STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Skriv in värde att jämföra mot STR_ORDERS_SKIP_BUTTON :{BLACK}Skippa -STR_ORDERS_SKIP_TOOLTIP :{BLACK}Hoppa över nuvarande order och starta nästa. CTRL + klick hoppar över till vald order +STR_ORDERS_SKIP_TOOLTIP :{BLACK}Hoppa över nuvarande order och starta nästa. Ctrl+klick hoppar över till vald order STR_ORDERS_DELETE_BUTTON :{BLACK}Ta bort STR_ORDERS_DELETE_TOOLTIP :{BLACK}Ta bort markerad order @@ -4123,7 +4167,7 @@ STR_TIMETABLE_DAYS :{COMMA}{NBSP}da STR_TIMETABLE_TICKS :{COMMA}{NBSP}tick STR_TIMETABLE_TOTAL_TIME :{BLACK}Den här tidtabellen kommer ta {STRING} att slutföra -STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}Denna tidtabell kommer att ta åtminstonde {STRING} att slutföra (allt är inte inlagt i en tidtabell) +STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}Denna tidtabell kommer att ta åtminstone {STRING} att slutföra (allt är inte inlagt i en tidtabell) STR_TIMETABLE_STATUS_ON_TIME :{BLACK}Detta fordon kör enligt tidtabellen STR_TIMETABLE_STATUS_LATE :{BLACK}Detta fordon är för tillfället {STRING} sen @@ -4187,7 +4231,7 @@ STR_AI_DEBUG_CONTINUE :{BLACK}Fortsät STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Opausa och fortsätt datorspelaren STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Visa debug-utskrifter för denna datorspelare STR_AI_GAME_SCRIPT :{BLACK}Spelskript -STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Visa debug-utskrifter för spelskript +STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Visa felsökningsutskrifter för spelskript STR_ERROR_AI_NO_AI_FOUND :Ingen passande datorspelare hittades.{}Denna datorspelare är en test-datorspelare och kommer inte göra någonting.{}Du kan ladda ner nya datorspelare genom spelets 'Online-innehåll'-system STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Ett av skripten som körs har kraschat. Vänligen rapportera detta till datorspelarens skapare med en skärmdump av förstret 'Felsökning av datorspelare / spelskript' @@ -4794,7 +4838,7 @@ STR_INDUSTRY_NAME_SUGAR_MINE :Sockergruva ############ These strings may never get a new id, or savegames will break! ##id 0x6000 STR_SV_EMPTY : -STR_SV_UNNAMED :Inget namn +STR_SV_UNNAMED :Utan namn STR_SV_TRAIN_NAME :Tåg #{COMMA} STR_SV_ROAD_VEHICLE_NAME :Vägfordon #{COMMA} STR_SV_SHIP_NAME :Skepp #{COMMA} @@ -4809,10 +4853,10 @@ STR_SV_STNAME_CENTRAL :{STRING} centra STR_SV_STNAME_TRANSFER :{STRING} övergång STR_SV_STNAME_HALT :{STRING} hållplats STR_SV_STNAME_VALLEY :{STRING} dal -STR_SV_STNAME_HEIGHTS :{STRING} Höjder +STR_SV_STNAME_HEIGHTS :{STRING} höjder STR_SV_STNAME_WOODS :{STRING} skog STR_SV_STNAME_LAKESIDE :{STRING} sjöstrand -STR_SV_STNAME_EXCHANGE :{STRING} Växel +STR_SV_STNAME_EXCHANGE :{STRING} växel STR_SV_STNAME_AIRPORT :{STRING} flygplats STR_SV_STNAME_OILFIELD :{STRING} oljefält STR_SV_STNAME_MINES :{STRING} gruva diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index 9154e5cd9f..4c4b846f8c 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -3298,7 +3298,6 @@ STR_REPLACE_MAGLEV_VEHICLES :மேக்ல STR_REPLACE_ROAD_VEHICLES :சாலை வாகனங்கள் STR_REPLACE_TRAM_VEHICLES :அமிழ் தண்டூர்தி வாகனங்கள் -STR_REPLACE_REMOVE_WAGON :{BLACK}பெட்டி நீக்கம்: {ORANGE}{STRING} # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} diff --git a/src/lang/thai.txt b/src/lang/thai.txt index 4323e6f759..3f46f16f37 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -3404,7 +3404,6 @@ STR_REPLACE_MONORAIL_VEHICLES :ยานพา STR_REPLACE_MAGLEV_VEHICLES :รถไฟพลังงานแม่แหล็ก -STR_REPLACE_REMOVE_WAGON :{BLACK}ขายรถพ่วง: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}ทำให้การแทนที่ขบวนรถไฟทำให้ความยาวของขบวนยังเท่าเดิม # Vehicle view diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 31992d8cb9..512f1bfa18 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -925,6 +925,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :南非蘭特 (Z STR_GAME_OPTIONS_CURRENCY_CUSTOM :自訂... STR_GAME_OPTIONS_CURRENCY_GEL :喬治亞拉里 (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :伊朗里亞爾 (IRR) +STR_GAME_OPTIONS_CURRENCY_HKD :港幣 (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :靠左行駛 @@ -2667,6 +2668,7 @@ STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}沒有 STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF:{WHITE}{STRING} STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}覆蓋檔案 +STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}你確定要覆蓋現有存檔嗎? STR_SAVELOAD_DIRECTORY :{STRING} (路徑) STR_SAVELOAD_OSKTITLE :{BLACK}為存檔輸入一個名稱 @@ -3236,6 +3238,7 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}將工 STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}產出等級:{YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}該工業已宣佈關閉! +STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}需要: {YELLOW}{STRING}{STRING} STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :,{STRING}{STRING} @@ -3517,7 +3520,6 @@ STR_REPLACE_MONORAIL_VEHICLES :單軌列車 STR_REPLACE_MAGLEV_VEHICLES :磁浮列車 -STR_REPLACE_REMOVE_WAGON :{BLACK}移除車廂:{ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}如果替換後的車廂較長的話,讓自動替換功能移除多餘的車廂 (從頭開始) 以便維持列車長度 # Vehicle view diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index d4a638d8c8..3068e05e8e 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -3822,7 +3822,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Maglev Araçlar STR_REPLACE_ROAD_VEHICLES :Yol Araçları STR_REPLACE_TRAM_VEHICLES :Tramvay Araçları -STR_REPLACE_REMOVE_WAGON :{BLACK}Vagon kaldırma: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Otomatik yenilemede tren boyutunun artması gerekiyorsa vagonları kaldır (en önden başlayarak yeterli sayıda vagon silinir) # Vehicle view diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index 59dff32af1..b921d6408b 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -3905,7 +3905,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Магнітн STR_REPLACE_ROAD_VEHICLES :Авто STR_REPLACE_TRAM_VEHICLES :Трамвайні транспортні засоби -STR_REPLACE_REMOVE_WAGON :{BLACK}Ліквідація зайвих вагонів: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Дозволити автооновленню видаляти вагони, зберігаючи довжину потягу (починаючи спереду), якщо оновлення робить поїзд довшим # Vehicle view diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index dc5a3ca6ce..be402a2170 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -3777,7 +3777,6 @@ STR_REPLACE_MAGLEV_VEHICLES :Đầu máy đ STR_REPLACE_ROAD_VEHICLES :Các xe ô-tô STR_REPLACE_TRAM_VEHICLES :Các xe điện -STR_REPLACE_REMOVE_WAGON :{BLACK}Xoá bỏ toa xe: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Tự động thay thế sẽ giữ nguyên độ dài đoàn tàu bằng cách bỏ bớt toa xe (bỏ từ phía đầu), nếu như việc thay thế đầu máy làm đoàn tàu dài hơn. # Vehicle view diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 828ce58a7e..a82dcea40f 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -3513,7 +3513,6 @@ STR_REPLACE_MONORAIL_VEHICLES :Cerbydau Monore STR_REPLACE_MAGLEV_VEHICLES :Cerbydau Maglef -STR_REPLACE_REMOVE_WAGON :{BLACK}Tynnu wagenni: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Gwneud i awtoddisodli gadw hyd y trên yr un peth drwy dynnu wagenni (gan ddechrau yn y blaen), os byddai newid yr injan yn gwneud y trên yn hirach # Vehicle view diff --git a/src/linkgraph/linkgraph.h b/src/linkgraph/linkgraph.h index f0d32083db..e8c47b50d4 100644 --- a/src/linkgraph/linkgraph.h +++ b/src/linkgraph/linkgraph.h @@ -496,7 +496,7 @@ public: * Get the current size of the component. * @return Size. */ - inline uint Size() const { return (uint)this->nodes.size(); } + inline NodeID Size() const { return (NodeID)this->nodes.size(); } /** * Get date of last compression. diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp index 2d619125b4..7252ac328d 100644 --- a/src/linkgraph/linkgraphjob.cpp +++ b/src/linkgraph/linkgraphjob.cpp @@ -103,7 +103,7 @@ void LinkGraphJob::FinaliseJob() /* Link graph has been merged into another one. */ if (!LinkGraph::IsValidID(this->link_graph.index)) return; - uint size = this->Size(); + uint16 size = this->Size(); for (NodeID node_id = 0; node_id < size; ++node_id) { Node from = (*this)[node_id]; diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h index 471abbd756..f0df823191 100644 --- a/src/linkgraph/linkgraphjob.h +++ b/src/linkgraph/linkgraphjob.h @@ -364,7 +364,7 @@ public: * Get the size of the underlying link graph. * @return Size. */ - inline uint Size() const { return this->link_graph.Size(); } + inline NodeID Size() const { return this->link_graph.Size(); } /** * Get the cargo of the underlying link graph. diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index 8b45bb6440..f821e13ebc 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -247,7 +247,7 @@ void LinkGraphJobGroup::SpawnThread() * On the other hand, if you want to play games which make this hang noticably * on a platform without threads then you'll probably get other problems first. * OK: - * If someone comes and tells me that this hangs for him/her, I'll implement a + * If someone comes and tells me that this hangs for them, I'll implement a * smaller grained "Step" method for all handlers and add some more ticks where * "Step" is called. No problem in principle. */ LinkGraphJobGroup::Run(this); diff --git a/src/linkgraph/mcf.cpp b/src/linkgraph/mcf.cpp index b0d8b3b32f..f490c962a8 100644 --- a/src/linkgraph/mcf.cpp +++ b/src/linkgraph/mcf.cpp @@ -502,7 +502,7 @@ bool MCF1stPass::EliminateCycles(PathVector &path, NodeID origin_id, NodeID next bool MCF1stPass::EliminateCycles() { bool cycles_found = false; - uint size = this->job.Size(); + uint16 size = this->job.Size(); PathVector path(size, nullptr); for (NodeID node = 0; node < size; ++node) { /* Starting at each node in the graph find all cycles involving this @@ -520,7 +520,7 @@ bool MCF1stPass::EliminateCycles() MCF1stPass::MCF1stPass(LinkGraphJob &job) : MultiCommodityFlow(job) { PathVector paths; - uint size = job.Size(); + uint16 size = job.Size(); uint accuracy = job.Settings().accuracy; bool more_loops; std::vector finished_sources(size); @@ -569,7 +569,7 @@ MCF2ndPass::MCF2ndPass(LinkGraphJob &job) : MultiCommodityFlow(job) { this->max_saturation = UINT_MAX; // disable artificial cap on saturation PathVector paths; - uint size = job.Size(); + uint16 size = job.Size(); uint accuracy = job.Settings().accuracy; bool demand_left = true; std::vector finished_sources(size); diff --git a/src/misc/dbg_helpers.h b/src/misc/dbg_helpers.h index f9d251b8a9..53033110d8 100644 --- a/src/misc/dbg_helpers.h +++ b/src/misc/dbg_helpers.h @@ -106,12 +106,6 @@ struct DumpTarget { , m_ptr(ptr) {} - KnownStructKey(const KnownStructKey &src) - { - m_type_id = src.m_type_id; - m_ptr = src.m_ptr; - } - bool operator<(const KnownStructKey &other) const { if ((size_t)m_ptr < (size_t)other.m_ptr) return true; diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index f78fddea7f..be40234692 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -130,7 +130,7 @@ CommandCost CmdDecreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint * In case of an unsafe unpause, we want the * user to confirm that it might crash. * @param w unused - * @param confirmed whether the user confirms his/her action + * @param confirmed whether the user confirmed their action */ static void AskUnsafeUnpauseCallback(Window *w, bool confirmed) { diff --git a/src/music/CMakeLists.txt b/src/music/CMakeLists.txt index b20f8aaf7c..8f87a9c936 100644 --- a/src/music/CMakeLists.txt +++ b/src/music/CMakeLists.txt @@ -34,7 +34,7 @@ if(NOT OPTION_DEDICATED) add_files( bemidi.cpp bemidi.h - CONDITION OPTION_HAIKU + CONDITION HAIKU ) add_files( diff --git a/src/music/bemidi.cpp b/src/music/bemidi.cpp index 4175f526b0..3e4f5b311c 100644 --- a/src/music/bemidi.cpp +++ b/src/music/bemidi.cpp @@ -13,14 +13,8 @@ #include "../base_media_base.h" #include "midifile.hpp" -/* BeOS System Includes */ -#include - #include "../safeguards.h" -/** The file we're playing. */ -static BMidiSynthFile midiSynthFile; - /** Factory for BeOS' midi player. */ static FMusicDriver_BeMidi iFMusicDriver_BeMidi; @@ -31,7 +25,7 @@ const char *MusicDriver_BeMidi::Start(const StringList &parm) void MusicDriver_BeMidi::Stop() { - midiSynthFile.UnloadFile(); + this->StopSong(); } void MusicDriver_BeMidi::PlaySong(const MusicSongInfo &song) @@ -39,25 +33,44 @@ void MusicDriver_BeMidi::PlaySong(const MusicSongInfo &song) std::string filename = MidiFile::GetSMFFile(song); this->Stop(); + this->midi_synth_file = new BMidiSynthFile(); if (!filename.empty()) { entry_ref midiRef; get_ref_for_path(filename.c_str(), &midiRef); - midiSynthFile.LoadFile(&midiRef); - midiSynthFile.Start(); + if (this->midi_synth_file->LoadFile(&midiRef) == B_OK) { + this->midi_synth_file->SetVolume(this->current_volume); + this->midi_synth_file->Start(); + this->just_started = true; + } else { + this->Stop(); + } } } void MusicDriver_BeMidi::StopSong() { - midiSynthFile.UnloadFile(); + /* Reusing BMidiSynthFile can cause stuck notes when switching + * tracks, just delete whole object entirely. */ + delete this->midi_synth_file; + this->midi_synth_file = nullptr; } bool MusicDriver_BeMidi::IsSongPlaying() { - return !midiSynthFile.IsFinished(); + if (this->midi_synth_file == nullptr) return false; + + /* IsFinished() returns true for a moment after Start() + * but before it really starts playing, use just_started flag + * to prevent accidental track skipping. */ + if (this->just_started) { + if (!this->midi_synth_file->IsFinished()) this->just_started = false; + return true; + } + return !this->midi_synth_file->IsFinished(); } void MusicDriver_BeMidi::SetVolume(byte vol) { - fprintf(stderr, "BeMidi: Set volume not implemented\n"); + this->current_volume = vol / 128.0; + if (this->midi_synth_file != nullptr) this->midi_synth_file->SetVolume(this->current_volume); } diff --git a/src/music/bemidi.h b/src/music/bemidi.h index 8e96acc8d7..c4ab1f3599 100644 --- a/src/music/bemidi.h +++ b/src/music/bemidi.h @@ -12,6 +12,9 @@ #include "music_driver.hpp" +/* For BMidiSynthFile */ +#include + /** The midi player for BeOS. */ class MusicDriver_BeMidi : public MusicDriver { public: @@ -27,6 +30,11 @@ public: void SetVolume(byte vol) override; const char *GetName() const override { return "bemidi"; } + +private: + BMidiSynthFile *midi_synth_file = nullptr; + double current_volume = 1.0; + bool just_started = false; }; /** Factory for the BeOS midi player. */ diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp index 6120ece09c..0807f427fd 100644 --- a/src/network/core/address.cpp +++ b/src/network/core/address.cpp @@ -180,7 +180,7 @@ bool NetworkAddress::IsInNetmask(const char *netmask) int tmp_cidr = atoi(chr_cidr + 1); /* Invalid CIDR, treat as single host */ - if (tmp_cidr > 0 || tmp_cidr < cidr) cidr = tmp_cidr; + if (tmp_cidr > 0 && tmp_cidr < cidr) cidr = tmp_cidr; /* Remove the / so that NetworkAddress works on the IP portion */ std::string ip_str(netmask, chr_cidr - netmask); diff --git a/src/network/core/core.h b/src/network/core/core.h index a16ed9f23b..3e470ef5f1 100644 --- a/src/network/core/core.h +++ b/src/network/core/core.h @@ -40,7 +40,9 @@ struct Packet; * SocketHandler for all network sockets in OpenTTD. */ class NetworkSocketHandler { +private: bool has_quit; ///< Whether the current client has quit/send a bad packet + public: /** Create a new unbound socket */ NetworkSocketHandler() { this->has_quit = false; } @@ -49,12 +51,13 @@ public: virtual ~NetworkSocketHandler() {} /** - * Close the current connection; for TCP this will be mostly equivalent - * to Close(), but for UDP it just means the packet has to be dropped. - * @param error Whether we quit under an error condition or not. - * @return new status of the connection. + * Mark the connection as closed. + * + * This doesn't mean the actual connection is closed, but just that we + * act like it is. This is useful for UDP, which doesn't normally close + * a socket, but its handler might need to pretend it does. */ - virtual NetworkRecvStatus CloseConnection(bool error = true) { this->has_quit = true; return NETWORK_RECV_STATUS_OKAY; } + void MarkClosed() { this->has_quit = true; } /** * Whether the current client connected to the socket has quit. diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp index d85d512b46..dcba625e12 100644 --- a/src/network/core/game_info.cpp +++ b/src/network/core/game_info.cpp @@ -128,7 +128,7 @@ void CheckGameCompatibility(NetworkGameInfo &ngi, bool extended) */ void FillStaticNetworkServerGameInfo() { - _network_game_info.use_password = !StrEmpty(_settings_client.network.server_password); + _network_game_info.use_password = !_settings_client.network.server_password.empty(); _network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); _network_game_info.clients_max = _settings_client.network.max_clients; _network_game_info.companies_max = _settings_client.network.max_companies; diff --git a/src/network/core/host.cpp b/src/network/core/host.cpp index d40651f132..65a54b358b 100644 --- a/src/network/core/host.cpp +++ b/src/network/core/host.cpp @@ -20,72 +20,7 @@ */ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast); -#if defined(__HAIKU__) /* doesn't have neither getifaddrs or net/if.h */ -/* Based on Andrew Bachmann's netstat+.c. Big thanks to him! */ -extern "C" int _netstat(int fd, char **output, int verbose); - -int seek_past_header(char **pos, const char *header) -{ - char *new_pos = strstr(*pos, header); - if (new_pos == 0) { - return B_ERROR; - } - *pos += strlen(header) + new_pos - *pos + 1; - return B_OK; -} - -static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // BEOS implementation -{ - int sock = socket(AF_INET, SOCK_DGRAM, 0); - - if (sock < 0) { - DEBUG(net, 0, "Could not create socket: %s", NetworkError::GetLast().AsString()); - return; - } - - char *output_pointer = nullptr; - int output_length = _netstat(sock, &output_pointer, 1); - if (output_length < 0) { - DEBUG(net, 0, "Error running _netstat()"); - return; - } - - char **output = &output_pointer; - if (seek_past_header(output, "IP Interfaces:") == B_OK) { - for (;;) { - uint32 n; - int fields, read; - uint8 i1, i2, i3, i4, j1, j2, j3, j4; - uint32 ip; - uint32 netmask; - - fields = sscanf(*output, "%u: %hhu.%hhu.%hhu.%hhu, netmask %hhu.%hhu.%hhu.%hhu%n", - &n, &i1, &i2, &i3, &i4, &j1, &j2, &j3, &j4, &read); - read += 1; - if (fields != 9) { - break; - } - - ip = (uint32)i1 << 24 | (uint32)i2 << 16 | (uint32)i3 << 8 | (uint32)i4; - netmask = (uint32)j1 << 24 | (uint32)j2 << 16 | (uint32)j3 << 8 | (uint32)j4; - - if (ip != INADDR_LOOPBACK && ip != INADDR_ANY) { - sockaddr_storage address; - memset(&address, 0, sizeof(address)); - ((sockaddr_in*)&address)->sin_addr.s_addr = htonl(ip | ~netmask); - NetworkAddress addr(address, sizeof(sockaddr)); - if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const& elem) -> bool { return elem == addr; })) broadcast->push_back(addr); - } - if (read < 0) { - break; - } - *output += read; - } - closesocket(sock); - } -} - -#elif defined(HAVE_GETIFADDRS) +#if defined(HAVE_GETIFADDRS) static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // GETIFADDRS implementation { struct ifaddrs *ifap, *ifa; diff --git a/src/network/core/os_abstraction.h b/src/network/core/os_abstraction.h index ecbc6f3240..9f812ee459 100644 --- a/src/network/core/os_abstraction.h +++ b/src/network/core/os_abstraction.h @@ -124,6 +124,13 @@ typedef unsigned long in_addr_t; # undef FD_SETSIZE # define FD_SETSIZE 64 # endif + +/* Haiku says it supports FD_SETSIZE fds, but it really only supports 512. */ +# if defined(__HAIKU__) +# undef FD_SETSIZE +# define FD_SETSIZE 512 +# endif + #endif /* UNIX */ /* OS/2 stuff */ diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index 05e9316fc0..21f50503c5 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -224,7 +224,7 @@ bool Packet::CanReadFromPacket(size_t bytes_to_read, bool close_connection) /* Check if variable is within packet-size */ if (this->pos + bytes_to_read > this->Size()) { - if (close_connection) this->cs->NetworkSocketHandler::CloseConnection(); + if (close_connection) this->cs->NetworkSocketHandler::MarkClosed(); return false; } @@ -381,14 +381,13 @@ uint64 Packet::Recv_uint64() */ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings settings) { - PacketSize pos; char *bufp = buffer; const char *last = buffer + size - 1; /* Don't allow reading from a closed socket */ if (cs->HasClientQuit()) return; - pos = this->pos; + size_t pos = this->pos; while (--size > 0 && pos < this->Size() && (*buffer++ = this->buffer[pos++]) != '\0') {} if (size == 0 || pos == this->Size()) { @@ -398,7 +397,9 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set while (pos < this->Size() && this->buffer[pos] != '\0') pos++; pos++; } - this->pos = pos; + + assert(pos <= std::numeric_limits::max()); + this->pos = static_cast(pos); str_validate(bufp, last, settings); } diff --git a/src/network/core/tcp.cpp b/src/network/core/tcp.cpp index a98659113b..7cc8f9b957 100644 --- a/src/network/core/tcp.cpp +++ b/src/network/core/tcp.cpp @@ -28,21 +28,42 @@ NetworkTCPSocketHandler::NetworkTCPSocketHandler(SOCKET s) : NetworkTCPSocketHandler::~NetworkTCPSocketHandler() { - /* Virtual functions get called statically in destructors, so make it explicit to remove any confusion. */ - this->NetworkTCPSocketHandler::CloseConnection(); + this->EmptyPacketQueue(); + this->CloseSocket(); +} + +/** + * Free all pending and partially received packets. + */ +void NetworkTCPSocketHandler::EmptyPacketQueue() +{ + this->packet_queue.clear(); + this->packet_recv.reset(); +} +/** + * Close the actual socket of the connection. + * Please make sure CloseConnection is called before CloseSocket, as + * otherwise not all resources might be released. + */ +void NetworkTCPSocketHandler::CloseSocket() +{ if (this->sock != INVALID_SOCKET) closesocket(this->sock); this->sock = INVALID_SOCKET; } +/** + * This will put this socket handler in a close state. It will not + * actually close the OS socket; use CloseSocket for this. + * @param error Whether we quit under an error condition or not. + * @return new status of the connection. + */ NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection(bool error) { + this->MarkClosed(); this->writable = false; - NetworkSocketHandler::CloseConnection(error); - /* Free all pending and partially received packets */ - this->packet_queue.clear(); - this->packet_recv.reset(); + this->EmptyPacketQueue(); return NETWORK_RECV_STATUS_OKAY; } diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h index 39ab0001e4..1348039a91 100644 --- a/src/network/core/tcp.h +++ b/src/network/core/tcp.h @@ -35,6 +35,8 @@ class NetworkTCPSocketHandler : public NetworkSocketHandler { private: std::deque> packet_queue; ///< Packets that are awaiting delivery std::unique_ptr packet_recv; ///< Partially received packet + + void EmptyPacketQueue(); public: SOCKET sock; ///< The socket currently connected to bool writable; ///< Can we write to this socket? @@ -45,7 +47,9 @@ public: */ bool IsConnected() const { return this->sock != INVALID_SOCKET; } - NetworkRecvStatus CloseConnection(bool error = true) override; + virtual NetworkRecvStatus CloseConnection(bool error = true); + void CloseSocket(); + void SendPacket(std::unique_ptr packet); void SendPrependPacket(std::unique_ptr packet, int queue_after_packet_type); diff --git a/src/network/core/tcp_admin.cpp b/src/network/core/tcp_admin.cpp index 9c23278350..fe19622f78 100644 --- a/src/network/core/tcp_admin.cpp +++ b/src/network/core/tcp_admin.cpp @@ -34,10 +34,6 @@ NetworkAdminSocketHandler::NetworkAdminSocketHandler(SOCKET s) : status(ADMIN_ST this->admin_version[0] = '\0'; } -NetworkAdminSocketHandler::~NetworkAdminSocketHandler() -{ -} - NetworkRecvStatus NetworkAdminSocketHandler::CloseConnection(bool error) { delete this; diff --git a/src/network/core/tcp_admin.h b/src/network/core/tcp_admin.h index e5bcefa86f..8b4a738bfa 100644 --- a/src/network/core/tcp_admin.h +++ b/src/network/core/tcp_admin.h @@ -482,7 +482,6 @@ public: NetworkRecvStatus CloseConnection(bool error = true) override; NetworkAdminSocketHandler(SOCKET s); - ~NetworkAdminSocketHandler(); NetworkRecvStatus ReceivePackets(); diff --git a/src/network/core/tcp_content.cpp b/src/network/core/tcp_content.cpp index 2531efd185..fa39d8a958 100644 --- a/src/network/core/tcp_content.cpp +++ b/src/network/core/tcp_content.cpp @@ -137,17 +137,6 @@ const char *ContentInfo::GetTextfile(TextfileType type) const return ::GetTextfile(type, GetContentInfoSubDir(this->type), tmp); } -/** - * Close the actual socket. - */ -void NetworkContentSocketHandler::CloseSocket() -{ - if (this->sock == INVALID_SOCKET) return; - - closesocket(this->sock); - this->sock = INVALID_SOCKET; -} - /** * Handle the given packet, i.e. pass it to the right * parser receive command. diff --git a/src/network/core/tcp_content.h b/src/network/core/tcp_content.h index 44ede71c85..00e58d6f07 100644 --- a/src/network/core/tcp_content.h +++ b/src/network/core/tcp_content.h @@ -21,8 +21,6 @@ /** Base socket handler for all Content TCP sockets */ class NetworkContentSocketHandler : public NetworkTCPSocketHandler { protected: - void CloseSocket(); - bool ReceiveInvalidPacket(PacketContentType type); /** diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index 8618574d3d..584c9cea1e 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.h @@ -310,7 +310,7 @@ protected: virtual NetworkRecvStatus Receive_SERVER_SETTINGS_ACCESS(Packet *p); /** - * The client is joined and ready to receive his map: + * The client is joined and ready to receive their map: * uint32 Own client ID. * uint32 Generation seed. * string Network ID of the server. diff --git a/src/network/core/tcp_http.cpp b/src/network/core/tcp_http.cpp index 2e9081f1e2..b22de91022 100644 --- a/src/network/core/tcp_http.cpp +++ b/src/network/core/tcp_http.cpp @@ -68,17 +68,18 @@ NetworkHTTPSocketHandler::NetworkHTTPSocketHandler(SOCKET s, /** Free whatever needs to be freed. */ NetworkHTTPSocketHandler::~NetworkHTTPSocketHandler() { - this->CloseConnection(); + this->CloseSocket(); - if (this->sock != INVALID_SOCKET) closesocket(this->sock); - this->sock = INVALID_SOCKET; free(this->data); } -NetworkRecvStatus NetworkHTTPSocketHandler::CloseConnection(bool error) +/** + * Close the actual socket of the connection. + */ +void NetworkHTTPSocketHandler::CloseSocket() { - NetworkSocketHandler::CloseConnection(error); - return NETWORK_RECV_STATUS_OKAY; + if (this->sock != INVALID_SOCKET) closesocket(this->sock); + this->sock = INVALID_SOCKET; } /** @@ -313,7 +314,7 @@ int NetworkHTTPSocketHandler::Receive() if (ret < 0) cur->callback->OnFailure(); if (ret <= 0) { /* Then... the connection can be closed */ - cur->CloseConnection(); + cur->CloseSocket(); iter = _http_connections.erase(iter); delete cur; continue; diff --git a/src/network/core/tcp_http.h b/src/network/core/tcp_http.h index d7be0c327b..da7a04ac48 100644 --- a/src/network/core/tcp_http.h +++ b/src/network/core/tcp_http.h @@ -58,7 +58,7 @@ public: return this->sock != INVALID_SOCKET; } - NetworkRecvStatus CloseConnection(bool error = true) override; + void CloseSocket(); NetworkHTTPSocketHandler(SOCKET sock, HTTPCallback *callback, const char *host, const char *url, const char *data, int depth); diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index 3202e6f539..52caa7af09 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -46,7 +46,7 @@ NetworkUDPSocketHandler::NetworkUDPSocketHandler(NetworkAddressList *bind) bool NetworkUDPSocketHandler::Listen() { /* Make sure socket is closed */ - this->Close(); + this->CloseSocket(); for (NetworkAddress &addr : this->bind) { addr.Listen(SOCK_DGRAM, &this->sockets); @@ -56,9 +56,9 @@ bool NetworkUDPSocketHandler::Listen() } /** - * Close the given UDP socket + * Close the actual UDP socket. */ -void NetworkUDPSocketHandler::Close() +void NetworkUDPSocketHandler::CloseSocket() { for (auto &s : this->sockets) { closesocket(s.second); @@ -66,12 +66,6 @@ void NetworkUDPSocketHandler::Close() this->sockets.clear(); } -NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection(bool error) -{ - NetworkSocketHandler::CloseConnection(error); - return NETWORK_RECV_STATUS_OKAY; -} - /** * Send a packet over UDP * @param p the packet to send diff --git a/src/network/core/udp.h b/src/network/core/udp.h index 07ab04986f..2270434392 100644 --- a/src/network/core/udp.h +++ b/src/network/core/udp.h @@ -66,8 +66,6 @@ protected: }; std::vector fragments; - NetworkRecvStatus CloseConnection(bool error = true) override; - void ReceiveInvalidPacket(PacketUDPType, NetworkAddress *client_addr); /** @@ -208,10 +206,10 @@ public: NetworkUDPSocketHandler(NetworkAddressList *bind = nullptr); /** On destructing of this class, the socket needs to be closed */ - virtual ~NetworkUDPSocketHandler() { this->Close(); } + virtual ~NetworkUDPSocketHandler() { this->CloseSocket(); } bool Listen(); - void Close(); + void CloseSocket(); void SendPacket(Packet *p, NetworkAddress *recv, bool all = false, bool broadcast = false, bool short_mtu = false); void ReceivePackets(); diff --git a/src/network/network.cpp b/src/network/network.cpp index 2cc00b32bf..3337f94419 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -35,6 +35,8 @@ #include "../error.h" #include "../core/checksum_func.hpp" #include +#include +#include #include "../safeguards.h" @@ -158,9 +160,9 @@ byte NetworkSpectatorCount() * @param password The unhashed password we like to set ('*' or '' resets the password) * @return The password. */ -const char *NetworkChangeCompanyPassword(CompanyID company_id, const char *password) +std::string NetworkChangeCompanyPassword(CompanyID company_id, std::string password) { - if (strcmp(password, "*") == 0) password = ""; + if (password.compare("*") == 0) password = ""; if (_network_server) { NetworkServerSetCompanyPassword(company_id, password, false); @@ -178,33 +180,35 @@ const char *NetworkChangeCompanyPassword(CompanyID company_id, const char *passw * @param password_game_seed Game seed. * @return The hashed password. */ -const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed) +std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32 password_game_seed) { - if (StrEmpty(password)) return password; + if (password.empty()) return password; - char salted_password[NETWORK_SERVER_ID_LENGTH]; - size_t password_length = strlen(password); - size_t password_server_id_length = strlen(password_server_id); + size_t password_length = password.size(); + size_t password_server_id_length = password_server_id.size(); - /* Add the game seed and the server's ID as the salt. */ + std::ostringstream salted_password; + /* Add the password with the server's ID and game seed as the salt. */ for (uint i = 0; i < NETWORK_SERVER_ID_LENGTH - 1; i++) { char password_char = (i < password_length ? password[i] : 0); char server_id_char = (i < password_server_id_length ? password_server_id[i] : 0); char seed_char = password_game_seed >> (i % 32); - salted_password[i] = password_char ^ server_id_char ^ seed_char; + salted_password << (char)(password_char ^ server_id_char ^ seed_char); // Cast needed, otherwise interpreted as integer to format } Md5 checksum; uint8 digest[16]; - static char hashed_password[NETWORK_SERVER_ID_LENGTH]; /* Generate the MD5 hash */ - checksum.Append(salted_password, sizeof(salted_password) - 1); + std::string salted_password_string = salted_password.str(); + checksum.Append(salted_password_string.data(), salted_password_string.size()); checksum.Finish(digest); - for (int di = 0; di < 16; di++) seprintf(hashed_password + di * 2, lastof(hashed_password), "%02x", digest[di]); + std::ostringstream hashed_password; + hashed_password << std::hex << std::setfill('0'); + for (int di = 0; di < 16; di++) hashed_password << std::setw(2) << (int)digest[di]; // Cast needed, otherwise interpreted as character to add - return hashed_password; + return hashed_password.str(); } /** @@ -220,8 +224,10 @@ bool NetworkCompanyIsPassworded(CompanyID company_id) /* This puts a text-message to the console, or in the future, the chat-box, * (to keep it all a bit more general) * If 'self_send' is true, this is the client who is sending the message */ -void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const char *name, const char *str, NetworkTextMessageData data) +void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const std::string &name, const std::string &str, NetworkTextMessageData data) { + SetDParamStr(0, name); + char message_src[256]; StringID strid; switch (action) { @@ -250,10 +256,9 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, case NETWORK_ACTION_NAME_CHANGE: strid = STR_NETWORK_MESSAGE_NAME_CHANGE; break; case NETWORK_ACTION_GIVE_MONEY: { - SetDParamStr(0, name); SetDParam(1, data.auxdata >> 16); GetString(message_src, STR_NETWORK_MESSAGE_MONEY_GIVE_SRC_DESCRIPTION, lastof(message_src)); - name = message_src; + SetDParamStr(0, message_src); extern byte GetCurrentGrfLangID(); byte lang_id = GetCurrentGrfLangID(); @@ -275,7 +280,6 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, } char message[1024]; - SetDParamStr(0, name); SetDParamStr(1, str); SetDParam(2, data.data); @@ -295,8 +299,8 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, uint NetworkCalculateLag(const NetworkClientSocket *cs) { int lag = cs->last_frame_server - cs->last_frame; - /* This client has missed his ACK packet after 1 DAY_TICKS.. - * so we increase his lag for every frame that passes! + /* This client has missed their ACK packet after 1 DAY_TICKS.. + * so we increase their lag for every frame that passes! * The packet can be out by a max of _net_frame_freq */ if (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq < _frame_counter) { lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq); @@ -393,9 +397,7 @@ void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode) str = paused ? STR_NETWORK_SERVER_MESSAGE_GAME_PAUSED : STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED; } - char buffer[DRAW_STRING_BUFFER]; - GetString(buffer, str, lastof(buffer)); - NetworkTextMessage(NETWORK_ACTION_SERVER_MESSAGE, CC_DEFAULT, false, nullptr, buffer); + NetworkTextMessage(NETWORK_ACTION_SERVER_MESSAGE, CC_DEFAULT, false, "", GetString(str)); break; } @@ -627,7 +629,7 @@ void NetworkClose(bool close_admins) NetworkFreeLocalCommandQueue(); - free(_network_company_states); + delete[] _network_company_states; _network_company_states = nullptr; InitializeNetworkPools(close_admins); @@ -710,7 +712,7 @@ public: }; /** - * Query a server to fetch his game-info for the lobby. + * Query a server to fetch the game-info for the lobby. * @param connection_string the address to query. */ void NetworkQueryLobbyServer(const std::string &connection_string) @@ -817,7 +819,7 @@ public: * @param join_company_password The password for the company. * @return Whether the join has started. */ -bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const char *join_server_password, const char *join_company_password) +bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password, const std::string &join_company_password) { CompanyID join_as = default_company; std::string resolved_connection_string = ParseGameConnectionString(connection_string, NETWORK_DEFAULT_PORT, &join_as).GetAddressAsString(false); @@ -854,7 +856,7 @@ void NetworkClientJoinGame() NetworkDisconnect(); NetworkInitialize(); - strecpy(_settings_client.network.last_joined, _network_join.connection_string.c_str(), lastof(_settings_client.network.last_joined)); + _settings_client.network.last_joined = _network_join.connection_string; _network_join_status = NETWORK_JOIN_STATUS_CONNECTING; ShowJoinStatusWindow(); @@ -863,8 +865,8 @@ void NetworkClientJoinGame() static void NetworkInitGameInfo() { - if (StrEmpty(_settings_client.network.server_name)) { - strecpy(_settings_client.network.server_name, "Unnamed Server", lastof(_settings_client.network.server_name)); + if (_settings_client.network.server_name.empty()) { + _settings_client.network.server_name = "Unnamed Server"; } FillStaticNetworkServerGameInfo(); @@ -876,7 +878,7 @@ static void NetworkInitGameInfo() NetworkClientInfo *ci = new NetworkClientInfo(CLIENT_ID_SERVER); ci->client_playas = _network_dedicated ? COMPANY_SPECTATOR : GetDefaultLocalCompany(); - strecpy(ci->client_name, _settings_client.network.client_name, lastof(ci->client_name)); + ci->client_name = _settings_client.network.client_name; } /** @@ -887,16 +889,16 @@ static void NetworkInitGameInfo() */ static void CheckClientAndServerName() { - static const char *fallback_client_name = "Unnamed Client"; - if (StrEmpty(_settings_client.network.client_name) || strcmp(_settings_client.network.client_name, fallback_client_name) == 0) { - DEBUG(net, 1, "No \"client_name\" has been set, using \"%s\" instead. Please set this now using the \"name \" command", fallback_client_name); - strecpy(_settings_client.network.client_name, fallback_client_name, lastof(_settings_client.network.client_name)); + static const std::string fallback_client_name = "Unnamed Client"; + if (_settings_client.network.client_name.empty() || _settings_client.network.client_name.compare(fallback_client_name) == 0) { + DEBUG(net, 1, "No \"client_name\" has been set, using \"%s\" instead. Please set this now using the \"name \" command", fallback_client_name.c_str()); + _settings_client.network.client_name = fallback_client_name; } - static const char *fallback_server_name = "Unnamed Server"; - if (StrEmpty(_settings_client.network.server_name) || strcmp(_settings_client.network.server_name, fallback_server_name) == 0) { - DEBUG(net, 1, "No \"server_name\" has been set, using \"%s\" instead. Please set this now using the \"server_name \" command", fallback_server_name); - strecpy(_settings_client.network.server_name, fallback_server_name, lastof(_settings_client.network.server_name)); + static const std::string fallback_server_name = "Unnamed Server"; + if (_settings_client.network.server_name.empty() || _settings_client.network.server_name.compare(fallback_server_name) == 0) { + DEBUG(net, 1, "No \"server_name\" has been set, using \"%s\" instead. Please set this now using the \"server_name \" command", fallback_server_name.c_str()); + _settings_client.network.server_name = fallback_server_name; } } @@ -917,7 +919,7 @@ bool NetworkServerStart() if (!ServerNetworkGameSocketHandler::Listen(_settings_client.network.server_port)) return false; /* Only listen for admins when the password isn't empty. */ - if (!StrEmpty(_settings_client.network.admin_password)) { + if (!_settings_client.network.admin_password.empty()) { DEBUG(net, 5, "Starting listeners for admins"); if (!ServerNetworkAdminSocketHandler::Listen(_settings_client.network.server_admin_port)) return false; } @@ -926,7 +928,7 @@ bool NetworkServerStart() DEBUG(net, 5, "Starting listeners for incoming server queries"); NetworkUDPServerListen(); - _network_company_states = CallocT(MAX_COMPANIES); + _network_company_states = new NetworkCompanyState[MAX_COMPANIES]; _network_server = true; _networking = true; _frame_counter = 0; @@ -1241,7 +1243,7 @@ static void NetworkGenerateServerId() } /* _settings_client.network.network_id is our id */ - seprintf(_settings_client.network.network_id, lastof(_settings_client.network.network_id), "%s", hex_output); + _settings_client.network.network_id = hex_output; } class TCPNetworkDebugConnecter : TCPConnecter { @@ -1281,7 +1283,7 @@ void NetworkStartUp() _network_need_advertise = true; /* Generate an server id when there is none yet */ - if (StrEmpty(_settings_client.network.network_id)) NetworkGenerateServerId(); + if (_settings_client.network.network_id.empty()) NetworkGenerateServerId(); _network_game_info = {}; diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 7e53a4c0e2..8a284daf38 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -89,7 +89,7 @@ ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler() */ /* static */ bool ServerNetworkAdminSocketHandler::AllowConnection() { - bool accept = !StrEmpty(_settings_client.network.admin_password) && _network_admins_connected < MAX_ADMINS; + bool accept = !_settings_client.network.admin_password.empty() && _network_admins_connected < MAX_ADMINS; /* We can't go over the MAX_ADMINS limit here. However, if we accept * the connection, there has to be space in the pool. */ static_assert(NetworkAdminSocketPool::MAX_SIZE == MAX_ADMINS); @@ -138,11 +138,9 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode er p->Send_uint8(error); this->SendPacket(p); - char str[100]; - StringID strid = GetNetworkErrorMsg(error); - GetString(str, strid, lastof(str)); + std::string error_message = GetString(GetNetworkErrorMsg(error)); - DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name, this->admin_version, str); + DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name, this->admin_version, error_message.c_str()); return this->CloseConnection(true); } @@ -321,20 +319,13 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyNew(CompanyID comp */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company *c) { - char company_name[NETWORK_COMPANY_NAME_LENGTH]; - char manager_name[NETWORK_COMPANY_NAME_LENGTH]; - - SetDParam(0, c->index); - GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); - - SetDParam(0, c->index); - GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name)); - Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_INFO); p->Send_uint8 (c->index); - p->Send_string(company_name); - p->Send_string(manager_name); + SetDParam(0, c->index); + p->Send_string(GetString(STR_COMPANY_NAME)); + SetDParam(0, c->index); + p->Send_string(GetString(STR_PRESIDENT_NAME)); p->Send_uint8 (c->colour); p->Send_bool (NetworkCompanyIsPassworded(c->index)); p->Send_uint32(c->inaugurated_year); @@ -357,20 +348,13 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Company *c) { - char company_name[NETWORK_COMPANY_NAME_LENGTH]; - char manager_name[NETWORK_COMPANY_NAME_LENGTH]; - - SetDParam(0, c->index); - GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); - - SetDParam(0, c->index); - GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name)); - Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_UPDATE); p->Send_uint8 (c->index); - p->Send_string(company_name); - p->Send_string(manager_name); + SetDParam(0, c->index); + p->Send_string(GetString(STR_COMPANY_NAME)); + SetDParam(0, c->index); + p->Send_string(GetString(STR_PRESIDENT_NAME)); p->Send_uint8 (c->colour); p->Send_bool (NetworkCompanyIsPassworded(c->index)); p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy @@ -471,7 +455,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyStats() * @param msg The actual message. * @param data Arbitrary extra data. */ -NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, NetworkTextMessageData data) +NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data) { Packet *p = new Packet(ADMIN_PACKET_SERVER_CHAT); @@ -669,11 +653,10 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet *p) { if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); - char password[NETWORK_PASSWORD_LENGTH]; - p->Recv_string(password, sizeof(password)); + std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH); - if (StrEmpty(_settings_client.network.admin_password) || - strcmp(password, _settings_client.network.admin_password) != 0) { + if (_settings_client.network.admin_password.empty() || + _settings_client.network.admin_password.compare(password) != 0) { /* Password is invalid */ return this->SendError(NETWORK_ERROR_WRONG_PASSWORD); } @@ -793,8 +776,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p) DestType desttype = (DestType)p->Recv_uint8(); int dest = p->Recv_uint32(); - char msg[NETWORK_CHAT_LENGTH]; - p->Recv_string(msg, NETWORK_CHAT_LENGTH); + std::string msg = p->Recv_string(NETWORK_CHAT_LENGTH); switch (action) { case NETWORK_ACTION_CHAT: @@ -926,7 +908,7 @@ void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bc /** * Send chat to the admin network (if they did opt in for the respective update). */ -void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, NetworkTextMessageData data, bool from_admin) +void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data, bool from_admin) { if (from_admin) return; diff --git a/src/network/network_admin.h b/src/network/network_admin.h index 5d6f1cdbc7..009c7fb359 100644 --- a/src/network/network_admin.h +++ b/src/network/network_admin.h @@ -61,7 +61,7 @@ public: NetworkRecvStatus SendCompanyEconomy(); NetworkRecvStatus SendCompanyStats(); - NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, NetworkTextMessageData data); + NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data); NetworkRecvStatus SendRcon(uint16 colour, const char *command); NetworkRecvStatus SendConsole(const char *origin, const char *command); NetworkRecvStatus SendGameScript(const char *json); @@ -106,7 +106,7 @@ void NetworkAdminCompanyInfo(const Company *company, bool new_company); void NetworkAdminCompanyUpdate(const Company *company); void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr); -void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false); +void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false); void NetworkAdminUpdate(AdminUpdateFrequency freq); void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string); void NetworkAdminConsole(const char *origin, const char *string); diff --git a/src/network/network_base.h b/src/network/network_base.h index 9ad0300629..479f340f18 100644 --- a/src/network/network_base.h +++ b/src/network/network_base.h @@ -22,10 +22,10 @@ extern NetworkClientInfoPool _networkclientinfo_pool; /** Container for all information known about a client. */ struct NetworkClientInfo : NetworkClientInfoPool::PoolItem<&_networkclientinfo_pool> { - ClientID client_id; ///< Client identifier (same as ClientState->client_id) - char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< Name of the client - CompanyID client_playas; ///< As which company is this client playing (CompanyID) - Date join_date; ///< Gamedate the client has joined + ClientID client_id; ///< Client identifier (same as ClientState->client_id) + std::string client_name; ///< Name of the client + CompanyID client_playas; ///< As which company is this client playing (CompanyID) + Date join_date; ///< Gamedate the client has joined /** * Create a new client. diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index 2858dc819f..edf79231d1 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.cpp @@ -128,7 +128,7 @@ void NetworkUndrawChatMessage() /* Sometimes we also need to hide the cursor * This is because both textmessage and the cursor take a shot of the * screen before drawing. - * Now the textmessage takes his shot and paints his data before the cursor + * Now the textmessage takes its shot and paints its data before the cursor * does, so in the shot of the cursor is the screen-data of the textmessage * included when the cursor hangs somewhere over the textmessage. To * avoid wrong repaints, we undraw the cursor in that case, and everything @@ -259,9 +259,9 @@ void NetworkDrawChatMessage() * @param type The type of destination. * @param dest The actual destination index. */ -static void SendChat(const char *buf, DestType type, int dest) +static void SendChat(const std::string &buf, DestType type, int dest) { - if (StrEmpty(buf)) return; + if (buf.empty()) return; assert(type >= DESTTYPE_BROADCAST && type <= DESTTYPE_CLIENT); if (!_network_server) { MyClient::SendChat((NetworkAction)(NETWORK_ACTION_CHAT + type), type, dest, buf, NetworkTextMessageData()); @@ -334,7 +334,7 @@ struct NetworkChatWindow : public Window { /* Skip inactive clients */ for (NetworkClientInfo *ci : NetworkClientInfo::Iterate(*item)) { *item = ci->index; - return ci->client_name; + return ci->client_name.c_str(); } *item = MAX_CLIENT_SLOTS; } diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 1f5cc1343e..a582c87ad4 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -166,6 +166,7 @@ ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler() _network_settings_access = false; delete this->savegame; + delete this->GetInfo(); if (this->desync_log_file) { if (!this->server_desync_log.empty()) { @@ -212,7 +213,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvSta this->ReceivePackets(); } - delete this->GetInfo(); delete this; return status; @@ -230,7 +230,7 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res) /* We just want to close the connection.. */ if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) { - this->NetworkSocketHandler::CloseConnection(); + this->NetworkSocketHandler::MarkClosed(); this->CloseConnection(res); _networking = false; @@ -382,7 +382,7 @@ static uint32 _rcon_password_game_seed; /** One bit of 'entropy' used to generate a salt for the settings passwords. */ static uint32 _settings_password_game_seed; /** The other bit of 'entropy' used to generate a salt for the company, server, rcon, and settings passwords. */ -static char _password_server_id[NETWORK_SERVER_ID_LENGTH]; +static std::string _password_server_id; /** Maximum number of companies of the currently joined server. */ static uint8 _network_server_max_companies; @@ -454,7 +454,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendNewGRFsOk() * Set the game password as requested. * @param password The game password. */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const char *password) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const std::string &password) { Packet *p = new Packet(PACKET_CLIENT_GAME_PASSWORD, SHRT_MAX); p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _server_password_game_seed)); @@ -466,7 +466,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const char *p * Set the company password as requested. * @param password The company password. */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const char *password) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const std::string &password) { Packet *p = new Packet(PACKET_CLIENT_COMPANY_PASSWORD, SHRT_MAX); p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _company_password_game_seed)); @@ -478,10 +478,10 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const char * Set the game password as requested. * @param password The game password. */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendSettingsPassword(const char *password) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendSettingsPassword(const std::string &password) { Packet *p = new Packet(PACKET_CLIENT_SETTINGS_PASSWORD, SHRT_MAX); - if (StrEmpty(password)) { + if (password.empty()) { p->Send_string(""); } else { p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _settings_password_game_seed)); @@ -540,7 +540,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCommand(const CommandPacke } /** Send a chat-packet over the network */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data) { if (!my_client) return NETWORK_RECV_STATUS_CLIENT_QUIT; Packet *p = new Packet(PACKET_CLIENT_CHAT, SHRT_MAX); @@ -599,7 +599,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendDesyncMessage(const char * * Tell the server that we like to change the password of the company. * @param password The new password. */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const char *password) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::string &password) { Packet *p = new Packet(PACKET_CLIENT_SET_PASSWORD, SHRT_MAX); @@ -637,7 +637,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit() * @param pass The password for the remote command. * @param command The actual command. */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const char *pass, const char *command) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pass, const char *command) { Packet *p = new Packet(PACKET_CLIENT_RCON, SHRT_MAX); p->Send_string(GenerateCompanyPasswordHash(pass, _password_server_id, _rcon_password_game_seed)); @@ -651,7 +651,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const char *pass, con * @param company The company to move to. * @param password The password of the company to move to. */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, const char *password) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, const std::string &password) { Packet *p = new Packet(PACKET_CLIENT_MOVE, SHRT_MAX); p->Send_uint8(company); @@ -761,7 +761,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_INFO(Pa NetworkCompanyInfo *company_info = GetLobbyCompanyInfo(current); if (company_info == nullptr) return NETWORK_RECV_STATUS_CLOSE_QUERY; - p->Recv_string(company_info->company_name, sizeof(company_info->company_name)); + company_info->company_name = p->Recv_string(NETWORK_COMPANY_NAME_LENGTH); company_info->inaugurated_year = p->Recv_uint32(); company_info->company_value = p->Recv_uint64(); company_info->money = p->Recv_uint64(); @@ -776,7 +776,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_INFO(Pa } company_info->ai = p->Recv_bool(); - p->Recv_string(company_info->clients, sizeof(company_info->clients)); + company_info->clients = p->Recv_string(NETWORK_CLIENTS_LENGTH); SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY); @@ -794,9 +794,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac NetworkClientInfo *ci; ClientID client_id = (ClientID)p->Recv_uint32(); CompanyID playas = (CompanyID)p->Recv_uint8(); - char name[NETWORK_NAME_LENGTH]; - p->Recv_string(name, sizeof(name)); + std::string name = p->Recv_string(NETWORK_NAME_LENGTH); if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET; if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT; @@ -807,7 +806,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac ci = NetworkClientInfo::GetByClientID(client_id); if (ci != nullptr) { - if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) { + if (playas == ci->client_playas && name.compare(ci->client_name) != 0) { /* Client name changed, display the change */ NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, name); } else if (playas != ci->client_playas) { @@ -820,7 +819,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac if (client_id == _network_own_client_id) SetLocalCompany(!Company::IsValidID(playas) ? COMPANY_SPECTATOR : playas); ci->client_playas = playas; - strecpy(ci->client_name, name, lastof(ci->client_name)); + ci->client_name = name; InvalidateWindowData(WC_CLIENT_LIST, 0); @@ -839,7 +838,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac ci->client_playas = playas; if (client_id == _network_own_client_id) this->SetInfo(ci); - strecpy(ci->client_name, name, lastof(ci->client_name)); + ci->client_name = name; InvalidateWindowData(WC_CLIENT_LIST, 0); @@ -888,8 +887,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p if (error < (ptrdiff_t)lengthof(network_error_strings)) err = network_error_strings[error]; /* In case of kicking a client, we assume there is a kick message in the packet if we can read one byte */ if (error == NETWORK_ERROR_KICKED && p->CanReadFromPacket(1)) { - char kick_msg[255]; - p->Recv_string(kick_msg, sizeof(kick_msg)); + std::string kick_msg = p->Recv_string(NETWORK_CHAT_LENGTH); SetDParamStr(0, kick_msg); ShowErrorMessage(err, STR_NETWORK_ERROR_KICK_MESSAGE, WL_CRITICAL); } else { @@ -944,12 +942,11 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_GAME_PASSW this->status = STATUS_AUTH_GAME; _server_password_game_seed = p->Recv_uint32(); - p->Recv_string(_password_server_id, sizeof(_password_server_id)); + _password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH); if (this->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - const char *password = _network_join.server_password; - if (!StrEmpty(password)) { - return SendGamePassword(password); + if (!_network_join.server_password.empty()) { + return SendGamePassword(_network_join.server_password); } ShowNetworkNeedPassword(NETWORK_GAME_PASSWORD); @@ -963,12 +960,11 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PA this->status = STATUS_AUTH_COMPANY; _company_password_game_seed = p->Recv_uint32(); - p->Recv_string(_password_server_id, sizeof(_password_server_id)); + _password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH); if (this->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - const char *password = _network_join.company_password; - if (!StrEmpty(password)) { - return SendCompanyPassword(password); + if (!_network_join.company_password.empty()) { + return SendCompanyPassword(_network_join.company_password); } ShowNetworkNeedPassword(NETWORK_COMPANY_PASSWORD); @@ -988,7 +984,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet _server_password_game_seed = p->Recv_uint32(); _rcon_password_game_seed = p->Recv_uint32(); _settings_password_game_seed = p->Recv_uint32(); - p->Recv_string(_password_server_id, sizeof(_password_server_id)); + _password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH); /* Start receiving the map */ return SendGetMap(); @@ -1184,13 +1180,13 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p) if (this->status == STATUS_CLOSING) return NETWORK_RECV_STATUS_OKAY; if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - char name[NETWORK_NAME_LENGTH], msg[NETWORK_CHAT_LENGTH]; + std::string name; const NetworkClientInfo *ci = nullptr, *ci_to; NetworkAction action = (NetworkAction)p->Recv_uint8(); ClientID client_id = (ClientID)p->Recv_uint32(); bool self_send = p->Recv_bool(); - p->Recv_string(msg, NETWORK_CHAT_LENGTH); + std::string msg = p->Recv_string(NETWORK_CHAT_LENGTH); NetworkTextMessageData data; data.recv(p); @@ -1202,7 +1198,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p) switch (action) { case NETWORK_ACTION_CHAT_CLIENT: /* For speaking to client we need the client-name */ - seprintf(name, lastof(name), "%s", ci_to->client_name); + name = ci_to->client_name; ci = NetworkClientInfo::GetByClientID(_network_own_client_id); break; @@ -1215,7 +1211,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p) StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS; SetDParam(0, ci_to->client_playas); - GetString(name, str, lastof(name)); + name = GetString(str); ci = NetworkClientInfo::GetByClientID(_network_own_client_id); break; } @@ -1224,7 +1220,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p) } } else { /* Display message from somebody else */ - seprintf(name, lastof(name), "%s", ci_to->client_name); + name = ci_to->client_name; ci = ci_to; } @@ -1243,7 +1239,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR_QUIT(Pack NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); if (ci != nullptr) { - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, nullptr, GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8())); + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, "", GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8())); delete ci; } @@ -1269,7 +1265,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p) NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); if (ci != nullptr) { - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, nullptr, STR_NETWORK_MESSAGE_CLIENT_LEAVING); + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, "", STR_NETWORK_MESSAGE_CLIENT_LEAVING); delete ci; } else { DEBUG(net, 1, "Unknown client (%d) is leaving the game", client_id); @@ -1334,10 +1330,9 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_RCON(Packet *p) TextColour colour_code = (TextColour)p->Recv_uint16(); if (!IsValidConsoleColour(colour_code)) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - char rcon_out[NETWORK_RCONCOMMAND_LENGTH]; - p->Recv_string(rcon_out, sizeof(rcon_out)); + std::string rcon_out = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH); - IConsolePrint(colour_code, rcon_out); + IConsolePrint(colour_code, rcon_out.c_str()); return NETWORK_RECV_STATUS_OKAY; } @@ -1472,7 +1467,7 @@ void NetworkClient_Connected() * @param password The password. * @param command The command to execute. */ -void NetworkClientSendRcon(const char *password, const char *command) +void NetworkClientSendRcon(const std::string &password, const char *command) { MyClient::SendRCon(password, command); } @@ -1482,7 +1477,7 @@ void NetworkClientSendRcon(const char *password, const char *command) * @param password The password. * @param command The command to execute. */ -void NetworkClientSendSettingsPassword(const char *password) +void NetworkClientSendSettingsPassword(const std::string &password) { MyClient::SendSettingsPassword(password); } @@ -1493,7 +1488,7 @@ void NetworkClientSendSettingsPassword(const char *password) * @param pass the password, is only checked on the server end if a password is needed. * @return void */ -void NetworkClientRequestMove(CompanyID company_id, const char *pass) +void NetworkClientRequestMove(CompanyID company_id, const std::string &pass) { MyClient::SendMove(company_id, pass); } @@ -1524,10 +1519,10 @@ void NetworkClientsToSpectators(CompanyID cid) * @param client_name The client name to check for validity. * @return True iff the name is valid. */ -bool NetworkIsValidClientName(const char *client_name) +bool NetworkIsValidClientName(const std::string_view client_name) { - if (StrEmpty(client_name)) return false; - if (*client_name == ' ') return false; + if (client_name.empty()) return false; + if (client_name[0] == ' ') return false; return true; } @@ -1546,7 +1541,7 @@ bool NetworkIsValidClientName(const char *client_name) * and trailing spaces. * @return True iff the client name is valid. */ -bool NetworkValidateClientName(char *client_name) +bool NetworkValidateClientName(std::string &client_name) { StrTrimInPlace(client_name); if (NetworkIsValidClientName(client_name)) return true; @@ -1582,13 +1577,16 @@ void NetworkUpdateClientName() if (!NetworkValidateClientName()) return; /* Don't change the name if it is the same as the old name */ - if (strcmp(ci->client_name, _settings_client.network.client_name) != 0) { + if (_settings_client.network.client_name.compare(ci->client_name) != 0) { if (!_network_server) { - MyClient::SendSetName(_settings_client.network.client_name); + MyClient::SendSetName(_settings_client.network.client_name.c_str()); } else { - if (NetworkFindName(_settings_client.network.client_name, lastof(_settings_client.network.client_name))) { - NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, _settings_client.network.client_name); - strecpy(ci->client_name, _settings_client.network.client_name, lastof(ci->client_name)); + /* Copy to a temporary buffer so no #n gets added after our name in the settings when there are duplicate names. */ + char temporary_name[NETWORK_CLIENT_NAME_LENGTH]; + strecpy(temporary_name, _settings_client.network.client_name.c_str(), lastof(temporary_name)); + if (NetworkFindName(temporary_name, lastof(temporary_name))) { + NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name); + ci->client_name = temporary_name; NetworkUpdateClientInfo(CLIENT_ID_SERVER); } } @@ -1603,7 +1601,7 @@ void NetworkUpdateClientName() * @param msg The actual message. * @param data Arbitrary extra data. */ -void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data) +void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data) { MyClient::SendChat(action, type, dest, msg, data); } @@ -1618,7 +1616,7 @@ void NetworkClientSendDesyncMsg(const char *msg) * Set/Reset company password on the client side. * @param password Password to be set. */ -void NetworkClientSetCompanyPassword(const char *password) +void NetworkClientSetCompanyPassword(const std::string &password) { MyClient::SendSetPassword(password); } diff --git a/src/network/network_client.h b/src/network/network_client.h index b7092e824a..97482a12b8 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -104,15 +104,15 @@ public: static NetworkRecvStatus SendQuit(); static NetworkRecvStatus SendAck(); - static NetworkRecvStatus SendGamePassword(const char *password); - static NetworkRecvStatus SendCompanyPassword(const char *password); - static NetworkRecvStatus SendSettingsPassword(const char *password); + static NetworkRecvStatus SendGamePassword(const std::string &password); + static NetworkRecvStatus SendCompanyPassword(const std::string &password); + static NetworkRecvStatus SendSettingsPassword(const std::string &password); - static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data); - static NetworkRecvStatus SendSetPassword(const char *password); + static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data); + static NetworkRecvStatus SendSetPassword(const std::string &password); static NetworkRecvStatus SendSetName(const char *name); - static NetworkRecvStatus SendRCon(const char *password, const char *command); - static NetworkRecvStatus SendMove(CompanyID company, const char *password); + static NetworkRecvStatus SendRCon(const std::string &password, const char *command); + static NetworkRecvStatus SendMove(CompanyID company, const std::string &password); static bool IsConnected(); @@ -127,15 +127,15 @@ public: typedef ClientNetworkGameSocketHandler MyClient; void NetworkClient_Connected(); -void NetworkClientSetCompanyPassword(const char *password); +void NetworkClientSetCompanyPassword(const std::string &password); /** Information required to join a server. */ struct NetworkJoinInfo { - NetworkJoinInfo() : company(COMPANY_SPECTATOR), server_password(nullptr), company_password(nullptr) {} + NetworkJoinInfo() : company(COMPANY_SPECTATOR) {} std::string connection_string; ///< The address of the server to join. CompanyID company; ///< The company to join. - const char *server_password; ///< The password of the server to join. - const char *company_password; ///< The password of the company to join. + std::string server_password; ///< The password of the server to join. + std::string company_password; ///< The password of the company to join. }; extern NetworkJoinInfo _network_join; diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index e6e42d7fce..7cde22cdae 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -79,7 +79,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p) if (!ci->IsValid()) { delete ci; - this->Close(); + this->CloseConnection(); return false; } @@ -512,7 +512,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_CONTENT(Packet *p) p->Recv_string(this->curInfo->filename, lengthof(this->curInfo->filename)); if (!this->BeforeDownload()) { - this->Close(); + this->CloseConnection(); return false; } } else { @@ -521,7 +521,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_CONTENT(Packet *p) if (toRead != 0 && (size_t)p->TransferOut(TransferOutFWrite, this->curFile) != toRead) { DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD); ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD, STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE, WL_ERROR); - this->Close(); + this->CloseConnection(); fclose(this->curFile); this->curFile = nullptr; @@ -805,14 +805,16 @@ void ClientNetworkContentSocketHandler::Connect() /** * Disconnect from the content server. */ -void ClientNetworkContentSocketHandler::Close() +NetworkRecvStatus ClientNetworkContentSocketHandler::CloseConnection(bool error) { - if (this->sock == INVALID_SOCKET) return; + NetworkContentSocketHandler::CloseConnection(); - this->CloseConnection(); - this->CloseSocket(); + if (this->sock == INVALID_SOCKET) return NETWORK_RECV_STATUS_OKAY; + this->CloseSocket(); this->OnDisconnect(); + + return NETWORK_RECV_STATUS_OKAY; } /** @@ -824,7 +826,7 @@ void ClientNetworkContentSocketHandler::SendReceive() if (this->sock == INVALID_SOCKET || this->isConnecting) return; if (std::chrono::steady_clock::now() > this->lastActivity + IDLE_TIMEOUT) { - this->Close(); + this->CloseConnection(); return; } @@ -1027,9 +1029,9 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci) /* First check whether anything depends on us */ int sel_count = 0; bool force_selection = false; - for (const ContentInfo *ci : parents) { - if (ci->IsSelected()) sel_count++; - if (ci->state == ContentInfo::SELECTED) force_selection = true; + for (const ContentInfo *parent_ci : parents) { + if (parent_ci->IsSelected()) sel_count++; + if (parent_ci->state == ContentInfo::SELECTED) force_selection = true; } if (sel_count == 0) { /* Nothing depends on us */ @@ -1044,8 +1046,8 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci) this->ReverseLookupTreeDependency(parents, c); /* Is there anything that is "force" selected?, if so... we're done. */ - for (const ContentInfo *ci : parents) { - if (ci->state != ContentInfo::SELECTED) continue; + for (const ContentInfo *parent_ci : parents) { + if (parent_ci->state != ContentInfo::SELECTED) continue; force_selection = true; break; diff --git a/src/network/network_content.h b/src/network/network_content.h index 2f699398e3..c5de5dbe0f 100644 --- a/src/network/network_content.h +++ b/src/network/network_content.h @@ -110,7 +110,7 @@ public: void Connect(); void SendReceive(); - void Close(); + NetworkRecvStatus CloseConnection(bool error = true) override; void RequestContentList(ContentType type); void RequestContentList(uint count, const ContentID *content_ids); diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 0cd711877d..dd9590e99c 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -260,7 +260,7 @@ public: { if (widget == WID_NCDS_CANCELOK) { if (this->downloaded_bytes != this->total_bytes) { - _network_content_client.Close(); + _network_content_client.CloseConnection(); delete this; } else { /* If downloading succeeded, close the online content window. This will close diff --git a/src/network/network_func.h b/src/network/network_func.h index f76116083c..377effb30d 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -35,12 +35,12 @@ extern StringList _network_host_list; extern StringList _network_ban_list; byte NetworkSpectatorCount(); -bool NetworkIsValidClientName(const char *client_name); +bool NetworkIsValidClientName(const std::string_view client_name); bool NetworkValidateClientName(); -bool NetworkValidateClientName(char *client_name); +bool NetworkValidateClientName(std::string &client_name); void NetworkUpdateClientName(); bool NetworkCompanyHasClients(CompanyID company); -const char *NetworkChangeCompanyPassword(CompanyID company_id, const char *password); +std::string NetworkChangeCompanyPassword(CompanyID company_id, std::string password); void NetworkReboot(); void NetworkDisconnect(bool blocking = false, bool close_admins = true); void NetworkGameLoop(); @@ -51,12 +51,12 @@ void NetworkPopulateCompanyStats(NetworkCompanyStats *stats); void NetworkUpdateClientInfo(ClientID client_id); void NetworkClientsToSpectators(CompanyID cid); -bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const char *join_server_password = nullptr, const char *join_company_password = nullptr); +bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password = "", const std::string &join_company_password = ""); void NetworkClientJoinGame(); -void NetworkClientRequestMove(CompanyID company, const char *pass = ""); -void NetworkClientSendRcon(const char *password, const char *command); -void NetworkClientSendSettingsPassword(const char *password); -void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data = NetworkTextMessageData()); +void NetworkClientRequestMove(CompanyID company, const std::string &pass = ""); +void NetworkClientSendRcon(const std::string &password, const char *command); +void NetworkClientSendSettingsPassword(const std::string &password); +void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData()); void NetworkClientSendDesyncMsg(const char *msg); bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio); bool NetworkCompanyIsPassworded(CompanyID company_id); @@ -79,7 +79,7 @@ bool NetworkServerChangeClientName(ClientID client_id, const char *new_name); void NetworkServerDoMove(ClientID client_id, CompanyID company_id); void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string); -void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const char *msg, ClientID from_id, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false); +void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, ClientID from_id, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false); void NetworkServerKickClient(ClientID client_id, const char *reason); uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index c15efdeee5..9e66623eec 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -477,7 +477,7 @@ public: this->FinishInitNested(WN_NETWORK_WINDOW_GAME); this->querystrings[WID_NG_CLIENT] = &this->name_editbox; - this->name_editbox.text.Assign(_settings_client.network.client_name); + this->name_editbox.text.Assign(_settings_client.network.client_name.c_str()); this->querystrings[WID_NG_FILTER] = &this->filter_editbox; this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR; @@ -663,7 +663,7 @@ public: DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version y += FONT_HEIGHT_NORMAL; - SetDParamStr(0, sel->connection_string.c_str()); + SetDParamStr(0, sel->connection_string); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_ADDRESS); // server address y += FONT_HEIGHT_NORMAL; @@ -835,7 +835,7 @@ public: case WID_NG_CLIENT: /* Validation of the name will happen once the user tries to join or start a game, as getting * error messages while typing (e.g. when you clear the name) defeats the purpose of the check. */ - strecpy(_settings_client.network.client_name, this->name_editbox.text.buf, lastof(_settings_client.network.client_name)); + _settings_client.network.client_name = this->name_editbox.text.buf; break; } } @@ -843,7 +843,7 @@ public: void OnQueryTextFinished(char *str) override { if (!StrEmpty(str)) { - strecpy(_settings_client.network.connect_to_ip, str, lastof(_settings_client.network.connect_to_ip)); + _settings_client.network.connect_to_ip = str; NetworkAddServer(str); NetworkRebuildHostList(); } @@ -1005,7 +1005,7 @@ struct NetworkStartServerWindow : public Window { this->InitNested(WN_NETWORK_WINDOW_START); this->querystrings[WID_NSS_GAMENAME] = &this->name_editbox; - this->name_editbox.text.Assign(_settings_client.network.server_name); + this->name_editbox.text.Assign(_settings_client.network.server_name.c_str()); this->SetFocusedWidget(WID_NSS_GAMENAME); } @@ -1047,7 +1047,7 @@ struct NetworkStartServerWindow : public Window { switch (widget) { case WID_NSS_SETPWD: /* If password is set, draw red '*' next to 'Set password' button. */ - if (!StrEmpty(_settings_client.network.server_password)) DrawString(r.right + WD_FRAMERECT_LEFT, this->width - WD_FRAMERECT_RIGHT, r.top, "*", TC_RED); + if (!_settings_client.network.server_password.empty()) DrawString(r.right + WD_FRAMERECT_LEFT, this->width - WD_FRAMERECT_RIGHT, r.top, "*", TC_RED); } } @@ -1151,7 +1151,7 @@ struct NetworkStartServerWindow : public Window { void OnEditboxChanged(int wid) override { if (wid == WID_NSS_GAMENAME) { - strecpy(_settings_client.network.server_name, this->name_editbox.text.buf, lastof(_settings_client.network.server_name)); + _settings_client.network.server_name = this->name_editbox.text.buf; } } @@ -1171,7 +1171,7 @@ struct NetworkStartServerWindow : public Window { if (str == nullptr) return; if (this->widget_id == WID_NSS_SETPWD) { - strecpy(_settings_client.network.server_password, str, lastof(_settings_client.network.server_password)); + _settings_client.network.server_password = str; } else { int32 value = atoi(str); this->SetWidgetDirty(this->widget_id); @@ -1298,7 +1298,7 @@ struct NetworkLobbyWindow : public Window { { /* Scroll through all this->company_info and get the 'pos' item that is not empty. */ for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { - if (!StrEmpty(this->company_info[i].company_name)) { + if (!this->company_info[i].company_name.empty()) { if (pos-- == 0) return i; } } @@ -1413,7 +1413,7 @@ struct NetworkLobbyWindow : public Window { GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, PC_DARK_BLUE); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 12, STR_NETWORK_GAME_LOBBY_COMPANY_INFO, TC_FROMSTRING, SA_HOR_CENTER); - if (this->company == INVALID_COMPANY || StrEmpty(this->company_info[this->company].company_name)) return; + if (this->company == INVALID_COMPANY || this->company_info[this->company].company_name.empty()) return; int y = r.top + detail_height + 4; const NetworkGameInfo *gi = &this->server->info; @@ -1571,7 +1571,7 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl) DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_START); DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME); - strecpy(_settings_client.network.last_joined, ngl->connection_string.c_str(), lastof(_settings_client.network.last_joined)); + _settings_client.network.last_joined = ngl->connection_string; NetworkQueryLobbyServer(ngl->connection_string); @@ -2214,19 +2214,16 @@ public: case WID_CL_SERVER_NAME_EDIT: { if (!_network_server) break; - uint index; - GetSettingFromName("network.server_name", &index); - SetSettingValue(index, StrEmpty(str) ? "Unnamed Server" : str); + SetSettingValue(GetSettingFromName("network.server_name"), StrEmpty(str) ? "Unnamed Server" : str); this->InvalidateData(); break; } case WID_CL_CLIENT_NAME_EDIT: { - if (!NetworkValidateClientName(str)) break; + std::string client_name(str); + if (!NetworkValidateClientName(client_name)) break; - uint index; - GetSettingFromName("network.client_name", &index); - SetSettingValue(index, str); + SetSettingValue(GetSettingFromName("network.client_name"), client_name.c_str()); this->InvalidateData(); break; } @@ -2598,7 +2595,7 @@ struct NetworkCompanyPasswordWindow : public Window { void OnOk() { if (this->IsWidgetLowered(WID_NCP_SAVE_AS_DEFAULT_PASSWORD)) { - strecpy(_settings_client.network.default_company_pass, this->password_editbox.text.buf, lastof(_settings_client.network.default_company_pass)); + _settings_client.network.default_company_pass = this->password_editbox.text.buf; } NetworkChangeCompanyPassword(_local_company, this->password_editbox.text.buf); diff --git a/src/network/network_gui.h b/src/network/network_gui.h index 249968abda..b5e834e608 100644 --- a/src/network/network_gui.h +++ b/src/network/network_gui.h @@ -28,14 +28,14 @@ void ShowNetworkCompanyPasswordWindow(Window *parent); /** Company information stored at the client side */ struct NetworkCompanyInfo : NetworkCompanyStats { - char company_name[NETWORK_COMPANY_NAME_LENGTH]; ///< Company name - Year inaugurated_year; ///< What year the company started in - Money company_value; ///< The company value - Money money; ///< The amount of money the company has - Money income; ///< How much did the company earned last year - uint16 performance; ///< What was his performance last month? - bool use_password; ///< Is there a password - char clients[NETWORK_CLIENTS_LENGTH]; ///< The clients that control this company (Name1, name2, ..) + std::string company_name; ///< Company name + Year inaugurated_year; ///< What year the company started in + Money company_value; ///< The company value + Money money; ///< The amount of money the company has + Money income; ///< How much did the company earn last year + uint16 performance; ///< What was his performance last month? + bool use_password; ///< Is there a password + std::string clients; ///< The clients that control this company (Name1, name2, ..) }; NetworkCompanyInfo *GetLobbyCompanyInfo(CompanyID company); diff --git a/src/network/network_internal.h b/src/network/network_internal.h index 7d1b803288..a9beabf745 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -121,11 +121,11 @@ void NetworkFreeLocalCommandQueue(); void NetworkSyncCommandQueue(NetworkClientSocket *cs); void ShowNetworkError(StringID error_string); -void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const char *name, const char *str = "", NetworkTextMessageData data = NetworkTextMessageData()); +void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const std::string &name, const std::string &str = "", NetworkTextMessageData data = NetworkTextMessageData()); uint NetworkCalculateLag(const NetworkClientSocket *cs); StringID GetNetworkErrorMsg(NetworkErrorCode err); bool NetworkFindName(char *new_name, const char *last); -const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed); +std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32 password_game_seed); NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port); std::string NormalizeConnectionString(const std::string &connection_string, uint16 default_port); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index fa2e33a025..64dec9d0d6 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -259,7 +259,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta this->GetClientName(client_name, lastof(client_name)); - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST); + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST); /* Inform other clients of this... strange leaving ;) */ for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { @@ -386,13 +386,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo() NetworkPopulateCompanyStats(company_stats); /* Make a list of all clients per company */ - char clients[MAX_COMPANIES][NETWORK_CLIENTS_LENGTH]; - memset(clients, 0, sizeof(clients)); + std::string clients[MAX_COMPANIES]; /* Add the local player (if not dedicated) */ const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); if (ci != nullptr && Company::IsValidID(ci->client_playas)) { - strecpy(clients[ci->client_playas], ci->client_name, lastof(clients[ci->client_playas])); + clients[ci->client_playas] = ci->client_name; } for (NetworkClientSocket *csi : NetworkClientSocket::Iterate()) { @@ -402,11 +401,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo() ci = csi->GetInfo(); if (ci != nullptr && Company::IsValidID(ci->client_playas)) { - if (!StrEmpty(clients[ci->client_playas])) { - strecat(clients[ci->client_playas], ", ", lastof(clients[ci->client_playas])); + if (!clients[ci->client_playas].empty()) { + clients[ci->client_playas] += ", "; } - strecat(clients[ci->client_playas], client_name, lastof(clients[ci->client_playas])); + clients[ci->client_playas] += client_name; } } @@ -421,7 +420,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo() p->Send_bool (true); this->SendCompanyInformation(p, company, &company_stats[company->index]); - if (StrEmpty(clients[company->index])) { + if (clients[company->index].empty()) { p->Send_string(""); } else { p->Send_string(clients[company->index]); @@ -446,7 +445,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo() */ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const char *reason) { - char str[100]; Packet *p = new Packet(PACKET_SERVER_ERROR, SHRT_MAX); p->Send_uint8(error); @@ -454,7 +452,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err this->SendPacket(p); StringID strid = GetNetworkErrorMsg(error); - GetString(str, strid, lastof(str)); /* Only send when the current client was in game */ if (this->status > STATUS_AUTHORIZED) { @@ -462,12 +459,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err this->GetClientName(client_name, lastof(client_name)); - DEBUG(net, 1, "'%s' made an error and has been disconnected: %s", client_name, str); + DEBUG(net, 1, "'%s' made an error and has been disconnected: %s", client_name, GetString(strid).c_str()); if (error == NETWORK_ERROR_KICKED && reason != nullptr) { NetworkTextMessage(NETWORK_ACTION_KICKED, CC_DEFAULT, false, client_name, reason, strid); } else { - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, strid); + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid); } for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { @@ -483,10 +480,10 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err NetworkAdminClientError(this->client_id, error); } else { - DEBUG(net, 1, "Client %d made an error and has been disconnected: %s", this->client_id, str); + DEBUG(net, 1, "Client %d made an error and has been disconnected: %s", this->client_id, GetString(strid).c_str()); } - /* The client made a mistake, so drop his connection now! */ + /* The client made a mistake, so drop the connection now! */ return this->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR); } @@ -759,7 +756,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCommand(const CommandPacke * @param msg The actual message. * @param data Arbitrary extra data. */ -NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, NetworkTextMessageData data) +NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action, ClientID client_id, bool self_send, const std::string &msg, NetworkTextMessageData data) { if (this->status < STATUS_PRE_ACTIVE) return NETWORK_RECV_STATUS_OKAY; @@ -912,12 +909,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_NEWGRFS_CHECKED NetworkClientInfo *ci = this->GetInfo(); - /* We now want a password from the client else we do not allow him in! */ - if (!StrEmpty(_settings_client.network.server_password)) { + /* We now want a password from the client else we do not allow them in! */ + if (!_settings_client.network.server_password.empty()) { return this->SendNeedGamePassword(); } - if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) { + if (Company::IsValidID(ci->client_playas) && !_network_company_states[ci->client_playas].password.empty()) { return this->SendNeedCompanyPassword(); } @@ -984,7 +981,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p) NetworkClientInfo *ci = new NetworkClientInfo(this->client_id); this->SetInfo(ci); ci->join_date = _date; - strecpy(ci->client_name, name, lastof(ci->client_name)); + ci->client_name = name; ci->client_playas = playas; DEBUG(desync, 1, "client: date{%08x; %02x; %02x}; client: %02x; company: %02x", _date, _date_fract, _tick_skip_counter, (int)ci->index, (int)ci->client_playas); @@ -1007,18 +1004,17 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GAME_PASSWORD(P return this->SendError(NETWORK_ERROR_NOT_EXPECTED); } - char password[NETWORK_PASSWORD_LENGTH]; - p->Recv_string(password, sizeof(password)); + std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH); /* Check game password. Allow joining if we cleared the password meanwhile */ - if (!StrEmpty(_settings_client.network.server_password) && - strcmp(password, GenerateCompanyPasswordHash(_settings_client.network.server_password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed ^ this->server_hash_bits)) != 0) { + if (!_settings_client.network.server_password.empty() && + password != GenerateCompanyPasswordHash(_settings_client.network.server_password.c_str(), _settings_client.network.network_id.c_str(), _settings_game.game_creation.generation_seed ^ this->server_hash_bits)) { /* Password is invalid */ return this->SendError(NETWORK_ERROR_WRONG_PASSWORD); } const NetworkClientInfo *ci = this->GetInfo(); - if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) { + if (Company::IsValidID(ci->client_playas) && !_network_company_states[ci->client_playas].password.empty()) { return this->SendNeedCompanyPassword(); } @@ -1032,15 +1028,14 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWOR return this->SendError(NETWORK_ERROR_NOT_EXPECTED); } - char password[NETWORK_PASSWORD_LENGTH]; - p->Recv_string(password, sizeof(password)); + std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH); /* Check company password. Allow joining if we cleared the password meanwhile. * Also, check the company is still valid - client could be moved to spectators * in the middle of the authorization process */ CompanyID playas = this->GetInfo()->client_playas; - if (Company::IsValidID(playas) && !StrEmpty(_network_company_states[playas].password) && - strcmp(password, _network_company_states[playas].password) != 0) { + if (Company::IsValidID(playas) && !_network_company_states[playas].password.empty() && + _network_company_states[playas].password.compare(password) != 0) { /* Password is invalid */ return this->SendError(NETWORK_ERROR_WRONG_PASSWORD); } @@ -1062,8 +1057,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SETTINGS_PASSWO if (StrEmpty(password)) { if (this->settings_authed) DEBUG(net, 0, "[settings-ctrl] client-id %d deauthed", this->client_id); this->settings_authed = false; - } else if (StrEmpty(_settings_client.network.settings_password) || - strcmp(password, GenerateCompanyPasswordHash(_settings_client.network.settings_password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed ^ this->settings_hash_bits)) != 0) { + } else if (_settings_client.network.settings_password.empty() || + password != GenerateCompanyPasswordHash(_settings_client.network.settings_password.c_str(), _settings_client.network.network_id.c_str(), _settings_game.game_creation.generation_seed ^ this->settings_hash_bits)) { DEBUG(net, 0, "[settings-ctrl] wrong password from client-id %d", this->client_id); NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied"); this->settings_authed = false; @@ -1078,7 +1073,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SETTINGS_PASSWO NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p) { /* The client was never joined.. so this is impossible, right? - * Ignore the packet, give the client a warning, and close his connection */ + * Ignore the packet, give the client a warning, and close the connection */ if (this->status < STATUS_AUTHORIZED || this->HasClientQuit()) { return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED); } @@ -1106,7 +1101,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet * this->GetClientName(client_name, lastof(client_name)); - NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, nullptr, this->client_id); + NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, "", this->client_id); InvalidateWindowData(WC_CLIENT_LIST, 0); /* Mark the client as pre-active, and wait for an ACK @@ -1148,7 +1143,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet * NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet *p) { /* The client was never joined.. so this is impossible, right? - * Ignore the packet, give the client a warning, and close his connection */ + * Ignore the packet, give the client a warning, and close the connection */ if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) { return this->SendError(NETWORK_ERROR_NOT_EXPECTED); } @@ -1214,7 +1209,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p { /* This packets means a client noticed an error and is reporting this * to us. Display the error and report it to the other clients */ - char str[100]; char client_name[NETWORK_CLIENT_NAME_LENGTH]; NetworkErrorCode errorno = (NetworkErrorCode)p->Recv_uint8(); NetworkRecvStatus rx_status = p->CanReadFromPacket(1) ? (NetworkRecvStatus)p->Recv_uint8() : NETWORK_RECV_STATUS_OKAY; @@ -1223,19 +1217,17 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p /* The client was never joined.. thank the client for the packet, but ignore it */ if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) { - if (_debug_net_level >= 2) GetString(str, GetNetworkErrorMsg(errorno), lastof(str)); - DEBUG(net, 2, "non-joined client %d reported an error and is closing its connection (%s) (%d, %d, %d)", this->client_id, str, rx_status, status, last_pkt_type); + DEBUG(net, 2, "non-joined client %d reported an error and is closing its connection (%s) (%d, %d, %d)", this->client_id, GetString(GetNetworkErrorMsg(errorno)).c_str(), rx_status, status, last_pkt_type); return this->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT); } this->GetClientName(client_name, lastof(client_name)); StringID strid = GetNetworkErrorMsg(errorno); - GetString(str, strid, lastof(str)); - DEBUG(net, 1, "'%s' reported an error and is closing its connection (%s) (%d, %d, %d)", client_name, str, rx_status, status, last_pkt_type); + DEBUG(net, 1, "'%s' reported an error and is closing its connection (%s) (%d, %d, %d)", client_name, GetString(strid).c_str(), rx_status, status, last_pkt_type); - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, strid); + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid); for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status >= STATUS_AUTHORIZED) { @@ -1301,7 +1293,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p) this->GetClientName(client_name, lastof(client_name)); - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, STR_NETWORK_MESSAGE_CLIENT_LEAVING); + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", STR_NETWORK_MESSAGE_CLIENT_LEAVING); for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status >= STATUS_AUTHORIZED && new_cs != this) { @@ -1370,7 +1362,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p) * @param data Arbitrary data. * @param from_admin Whether the origin is an admin or not. */ -void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, NetworkTextMessageData data, bool from_admin) +void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const std::string &msg, ClientID from_id, NetworkTextMessageData data, bool from_admin) { const NetworkClientInfo *ci, *ci_own, *ci_to; @@ -1448,10 +1440,9 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co /* Display the message locally (so you know you have sent it) */ if (ci != nullptr && show_local) { if (from_id == CLIENT_ID_SERVER) { - char name[NETWORK_NAME_LENGTH]; StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS; SetDParam(0, ci_to->client_playas); - GetString(name, str, lastof(name)); + std::string name = GetString(str); NetworkTextMessage(action, GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data); } else { for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { @@ -1494,9 +1485,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet *p) NetworkAction action = (NetworkAction)p->Recv_uint8(); DestType desttype = (DestType)p->Recv_uint8(); int dest = p->Recv_uint32(); - char msg[NETWORK_CHAT_LENGTH]; - p->Recv_string(msg, NETWORK_CHAT_LENGTH); + std::string msg = p->Recv_string(NETWORK_CHAT_LENGTH); NetworkTextMessageData data; data.recv(p); @@ -1524,11 +1514,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_PASSWORD(Pa return this->SendError(NETWORK_ERROR_NOT_EXPECTED); } - char password[NETWORK_PASSWORD_LENGTH]; - const NetworkClientInfo *ci; - - p->Recv_string(password, sizeof(password)); - ci = this->GetInfo(); + std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH); + const NetworkClientInfo *ci = this->GetInfo(); NetworkServerSetCompanyPassword(ci->client_playas, password); return NETWORK_RECV_STATUS_OKAY; @@ -1560,7 +1547,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet /* Display change */ if (NetworkFindName(client_name, lastof(client_name))) { NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name); - strecpy(ci->client_name, client_name, lastof(ci->client_name)); + ci->client_name = client_name; NetworkUpdateClientInfo(ci->client_id); } } @@ -1571,18 +1558,17 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p) { if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); - char pass[NETWORK_PASSWORD_LENGTH]; char command[NETWORK_RCONCOMMAND_LENGTH]; - if (StrEmpty(_settings_client.network.rcon_password)) { + if (_settings_client.network.rcon_password.empty()) { NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied"); return NETWORK_RECV_STATUS_OKAY; } - p->Recv_string(pass, sizeof(pass)); + std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH); p->Recv_string(command, sizeof(command)); - if (strcmp(pass, GenerateCompanyPasswordHash(_settings_client.network.rcon_password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed ^ this->rcon_hash_bits)) != 0) { + if (password != GenerateCompanyPasswordHash(_settings_client.network.rcon_password.c_str(), _settings_client.network.network_id.c_str(), _settings_game.game_creation.generation_seed ^ this->rcon_hash_bits)) { DEBUG(net, 0, "[rcon] wrong password from client-id %d", this->client_id); NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied"); return NETWORK_RECV_STATUS_OKAY; @@ -1606,13 +1592,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet *p) if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY; /* Check if we require a password for this company */ - if (company_id != COMPANY_SPECTATOR && !StrEmpty(_network_company_states[company_id].password)) { + if (company_id != COMPANY_SPECTATOR && !_network_company_states[company_id].password.empty()) { /* we need a password from the client - should be in this packet */ - char password[NETWORK_PASSWORD_LENGTH]; - p->Recv_string(password, sizeof(password)); + std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH); /* Incorrect password sent, return! */ - if (strcmp(password, _network_company_states[company_id].password) != 0) { + if (_network_company_states[company_id].password.compare(password) != 0) { DEBUG(net, 2, "Wrong password from client-id #%d for company #%d", this->client_id, company_id + 1); return NETWORK_RECV_STATUS_OKAY; } @@ -1686,7 +1671,7 @@ void NetworkSocketHandler::SendCompanyInformation(Packet *p, const Company *c, c p->Send_uint16(c->old_economy[0].performance_history); /* Send 1 if there is a password for the company else send 0 */ - p->Send_bool (!StrEmpty(_network_company_states[c->index].password)); + p->Send_bool (!_network_company_states[c->index].password.empty()); for (uint i = 0; i < NETWORK_VEH_END; i++) { p->Send_uint16(stats->num_vehicle[i]); @@ -1823,15 +1808,15 @@ static void NetworkAutoCleanCompanies() _network_company_states[c->index].months_empty++; /* Is the company empty for autoclean_unprotected-months, and is there no protection? */ - if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && StrEmpty(_network_company_states[c->index].password)) { + if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) { /* Shut the company down */ DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL); IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1); } /* Is the company empty for autoclean_protected-months, and there is a protection? */ - if (_settings_client.network.autoclean_protected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_protected && !StrEmpty(_network_company_states[c->index].password)) { + if (_settings_client.network.autoclean_protected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_protected && !_network_company_states[c->index].password.empty()) { /* Unprotect the company */ - _network_company_states[c->index].password[0] = '\0'; + _network_company_states[c->index].password.clear(); IConsolePrintF(CC_DEFAULT, "Auto-removed protection from company #%d", c->index + 1); _network_company_states[c->index].months_empty = 0; NetworkServerUpdateCompanyPassworded(c->index, false); @@ -1866,7 +1851,7 @@ bool NetworkFindName(char *new_name, const char *last) while (!found_name) { found_name = true; for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { - if (strcmp(ci->client_name, new_name) == 0) { + if (ci->client_name.compare(new_name) == 0) { /* Name already in use */ found_name = false; break; @@ -1875,7 +1860,7 @@ bool NetworkFindName(char *new_name, const char *last) /* Check if it is the same as the server-name */ const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); if (ci != nullptr) { - if (strcmp(ci->client_name, new_name) == 0) found_name = false; // name already in use + if (ci->client_name.compare(new_name) == 0) found_name = false; // name already in use } if (!found_name) { @@ -1900,7 +1885,7 @@ bool NetworkServerChangeClientName(ClientID client_id, const char *new_name) { /* Check if the name's already in use */ for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { - if (strcmp(ci->client_name, new_name) == 0) return false; + if (ci->client_name.compare(new_name) == 0) return false; } NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); @@ -1908,7 +1893,7 @@ bool NetworkServerChangeClientName(ClientID client_id, const char *new_name) NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, true, ci->client_name, new_name); - strecpy(ci->client_name, new_name, lastof(ci->client_name)); + ci->client_name = new_name; NetworkUpdateClientInfo(client_id); return true; @@ -1920,16 +1905,17 @@ bool NetworkServerChangeClientName(ClientID client_id, const char *new_name) * @param password The new password. * @param already_hashed Is the given password already hashed? */ -void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed) +void NetworkServerSetCompanyPassword(CompanyID company_id, const std::string &password, bool already_hashed) { if (!Company::IsValidHumanID(company_id)) return; - if (!already_hashed) { - password = GenerateCompanyPasswordHash(password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed); + if (already_hashed) { + _network_company_states[company_id].password = password; + } else { + _network_company_states[company_id].password = GenerateCompanyPasswordHash(password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed); } - strecpy(_network_company_states[company_id].password, password, lastof(_network_company_states[company_id].password)); - NetworkServerUpdateCompanyPassworded(company_id, !StrEmpty(_network_company_states[company_id].password)); + NetworkServerUpdateCompanyPassworded(company_id, !_network_company_states[company_id].password.empty()); } /** @@ -2025,7 +2011,7 @@ void NetworkServer_Tick(bool send_frame) * spamming the client. Strictly speaking this variable * tracks when we last received a packet from the client, * but as it is waiting, it will not send us any till we - * start sending him data. */ + * start sending them data. */ cs->last_packet = std::chrono::steady_clock::now(); } break; @@ -2144,7 +2130,7 @@ void NetworkServerShowStatusToConsole() status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown"); IConsolePrintF(CC_INFO, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s", - cs->client_id, ci->client_name, status, lag, + cs->client_id, ci->client_name.c_str(), status, lag, ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0), cs->GetClientIP()); } @@ -2316,10 +2302,10 @@ void ServerNetworkGameSocketHandler::GetClientName(char *client_name, const char { const NetworkClientInfo *ci = this->GetInfo(); - if (ci == nullptr || StrEmpty(ci->client_name)) { + if (ci == nullptr || ci->client_name.empty()) { seprintf(client_name, last, "Client #%4d", this->client_id); } else { - strecpy(client_name, ci->client_name, last); + strecpy(client_name, ci->client_name.c_str(), last); } } @@ -2332,13 +2318,13 @@ void NetworkPrintClients() if (_network_server) { IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d IP: %s", ci->client_id, - ci->client_name, + ci->client_name.c_str(), ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0), ci->client_id == CLIENT_ID_SERVER ? "server" : NetworkClientSocket::GetByClientID(ci->client_id)->GetClientIP()); } else { IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d", ci->client_id, - ci->client_name, + ci->client_name.c_str(), ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0)); } } @@ -2356,14 +2342,14 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci) if (!_network_server) return; _network_company_states[c->index].months_empty = 0; - _network_company_states[c->index].password[0] = '\0'; + _network_company_states[c->index].password.clear(); NetworkServerUpdateCompanyPassworded(c->index, false); if (ci != nullptr) { /* ci is nullptr when replaying, or for AIs. In neither case there is a client. */ ci->client_playas = c->index; NetworkUpdateClientInfo(ci->client_id); - NetworkSendCommand(0, 0, 0, 0, CMD_RENAME_PRESIDENT, nullptr, ci->client_name, c->index, 0); + NetworkSendCommand(0, 0, 0, 0, CMD_RENAME_PRESIDENT, nullptr, ci->client_name.c_str(), c->index, 0); } /* Announce new company on network. */ diff --git a/src/network/network_server.h b/src/network/network_server.h index 9bbd570ee0..950d3b4250 100644 --- a/src/network/network_server.h +++ b/src/network/network_server.h @@ -109,7 +109,7 @@ public: NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci); NetworkRecvStatus SendError(NetworkErrorCode error, const char *reason = nullptr); NetworkRecvStatus SendDesyncLog(const std::string &log); - NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, NetworkTextMessageData data); + NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const std::string &msg, NetworkTextMessageData data); NetworkRecvStatus SendJoin(ClientID client_id); NetworkRecvStatus SendFrame(); NetworkRecvStatus SendSync(); @@ -139,7 +139,7 @@ public: }; void NetworkServer_Tick(bool send_frame); -void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed = true); +void NetworkServerSetCompanyPassword(CompanyID company_id, const std::string &password, bool already_hashed = true); void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded); #endif /* NETWORK_SERVER_H */ diff --git a/src/network/network_type.h b/src/network/network_type.h index c84687db71..cb859e5c58 100644 --- a/src/network/network_type.h +++ b/src/network/network_type.h @@ -62,8 +62,8 @@ struct NetworkCompanyStats { /** Some state information of a company, especially for servers */ struct NetworkCompanyState { - char password[NETWORK_PASSWORD_LENGTH]; ///< The password for the company - uint16 months_empty; ///< How many months the company is empty + std::string password; ///< The password for the company + uint16 months_empty; ///< How many months the company is empty }; struct NetworkClientInfo; diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index a1639e8f83..12e7b95494 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -64,10 +64,10 @@ struct UDPSocket { UDPSocket(const std::string &name_) : name(name_), socket(nullptr) {} - void Close() + void CloseSocket() { std::lock_guard lock(mutex); - socket->Close(); + socket->CloseSocket(); delete socket; socket = nullptr; } @@ -715,9 +715,9 @@ void NetworkUDPServerListen() /** Close all UDP related stuff. */ void NetworkUDPClose() { - _udp_client.Close(); - _udp_server.Close(); - _udp_master.Close(); + _udp_client.CloseSocket(); + _udp_server.CloseSocket(); + _udp_master.CloseSocket(); _network_udp_server = false; _network_udp_broadcast = 0; diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 5454819845..90c3982ede 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -2667,6 +2667,22 @@ static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader return CIR_SUCCESS; } +/** + * Helper to read a DWord worth of bytes from the reader + * and to return it as a valid string. + * @param reader The source of the DWord. + * @return The read DWord as string. + */ +static std::string ReadDWordAsString(ByteReader *reader) +{ + char output[5]; + for (int i = 0; i < 4; i++) output[i] = reader->ReadByte(); + output[4] = '\0'; + str_validate(output, lastof(output)); + + return std::string(output); +} + /** * Define properties for global variables * @param gvid ID of the global variable. @@ -2754,11 +2770,10 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, co case 0x0D: { // Currency prefix symbol uint curidx = GetNewgrfCurrencyIdConverted(gvid + i); - uint32 tempfix = buf->ReadDWord(); + std::string prefix = ReadDWordAsString(buf); if (curidx < CURRENCY_END) { - memcpy(_currency_specs[curidx].prefix, &tempfix, 4); - _currency_specs[curidx].prefix[4] = 0; + _currency_specs[curidx].prefix = prefix; } else { grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx); } @@ -2767,11 +2782,10 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, co case 0x0E: { // Currency suffix symbol uint curidx = GetNewgrfCurrencyIdConverted(gvid + i); - uint32 tempfix = buf->ReadDWord(); + std::string suffix = ReadDWordAsString(buf); if (curidx < CURRENCY_END) { - memcpy(&_currency_specs[curidx].suffix, &tempfix, 4); - _currency_specs[curidx].suffix[4] = 0; + _currency_specs[curidx].suffix = suffix; } else { grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx); } @@ -3268,7 +3282,7 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr /* A copied tile should not have the animation infos copied too. * The anim_state should be left untouched, though - * It is up to the author to animate them himself */ + * It is up to the author to animate them */ tsp->anim_production = INDUSTRYTILE_NOANIM; tsp->anim_next = INDUSTRYTILE_NOANIM; @@ -4960,6 +4974,7 @@ static void FeatureChangeInfo(ByteReader *buf) /* GSF_ROADTYPES */ RoadTypeChangeInfo, /* GSF_TRAMTYPES */ TramTypeChangeInfo, }; + static_assert(GSF_END == lengthof(handler)); static_assert(lengthof(handler) == lengthof(_cur.grffile->action0_property_remaps), "Action 0 feature list length mismatch"); uint8 feature = buf->ReadByte(); @@ -4975,7 +4990,7 @@ static void FeatureChangeInfo(ByteReader *buf) grfmsg(6, "FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d", feature, numprops, engine, numinfo); - if (feature >= lengthof(handler) || handler[feature] == nullptr) { + if (handler[feature] == nullptr) { if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature); return; } @@ -8036,9 +8051,7 @@ static void TranslateGRFStrings(ByteReader *buf) * and disable this file. */ GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER); - char tmp[256]; - GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp)); - error->data = tmp; + error->data = GetString(STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE); return; } @@ -9481,59 +9494,116 @@ GRFFile::~GRFFile() } -/** - * List of what cargo labels are refittable for the given the vehicle-type. - * Only currently active labels are applied. - */ -static const CargoLabel _default_refitmasks_rail[] = { - 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', - 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', - 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', - 'PLST', 'FZDR', - 0 }; - -static const CargoLabel _default_refitmasks_road[] = { - 0 }; - -static const CargoLabel _default_refitmasks_ships[] = { - 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE', - 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR', - 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', - 'PLST', 'FZDR', - 0 }; - -static const CargoLabel _default_refitmasks_aircraft[] = { - 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR', - 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR', - 0 }; - -static const CargoLabel * const _default_refitmasks[] = { - _default_refitmasks_rail, - _default_refitmasks_road, - _default_refitmasks_ships, - _default_refitmasks_aircraft, -}; - - /** * Precalculate refit masks from cargo classes for all vehicles. */ static void CalculateRefitMasks() { + CargoTypes original_known_cargoes = 0; + for (int ct = 0; ct != NUM_ORIGINAL_CARGO; ++ct) { + CargoID cid = GetDefaultCargoID(_settings_game.game_creation.landscape, static_cast(ct)); + if (cid != CT_INVALID) SetBit(original_known_cargoes, cid); + } + for (Engine *e : Engine::Iterate()) { EngineID engine = e->index; EngineInfo *ei = &e->info; bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo - /* Did the newgrf specify any refitting? If not, use defaults. */ - if (_gted[engine].refittability != GRFTempEngineData::UNSET) { + /* If the NewGRF did not set any cargo properties, we apply default values. */ + if (_gted[engine].defaultcargo_grf == nullptr) { + /* If the vehicle has any capacity, apply the default refit masks */ + if (e->type != VEH_TRAIN || e->u.rail.capacity != 0) { + static constexpr byte T = 1 << LT_TEMPERATE; + static constexpr byte A = 1 << LT_ARCTIC; + static constexpr byte S = 1 << LT_TROPIC; + static constexpr byte Y = 1 << LT_TOYLAND; + static const struct DefaultRefitMasks { + byte climate; + CargoType cargo_type; + CargoTypes cargo_allowed; + CargoTypes cargo_disallowed; + } _default_refit_masks[] = { + {T | A | S | Y, CT_PASSENGERS, CC_PASSENGERS, 0}, + {T | A | S , CT_MAIL, CC_MAIL, 0}, + {T | A | S , CT_VALUABLES, CC_ARMOURED, CC_LIQUID}, + { Y, CT_MAIL, CC_MAIL | CC_ARMOURED, CC_LIQUID}, + {T | A , CT_COAL, CC_BULK, 0}, + { S , CT_COPPER_ORE, CC_BULK, 0}, + { Y, CT_SUGAR, CC_BULK, 0}, + {T | A | S , CT_OIL, CC_LIQUID, 0}, + { Y, CT_COLA, CC_LIQUID, 0}, + {T , CT_GOODS, CC_PIECE_GOODS | CC_EXPRESS, CC_LIQUID | CC_PASSENGERS}, + { A | S , CT_GOODS, CC_PIECE_GOODS | CC_EXPRESS, CC_LIQUID | CC_PASSENGERS | CC_REFRIGERATED}, + { A | S , CT_FOOD, CC_REFRIGERATED, 0}, + { Y, CT_CANDY, CC_PIECE_GOODS | CC_EXPRESS, CC_LIQUID | CC_PASSENGERS}, + }; + + if (e->type == VEH_AIRCRAFT) { + /* Aircraft default to "light" cargoes */ + _gted[engine].cargo_allowed = CC_PASSENGERS | CC_MAIL | CC_ARMOURED | CC_EXPRESS; + _gted[engine].cargo_disallowed = CC_LIQUID; + } else if (e->type == VEH_SHIP) { + switch (ei->cargo_type) { + case CT_PASSENGERS: + /* Ferries */ + _gted[engine].cargo_allowed = CC_PASSENGERS; + _gted[engine].cargo_disallowed = 0; + break; + case CT_OIL: + /* Tankers */ + _gted[engine].cargo_allowed = CC_LIQUID; + _gted[engine].cargo_disallowed = 0; + break; + default: + /* Cargo ships */ + if (_settings_game.game_creation.landscape == LT_TOYLAND) { + /* No tanker in toyland :( */ + _gted[engine].cargo_allowed = CC_MAIL | CC_ARMOURED | CC_EXPRESS | CC_BULK | CC_PIECE_GOODS | CC_LIQUID; + _gted[engine].cargo_disallowed = CC_PASSENGERS; + } else { + _gted[engine].cargo_allowed = CC_MAIL | CC_ARMOURED | CC_EXPRESS | CC_BULK | CC_PIECE_GOODS; + _gted[engine].cargo_disallowed = CC_LIQUID | CC_PASSENGERS; + } + break; + } + e->u.ship.old_refittable = true; + } else if (e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON) { + /* Train engines default to all cargoes, so you can build single-cargo consists with fast engines. + * Trains loading multiple cargoes may start stations accepting unwanted cargoes. */ + _gted[engine].cargo_allowed = CC_PASSENGERS | CC_MAIL | CC_ARMOURED | CC_EXPRESS | CC_BULK | CC_PIECE_GOODS | CC_LIQUID; + _gted[engine].cargo_disallowed = 0; + } else { + /* Train wagons and road vehicles are classified by their default cargo type */ + for (const auto &drm : _default_refit_masks) { + if (!HasBit(drm.climate, _settings_game.game_creation.landscape)) continue; + if (drm.cargo_type != ei->cargo_type) continue; + + _gted[engine].cargo_allowed = drm.cargo_allowed; + _gted[engine].cargo_disallowed = drm.cargo_disallowed; + break; + } + + /* All original cargoes have specialised vehicles, so exclude them */ + _gted[engine].ctt_exclude_mask = original_known_cargoes; + } + } + _gted[engine].UpdateRefittability(_gted[engine].cargo_allowed != 0); + + /* Translate cargo_type using the original climate-specific cargo table. */ + ei->cargo_type = GetDefaultCargoID(_settings_game.game_creation.landscape, static_cast(ei->cargo_type)); + if (ei->cargo_type != CT_INVALID) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type); + } + + /* Compute refittability */ + { CargoTypes mask = 0; CargoTypes not_mask = 0; CargoTypes xor_mask = ei->refit_mask; /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo. * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */ - only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY; + only_defaultcargo = _gted[engine].refittability != GRFTempEngineData::NONEMPTY; if (_gted[engine].cargo_allowed != 0) { /* Build up the list of cargo types from the set cargo classes. */ @@ -9548,26 +9618,6 @@ static void CalculateRefitMasks() /* Apply explicit refit includes/excludes. */ ei->refit_mask |= _gted[engine].ctt_include_mask; ei->refit_mask &= ~_gted[engine].ctt_exclude_mask; - } else { - CargoTypes xor_mask = 0; - - /* Don't apply default refit mask to wagons nor engines with no capacity */ - if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) { - const CargoLabel *cl = _default_refitmasks[e->type]; - for (uint i = 0;; i++) { - if (cl[i] == 0) break; - - CargoID cargo = GetCargoIDByLabel(cl[i]); - if (cargo == CT_INVALID) continue; - - SetBit(xor_mask, cargo); - } - } - - ei->refit_mask = xor_mask & _cargo_mask; - - /* If the mask is zero, the vehicle shall only carry the default cargo */ - only_defaultcargo = (ei->refit_mask == 0); } /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */ diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index c60ed84022..61778b304a 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -155,7 +155,7 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 } } /* The tile has no spritegroup */ - return 0xFF << 8 | ats->grf_prop.subst_id; // so just give him the substitute + return 0xFF << 8 | ats->grf_prop.subst_id; // so just give it the substitute } /* virtual */ uint32 AirportTileScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index 64eed8139a..55674a60db 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -264,7 +264,7 @@ void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds) if (ind_id == invalid_ID) { /* Not found. - * Or it has already been overridden, so you've lost your place old boy. + * Or it has already been overridden, so you've lost your place. * Or it is a simple substitute. * We need to find a free available slot */ ind_id = this->AddEntityID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid, inds->grf_prop.subst_id); @@ -319,7 +319,7 @@ void ObjectOverrideManager::SetEntitySpec(ObjectSpec *spec) if (type == invalid_ID) { /* Not found. - * Or it has already been overridden, so you've lost your place old boy. + * Or it has already been overridden, so you've lost your place. * Or it is a simple substitute. * We need to find a free available slot */ type = this->AddEntityID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid, OBJECT_TRANSMITTER); diff --git a/src/newgrf_config.h b/src/newgrf_config.h index 63784b5dd5..90700cda58 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -115,6 +115,9 @@ struct GRFError { GRFError(StringID severity, StringID message = 0); GRFError(const GRFError &error); + /* Remove the copy assignment, as the default implementation will not do the right thing. */ + GRFError &operator=(GRFError &rhs) = delete; + std::string custom_message; ///< Custom message (if present) std::string data; ///< Additional data for message and custom_message StringID message; ///< Default message @@ -156,6 +159,9 @@ struct GRFConfig : ZeroedMemoryAllocator { GRFConfig(const GRFConfig &config); ~GRFConfig(); + /* Remove the copy assignment, as the default implementation will not do the right thing. */ + GRFConfig &operator=(GRFConfig &rhs) = delete; + GRFIdentifier ident; ///< grfid and md5sum to uniquely identify newgrfs uint8 original_md5sum[16]; ///< MD5 checksum of original file if only a 'compatible' file was loaded char *filename; ///< Filename - either with or without full path diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 9949482ee9..447dd38d69 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -85,7 +85,7 @@ uint32 GetIndustryIDAtOffset(TileIndex tile, const Industry *i, uint32 cur_grfid } } /* The tile has no spritegroup */ - return 0xFF << 8 | indtsp->grf_prop.subst_id; // so just give him the substitute + return 0xFF << 8 | indtsp->grf_prop.subst_id; // so just give it the substitute } static uint32 GetClosestIndustry(TileIndex tile, IndustryType type, const Industry *current) diff --git a/src/newgrf_profiling.cpp b/src/newgrf_profiling.cpp index 8ec8cff546..27a1bc80ef 100644 --- a/src/newgrf_profiling.cpp +++ b/src/newgrf_profiling.cpp @@ -13,9 +13,9 @@ #include "string_func.h" #include "console_func.h" #include "spritecache.h" +#include "walltime_func.h" #include -#include std::vector _newgrf_profilers; @@ -130,10 +130,8 @@ void NewGRFProfiler::Abort() */ std::string NewGRFProfiler::GetOutputFilename() const { - time_t write_time = time(nullptr); - char timestamp[16] = {}; - strftime(timestamp, lengthof(timestamp), "%Y%m%d-%H%M", localtime(&write_time)); + LocalTime::Format(timestamp, lastof(timestamp), "%Y%m%d-%H%M"); char filepath[MAX_PATH] = {}; seprintf(filepath, lastof(filepath), "%sgrfprofile-%s-%08X.csv", FiosGetScreenshotDir(), timestamp, BSWAP32(this->grffile->grfid)); diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 31205b9c4a..b164a6aa16 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -550,17 +550,17 @@ uint32 StationResolverObject::GetDebugID() const /** * Resolver for stations. * @param statspec Station (type) specification. - * @param st Instance of the station. + * @param base_station Instance of the station. * @param tile %Tile of the station. * @param rt %RailType of the station (unbuilt stations only). * @param callback Callback ID. * @param callback_param1 First parameter (var 10) of the callback. * @param callback_param2 Second parameter (var 18) of the callback. */ -StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseStation *st, TileIndex tile, RailType rt, +StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseStation *base_station, TileIndex tile, RailType rt, CallbackID callback, uint32 callback_param1, uint32 callback_param2) : ResolverObject(statspec->grf_prop.grffile, callback, callback_param1, callback_param2), - station_scope(*this, statspec, st, tile, rt), town_scope(nullptr) + station_scope(*this, statspec, base_station, tile, rt), town_scope(nullptr) { /* Invalidate all cached vars */ _svc.valid = 0; @@ -931,7 +931,7 @@ uint8 GetStationTileAnimationSpeed(TileIndex tile) return StationAnimationBase::GetAnimationSpeed(ss); } -void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type) +void TriggerStationAnimation(BaseStation *st, TileIndex trigger_tile, StationAnimationTrigger trigger, CargoID cargo_type) { /* List of coverage areas for each animation trigger */ static const TriggerArea tas[] = { @@ -939,14 +939,14 @@ void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTr }; /* Get Station if it wasn't supplied */ - if (st == nullptr) st = BaseStation::GetByTile(tile); + if (st == nullptr) st = BaseStation::GetByTile(trigger_tile); /* Check the cached animation trigger bitmask to see if we need * to bother with any further processing. */ if (!HasBit(st->cached_anim_triggers, trigger)) return; uint16 random_bits = Random(); - ETileArea area = ETileArea(st, tile, tas[trigger]); + ETileArea area = ETileArea(st, trigger_tile, tas[trigger]); /* Check all tiles over the station to check if the specindex is still in use */ for (TileIndex tile : area) { @@ -968,11 +968,11 @@ void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTr /** * Trigger station randomisation * @param st station being triggered - * @param tile specific tile of platform to trigger + * @param trigger_tile specific tile of platform to trigger * @param trigger trigger type * @param cargo_type cargo type causing trigger */ -void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoID cargo_type) +void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRandomTrigger trigger, CargoID cargo_type) { /* List of coverage areas for each animation trigger */ static const TriggerArea tas[] = { @@ -980,7 +980,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg }; /* Get Station if it wasn't supplied */ - if (st == nullptr) st = Station::GetByTile(tile); + if (st == nullptr) st = Station::GetByTile(trigger_tile); /* Check the cached cargo trigger bitmask to see if we need * to bother with any further processing. */ @@ -988,7 +988,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg if (cargo_type != CT_INVALID && !HasBit(st->cached_cargo_triggers, cargo_type)) return; uint32 whole_reseed = 0; - ETileArea area = ETileArea(st, tile, tas[trigger]); + ETileArea area = ETileArea(st, trigger_tile, tas[trigger]); CargoTypes empty_mask = 0; if (trigger == SRT_CARGO_TAKEN) { diff --git a/src/newgrf_storage.h b/src/newgrf_storage.h index ff322c9445..819e8d9394 100644 --- a/src/newgrf_storage.h +++ b/src/newgrf_storage.h @@ -21,7 +21,7 @@ enum PersistentStorageMode { PSM_LEAVE_GAMELOOP, ///< Leave the gameloop, changes will be temporary. PSM_ENTER_COMMAND, ///< Enter command scope, changes will be permanent. PSM_LEAVE_COMMAND, ///< Leave command scope, revert to previous mode. - PSM_ENTER_TESTMODE, ///< Enter command test mode, changes will be tempoary. + PSM_ENTER_TESTMODE, ///< Enter command test mode, changes will be temporary. PSM_LEAVE_TESTMODE, ///< Leave command test mode, revert to previous mode. }; diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 4556f8dbfc..976afafbbb 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -402,7 +402,6 @@ std::string TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_n int index = (code == 0x10 ? *src++ : 0); if (mapping->strings.find(index) != mapping->strings.end()) { grfmsg(1, "duplicate choice list string, ignoring"); - d++; } else { d = std::ostreambuf_iterator(mapping->strings[index]); } diff --git a/src/news_gui.cpp b/src/news_gui.cpp index ff225a052a..56b53bcb02 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -253,8 +253,7 @@ static_assert(lengthof(_news_type_data) == NT_END); */ NewsDisplay NewsTypeData::GetDisplay() const { - uint index; - const SettingDesc *sd = GetSettingFromName(this->name, &index); + const SettingDesc *sd = GetSettingFromName(this->name); assert(sd != nullptr); void *ptr = GetVariableAddress(nullptr, &sd->save); return (NewsDisplay)ReadValue(ptr, sd->save.conv); diff --git a/src/openttd.cpp b/src/openttd.cpp index d51e302a08..8ee3c48326 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -553,23 +553,19 @@ void OpenBrowser(const char *url) /** Callback structure of statements to be executed after the NewGRF scan. */ struct AfterNewGRFScan : NewGRFScanCallback { - Year startyear; ///< The start year. - uint32 generation_seed; ///< Seed for the new game. - std::string dedicated_host; ///< Hostname for the dedicated server. - uint16 dedicated_port; ///< Port for the dedicated server. - char *network_conn; ///< Information about the server to connect to, or nullptr. - const char *join_server_password; ///< The password to join the server with. - const char *join_company_password; ///< The password to join the company with. - bool save_config; ///< The save config setting. + Year startyear = INVALID_YEAR; ///< The start year. + uint32 generation_seed = GENERATE_NEW_SEED; ///< Seed for the new game. + std::string dedicated_host; ///< Hostname for the dedicated server. + uint16 dedicated_port = 0; ///< Port for the dedicated server. + std::string connection_string; ///< Information about the server to connect to + std::string join_server_password; ///< The password to join the server with. + std::string join_company_password; ///< The password to join the company with. + bool save_config = true; ///< The save config setting. /** * Create a new callback. */ - AfterNewGRFScan() : - startyear(INVALID_YEAR), generation_seed(GENERATE_NEW_SEED), - dedicated_port(0), network_conn(nullptr), - join_server_password(nullptr), join_company_password(nullptr), - save_config(true) + AfterNewGRFScan() { /* Visual C++ 2015 fails compiling this line (AfterNewGRFScan::generation_seed undefined symbol) * if it's placed outside a member function, directly in the struct body. */ @@ -622,11 +618,11 @@ struct AfterNewGRFScan : NewGRFScanCallback { /* Make sure _settings is filled with _settings_newgame if we switch to a game directly */ if (_switch_mode != SM_NONE) MakeNewgameSettingsLive(); - if (_network_available && network_conn != nullptr) { + if (_network_available && !connection_string.empty()) { LoadIntroGame(); _switch_mode = SM_NONE; - NetworkClientConnectGame(network_conn, COMPANY_NEW_COMPANY, join_server_password, join_company_password); + NetworkClientConnectGame(connection_string, COMPANY_NEW_COMPANY, join_server_password, join_company_password); } /* After the scan we're not used anymore. */ @@ -725,7 +721,7 @@ int openttd_main(int argc, char *argv[]) break; case 'f': _dedicated_forks = true; break; case 'n': - scanner->network_conn = mgo.opt; // optional IP parameter, nullptr if unset + scanner->connection_string = mgo.opt; // optional IP:port#company parameter break; case 'l': debuglog_conn = mgo.opt; @@ -1055,7 +1051,7 @@ static void MakeNewGameDone() /* We are the server, we start a new company (not dedicated), * so set the default password *if* needed. */ - if (_network_server && !StrEmpty(_settings_client.network.default_company_pass)) { + if (_network_server && !_settings_client.network.default_company_pass.empty()) { NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass); } @@ -1173,7 +1169,7 @@ bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileTy void SwitchToMode(SwitchMode new_mode) { - /* If we are saving something, the network stays in his current state */ + /* If we are saving something, the network stays in its current state */ if (new_mode != SM_SAVE_GAME) { /* If the network is active, make it not-active */ if (_networking) { diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index de4fd69ddb..5b93bca22b 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1361,7 +1361,7 @@ static void CancelLoadingDueToDeletedOrder(Vehicle *v) assert(v->current_order.IsType(OT_LOADING)); /* NON-stop flag is misused to see if a train is in a station that is - * on his order list or not */ + * on its order list or not */ v->current_order.SetNonStopType(ONSF_STOP_EVERYWHERE); /* When full loading, "cancel" that order so the vehicle doesn't * stay indefinitely at this station anymore. */ diff --git a/src/os/macosx/font_osx.cpp b/src/os/macosx/font_osx.cpp index f5ceed8507..295fcf257a 100644 --- a/src/os/macosx/font_osx.cpp +++ b/src/os/macosx/font_osx.cpp @@ -359,7 +359,7 @@ void LoadCoreTextFont(FontSize fs) case FS_MONO: settings = &_freetype.mono; break; } - if (StrEmpty(settings->font)) return; + if (settings->font.empty()) return; CFAutoRelease font_ref; @@ -375,10 +375,10 @@ void LoadCoreTextFont(FontSize fs) /* See if this is an absolute path. */ if (FileExists(settings->font)) { - path.reset(CFStringCreateWithCString(kCFAllocatorDefault, settings->font, kCFStringEncodingUTF8)); + path.reset(CFStringCreateWithCString(kCFAllocatorDefault, settings->font.c_str(), kCFStringEncodingUTF8)); } else { /* Scan the search-paths to see if it can be found. */ - std::string full_font = FioFindFullPath(BASE_DIR, settings->font); + std::string full_font = FioFindFullPath(BASE_DIR, settings->font.c_str()); if (!full_font.empty()) { path.reset(CFStringCreateWithCString(kCFAllocatorDefault, full_font.c_str(), kCFStringEncodingUTF8)); } @@ -393,13 +393,13 @@ void LoadCoreTextFont(FontSize fs) font_ref.reset((CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), 0)); CFRetain(font_ref.get()); } else { - ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font, SIZE_TO_NAME[fs]); + ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font.c_str(), SIZE_TO_NAME[fs]); } } } if (!font_ref) { - CFAutoRelease name(CFStringCreateWithCString(kCFAllocatorDefault, settings->font, kCFStringEncodingUTF8)); + CFAutoRelease name(CFStringCreateWithCString(kCFAllocatorDefault, settings->font.c_str(), kCFStringEncodingUTF8)); /* Simply creating the font using CTFontCreateWithNameAndSize will *always* return * something, no matter the name. As such, we can't use it to check for existence. @@ -417,7 +417,7 @@ void LoadCoreTextFont(FontSize fs) } if (!font_ref) { - ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font, SIZE_TO_NAME[fs]); + ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font.c_str(), SIZE_TO_NAME[fs]); return; } diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index fac366f8bf..6b224c40fc 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -590,8 +590,9 @@ void LoadWin32Font(FontSize fs) default: NOT_REACHED(); } - if (StrEmpty(settings->font)) return; + if (settings->font.empty()) return; + const char *font_name = settings->font.c_str(); LOGFONT logfont; MemSetT(&logfont, 0); logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH; @@ -601,19 +602,19 @@ void LoadWin32Font(FontSize fs) if (settings->os_handle != nullptr) { logfont = *(const LOGFONT *)settings->os_handle; - } else if (strchr(settings->font, '.') != nullptr) { + } else if (strchr(font_name, '.') != nullptr) { /* Might be a font file name, try load it. */ wchar_t fontPath[MAX_PATH] = {}; /* See if this is an absolute path. */ if (FileExists(settings->font)) { - convert_to_fs(settings->font, fontPath, lengthof(fontPath)); + convert_to_fs(font_name, fontPath, lengthof(fontPath)); } else { /* Scan the search-paths to see if it can be found. */ - std::string full_font = FioFindFullPath(BASE_DIR, settings->font); + std::string full_font = FioFindFullPath(BASE_DIR, font_name); if (!full_font.empty()) { - convert_to_fs(full_font.c_str(), fontPath, lengthof(fontPath)); + convert_to_fs(font_name, fontPath, lengthof(fontPath)); } } @@ -641,22 +642,22 @@ void LoadWin32Font(FontSize fs) _wsplitpath(fontPath, nullptr, nullptr, fname, nullptr); wcsncpy_s(logfont.lfFaceName, lengthof(logfont.lfFaceName), fname, _TRUNCATE); - logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr || strcasestr(settings->font, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts. + logfont.lfWeight = strcasestr(font_name, " bold") != nullptr || strcasestr(font_name, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts. } } else { - ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", settings->font, SIZE_TO_NAME[fs]); + ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", font_name, SIZE_TO_NAME[fs]); } } } if (logfont.lfFaceName[0] == 0) { - logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts. - convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName)); + logfont.lfWeight = strcasestr(font_name, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts. + convert_to_fs(font_name, logfont.lfFaceName, lengthof(logfont.lfFaceName)); } HFONT font = CreateFontIndirect(&logfont); if (font == nullptr) { - ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", settings->font, SIZE_TO_NAME[fs], GetLastError()); + ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", font_name, SIZE_TO_NAME[fs], GetLastError()); return; } DeleteObject(font); diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp index b27e8fefce..c31ab4c39e 100644 --- a/src/osk_gui.cpp +++ b/src/osk_gui.cpp @@ -24,7 +24,7 @@ #include "safeguards.h" -char _keyboard_opt[2][OSK_KEYBOARD_ENTRIES * 4 + 1]; +std::string _keyboard_opt[2]; static WChar _keyboard[2][OSK_KEYBOARD_ENTRIES]; enum KeyStateBits { @@ -356,16 +356,16 @@ void GetKeyboardLayout() char errormark[2][OSK_KEYBOARD_ENTRIES + 1]; // used for marking invalid chars bool has_error = false; // true when an invalid char is detected - if (StrEmpty(_keyboard_opt[0])) { + if (_keyboard_opt[0].empty()) { GetString(keyboard[0], STR_OSK_KEYBOARD_LAYOUT, lastof(keyboard[0])); } else { - strecpy(keyboard[0], _keyboard_opt[0], lastof(keyboard[0])); + strecpy(keyboard[0], _keyboard_opt[0].c_str(), lastof(keyboard[0])); } - if (StrEmpty(_keyboard_opt[1])) { + if (_keyboard_opt[1].empty()) { GetString(keyboard[1], STR_OSK_KEYBOARD_LAYOUT_CAPS, lastof(keyboard[1])); } else { - strecpy(keyboard[1], _keyboard_opt[1], lastof(keyboard[1])); + strecpy(keyboard[1], _keyboard_opt[1].c_str(), lastof(keyboard[1])); } for (uint j = 0; j < 2; j++) { diff --git a/src/pathfinder/npf/aystar.cpp b/src/pathfinder/npf/aystar.cpp index e68146bbde..3ca787722f 100644 --- a/src/pathfinder/npf/aystar.cpp +++ b/src/pathfinder/npf/aystar.cpp @@ -151,14 +151,14 @@ void AyStar::CheckTile(AyStarNode *current, OpenListNode *parent) /* Re-add it in the openlist_queue. */ this->openlist_queue.Push(check, new_f); } else { - /* A new node, add him to the OpenList */ + /* A new node, add it to the OpenList */ this->OpenListAdd(closedlist_parent, current, new_f, new_g); } } /** * This function is the core of %AyStar. It handles one item and checks - * his neighbour items. If they are valid, they are added to be checked too. + * its neighbour items. If they are valid, they are added to be checked too. * @return Possible values: * - #AYSTAR_EMPTY_OPENLIST : indicates all items are tested, and no path has been found. * - #AYSTAR_LIMIT_REACHED : Indicates that the max_search_nodes limit has been reached. diff --git a/src/pathfinder/yapf/yapf_node_rail.hpp b/src/pathfinder/yapf/yapf_node_rail.hpp index e337c17e55..1846521c4d 100644 --- a/src/pathfinder/yapf/yapf_node_rail.hpp +++ b/src/pathfinder/yapf/yapf_node_rail.hpp @@ -15,8 +15,6 @@ struct CYapfRailSegmentKey { uint32 m_value; - inline CYapfRailSegmentKey(const CYapfRailSegmentKey &src) : m_value(src.m_value) {} - inline CYapfRailSegmentKey(const CYapfNodeKeyTrackDir &node_key) { Set(node_key); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index ab56d5243a..da91cf04e3 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1944,11 +1944,11 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin /* only build/remove signals with the specified density */ if (tile_ok && (remove || minimise_gaps || signal_ctr % signal_density == 0 || IsTileType(tile, MP_TUNNELBRIDGE))) { - uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3); - SB(p1, 3, 1, mode); - SB(p1, 4, 1, semaphores); - SB(p1, 5, 3, sigtype); - if (!remove && signal_ctr == 0) SetBit(p1, 17); + uint32 param1 = GB(TrackdirToTrack(trackdir), 0, 3); + SB(param1, 3, 1, mode); + SB(param1, 4, 1, semaphores); + SB(param1, 5, 3, sigtype); + if (!remove && signal_ctr == 0) SetBit(param1, 17); /* Pick the correct orientation for the track direction */ signals = 0; @@ -1957,7 +1957,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin /* Test tiles in between for suitability as well if minimising gaps. */ bool test_only = !remove && minimise_gaps && signal_ctr < (last_used_ctr + signal_density); - CommandCost ret = DoCommand(tile, p1, signals, test_only ? flags & ~DC_EXEC : flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS); + CommandCost ret = DoCommand(tile, param1, signals, test_only ? flags & ~DC_EXEC : flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS); if (!test_only && ret.Succeeded() && IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(tile) == TrackdirToExitdir(trackdir)) { /* Blacklist far end of tunnel if we just actioned the near end */ tunnel_bridge_blacklist.push_back(GetOtherTunnelBridgeEnd(tile)); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index ad65a43e86..57fe63057c 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -468,7 +468,7 @@ static void HandleAutoSignalPlacement() } /* _settings_client.gui.drag_signals_density is given as a parameter such that each user - * in a network game can specify his/her own signal density */ + * in a network game can specify their own signal density */ DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, _remove_button_clicked ? CMD_REMOVE_SIGNAL_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM) : @@ -1338,7 +1338,7 @@ public: StringID str = this->GetWidget(widget)->widget_data; for (auto station_class : this->station_classes) { StationClass *stclass = StationClass::Get(station_class); - for (uint16 j = 0; j < stclass->GetSpecCount(); j++) { + for (uint j = 0; j < stclass->GetSpecCount(); j++) { const StationSpec *statspec = stclass->GetSpec(j); SetDParam(0, (statspec != nullptr && statspec->name != 0) ? statspec->name : STR_STATION_CLASS_DFLT); d = maxdim(d, GetStringBoundingBox(str)); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 9b3a67fd5e..135837ecfe 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -189,7 +189,7 @@ static void UpdateExclusiveRights() * Build an array town_blocked[ town_id ][ company_id ] * that stores if at least one station in that town is blocked for a company * 2.) Go through that array, if you find a town that is not blocked for - * one company, but for all others, then give him exclusivity. + * one company, but for all others, then give it exclusivity. */ } diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index 0ece819813..3bc1d0f879 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -20,14 +20,14 @@ #include "../safeguards.h" -static char _ai_saveload_name[64]; -static int _ai_saveload_version; -static char _ai_saveload_settings[1024]; -static bool _ai_saveload_is_random; +static std::string _ai_saveload_name; +static int _ai_saveload_version; +static std::string _ai_saveload_settings; +static bool _ai_saveload_is_random; static const SaveLoad _ai_company[] = { - SLEG_STR(_ai_saveload_name, SLE_STRB), - SLEG_STR(_ai_saveload_settings, SLE_STRB), + SLEG_SSTR(_ai_saveload_name, SLE_STR), + SLEG_SSTR(_ai_saveload_settings, SLE_STR), SLEG_CONDVAR(_ai_saveload_version, SLE_UINT32, SLV_108, SL_MAX_VERSION), SLEG_CONDVAR(_ai_saveload_is_random, SLE_BOOL, SLV_136, SL_MAX_VERSION), SLE_END() @@ -39,20 +39,19 @@ static void SaveReal_AIPL(int *index_ptr) AIConfig *config = AIConfig::GetConfig(index); if (config->HasScript()) { - strecpy(_ai_saveload_name, config->GetName(), lastof(_ai_saveload_name)); + _ai_saveload_name = config->GetName(); _ai_saveload_version = config->GetVersion(); } else { /* No AI is configured for this so store an empty string as name. */ - _ai_saveload_name[0] = '\0'; + _ai_saveload_name.clear(); _ai_saveload_version = -1; } _ai_saveload_is_random = config->IsRandom(); - _ai_saveload_settings[0] = '\0'; - config->SettingsToString(_ai_saveload_settings, lastof(_ai_saveload_settings)); + _ai_saveload_settings = config->SettingsToString(); SlObject(nullptr, _ai_company); - /* If the AI was active, store his data too */ + /* If the AI was active, store its data too */ if (Company::IsValidAiID(index)) AI::Save(index); } @@ -77,25 +76,25 @@ static void Load_AIPL() } AIConfig *config = AIConfig::GetConfig(index, AIConfig::SSS_FORCE_GAME); - if (StrEmpty(_ai_saveload_name)) { + if (_ai_saveload_name.empty()) { /* A random AI. */ config->Change(nullptr, -1, false, true); } else { - config->Change(_ai_saveload_name, _ai_saveload_version, false, _ai_saveload_is_random); + config->Change(_ai_saveload_name.c_str(), _ai_saveload_version, false, _ai_saveload_is_random); if (!config->HasScript()) { /* No version of the AI available that can load the data. Try to load the * latest version of the AI instead. */ - config->Change(_ai_saveload_name, -1, false, _ai_saveload_is_random); + config->Change(_ai_saveload_name.c_str(), -1, false, _ai_saveload_is_random); if (!config->HasScript()) { - if (strcmp(_ai_saveload_name, "%_dummy") != 0) { - DEBUG(script, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name, _ai_saveload_version); + if (_ai_saveload_name.compare("%_dummy") != 0) { + DEBUG(script, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name.c_str(), _ai_saveload_version); DEBUG(script, 0, "A random other AI will be loaded in its place."); } else { DEBUG(script, 0, "The savegame had no AIs available at the time of saving."); DEBUG(script, 0, "A random available AI will be loaded now."); } } else { - DEBUG(script, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name, _ai_saveload_version); + DEBUG(script, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name.c_str(), _ai_saveload_version); DEBUG(script, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible."); } /* Make sure the AI doesn't get the saveload data, as it was not the diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index b570d1054d..00ca6d9ab9 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -20,14 +20,14 @@ #include "../safeguards.h" -static char _game_saveload_name[64]; -static int _game_saveload_version; -static char _game_saveload_settings[1024]; -static bool _game_saveload_is_random; +static std::string _game_saveload_name; +static int _game_saveload_version; +static std::string _game_saveload_settings; +static bool _game_saveload_is_random; static const SaveLoad _game_script[] = { - SLEG_STR(_game_saveload_name, SLE_STRB), - SLEG_STR(_game_saveload_settings, SLE_STRB), + SLEG_SSTR(_game_saveload_name, SLE_STR), + SLEG_SSTR(_game_saveload_settings, SLE_STR), SLEG_VAR(_game_saveload_version, SLE_UINT32), SLEG_VAR(_game_saveload_is_random, SLE_BOOL), SLE_END() @@ -38,17 +38,16 @@ static void SaveReal_GSDT(int *index_ptr) GameConfig *config = GameConfig::GetConfig(); if (config->HasScript()) { - strecpy(_game_saveload_name, config->GetName(), lastof(_game_saveload_name)); + _game_saveload_name = config->GetName(); _game_saveload_version = config->GetVersion(); } else { /* No GameScript is configured for this so store an empty string as name. */ - _game_saveload_name[0] = '\0'; + _game_saveload_name.clear(); _game_saveload_version = -1; } _game_saveload_is_random = config->IsRandom(); - _game_saveload_settings[0] = '\0'; - config->SettingsToString(_game_saveload_settings, lastof(_game_saveload_settings)); + _game_saveload_settings = config->SettingsToString(); SlObject(nullptr, _game_script); Game::Save(); @@ -71,23 +70,22 @@ static void Load_GSDT() } GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME); - if (StrEmpty(_game_saveload_name)) { - } else { - config->Change(_game_saveload_name, _game_saveload_version, false, _game_saveload_is_random); + if (!_game_saveload_name.empty()) { + config->Change(_game_saveload_name.c_str(), _game_saveload_version, false, _game_saveload_is_random); if (!config->HasScript()) { /* No version of the GameScript available that can load the data. Try to load the * latest version of the GameScript instead. */ - config->Change(_game_saveload_name, -1, false, _game_saveload_is_random); + config->Change(_game_saveload_name.c_str(), -1, false, _game_saveload_is_random); if (!config->HasScript()) { - if (strcmp(_game_saveload_name, "%_dummy") != 0) { - DEBUG(script, 0, "The savegame has an GameScript by the name '%s', version %d which is no longer available.", _game_saveload_name, _game_saveload_version); + if (_game_saveload_name.compare("%_dummy") != 0) { + DEBUG(script, 0, "The savegame has an GameScript by the name '%s', version %d which is no longer available.", _game_saveload_name.c_str(), _game_saveload_version); DEBUG(script, 0, "This game will continue to run without GameScript."); } else { DEBUG(script, 0, "The savegame had no GameScript available at the time of saving."); DEBUG(script, 0, "This game will continue to run without GameScript."); } } else { - DEBUG(script, 0, "The savegame has an GameScript by the name '%s', version %d which is no longer available.", _game_saveload_name, _game_saveload_version); + DEBUG(script, 0, "The savegame has an GameScript by the name '%s', version %d which is no longer available.", _game_saveload_name.c_str(), _game_saveload_version); DEBUG(script, 0, "The latest version of that GameScript has been loaded instead, but it'll not get the savegame data as it's incompatible."); } /* Make sure the GameScript doesn't get the saveload data, as it was not the diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index bb0382a5c5..207a6e3670 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -154,7 +154,7 @@ static void FilterDescs() */ void Save_LinkGraph(LinkGraph &lg) { - uint size = lg.Size(); + uint16 size = lg.Size(); for (NodeID from = 0; from < size; ++from) { Node *node = &lg.nodes[from]; SlObjectSaveFiltered(node, _filtered_node_desc.data()); diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 3351e5c193..232f2de558 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -80,11 +80,11 @@ const SaveLoadVersion SAVEGAME_VERSION_EXT = (SaveLoadVersion)(0x8000); ///< Sav SavegameType _savegame_type; ///< type of savegame we are loading FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop. -uint32 _ttdp_version; ///< version of TTDP savegame (if applicable) -SaveLoadVersion _sl_version; ///< the major savegame version identifier -byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! -char _savegame_format[8]; ///< how to compress savegames -bool _do_autosave; ///< are we doing an autosave at the moment? +uint32 _ttdp_version; ///< version of TTDP savegame (if applicable) +SaveLoadVersion _sl_version; ///< the major savegame version identifier +byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! +std::string _savegame_format; ///< how to compress savegames +bool _do_autosave; ///< are we doing an autosave at the moment? extern bool _sl_is_ext_version; extern bool _sl_maybe_springpp; @@ -689,7 +689,6 @@ static inline uint SlCalcConvMemLen(VarType conv) switch (length << 4) { case SLE_VAR_STRB: - case SLE_VAR_STRBQ: case SLE_VAR_STR: case SLE_VAR_STRQ: return SlReadArrayLength(); @@ -1036,7 +1035,6 @@ static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType con len = SIZE_MAX; break; case SLE_VAR_STRB: - case SLE_VAR_STRBQ: str = (const char *)ptr; len = length; break; @@ -1060,7 +1058,6 @@ static void SlString(void *ptr, size_t length, VarType conv) switch (GetVarMemType(conv)) { default: NOT_REACHED(); case SLE_VAR_STRB: - case SLE_VAR_STRBQ: len = SlCalcNetStringLen((char *)ptr, length); break; case SLE_VAR_STR: @@ -1081,7 +1078,6 @@ static void SlString(void *ptr, size_t length, VarType conv) switch (GetVarMemType(conv)) { default: NOT_REACHED(); case SLE_VAR_STRB: - case SLE_VAR_STRBQ: if (len >= length) { DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating"); SlCopyBytes(ptr, length); @@ -2947,36 +2943,33 @@ static const SaveLoadFormat _saveload_formats[] = { /** * Return the savegameformat of the game. Whether it was created with ZLIB compression * uncompressed, or another type - * @param s Name of the savegame format. If nullptr it picks the first available one + * @param full_name Name of the savegame format. If empty it picks the first available one * @param compression_level Output for telling what compression level we want. * @return Pointer to SaveLoadFormat struct giving all characteristics of this type of savegame */ -static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level, SaveModeFlags flags) +static const SaveLoadFormat *GetSavegameFormat(const std::string &full_name, byte *compression_level, SaveModeFlags flags) { const SaveLoadFormat *def = lastof(_saveload_formats); /* find default savegame format, the highest one with which files can be written */ while (!def->init_write || ((def->flags & SLF_REQUIRES_ZSTD) && !(flags & SMF_ZSTD_OK))) def--; - if (!StrEmpty(s)) { + if (!full_name.empty()) { /* Get the ":..." of the compression level out of the way */ - char *complevel = strrchr(s, ':'); - if (complevel != nullptr) *complevel = '\0'; + size_t separator = full_name.find(':'); + bool has_comp_level = separator != std::string::npos; + const std::string name(full_name, 0, has_comp_level ? separator : full_name.size()); for (const SaveLoadFormat *slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) { - if (slf->init_write != nullptr && strcmp(s, slf->name) == 0) { + if (slf->init_write != nullptr && name.compare(slf->name) == 0) { *compression_level = slf->default_compression; - if (complevel != nullptr) { - /* There is a compression level in the string. - * First restore the : we removed to do proper name matching, - * then move the the begin of the actual version. */ - *complevel = ':'; - complevel++; - - /* Get the version and determine whether all went fine. */ - char *end; - long level = strtol(complevel, &end, 10); - if (end == complevel || level != Clamp(level, slf->min_compression, slf->max_compression)) { + if (has_comp_level) { + const std::string complevel(full_name, separator + 1); + + /* Get the level and determine whether all went fine. */ + size_t processed; + long level = std::stol(complevel, &processed, 10); + if (processed == 0 || level != Clamp(level, slf->min_compression, slf->max_compression)) { SetDParamStr(0, complevel); ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL, WL_CRITICAL); } else { @@ -2987,12 +2980,9 @@ static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level, } } - SetDParamStr(0, s); + SetDParamStr(0, name); SetDParamStr(1, def->name); ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM, WL_CRITICAL); - - /* Restore the string by adding the : back */ - if (complevel != nullptr) *complevel = ':'; } *compression_level = def->default_compression; return def; @@ -3351,7 +3341,7 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) fmt = _saveload_formats; for (;;) { if (fmt == endof(_saveload_formats)) { - /* Who removed LZO support? Bad bad boy! */ + /* Who removed LZO support? */ NOT_REACHED(); } if (fmt->tag == TO_BE32X('OTTD')) break; diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 46a203e15c..c0d1186e76 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -495,7 +495,6 @@ enum VarTypes { SLE_VAR_U64 = 8 << 4, SLE_VAR_NULL = 9 << 4, ///< useful to write zeros in savegame. SLE_VAR_STRB = 10 << 4, ///< string (with pre-allocated buffer) - SLE_VAR_STRBQ = 11 << 4, ///< string enclosed in quotes (with pre-allocated buffer) SLE_VAR_STR = 12 << 4, ///< string pointer SLE_VAR_STRQ = 13 << 4, ///< string pointer enclosed in quotes SLE_VAR_NAME = 14 << 4, ///< old custom name to be converted to a std::string @@ -520,7 +519,6 @@ enum VarTypes { SLE_CHAR = SLE_FILE_I8 | SLE_VAR_CHAR, SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U32, SLE_STRINGBUF = SLE_FILE_STRING | SLE_VAR_STRB, - SLE_STRINGBQUOTE = SLE_FILE_STRING | SLE_VAR_STRBQ, SLE_STRING = SLE_FILE_STRING | SLE_VAR_STR, SLE_STRINGQUOTE = SLE_FILE_STRING | SLE_VAR_STRQ, SLE_NAME = SLE_FILE_STRINGID | SLE_VAR_NAME, @@ -531,7 +529,6 @@ enum VarTypes { SLE_UINT = SLE_UINT32, SLE_INT = SLE_INT32, SLE_STRB = SLE_STRINGBUF, - SLE_STRBQ = SLE_STRINGBQUOTE, SLE_STR = SLE_STRING, SLE_STRQ = SLE_STRINGQUOTE, @@ -1133,7 +1130,7 @@ bool SaveloadCrashWithMissingNewGRFs(); void SlResetVENC(); void SlProcessVENC(); -extern char _savegame_format[8]; +extern std::string _savegame_format; extern bool _do_autosave; #endif /* SAVELOAD_H */ diff --git a/src/screenshot.cpp b/src/screenshot.cpp index da024d21c8..968b216375 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -39,7 +39,7 @@ static const char * const SCREENSHOT_NAME = "screenshot"; ///< Default filename of a saved screenshot. static const char * const HEIGHTMAP_NAME = "heightmap"; ///< Default filename of a saved heightmap. -char _screenshot_format_name[8]; ///< Extension of the current screenshot format (corresponds with #_cur_screenshot_format). +std::string _screenshot_format_name; ///< Extension of the current screenshot format (corresponds with #_cur_screenshot_format). uint _num_screenshot_formats; ///< Number of available screenshot formats. uint _cur_screenshot_format; ///< Index of the currently selected screenshot format in #_screenshot_formats. static char _screenshot_name[128]; ///< Filename of the screenshot file. @@ -604,7 +604,7 @@ void InitializeScreenshotFormats() { uint j = 0; for (uint i = 0; i < lengthof(_screenshot_formats); i++) { - if (!strcmp(_screenshot_format_name, _screenshot_formats[i].extension)) { + if (_screenshot_format_name.compare(_screenshot_formats[i].extension) != 0) { j = i; break; } diff --git a/src/screenshot.h b/src/screenshot.h index e5e0bf03f3..e3221ce7fc 100644 --- a/src/screenshot.h +++ b/src/screenshot.h @@ -42,7 +42,7 @@ bool MakeIndustryScreenshot(const char *name); void SetScreenshotAuxiliaryText(const char *key, const char *value); inline void ClearScreenshotAuxiliaryText() { SetScreenshotAuxiliaryText(nullptr, nullptr); } -extern char _screenshot_format_name[8]; +extern std::string _screenshot_format_name; extern uint _num_screenshot_formats; extern uint _cur_screenshot_format; extern char _full_screenshot_name[MAX_PATH]; diff --git a/src/script/api/script_client.cpp b/src/script/api/script_client.cpp index da646516bc..ede1b925fe 100644 --- a/src/script/api/script_client.cpp +++ b/src/script/api/script_client.cpp @@ -36,7 +36,7 @@ static NetworkClientInfo *FindClientInfo(ScriptClient::ClientID client) { NetworkClientInfo *ci = FindClientInfo(client); if (ci == nullptr) return nullptr; - return stredup(ci->client_name); + return stredup(ci->client_name.c_str()); } /* static */ ScriptCompany::CompanyID ScriptClient::GetCompany(ScriptClient::ClientID client) diff --git a/src/script/api/script_controller.cpp b/src/script/api/script_controller.cpp index 6fc3f9621f..a36e03c230 100644 --- a/src/script/api/script_controller.cpp +++ b/src/script/api/script_controller.cpp @@ -54,7 +54,7 @@ seprintf(log_message, lastof(log_message), "Break: %s", message); ScriptLog::Log(ScriptLog::LOG_SQ_ERROR, log_message); - /* Inform script developer that his script has been paused and + /* Inform script developer that their script has been paused and * needs manual action to continue. */ ShowAIDebugWindow(ScriptObject::GetRootCompany()); diff --git a/src/script/api/script_gamesettings.cpp b/src/script/api/script_gamesettings.cpp index bdaeb6c93e..12435d253f 100644 --- a/src/script/api/script_gamesettings.cpp +++ b/src/script/api/script_gamesettings.cpp @@ -17,17 +17,15 @@ /* static */ bool ScriptGameSettings::IsValid(const char *setting) { - uint i; - const SettingDesc *sd = GetSettingFromName(setting, &i); - return sd != nullptr && sd->desc.cmd != SDT_STRING; + const SettingDesc *sd = GetSettingFromName(setting); + return sd != nullptr && sd->desc.cmd != SDT_STDSTRING; } /* static */ int32 ScriptGameSettings::GetValue(const char *setting) { if (!IsValid(setting)) return -1; - uint index; - const SettingDesc *sd = GetSettingFromName(setting, &index); + const SettingDesc *sd = GetSettingFromName(setting); void *ptr = GetVariableAddress(&_settings_game, &sd->save); if (sd->desc.cmd == SDT_BOOLX) return *(bool*)ptr; @@ -39,13 +37,12 @@ { if (!IsValid(setting)) return false; - uint index; - const SettingDesc *sd = GetSettingFromName(setting, &index); + const SettingDesc *sd = GetSettingFromName(setting); if ((sd->save.conv & SLF_NO_NETWORK_SYNC) != 0) return false; if (sd->desc.cmd != SDT_BOOLX && sd->desc.cmd != SDT_NUMX) return false; - return ScriptObject::DoCommand(0, index, value, CMD_CHANGE_SETTING); + return ScriptObject::DoCommand(0, GetSettingIndex(sd), value, CMD_CHANGE_SETTING); } /* static */ bool ScriptGameSettings::IsDisabledVehicleType(ScriptVehicle::VehicleType vehicle_type) diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index 314dedc977..9c81ee01da 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -372,7 +372,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() IncreaseDoCommandCosts(res.GetCost()); /* Suspend the script player for 1+ ticks, so it simulates multiplayer. This - * both avoids confusion when a developer launched his script in a + * both avoids confusion when a developer launched the script in a * multiplayer game, but also gives time for the GUI and human player * to interact with the game. */ throw Script_Suspend(GetDoCommandDelay(), callback); diff --git a/src/script/api/script_waypointlist.hpp b/src/script/api/script_waypointlist.hpp index 0ee33eff68..f05754b1e0 100644 --- a/src/script/api/script_waypointlist.hpp +++ b/src/script/api/script_waypointlist.hpp @@ -34,7 +34,9 @@ public: class ScriptWaypointList_Vehicle : public ScriptList { public: /** - * @param vehicle_id The vehicle to get the list of waypoints he has in its orders from. + * Get the waypoints from the orders of the given vehicle. Duplicates are + * not added. Waypoints are added in the order of the vehicle's orders. + * @param vehicle_id The vehicle to get the list of waypoints for. */ ScriptWaypointList_Vehicle(VehicleID vehicle_id); }; diff --git a/src/script/script_config.cpp b/src/script/script_config.cpp index eeab51bede..340b3b3f13 100644 --- a/src/script/script_config.cpp +++ b/src/script/script_config.cpp @@ -179,9 +179,9 @@ int ScriptConfig::GetVersion() const return this->version; } -void ScriptConfig::StringToSettings(const char *value) +void ScriptConfig::StringToSettings(const std::string &value) { - char *value_copy = stredup(value); + char *value_copy = stredup(value.c_str()); char *s = value_copy; while (s != nullptr) { @@ -205,8 +205,10 @@ void ScriptConfig::StringToSettings(const char *value) free(value_copy); } -void ScriptConfig::SettingsToString(char *string, const char *last) const +std::string ScriptConfig::SettingsToString() const { + char string[1024]; + char *last = lastof(string); char *s = string; *s = '\0'; for (const auto &item : this->settings) { @@ -216,7 +218,7 @@ void ScriptConfig::SettingsToString(char *string, const char *last) const /* Check if the string would fit in the destination */ size_t needed_size = strlen(item.first) + 1 + strlen(no); /* If it doesn't fit, skip the next settings */ - if (string + needed_size > last) break; + if (s + needed_size > last) break; s = strecat(s, item.first, last); s = strecat(s, "=", last); @@ -226,6 +228,8 @@ void ScriptConfig::SettingsToString(char *string, const char *last) const /* Remove the last ',', but only if at least one setting was saved. */ if (s != string) s[-1] = '\0'; + + return string; } const char *ScriptConfig::GetTextfile(TextfileType type, CompanyID slot) const diff --git a/src/script/script_config.hpp b/src/script/script_config.hpp index be231fcdc2..13a136cbbf 100644 --- a/src/script/script_config.hpp +++ b/src/script/script_config.hpp @@ -116,7 +116,7 @@ public: void AnchorUnchangeableSettings(); /** - * Get the value of a setting for this config. It might fallback to his + * Get the value of a setting for this config. It might fallback to its * 'info' to find the default value (if not set or if not-custom difficulty * level). * @return The (default) value of the setting, or -1 if the setting was not @@ -169,13 +169,13 @@ public: * Convert a string which is stored in the config file or savegames to * custom settings of this Script. */ - void StringToSettings(const char *value); + void StringToSettings(const std::string &value); /** * Convert the custom settings to a string that can be stored in the config * file or savegames. */ - void SettingsToString(char *string, const char *last) const; + std::string SettingsToString() const; /** * Search a textfile file next to this script. diff --git a/src/script/script_info_dummy.cpp b/src/script/script_info_dummy.cpp index 063c028cc3..9438b77f09 100644 --- a/src/script/script_info_dummy.cpp +++ b/src/script/script_info_dummy.cpp @@ -15,7 +15,7 @@ #include "../safeguards.h" -/* The reason this exists in C++, is that a user can trash his ai/ or game/ dir, +/* The reason this exists in C++, is that a user can trash their ai/ or game/ dir, * leaving no Scripts available. The complexity to solve this is insane, and * therefore the alternative is used, and make sure there is always a Script * available, no matter what the situation is. By defining it in C++, there diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp index b6f0eb3d20..aa872d206e 100644 --- a/src/script/script_instance.hpp +++ b/src/script/script_instance.hpp @@ -55,7 +55,7 @@ public: virtual class ScriptInfo *FindLibrary(const char *library, int version) = 0; /** - * A script in multiplayer waits for the server to handle his DoCommand. + * A script in multiplayer waits for the server to handle its DoCommand. * It keeps waiting for this until this function is called. */ void Continue(); diff --git a/src/settings.cpp b/src/settings.cpp index 214e6c86e2..545ca2554f 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -431,8 +431,7 @@ static const void *StringToVal(const SettingDescBase *desc, const char *orig_str return desc->def; } - case SDT_STDSTRING: - case SDT_STRING: return orig_str; + case SDT_STDSTRING: return orig_str; case SDT_INTLIST: return str; default: break; } @@ -525,50 +524,29 @@ static void Write_ValidateSetting(void *ptr, const SettingDesc *sd, int32 val) WriteValue(ptr, sd->save.conv, (int64)val); } -/** - * Set the string value of a setting. - * @param ptr Pointer to the storage location (might be a pointer to a pointer). - * @param sld Pointer to the information for the conversions and limitations to apply. - * @param p The string to save. - */ -static void Write_ValidateString(void *ptr, const SaveLoad *sld, const char *p) -{ - switch (GetVarMemType(sld->conv)) { - case SLE_VAR_STRB: - case SLE_VAR_STRBQ: - if (p != nullptr) { - char *begin = (char*)ptr; - char *end = begin + sld->length - 1; - strecpy(begin, p, end); - str_validate(begin, end, SVS_NONE); - } - break; - - case SLE_VAR_STR: - case SLE_VAR_STRQ: - free(*(char**)ptr); - *(char**)ptr = p == nullptr ? nullptr : stredup(p); - break; - - default: NOT_REACHED(); - } -} - /** * Set the string value of a setting. * @param ptr Pointer to the std::string. - * @param sld Pointer to the information for the conversions and limitations to apply. + * @param sd Pointer to the information for the conversions and limitations to apply. * @param p The string to save. */ -static void Write_ValidateStdString(void *ptr, const SaveLoad *sld, const char *p) +static void Write_ValidateStdString(void *ptr, const SettingDesc *sd, const char *p) { std::string *dst = reinterpret_cast(ptr); - switch (GetVarMemType(sld->conv)) { + switch (GetVarMemType(sd->save.conv)) { case SLE_VAR_STR: case SLE_VAR_STRQ: if (p != nullptr) { - dst->assign(p); + if (sd->desc.max != 0 && strlen(p) >= sd->desc.max) { + /* In case a maximum length is imposed by the setting, the length + * includes the '\0' termination for network transfer purposes. + * Also ensure the string is valid after chopping of some bytes. */ + std::string str(p, sd->desc.max - 1); + dst->assign(str_validate(str, SVS_NONE)); + } else { + dst->assign(p); + } } else { dst->clear(); } @@ -637,12 +615,8 @@ static void IniLoadSettings(IniFile *ini, const SettingDesc *sd, const char *grp Write_ValidateSetting(ptr, sd, (int32)(size_t)p); break; - case SDT_STRING: - Write_ValidateString(ptr, sld, (const char *)p); - break; - case SDT_STDSTRING: - Write_ValidateStdString(ptr, sld, (const char *)p); + Write_ValidateStdString(ptr, sd, (const char *)p); break; case SDT_INTLIST: { @@ -763,24 +737,6 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp break; } - case SDT_STRING: - switch (GetVarMemType(sld->conv)) { - case SLE_VAR_STRB: strecpy(buf, (char*)ptr, lastof(buf)); break; - case SLE_VAR_STRBQ:seprintf(buf, lastof(buf), "\"%s\"", (char*)ptr); break; - case SLE_VAR_STR: strecpy(buf, *(char**)ptr, lastof(buf)); break; - - case SLE_VAR_STRQ: - if (*(char**)ptr == nullptr) { - buf[0] = '\0'; - } else { - seprintf(buf, lastof(buf), "\"%s\"", *(char**)ptr); - } - break; - - default: NOT_REACHED(); - } - break; - case SDT_STDSTRING: switch (GetVarMemType(sld->conv)) { case SLE_VAR_STR: strecpy(buf, reinterpret_cast(ptr)->c_str(), lastof(buf)); break; @@ -1821,8 +1777,8 @@ static bool UpdateClientName(int32 p1) static bool UpdateServerPassword(int32 p1) { - if (strcmp(_settings_client.network.server_password, "*") == 0) { - _settings_client.network.server_password[0] = '\0'; + if (_settings_client.network.server_password.compare("*") == 0) { + _settings_client.network.server_password.clear(); } NetworkServerUpdateGameInfo(); @@ -1831,8 +1787,8 @@ static bool UpdateServerPassword(int32 p1) static bool UpdateRconPassword(int32 p1) { - if (strcmp(_settings_client.network.rcon_password, "*") == 0) { - _settings_client.network.rcon_password[0] = '\0'; + if (_settings_client.network.rcon_password.compare("*") == 0) { + _settings_client.network.rcon_password.clear(); } return true; @@ -1840,8 +1796,8 @@ static bool UpdateRconPassword(int32 p1) static bool UpdateSettingsPassword(int32 p1) { - if (strcmp(_settings_client.network.settings_password, "*") == 0) { - _settings_client.network.settings_password[0] = '\0'; + if (_settings_client.network.settings_password.compare("*") == 0) { + _settings_client.network.settings_password.clear(); } return true; @@ -2116,8 +2072,7 @@ static void AISaveConfig(IniFile *ini, const char *grpname) for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME); const char *name; - char value[1024]; - config->SettingsToString(value, lastof(value)); + std::string value = config->SettingsToString(); if (config->HasScript()) { name = config->GetName(); @@ -2139,8 +2094,7 @@ static void GameSaveConfig(IniFile *ini, const char *grpname) GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME); const char *name; - char value[1024]; - config->SettingsToString(value, lastof(value)); + std::string value = config->SettingsToString(); if (config->HasScript()) { name = config->GetName(); @@ -2458,6 +2412,17 @@ const char *GetCompanySettingNameByIndex(uint32 idx) return _company_settings[idx].desc.name; } +/** + * Get the index of the setting with this description. + * @param sd the setting to get the index for. + * @return the index of the setting to be used for CMD_CHANGE_SETTING. + */ +uint GetSettingIndex(const SettingDesc *sd) +{ + assert((sd->desc.flags & SGF_PER_COMPANY) == 0); + return sd - _settings; +} + /** * Top function to save the new value of an element of the Settings struct * @param index offset in the SettingDesc array of the Settings struct which @@ -2465,9 +2430,21 @@ const char *GetCompanySettingNameByIndex(uint32 idx) * @param value new value of the setting * @param force_newgame force the newgame settings */ -bool SetSettingValue(uint index, int32 value, bool force_newgame) +bool SetSettingValue(const SettingDesc *sd, int32 value, bool force_newgame) { - const SettingDesc *sd = &_settings[index]; + if ((sd->desc.flags & SGF_PER_COMPANY) != 0) { + if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) { + return DoCommandP(0, sd - _company_settings, value, CMD_CHANGE_COMPANY_SETTING); + } else if (sd->desc.flags & SGF_NO_NEWGAME) { + return false; + } + + void *var = GetVariableAddress(&_settings_client.company, &sd->save); + Write_ValidateSetting(var, sd, value); + if (sd->desc.proc != nullptr) sd->desc.proc((int32)ReadValue(var, sd->save.conv)); + return true; + } + /* If an item is company-based, we do not send it over the network * (if any) to change. Also *hack*hack* we update the _newgame version * of settings because changing a company-based setting in a game also @@ -2500,29 +2477,11 @@ bool SetSettingValue(uint index, int32 value, bool force_newgame) /* send non-company-based settings over the network */ if (!_networking || (_networking && (_network_server || _network_settings_access))) { - return DoCommandP(0, index, value, CMD_CHANGE_SETTING); + return DoCommandP(0, GetSettingIndex(sd), value, CMD_CHANGE_SETTING); } return false; } -/** - * Top function to save the new value of an element of the Settings struct - * @param index offset in the SettingDesc array of the CompanySettings struct - * which identifies the setting member we want to change - * @param value new value of the setting - */ -void SetCompanySetting(uint index, int32 value) -{ - const SettingDesc *sd = &_company_settings[index]; - if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) { - DoCommandP(0, index, value, CMD_CHANGE_COMPANY_SETTING); - } else if (!(sd->desc.flags & SGF_NO_NEWGAME)) { - void *var = GetVariableAddress(&_settings_client.company, &sd->save); - Write_ValidateSetting(var, sd, value); - if (sd->desc.proc != nullptr) sd->desc.proc((int32)ReadValue(var, sd->save.conv)); - } -} - /** * Set the company settings for a new company to their default values. */ @@ -2559,23 +2518,20 @@ void SyncCompanySettings() */ uint GetCompanySettingIndex(const char *name) { - uint i; - const SettingDesc *sd = GetSettingFromName(name, &i); - (void)sd; // Unused without asserts + const SettingDesc *sd = GetSettingFromName(name); assert(sd != nullptr && (sd->desc.flags & SGF_PER_COMPANY) != 0); - return i; + return sd - _company_settings; } /** * Set a setting value with a string. - * @param index the settings index. + * @param sd the setting to change. * @param value the value to write * @param force_newgame force the newgame settings * @note Strings WILL NOT be synced over the network */ -bool SetSettingValue(uint index, const char *value, bool force_newgame) +bool SetSettingValue(const SettingDesc *sd, const char *value, bool force_newgame) { - const SettingDesc *sd = &_settings[index]; assert(sd->save.conv & SLF_NO_NETWORK_SYNC); if (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ && strcmp(value, "(null)") == 0) { @@ -2583,9 +2539,7 @@ bool SetSettingValue(uint index, const char *value, bool force_newgame) } void *ptr = GetVariableAddress((_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game, &sd->save); - if (sd->desc.cmd == SDT_STRING) { - Write_ValidateString(ptr, &sd->save, value); - } + Write_ValidateStdString(ptr, sd, value); if (sd->desc.proc != nullptr) sd->desc.proc(0); if (_save_config) SaveToConfig(); @@ -2600,19 +2554,17 @@ bool SetSettingValue(uint index, const char *value, bool force_newgame) * @return Pointer to the setting description of setting \a name if it can be found, * \c nullptr indicates failure to obtain the description */ -const SettingDesc *GetSettingFromName(const char *name, uint *i, bool ignore_version) +const SettingDesc *GetSettingFromName(const char *name, bool ignore_version) { - const SettingDesc *sd; - /* First check all full names */ - for (*i = 0, sd = _settings; sd->save.cmd != SL_END; sd++, (*i)++) { + for (const SettingDesc *sd = _settings; sd->save.cmd != SL_END; sd++) { if (sd->desc.name == nullptr) continue; if (!ignore_version && !SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; if (strcmp(sd->desc.name, name) == 0) return sd; } /* Then check the shortcut variant of the name. */ - for (*i = 0, sd = _settings; sd->save.cmd != SL_END; sd++, (*i)++) { + for (const SettingDesc *sd = _settings; sd->save.cmd != SL_END; sd++) { if (sd->desc.name == nullptr) continue; if (!ignore_version && !SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; const char *short_name = strchr(sd->desc.name, '.'); @@ -2624,7 +2576,7 @@ const SettingDesc *GetSettingFromName(const char *name, uint *i, bool ignore_ver if (strncmp(name, "company.", 8) == 0) name += 8; /* And finally the company-based settings */ - for (*i = 0, sd = _company_settings; sd->save.cmd != SL_END; sd++, (*i)++) { + for (const SettingDesc *sd = _company_settings; sd->save.cmd != SL_END; sd++) { if (sd->desc.name == nullptr) continue; if (!ignore_version && !SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; if (strcmp(sd->desc.name, name) == 0) return sd; @@ -2637,8 +2589,7 @@ const SettingDesc *GetSettingFromName(const char *name, uint *i, bool ignore_ver * and besides, it is also better to keep stuff like this at the same place */ void IConsoleSetSetting(const char *name, const char *value, bool force_newgame) { - uint index; - const SettingDesc *sd = GetSettingFromName(name, &index); + const SettingDesc *sd = GetSettingFromName(name); if (sd == nullptr || ((sd->desc.flags & SGF_NO_NEWGAME) && (_game_mode == GM_MENU || force_newgame))) { IConsolePrintF(CC_WARNING, "'%s' is an unknown setting.", name); @@ -2646,8 +2597,8 @@ void IConsoleSetSetting(const char *name, const char *value, bool force_newgame) } bool success; - if (sd->desc.cmd == SDT_STRING) { - success = SetSettingValue(index, value, force_newgame); + if (sd->desc.cmd == SDT_STDSTRING) { + success = SetSettingValue(sd, value, force_newgame); } else { uint32 val; extern bool GetArgumentInteger(uint32 *value, const char *arg); @@ -2657,7 +2608,7 @@ void IConsoleSetSetting(const char *name, const char *value, bool force_newgame) return; } - success = SetSettingValue(index, val, force_newgame); + success = SetSettingValue(sd, val, force_newgame); } if (!success) { @@ -2671,11 +2622,9 @@ void IConsoleSetSetting(const char *name, const char *value, bool force_newgame) void IConsoleSetSetting(const char *name, int value) { - uint index; - const SettingDesc *sd = GetSettingFromName(name, &index); - (void)sd; // Unused without asserts + const SettingDesc *sd = GetSettingFromName(name); assert(sd != nullptr); - SetSettingValue(index, value); + SetSettingValue(sd, value); } /** @@ -2686,8 +2635,7 @@ void IConsoleSetSetting(const char *name, int value) void IConsoleGetSetting(const char *name, bool force_newgame) { char value[20]; - uint index; - const SettingDesc *sd = GetSettingFromName(name, &index); + const SettingDesc *sd = GetSettingFromName(name); const void *ptr; if (sd == nullptr || ((sd->desc.flags & SGF_NO_NEWGAME) && (_game_mode == GM_MENU || force_newgame))) { @@ -2697,8 +2645,8 @@ void IConsoleGetSetting(const char *name, bool force_newgame) ptr = GetVariableAddress((_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game, &sd->save); - if (sd->desc.cmd == SDT_STRING) { - IConsolePrintF(CC_WARNING, "Current value for '%s' is: '%s'", name, (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ) ? *(const char * const *)ptr : (const char *)ptr); + if (sd->desc.cmd == SDT_STDSTRING) { + IConsolePrintF(CC_WARNING, "Current value for '%s' is: '%s'", name, reinterpret_cast(ptr)->c_str()); } else { bool show_min_max = true; int64 min_value = sd->desc.min; @@ -2751,8 +2699,8 @@ void IConsoleListSettings(const char *prefilter) if (sd->desc.cmd == SDT_BOOLX) { seprintf(value, lastof(value), (*(const bool *)ptr != 0) ? "on" : "off"); - } else if (sd->desc.cmd == SDT_STRING) { - seprintf(value, lastof(value), "%s", (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ) ? *(const char * const *)ptr : (const char *)ptr); + } else if (sd->desc.cmd == SDT_STDSTRING) { + seprintf(value, lastof(value), "%s", reinterpret_cast(ptr)->c_str()); } else { seprintf(value, lastof(value), sd->desc.min < 0 ? "%d" : "%u", (int32)ReadValue(ptr, sd->save.conv)); } @@ -2770,8 +2718,7 @@ void IConsoleListSettings(const char *prefilter) */ static void LoadSettingsXref(const SettingDesc *osd, void *object) { DEBUG(sl, 3, "PATS chunk: Loading xref setting: '%s'", osd->xref.target); - uint index = 0; - const SettingDesc *setting_xref = GetSettingFromName(osd->xref.target, &index, true); + const SettingDesc *setting_xref = GetSettingFromName(osd->xref.target, true); assert(setting_xref != nullptr); // Generate a new SaveLoad from the xref target using the version params from the source diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 899d7ab19f..0dca2312e7 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -832,7 +832,6 @@ protected: struct SettingEntry : BaseSettingEntry { const char *name; ///< Name of the setting const SettingDesc *setting; ///< Setting description of the setting - uint index; ///< Index of the setting in the settings table SettingEntry(const char *name); @@ -860,7 +859,7 @@ struct SettingEntry : BaseSettingEntry { void SetValueDParams(uint first_param, int32 value, std::unique_ptr &tempdata) const; protected: - SettingEntry(const SettingDesc *setting, uint index); + SettingEntry(const SettingDesc *setting); virtual void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const; virtual void DrawSettingString(uint left, uint right, int y, bool highlight, int32 value) const; @@ -872,7 +871,7 @@ private: struct CargoDestPerCargoSettingEntry : SettingEntry { CargoID cargo; - CargoDestPerCargoSettingEntry(CargoID cargo, const SettingDesc *setting, uint index); + CargoDestPerCargoSettingEntry(CargoID cargo, const SettingDesc *setting); virtual void Init(byte level = 0); virtual bool UpdateFilterState(SettingFilter &filter, bool force_visible); @@ -1056,14 +1055,12 @@ SettingEntry::SettingEntry(const char *name) { this->name = name; this->setting = nullptr; - this->index = 0; } -SettingEntry::SettingEntry(const SettingDesc *setting, uint index) +SettingEntry::SettingEntry(const SettingDesc *setting) { this->name = nullptr; this->setting = setting; - this->index = index; } /** @@ -1073,7 +1070,7 @@ SettingEntry::SettingEntry(const SettingDesc *setting, uint index) void SettingEntry::Init(byte level) { BaseSettingEntry::Init(level); - this->setting = GetSettingFromName(this->name, &this->index); + this->setting = GetSettingFromName(this->name); assert_msg(this->setting != nullptr, "name: %s", this->name); } @@ -1081,7 +1078,7 @@ void SettingEntry::Init(byte level) void SettingEntry::ResetAll() { int32 default_value = ReadValue(&this->setting->desc.def, this->setting->save.conv); - SetSettingValue(this->index, default_value); + SetSettingValue(this->setting, default_value); } /** @@ -1305,8 +1302,8 @@ void SettingEntry::DrawSettingString(uint left, uint right, int y, bool highligh /* == CargoDestPerCargoSettingEntry methods == */ -CargoDestPerCargoSettingEntry::CargoDestPerCargoSettingEntry(CargoID cargo, const SettingDesc *setting, uint index) - : SettingEntry(setting, index), cargo(cargo) {} +CargoDestPerCargoSettingEntry::CargoDestPerCargoSettingEntry(CargoID cargo, const SettingDesc *setting) + : SettingEntry(setting), cargo(cargo) {} void CargoDestPerCargoSettingEntry::Init(byte level) { @@ -2125,10 +2122,9 @@ static SettingsContainer &GetSettingsTree() cdist->Add(new SettingEntry("linkgraph.distribution_default")); SettingsPage *cdist_override = cdist->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST_PER_CARGO_OVERRIDE)); { - uint index = 0; - const SettingDesc *setting = GetSettingFromName("linkgraph.distribution_per_cargo[0]", &index); + const SettingDesc *setting = GetSettingFromName("linkgraph.distribution_per_cargo[0]"); for (CargoID c = 0; c < NUM_CARGO; c++) { - cdist_override->Add(new CargoDestPerCargoSettingEntry(c, setting + c, index + c)); + cdist_override->Add(new CargoDestPerCargoSettingEntry(c, setting + c)); } } cdist->Add(new SettingEntry("linkgraph.accuracy")); @@ -2636,11 +2632,7 @@ struct GameSettingsWindow : Window { } if (value != oldvalue) { - if ((sd->desc.flags & SGF_PER_COMPANY) != 0) { - SetCompanySetting(pe->index, value); - } else { - SetSettingValue(pe->index, value); - } + SetSettingValue(sd, value); this->SetDirty(); } } else { @@ -2698,11 +2690,7 @@ struct GameSettingsWindow : Window { value = (int32)(size_t)sd->desc.def; } - if ((sd->desc.flags & SGF_PER_COMPANY) != 0) { - SetCompanySetting(this->valuewindow_entry->index, value); - } else { - SetSettingValue(this->valuewindow_entry->index, value); - } + SetSettingValue(this->valuewindow_entry->setting, value); this->SetDirty(); } @@ -2738,12 +2726,7 @@ struct GameSettingsWindow : Window { const SettingDesc *sd = this->valuedropdown_entry->setting; assert(sd->desc.flags & (SGF_MULTISTRING | SGF_ENUM)); - if ((sd->desc.flags & SGF_PER_COMPANY) != 0) { - SetCompanySetting(this->valuedropdown_entry->index, index); - } else { - SetSettingValue(this->valuedropdown_entry->index, index); - } - + SetSettingValue(sd, index); this->SetDirty(); } break; @@ -3026,7 +3009,7 @@ struct CustomCurrencyWindow : Window { case WID_CC_SEPARATOR: SetDParamStr(0, _custom_currency.separator); str = STR_JUST_RAW_STRING; - len = sizeof(_custom_currency.separator) - 1; // Number of characters excluding '\0' termination + len = 7; line = WID_CC_SEPARATOR; break; @@ -3034,7 +3017,7 @@ struct CustomCurrencyWindow : Window { case WID_CC_PREFIX: SetDParamStr(0, _custom_currency.prefix); str = STR_JUST_RAW_STRING; - len = sizeof(_custom_currency.prefix) - 1; // Number of characters excluding '\0' termination + len = 15; line = WID_CC_PREFIX; break; @@ -3042,7 +3025,7 @@ struct CustomCurrencyWindow : Window { case WID_CC_SUFFIX: SetDParamStr(0, _custom_currency.suffix); str = STR_JUST_RAW_STRING; - len = sizeof(_custom_currency.suffix) - 1; // Number of characters excluding '\0' termination + len = 15; line = WID_CC_SUFFIX; break; @@ -3086,15 +3069,15 @@ struct CustomCurrencyWindow : Window { break; case WID_CC_SEPARATOR: // Thousands separator - strecpy(_custom_currency.separator, str, lastof(_custom_currency.separator)); + _custom_currency.separator = str; break; case WID_CC_PREFIX: - strecpy(_custom_currency.prefix, str, lastof(_custom_currency.prefix)); + _custom_currency.prefix = str; break; case WID_CC_SUFFIX: - strecpy(_custom_currency.suffix, str, lastof(_custom_currency.suffix)); + _custom_currency.suffix = str; break; case WID_CC_YEAR: { // Year to switch to euro diff --git a/src/settings_internal.h b/src/settings_internal.h index f0cd990519..237827f30b 100644 --- a/src/settings_internal.h +++ b/src/settings_internal.h @@ -19,23 +19,16 @@ * @see SettingDescBase */ enum SettingDescType : byte { - /* 4 bytes allocated a maximum of 16 types for GenericType */ - SDT_BEGIN = 0, SDT_NUMX = 0, ///< any number-type SDT_BOOLX = 1, ///< a boolean number SDT_ONEOFMANY = 2, ///< bitmasked number where only ONE bit may be set SDT_MANYOFMANY = 3, ///< bitmasked number where MULTIPLE bits may be set SDT_INTLIST = 4, ///< list of integers separated by a comma ',' - SDT_STRING = 5, ///< string with a pre-allocated buffer SDT_STDSTRING = 6, ///< \c std::string - SDT_END, - /* 9 more possible primitives */ }; - enum SettingGuiFlag : uint16 { - /* 1 byte allocated for a maximum of 8 flags - * Flags directing saving/loading of a variable */ + /* 2 bytes allocated for a maximum of 16 flags. */ SGF_NONE = 0, SGF_0ISDISABLED = 1 << 0, ///< a value of zero means the feature is disabled SGF_DISPLAY_ABS = 1 << 1, ///< display absolute value of the setting @@ -139,18 +132,9 @@ struct SettingDesc { SettingType GetType() const; }; -/* NOTE: The only difference between SettingDesc and SettingDescGlob is - * that one uses global variables as a source and the other offsets - * in a struct which are bound to a certain variable during runtime. - * The only way to differentiate between these two is to check if an object - * has been passed to the function or not. If not, then it is a global variable - * and save->variable has its address, otherwise save->variable only holds the - * offset in a certain struct */ -typedef SettingDesc SettingDescGlobVarList; - -const SettingDesc *GetSettingFromName(const char *name, uint *i, bool ignore_version = false); -bool SetSettingValue(uint index, int32 value, bool force_newgame = false); -bool SetSettingValue(uint index, const char *value, bool force_newgame = false); -void SetCompanySetting(uint index, int32 value); +const SettingDesc *GetSettingFromName(const char *name, bool ignore_version = false); +bool SetSettingValue(const SettingDesc *sd, int32 value, bool force_newgame = false); +bool SetSettingValue(const SettingDesc *sd, const char *value, bool force_newgame = false); +uint GetSettingIndex(const SettingDesc *sd); #endif /* SETTINGS_INTERNAL_H */ diff --git a/src/settings_type.h b/src/settings_type.h index a0ae416ee8..26c5c6bd7b 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -138,7 +138,7 @@ struct GUISettings : public TimeSettings { uint8 date_format_in_default_names; ///< should the default savegame/screenshot name use long dates (31th Dec 2008), short dates (31-12-2008) or ISO dates (2008-12-31) byte max_num_autosaves; ///< controls how many autosavegames are made before the game starts to overwrite (names them 0 to max_num_autosaves - 1) uint8 savegame_overwrite_confirm; ///< Mode for when to warn about overwriting an existing savegame - bool population_in_label; ///< show the population of a town in his label? + bool population_in_label; ///< show the population of a town in its label? uint8 right_mouse_btn_emulation; ///< should we emulate right mouse clicking? uint8 scrollwheel_scrolling; ///< scrolling using the scroll wheel? uint8 scrollwheel_multiplier; ///< how much 'wheel' per incoming event from the OS? @@ -281,16 +281,16 @@ struct MusicSettings { /** Settings related to currency/unit systems. */ struct LocaleSettings { - byte currency; ///< currency we currently use - byte units_velocity; ///< unit system for velocity - byte units_power; ///< unit system for power - byte units_weight; ///< unit system for weight - byte units_volume; ///< unit system for volume - byte units_force; ///< unit system for force - byte units_height; ///< unit system for height - char *digit_group_separator; ///< thousand separator for non-currencies - char *digit_group_separator_currency; ///< thousand separator for currencies - char *digit_decimal_separator; ///< decimal separator + byte currency; ///< currency we currently use + byte units_velocity; ///< unit system for velocity + byte units_power; ///< unit system for power + byte units_weight; ///< unit system for weight + byte units_volume; ///< unit system for volume + byte units_force; ///< unit system for force + byte units_height; ///< unit system for height + std::string digit_group_separator; ///< thousand separator for non-currencies + std::string digit_group_separator_currency; ///< thousand separator for currencies + std::string digit_decimal_separator; ///< decimal separator }; /** Settings related to news */ @@ -329,16 +329,16 @@ struct NetworkSettings { uint16 server_port; ///< port the server listens on uint16 server_admin_port; ///< port the server listens on for the admin network bool server_admin_chat; ///< allow private chat for the server to be distributed to the admin network - char server_name[NETWORK_NAME_LENGTH]; ///< name of the server - char server_password[NETWORK_PASSWORD_LENGTH]; ///< password for joining this server - char rcon_password[NETWORK_PASSWORD_LENGTH]; ///< password for rconsole (server side) - char admin_password[NETWORK_PASSWORD_LENGTH]; ///< password for the admin network - char settings_password[NETWORK_PASSWORD_LENGTH]; ///< password for game settings (server side) + std::string server_name; ///< name of the server + std::string server_password; ///< password for joining this server + std::string rcon_password; ///< password for rconsole (server side) + std::string admin_password; ///< password for the admin network + std::string settings_password; ///< password for game settings (server side) bool server_advertise; ///< advertise the server to the masterserver - char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< name of the player (as client) - char default_company_pass[NETWORK_PASSWORD_LENGTH]; ///< default password for new companies in encrypted form - char connect_to_ip[NETWORK_HOSTNAME_PORT_LENGTH]; ///< default for the "Add server" query - char network_id[NETWORK_SERVER_ID_LENGTH]; ///< network ID for servers + std::string client_name; ///< name of the player (as client) + std::string default_company_pass; ///< default password for new companies in encrypted form + std::string connect_to_ip; ///< default for the "Add server" query + std::string network_id; ///< network ID for servers bool autoclean_companies; ///< automatically remove companies that are not in use uint8 autoclean_unprotected; ///< remove passwordless companies after this many months uint8 autoclean_protected; ///< remove the password from passworded companies after this many months @@ -349,7 +349,7 @@ struct NetworkSettings { Year restart_game_year; ///< year the server restarts uint8 min_active_clients; ///< minimum amount of active clients to unpause the game bool reload_cfg; ///< reload the config file before restarting - char last_joined[NETWORK_HOSTNAME_PORT_LENGTH]; ///< Last joined server + std::string last_joined; ///< Last joined server bool no_http_content_downloads; ///< do not do content downloads over HTTP }; diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 95e9cd7351..3988972f32 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -268,7 +268,7 @@ Trackdir Ship::GetVehicleTrackdir() const } if (this->state == TRACK_BIT_WORMHOLE) { - /* ship on aqueduct, so just use his direction and assume a diagonal track */ + /* ship on aqueduct, so just use its direction and assume a diagonal track */ return DiagDirToDiagTrackdir(DirToDiagDir(this->direction)); } diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 0c505fcd85..3c416530a0 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -1350,8 +1350,8 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) case WID_SM_ZOOM_IN: case WID_SM_ZOOM_OUT: { const NWidgetBase *wid = this->GetWidget(WID_SM_MAP); - Point pt = { (int)wid->current_x / 2, (int)wid->current_y / 2}; - this->SetZoomLevel((widget == WID_SM_ZOOM_IN) ? ZLC_ZOOM_IN : ZLC_ZOOM_OUT, &pt); + Point zoom_pt = { (int)wid->current_x / 2, (int)wid->current_y / 2}; + this->SetZoomLevel((widget == WID_SM_ZOOM_IN) ? ZLC_ZOOM_IN : ZLC_ZOOM_OUT, &zoom_pt); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); break; } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index f9c2c58bb2..b7b9e18354 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -560,17 +560,17 @@ static void ShowRejectOrAcceptNews(const Station *st, uint num_items, CargoID *c /** * Get the cargo types being produced around the tile (in a rectangle). - * @param tile Northtile of area + * @param north_tile Northern most tile of area * @param w X extent of the area * @param h Y extent of the area * @param rad Search radius in addition to the given area */ -CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad) +CargoArray GetProductionAroundTiles(TileIndex north_tile, int w, int h, int rad) { CargoArray produced; btree::btree_set industries; - TileArea ta = TileArea(tile, w, h).Expand(rad); + TileArea ta = TileArea(north_tile, w, h).Expand(rad); /* Loop over all tiles to get the produced cargo of * everything except industries */ @@ -598,19 +598,19 @@ CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad) /** * Get the acceptance of cargoes around the tile in 1/8. - * @param tile Center of the search area + * @param center_tile Center of the search area * @param w X extent of area * @param h Y extent of area * @param rad Search radius in addition to given area * @param always_accepted bitmask of cargo accepted by houses and headquarters; can be nullptr * @param ind Industry associated with neutral station (e.g. oil rig) or nullptr */ -CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted) +CargoArray GetAcceptanceAroundTiles(TileIndex center_tile, int w, int h, int rad, CargoTypes *always_accepted) { CargoArray acceptance; if (always_accepted != nullptr) *always_accepted = 0; - TileArea ta = TileArea(tile, w, h).Expand(rad); + TileArea ta = TileArea(center_tile, w, h).Expand(rad); for (TileIndex tile : ta) { /* Ignore industry if it has a neutral station. */ @@ -3967,7 +3967,7 @@ static void UpdateStationRating(Station *st) for (const CargoSpec *cs : CargoSpec::Iterate()) { GoodsEntry *ge = &st->goods[cs->Index()]; - /* Slowly increase the rating back to his original level in the case we + /* Slowly increase the rating back to its original level in the case we * didn't deliver cargo yet to this station. This happens when a bribe * failed while you didn't moved that cargo yet to a station. */ if (!ge->HasRating() && ge->rating < INITIAL_STATION_RATING) { diff --git a/src/stdafx.h b/src/stdafx.h index e7a74608df..87b37b2698 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -33,6 +33,7 @@ #if defined(__HAIKU__) # include # include +# define _DEFAULT_SOURCE # define _GNU_SOURCE # define TROUBLED_INTS #endif @@ -130,6 +131,7 @@ /* Warn about functions using 'printf' format syntax. First argument determines which parameter * is the format string, second argument is start of values passed to printf. */ #define WARN_FORMAT(string, args) __attribute__ ((format (printf, string, args))) + #define WARN_TIME_FORMAT(string) __attribute__ ((format (strftime, string, 0))) #define FINAL final /* Use fallthrough attribute where supported */ @@ -154,6 +156,7 @@ # define NORETURN # define CDECL # define WARN_FORMAT(string, args) +# define WARN_TIME_FORMAT(string) # define FINAL # define FALLTHROUGH # include @@ -202,6 +205,7 @@ # define CDECL _cdecl # define WARN_FORMAT(string, args) +# define WARN_TIME_FORMAT(string) # define FINAL final /* fallthrough attribute, VS 2017 */ diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 0ed39ba045..ccb9ccf7b8 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -776,7 +776,7 @@ public: case WID_SB_SEL_PAGE: { /* Get max title width. */ - for (uint16 i = 0; i < this->story_pages.size(); i++) { + for (size_t i = 0; i < this->story_pages.size(); i++) { const StoryPage *s = this->story_pages[i]; if (s->title != nullptr) { @@ -822,7 +822,7 @@ public: if (!list.empty()) { /* Get the index of selected page. */ int selected = 0; - for (uint16 i = 0; i < this->story_pages.size(); i++) { + for (size_t i = 0; i < this->story_pages.size(); i++) { const StoryPage *p = this->story_pages[i]; if (p->index == this->selected_page_id) break; selected++; diff --git a/src/strgen/strgen_base.cpp b/src/strgen/strgen_base.cpp index 60e27e752b..9d1346e17f 100644 --- a/src/strgen/strgen_base.cpp +++ b/src/strgen/strgen_base.cpp @@ -457,7 +457,7 @@ void EmitGender(Buffer *buffer, char *buf, int value) /* This is a {G 0 foo bar two} command. * If no relative number exists, default to +0 */ - if (!ParseRelNum(&buf, &argidx, &offset)) {} + ParseRelNum(&buf, &argidx, &offset); const CmdStruct *cmd = _cur_pcs.cmd[argidx]; if (cmd == nullptr || (cmd->flags & C_GENDER) == 0) { diff --git a/src/string.cpp b/src/string.cpp index 5f852cc30b..5af0b8ba86 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -358,19 +358,10 @@ bool StrValid(const char *str, const char *last) * When there are spaces at the begin, the whole string is moved forward. * @param str The string to perform the in place left trimming on. */ -static void StrLeftTrimInPlace(char *str) +static void StrLeftTrimInPlace(std::string &str) { - if (StrEmpty(str)) return; - - char *first_non_space = str; - while (*first_non_space == ' ') first_non_space++; - - if (first_non_space == str) return; - - /* The source will reach '\0' first, but set the '\0' on the destination afterwards. */ - char *dst = str; - for (char *src = first_non_space; *src != '\0'; dst++, src++) *dst = *src; - *dst = '\0'; + size_t pos = str.find_first_not_of(' '); + str.erase(0, pos); } /** @@ -379,24 +370,10 @@ static void StrLeftTrimInPlace(char *str) * When there are spaces at the end, the '\0' will be moved forward. * @param str The string to perform the in place left trimming on. */ -static void StrRightTrimInPlace(char *str) +static void StrRightTrimInPlace(std::string &str) { - if (StrEmpty(str)) return; - - char *end = str; - while (*end != '\0') end++; - - char *last_non_space = end - 1; - while (last_non_space >= str && *last_non_space == ' ') last_non_space--; - - /* The last non space points to the last character of the string that is not - * a space. For a string with only spaces or an empty string this would be - * the position before the begin of the string. The previous search ensures - * that this location before the string is not read. - * In any case, the character after the last non space character will be - * either a space or the existing termination, so it can be set to '\0'. - */ - last_non_space[1] = '\0'; + size_t pos = str.find_last_not_of(' '); + if (pos != std::string::npos) str.erase(pos + 1); } /** @@ -406,7 +383,7 @@ static void StrRightTrimInPlace(char *str) * and when there are spaces at the back the '\0' termination is moved. * @param str The string to perform the in place trimming on. */ -void StrTrimInPlace(char *str) +void StrTrimInPlace(std::string &str) { StrLeftTrimInPlace(str); StrRightTrimInPlace(str); diff --git a/src/string_func.h b/src/string_func.h index d2f9ee067b..feef8d4c49 100644 --- a/src/string_func.h +++ b/src/string_func.h @@ -54,7 +54,7 @@ bool strtolower(char *str); bool strtolower(std::string &str, std::string::size_type offs = 0); bool StrValid(const char *str, const char *last) NOACCESS(2); -void StrTrimInPlace(char *str); +void StrTrimInPlace(std::string &str); /** * Check if a string buffer is empty. diff --git a/src/strings.cpp b/src/strings.cpp index c5ff5fc60b..324b7c94bc 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -289,6 +289,18 @@ char *GetString(char *buffr, StringID string, const char *last) return GetStringWithArgs(buffr, string, &_global_string_params, last); } +/** + * Resolve the given StringID into a std::string with all the associated + * DParam lookups and formatting. + * @param string The unique identifier of the translatable string. + * @return The std::string of the translated string. + */ +std::string GetString(StringID string) +{ + char buffer[DRAW_STRING_BUFFER]; + GetString(buffer, string, lastof(buffer)); + return buffer; +} /** * This function is used to "bind" a C string to a OpenTTD dparam slot. @@ -347,8 +359,8 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char uint64 tot = 0; for (int i = 0; i < max_digits; i++) { if (i == max_digits - fractional_digits) { - const char *decimal_separator = _settings_game.locale.digit_decimal_separator; - if (decimal_separator == nullptr) decimal_separator = _langpack.langpack->digit_decimal_separator; + const char *decimal_separator = _settings_game.locale.digit_decimal_separator.c_str(); + if (StrEmpty(decimal_separator)) decimal_separator = _langpack.langpack->digit_decimal_separator; buff += seprintf(buff, last, "%s", decimal_separator); } @@ -372,8 +384,8 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char static char *FormatCommaNumber(char *buff, int64 number, const char *last, int fractional_digits = 0) { - const char *separator = _settings_game.locale.digit_group_separator; - if (separator == nullptr) separator = _langpack.langpack->digit_group_separator; + const char *separator = _settings_game.locale.digit_group_separator.c_str(); + if (StrEmpty(separator)) separator = _langpack.langpack->digit_group_separator; return FormatNumber(buff, number, last, separator, 1, fractional_digits); } @@ -395,9 +407,9 @@ static char *FormatHexNumber(char *buff, uint64 number, const char *last) WChar GetDecimalSeparatorChar() { WChar decimal_char = '.'; - const char *decimal_separator = _settings_game.locale.digit_decimal_separator; - if (decimal_separator == nullptr) decimal_separator = _langpack.langpack->digit_decimal_separator; - if (decimal_separator != nullptr) Utf8Decode(&decimal_char, decimal_separator); + const char *decimal_separator = _settings_game.locale.digit_decimal_separator.c_str(); + if (StrEmpty(decimal_separator)) decimal_separator = _langpack.langpack->digit_decimal_separator; + if (!StrEmpty(decimal_separator)) Utf8Decode(&decimal_char, decimal_separator); return decimal_char; } @@ -420,8 +432,8 @@ static char *FormatBytes(char *buff, int64 number, const char *last) id++; } - const char *decimal_separator = _settings_game.locale.digit_decimal_separator; - if (decimal_separator == nullptr) decimal_separator = _langpack.langpack->digit_decimal_separator; + const char *decimal_separator = _settings_game.locale.digit_decimal_separator.c_str(); + if (StrEmpty(decimal_separator)) decimal_separator = _langpack.langpack->digit_decimal_separator; if (number < 1024) { id = 0; @@ -532,7 +544,7 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n /* Add prefix part, following symbol_pos specification. * Here, it can can be either 0 (prefix) or 2 (both prefix and suffix). * The only remaining value is 1 (suffix), so everything that is not 1 */ - if (spec->symbol_pos != 1) buff = strecpy(buff, spec->prefix, last); + if (spec->symbol_pos != 1) buff = strecpy(buff, spec->prefix.c_str(), last); /* for huge numbers, compact the number into k or M */ if (compact) { @@ -547,16 +559,16 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n } } - const char *separator = _settings_game.locale.digit_group_separator_currency; - if (separator == nullptr && !StrEmpty(_currency->separator)) separator = _currency->separator; - if (separator == nullptr) separator = _langpack.langpack->digit_group_separator_currency; + const char *separator = _settings_game.locale.digit_group_separator_currency.c_str(); + if (StrEmpty(separator)) separator = _currency->separator.c_str(); + if (StrEmpty(separator)) separator = _langpack.langpack->digit_group_separator_currency; buff = FormatNumber(buff, number, last, separator); buff = strecpy(buff, multiplier, last); /* Add suffix part, following symbol_pos specification. * Here, it can can be either 1 (suffix) or 2 (both prefix and suffix). * The only remaining value is 1 (prefix), so everything that is not 0 */ - if (spec->symbol_pos != 0) buff = strecpy(buff, spec->suffix, last); + if (spec->symbol_pos != 0) buff = strecpy(buff, spec->suffix.c_str(), last); if (negative) { if (buff + Utf8CharLen(SCC_POP_COLOUR) > last) return buff; @@ -1081,7 +1093,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg const char *&str = str_stack.top(); if (SCC_NEWGRF_FIRST <= b && b <= SCC_NEWGRF_LAST) { - /* We need to pass some stuff as it might be modified; oh boy. */ + /* We need to pass some stuff as it might be modified. */ //todo: should argve be passed here too? b = RemapNewGRFStringControlCode(b, buf_start, &buff, &str, (int64 *)args->GetDataPointer(), args->GetDataLeft(), dry_run); if (b == 0) continue; @@ -2459,9 +2471,9 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher { void SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) override { #if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) - strecpy(settings->small.font, font_name, lastof(settings->small.font)); - strecpy(settings->medium.font, font_name, lastof(settings->medium.font)); - strecpy(settings->large.font, font_name, lastof(settings->large.font)); + settings->small.font = font_name; + settings->medium.font = font_name; + settings->large.font = font_name; settings->small.os_handle = os_data; settings->medium.os_handle = os_data; @@ -2492,15 +2504,14 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) if (bad_font) { /* We found an unprintable character... lets try whether we can find * a fallback font that can print the characters in the current language. */ - FreeTypeSettings backup; - memcpy(&backup, &_freetype, sizeof(backup)); + FreeTypeSettings backup = _freetype; _freetype.mono.os_handle = nullptr; _freetype.medium.os_handle = nullptr; bad_font = !SetFallbackFont(&_freetype, _langpack.langpack->isocode, _langpack.langpack->winlangid, searcher); - memcpy(&_freetype, &backup, sizeof(backup)); + _freetype = backup; if (!bad_font) { /* Show that we loaded fallback font. To do this properly we have diff --git a/src/strings_func.h b/src/strings_func.h index 2303ad7e33..17a412cb04 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -172,6 +172,7 @@ public: extern StringParameters _global_string_params; char *GetString(char *buffr, StringID string, const char *last); +std::string GetString(StringID string); char *GetStringWithArgs(char *buffr, StringID string, StringParameters *args, const char *last, uint case_index = 0, bool game_script = false); const char *GetStringPtr(StringID string); uint32 GetStringGRFID(StringID string); diff --git a/src/table/cargo_const.h b/src/table/cargo_const.h index 8518a25614..bb6f811a92 100644 --- a/src/table/cargo_const.h +++ b/src/table/cargo_const.h @@ -96,7 +96,7 @@ static const CargoSpec _default_cargo[] = { /** Table of cargo types available in each climate, by default */ -static const CargoLabel _default_climate_cargo[NUM_LANDSCAPE][12] = { +static const CargoLabel _default_climate_cargo[NUM_LANDSCAPE][NUM_ORIGINAL_CARGO] = { { 'PASS', 'COAL', 'MAIL', 'OIL_', 'LVST', 'GOOD', 'GRAI', 'WOOD', 'IORE', 'STEL', 'VALU', 33, }, { 'PASS', 'COAL', 'MAIL', 'OIL_', 'LVST', 'GOOD', 'WHEA', 'WOOD', 34, 'PAPR', 'GOLD', 'FOOD', }, { 'PASS', 'RUBR', 'MAIL', 4, 'FRUT', 'GOOD', 'MAIZ', 11, 'CORE', 'WATR', 'DIAM', 'FOOD', }, diff --git a/src/table/currency_settings.ini b/src/table/currency_settings.ini index 9dd65b7eb3..95ef7a040b 100644 --- a/src/table/currency_settings.ini +++ b/src/table/currency_settings.ini @@ -9,9 +9,9 @@ static const SettingDesc _currency_settings[] = { [post-amble] }; [templates] -SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr, $orderproc), -SDT_STR = SDT_STR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr), -SDT_END = SDT_END() +SDT_VAR = SDT_VAR ($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr, $orderproc), +SDT_SSTR = SDT_SSTR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr), +SDT_END = SDT_END() [validation] SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for $base.$var exceeds storage size"); @@ -42,10 +42,10 @@ def = 1 min = 0 max = UINT16_MAX -[SDT_STR] +[SDT_SSTR] base = CurrencySpec var = separator -type = SLE_STRBQ +type = SLE_STRQ def = ""."" cat = SC_BASIC @@ -57,16 +57,16 @@ def = 0 min = MIN_YEAR max = MAX_YEAR -[SDT_STR] +[SDT_SSTR] base = CurrencySpec var = prefix -type = SLE_STRBQ +type = SLE_STRQ def = nullptr -[SDT_STR] +[SDT_SSTR] base = CurrencySpec var = suffix -type = SLE_STRBQ +type = SLE_STRQ def = "" credits"" [SDT_END] diff --git a/src/table/misc_settings.ini b/src/table/misc_settings.ini index eab963d0ee..0d0b0a2142 100644 --- a/src/table/misc_settings.ini +++ b/src/table/misc_settings.ini @@ -16,14 +16,13 @@ extern bool _allow_hidpi_window; #define WITHOUT_COCOA #endif -static const SettingDescGlobVarList _misc_settings[] = { +static const SettingDesc _misc_settings[] = { [post-amble] }; [templates] SDTG_LIST = SDTG_LIST($name, $type, $length, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr), SDTG_MMANY = SDTG_MMANY($name, $type, $flags, $guiflags, $var, $def, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr), SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr), -SDTG_STR = SDTG_STR($name, $type, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr), SDTG_SSTR = SDTG_SSTR($name, $type, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr), SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr), SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, nullptr, $orderproc), @@ -164,16 +163,16 @@ var = _cur_resolution def = ""0,0"" cat = SC_BASIC -[SDTG_STR] +[SDTG_SSTR] name = ""screenshot_format"" -type = SLE_STRB +type = SLE_STR var = _screenshot_format_name def = nullptr cat = SC_EXPERT -[SDTG_STR] +[SDTG_SSTR] name = ""savegame_format"" -type = SLE_STRB +type = SLE_STR var = _savegame_format def = nullptr cat = SC_EXPERT @@ -183,31 +182,31 @@ name = ""rightclick_emulate"" var = _rightclick_emulate def = false -[SDTG_STR] +[SDTG_SSTR] ifdef = HAS_TRUETYPE_FONT name = ""small_font"" -type = SLE_STRB +type = SLE_STR var = _freetype.small.font def = nullptr -[SDTG_STR] +[SDTG_SSTR] ifdef = HAS_TRUETYPE_FONT name = ""medium_font"" -type = SLE_STRB +type = SLE_STR var = _freetype.medium.font def = nullptr -[SDTG_STR] +[SDTG_SSTR] ifdef = HAS_TRUETYPE_FONT name = ""large_font"" -type = SLE_STRB +type = SLE_STR var = _freetype.large.font def = nullptr -[SDTG_STR] +[SDTG_SSTR] ifdef = HAS_TRUETYPE_FONT name = ""mono_font"" -type = SLE_STRB +type = SLE_STR var = _freetype.mono.font def = nullptr @@ -316,16 +315,16 @@ min = 0 max = 0xFF cat = SC_BASIC -[SDTG_STR] +[SDTG_SSTR] name = ""keyboard"" -type = SLE_STRB +type = SLE_STR var = _keyboard_opt[0] def = nullptr cat = SC_EXPERT -[SDTG_STR] +[SDTG_SSTR] name = ""keyboard_caps"" -type = SLE_STRB +type = SLE_STR var = _keyboard_opt[1] def = nullptr cat = SC_EXPERT diff --git a/src/table/settings.h.preamble b/src/table/settings.h.preamble index 5bc12b7e9b..c2968715e5 100644 --- a/src/table/settings.h.preamble +++ b/src/table/settings.h.preamble @@ -23,9 +23,7 @@ static size_t ConvertLandscape(const char *value); * The macros can be grouped depending on where the config variable is * stored: * 1. SDTG_something - * These are for global variables, so this is the one you will use - * for a #SettingDescGlobVarList section. Here 'var' refers to a - * global variable. + * These are for global variables. Here 'var' refers to a global variable. * 2. SDTC_something * These are for client-only variables. Here the 'var' refers to an * entry inside _settings_client. @@ -119,6 +117,9 @@ static size_t ConvertLandscape(const char *value); #define SDT_STR(base, var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, startup, extver, patxname)\ SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, base, var, sizeof(((base*)8)->var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, nullptr, from, to, cat, startup, extver, patxname) +#define SDT_SSTR(base, var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, startup, extver, patxname)\ + SDT_GENERAL(#var, SDT_STDSTRING, SL_STDSTR, type, flags, guiflags, base, var, sizeof(((base*)8)->var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, nullptr, from, to, cat, startup, extver, patxname) + #define SDT_OMANY(base, var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, load, cat, startup, extver, patxname)\ SDT_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, load, from, to, cat, startup, extver, patxname) @@ -144,6 +145,9 @@ static size_t ConvertLandscape(const char *value); #define SDTC_STR(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, startup, extver, patxname)\ SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, sizeof(_settings_client.var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat, startup, extver, patxname) +#define SDTC_SSTR(var, type, flags, guiflags, def, max_length, str, strhelp, strval, proc, from, to, cat, startup, extver, patxname)\ + SDTG_GENERAL(#var, SDT_STDSTRING, SL_STDSTR, type, flags, guiflags, _settings_client.var, sizeof(_settings_client.var), def, 0, max_length, 0, nullptr, str, strhelp, strval, proc, from, to, cat, startup, extver, patxname) + #define SDTC_OMANY(var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, cat, startup, extver, patxname)\ SDTG_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat, startup, extver, patxname) diff --git a/src/table/settings.ini b/src/table/settings.ini index 727af75efc..dcf8cd99fa 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -135,7 +135,7 @@ static const SettingDescEnumEntry _train_braking_model[] = { * It is also a bit tricky since you would think that service_interval * for example doesn't need to be synched. Every client assigns the * service_interval value to the v->service_interval, meaning that every client - * assigns his value. If the setting was company-based, that would mean that + * assigns its own value. If the setting was company-based, that would mean that * vehicles could decide on different moments that they are heading back to a * service depot, causing desyncs on a massive scale. */ const SettingDesc _settings[] = { @@ -149,11 +149,11 @@ SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, SDTC_BOOL = SDTC_BOOL( $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname), SDTC_LIST = SDTC_LIST( $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname), SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname), -SDTC_STR = SDTC_STR( $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname), +SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $guiflags, $def, $length, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname), SDTC_VAR = SDTC_VAR( $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname, $orderproc), SDT_BOOL = SDT_BOOL($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname), SDT_OMANY = SDT_OMANY($base, $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $load, $cat, $startup, $extver, $patxname), -SDT_STR = SDT_STR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname), +SDT_SSTR = SDT_SSTR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname), SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $startup, $extver, $patxname, $orderproc), SDT_ENUM = SDT_ENUM($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $proc, $from, $to, $cat, $startup, $extver, $patxname, $enumlist), SDT_NULL = SDT_NULL($length, $from, $to, $extver), @@ -4238,7 +4238,7 @@ str = STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL -[SDT_STR] +[SDT_SSTR] base = GameSettings var = locale.digit_group_separator type = SLE_STRQ @@ -4248,7 +4248,7 @@ def = nullptr proc = RedrawScreen cat = SC_BASIC -[SDT_STR] +[SDT_SSTR] base = GameSettings var = locale.digit_group_separator_currency type = SLE_STRQ @@ -4258,7 +4258,7 @@ def = nullptr proc = RedrawScreen cat = SC_BASIC -[SDT_STR] +[SDT_SSTR] base = GameSettings var = locale.digit_decimal_separator type = SLE_STRQ @@ -6178,73 +6178,82 @@ flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = false -[SDTC_STR] +[SDTC_SSTR] var = network.client_name -type = SLE_STRB +type = SLE_STR +length = NETWORK_CLIENT_NAME_LENGTH flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = nullptr proc = UpdateClientName cat = SC_BASIC -[SDTC_STR] +[SDTC_SSTR] var = network.server_password -type = SLE_STRB +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = nullptr proc = UpdateServerPassword cat = SC_BASIC -[SDTC_STR] +[SDTC_SSTR] var = network.rcon_password -type = SLE_STRB +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = nullptr proc = UpdateRconPassword cat = SC_BASIC -[SDTC_STR] +[SDTC_SSTR] var = network.admin_password -type = SLE_STRB +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = nullptr cat = SC_BASIC -[SDTC_STR] +[SDTC_SSTR] var = network.settings_password -type = SLE_STRB +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = nullptr proc = UpdateSettingsPassword cat = SC_EXPERT -[SDTC_STR] +[SDTC_SSTR] var = network.default_company_pass -type = SLE_STRB +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = nullptr -[SDTC_STR] +[SDTC_SSTR] var = network.server_name -type = SLE_STRB +type = SLE_STR +length = NETWORK_NAME_LENGTH flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = nullptr proc = UpdateClientConfigValues cat = SC_BASIC -[SDTC_STR] +[SDTC_SSTR] var = network.connect_to_ip -type = SLE_STRB +type = SLE_STR +length = 0 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = nullptr -[SDTC_STR] +[SDTC_SSTR] var = network.network_id -type = SLE_STRB +type = SLE_STR +length = NETWORK_SERVER_ID_LENGTH flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = nullptr @@ -6341,9 +6350,10 @@ guiflags = SGF_NETWORK_ONLY def = false cat = SC_EXPERT -[SDTC_STR] +[SDTC_SSTR] var = network.last_joined -type = SLE_STRB +type = SLE_STR +length = 0 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = """" cat = SC_EXPERT diff --git a/src/table/win32_settings.ini b/src/table/win32_settings.ini index c6c56516c5..5005c74930 100644 --- a/src/table/win32_settings.ini +++ b/src/table/win32_settings.ini @@ -9,7 +9,7 @@ #if defined(_WIN32) && !defined(DEDICATED) extern bool _window_maximize; -static const SettingDescGlobVarList _win32_settings[] = { +static const SettingDesc _win32_settings[] = { [post-amble] }; #endif /* _WIN32 */ diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index 146904d584..551109a078 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -226,18 +226,18 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin * Pass == 1: Collect the actual cost. */ for (int pass = 0; pass < 2; pass++) { for (TileIndexSet::const_iterator it = ts.dirty_tiles.begin(); it != ts.dirty_tiles.end(); it++) { - TileIndex tile = *it; + TileIndex t = *it; - assert(tile < MapSize()); + assert(t < MapSize()); /* MP_VOID tiles can be terraformed but as tunnels and bridges * cannot go under / over these tiles they don't need checking. */ - if (IsTileType(tile, MP_VOID)) continue; + if (IsTileType(t, MP_VOID)) continue; /* Find new heights of tile corners */ - int z_N = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 0)); - int z_W = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 0)); - int z_S = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 1)); - int z_E = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 1)); + int z_N = TerraformGetHeightOfTile(&ts, t + TileDiffXY(0, 0)); + int z_W = TerraformGetHeightOfTile(&ts, t + TileDiffXY(1, 0)); + int z_S = TerraformGetHeightOfTile(&ts, t + TileDiffXY(1, 1)); + int z_E = TerraformGetHeightOfTile(&ts, t + TileDiffXY(0, 1)); /* Find min and max height of tile */ int z_min = std::min({z_N, z_W, z_S, z_E}); @@ -252,31 +252,31 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (pass == 0) { /* Check if bridge would take damage */ - if (IsBridgeAbove(tile)) { - int bridge_height = GetBridgeHeight(GetSouthernBridgeEnd(tile)); + if (IsBridgeAbove(t)) { + int bridge_height = GetBridgeHeight(GetSouthernBridgeEnd(t)); /* Check if bridge would take damage. */ if (direction == 1 && bridge_height <= z_max) { - _terraform_err_tile = tile; // highlight the tile under the bridge + _terraform_err_tile = t; // highlight the tile under the bridge return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); } /* Is the bridge above not too high afterwards? */ if (direction == -1 && bridge_height > (z_min + _settings_game.construction.max_bridge_height)) { - _terraform_err_tile = tile; + _terraform_err_tile = t; return_cmd_error(STR_ERROR_BRIDGE_TOO_HIGH_AFTER_LOWER_LAND); } } /* Check if tunnel would take damage */ - if (direction == -1 && IsTunnelInWay(tile, z_min, ITIWF_IGNORE_CHUNNEL)) { - _terraform_err_tile = tile; // highlight the tile above the tunnel + if (direction == -1 && IsTunnelInWay(t, z_min, ITIWF_IGNORE_CHUNNEL)) { + _terraform_err_tile = t; // highlight the tile above the tunnel return_cmd_error(STR_ERROR_EXCAVATION_WOULD_DAMAGE); } } /* Is the tile already cleared? */ - const ClearedObjectArea *coa = FindClearedObject(tile); - bool indirectly_cleared = coa != nullptr && coa->first_tile != tile; + const ClearedObjectArea *coa = FindClearedObject(t); + bool indirectly_cleared = coa != nullptr && coa->first_tile != t; /* Check tiletype-specific things, and add extra-cost */ const bool curr_gen = _generating_world; @@ -288,13 +288,13 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin } CommandCost cost; if (indirectly_cleared) { - cost = DoCommand(tile, 0, 0, tile_flags, CMD_LANDSCAPE_CLEAR); + cost = DoCommand(t, 0, 0, tile_flags, CMD_LANDSCAPE_CLEAR); } else { - cost = _tile_type_procs[GetTileType(tile)]->terraform_tile_proc(tile, tile_flags, z_min, tileh); + cost = _tile_type_procs[GetTileType(t)]->terraform_tile_proc(t, tile_flags, z_min, tileh); } _generating_world = curr_gen; if (cost.Failed()) { - _terraform_err_tile = tile; + _terraform_err_tile = t; return cost; } if (pass == 1) total_cost.AddCost(cost); @@ -318,10 +318,10 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin /* change the height */ for (TileIndexToHeightMap::const_iterator it = ts.tile_to_new_height.begin(); it != ts.tile_to_new_height.end(); it++) { - TileIndex tile = it->first; + TileIndex t = it->first; int height = it->second; - SetTileHeight(tile, (uint)height); + SetTileHeight(t, (uint)height); } if (c != nullptr) c->terraform_limit -= (uint32)ts.tile_to_new_height.size() << 16; diff --git a/src/textbuf_gui.h b/src/textbuf_gui.h index c96f4e2e06..200d62582b 100644 --- a/src/textbuf_gui.h +++ b/src/textbuf_gui.h @@ -37,8 +37,7 @@ static const uint OSK_KEYBOARD_ENTRIES = 50; /** * The number of characters has to be OSK_KEYBOARD_ENTRIES. However, these * have to be UTF-8 encoded, which means up to 4 bytes per character. - * Furthermore the string needs to be '\0'-terminated. */ -extern char _keyboard_opt[2][OSK_KEYBOARD_ENTRIES * 4 + 1]; +extern std::string _keyboard_opt[2]; #endif /* TEXTBUF_GUI_H */ diff --git a/src/texteff.hpp b/src/texteff.hpp index d122b17e9b..56b5933926 100644 --- a/src/texteff.hpp +++ b/src/texteff.hpp @@ -24,7 +24,7 @@ enum TextEffectMode { INVALID_TE_ID = 0xFFFF, }; -typedef uint16 TextEffectID; +typedef size_t TextEffectID; void MoveAllTextEffects(uint delta_ms); TextEffectID AddTextEffect(StringID msg, int x, int y, uint8 duration, TextEffectMode mode); diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index ac8da5c2e9..d6c37a4580 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -218,7 +218,7 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) /* virtual */ void TextfileWindow::SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) { #if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) - strecpy(settings->mono.font, font_name, lastof(settings->mono.font)); + settings->mono.font = font_name; settings->mono.os_handle = os_data; #endif } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index a9933ae5b9..f30766fbda 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -3339,27 +3339,27 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 * these do not directly have an owner so we need to check adjacent * tiles. This won't work correctly in the same loop if the adjacent * tile was already deleted earlier in the loop. */ - for (TileIndex tile = 0; tile < MapSize(); ++tile) { - if (IsTileType(tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(tile, t)) { - CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + for (TileIndex current_tile = 0; current_tile < MapSize(); ++current_tile) { + if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) { + CommandCost ret = DoCommand(current_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; } } /* Check all remaining tiles for town ownership. */ - for (TileIndex tile = 0; tile < MapSize(); ++tile) { + for (TileIndex current_tile = 0; current_tile < MapSize(); ++current_tile) { bool try_clear = false; - switch (GetTileType(tile)) { + switch (GetTileType(current_tile)) { case MP_ROAD: - try_clear = HasTownOwnedRoad(tile) && GetTownIndex(tile) == t->index; + try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index; break; case MP_HOUSE: - try_clear = GetTownIndex(tile) == t->index; + try_clear = GetTownIndex(current_tile) == t->index; break; case MP_INDUSTRY: - try_clear = Industry::GetByTile(tile)->town == t; + try_clear = Industry::GetByTile(current_tile)->town == t; break; case MP_OBJECT: @@ -3367,7 +3367,7 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* No towns will be left, remove it! */ try_clear = true; } else { - Object *o = Object::GetByTile(tile); + Object *o = Object::GetByTile(current_tile); if (o->town == t) { if (o->type == OBJECT_STATUE) { /* Statue... always remove. */ @@ -3384,7 +3384,7 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 break; } if (try_clear) { - CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(current_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; } } diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index f58ba4ca1b..0597366e23 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -1757,10 +1757,10 @@ public: ConvertValueToDecimal(type, GetTraceRestrictValue(item), value, decimal); SetDParam(0, value); SetDParam(1, decimal); - char *saved = _settings_game.locale.digit_group_separator; - _settings_game.locale.digit_group_separator = const_cast(""); + std::string saved = std::move(_settings_game.locale.digit_group_separator); + _settings_game.locale.digit_group_separator.clear(); ShowQueryString(STR_JUST_DECIMAL, STR_TRACE_RESTRICT_VALUE_CAPTION, 16, this, CS_NUMERAL_DECIMAL, QSF_NONE); - _settings_game.locale.digit_group_separator = saved; + _settings_game.locale.digit_group_separator = std::move(saved); } break; } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index df8650374c..b8bacbf397 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2215,7 +2215,7 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3 } CommandCost cost(EXPENSES_NEW_VEHICLES); - for (Train *t = sell_head; t != nullptr; t = t->Next()) cost.AddCost(-t->value); + for (Train *part = sell_head; part != nullptr; part = part->Next()) cost.AddCost(-part->value); /* do it? */ if (flags & DC_EXEC) { @@ -6460,7 +6460,7 @@ Trackdir Train::GetVehicleTrackdir() const } if (this->track == TRACK_BIT_WORMHOLE) { - /* Train in tunnel or on bridge, so just use his direction and make an educated guess + /* Train in tunnel or on bridge, so just use its direction and make an educated guess * given the track bits on the tunnel/bridge head tile. * If a reachable track piece is reserved, use that, otherwise use the first reachable track piece. */ diff --git a/src/viewport.cpp b/src/viewport.cpp index d09fa3578c..9dd9051c9a 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -456,8 +456,8 @@ void InitializeWindowViewport(Window *w, int x, int y, MarkAllRoutePathsDirty(veh); MarkAllRouteStepsDirty(veh); } else { - uint x = TileX(follow_flags) * TILE_SIZE; - uint y = TileY(follow_flags) * TILE_SIZE; + x = TileX(follow_flags) * TILE_SIZE; + y = TileY(follow_flags) * TILE_SIZE; vp->follow_vehicle = INVALID_VEHICLE; pt = MapXYZToViewport(vp, x, y, GetSlopePixelZ(x, y)); diff --git a/src/walltime_func.h b/src/walltime_func.h new file mode 100644 index 0000000000..219a8907de --- /dev/null +++ b/src/walltime_func.h @@ -0,0 +1,80 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + + /** @file walltime_func.h Functionality related to the time of the clock on your wall. */ + +#ifndef WALLTIME_FUNC_H +#define WALLTIME_FUNC_H + +#include + +/** Helper for safely converting a std::time_t to a local time std::tm using localtime_s. */ +struct LocalTimeToStruct { + static inline std::tm ToTimeStruct(std::time_t time_since_epoch) + { + std::tm time = {}; +#ifdef WIN32 + /* Windows has swapped the parameters around for localtime_s. */ + localtime_s(&time, &time_since_epoch); +#else + localtime_r(&time_since_epoch, &time); +#endif + return time; + } +}; + +/** Helper for safely converting a std::time_t to a UTC time std::tm using gmtime_s. */ +struct UTCTimeToStruct { + static inline std::tm ToTimeStruct(std::time_t time_since_epoch) + { + std::tm time = {}; +#ifdef WIN32 + /* Windows has swapped the parameters around for gmtime_s. */ + gmtime_s(&time, &time_since_epoch); +#else + gmtime_r(&time_since_epoch, &time); +#endif + return time; + } +}; + +/** + * Container for wall clock time related functionality not directly provided by C++. + * @tparam T The type of the time-to-struct implementation class. + */ +template +struct Time { + /** + * Format the current time with the given strftime format specifiers. + * @param buffer The buffer to write the time string to. + * @param last The last element in the buffer. + * @param format The format according to strftime format specifiers. + * @return The number of characters that were written to the buffer. + */ + static inline size_t Format(char *buffer, const char *last, const char *format) NOACCESS(2) WARN_TIME_FORMAT(3) + { + std::tm time_struct = T::ToTimeStruct(time(nullptr)); +#ifndef _MSC_VER + /* GCC bug #39438; unlike for printf where the appropriate attribute prevent the + * "format non literal" warning, that does not happen for strftime. Even though + * format warnings will be created for invalid strftime formats. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif /* _MSC_VER */ + return strftime(buffer, last - buffer, format, &time_struct); +#ifndef _MSC_VER +#pragma GCC diagnostic pop +#endif /* _MSC_VER */ + } +}; + +/** Wall clock time functionality using the local time zone. */ +using LocalTime = Time; +/** Wall clock time functionality using the UTC time zone. */ +using UTCTime = Time; + +#endif diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index e39e745271..92ce2ee331 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -481,19 +481,19 @@ CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 std::unique_ptr iter(HasBit(p2, 2) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1)); for (; *iter != INVALID_TILE; ++(*iter)) { - TileIndex tile = *iter; + TileIndex current_tile = *iter; CommandCost ret; - Slope slope = GetTileSlope(tile); + Slope slope = GetTileSlope(current_tile); if (slope != SLOPE_FLAT && (wc != WATER_CLASS_RIVER || !IsInclinedSlope(slope))) { return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); } /* can't make water of water! */ - if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || wc == WATER_CLASS_SEA)) continue; + if (IsTileType(current_tile, MP_WATER) && (!IsTileOwner(current_tile, OWNER_WATER) || wc == WATER_CLASS_SEA)) continue; - bool water = IsWaterTile(tile); - ret = DoCommand(tile, 0, 0, flags | DC_FORCE_CLEAR_TILE, CMD_LANDSCAPE_CLEAR); + bool water = IsWaterTile(current_tile); + ret = DoCommand(current_tile, 0, 0, flags | DC_FORCE_CLEAR_TILE, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; if (!water) cost.AddCost(ret); @@ -501,31 +501,31 @@ CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (flags & DC_EXEC) { switch (wc) { case WATER_CLASS_RIVER: - MakeRiver(tile, Random()); + MakeRiver(current_tile, Random()); if (_game_mode == GM_EDITOR) { - TileIndex tile2 = tile; + TileIndex tile2 = current_tile; CircularTileSearch(&tile2, _settings_game.game_creation.river_tropics_width, RiverModifyDesertZone, nullptr); } break; case WATER_CLASS_SEA: - if (TileHeight(tile) == 0) { - MakeSea(tile); + if (TileHeight(current_tile) == 0) { + MakeSea(current_tile); break; } FALLTHROUGH; default: - MakeCanal(tile, _current_company, Random()); + MakeCanal(current_tile, _current_company, Random()); if (Company::IsValidID(_current_company)) { Company::Get(_current_company)->infrastructure.water++; DirtyCompanyInfrastructureWindows(_current_company); } break; } - MarkTileDirtyByTile(tile); - MarkCanalsAndRiversAroundDirty(tile); - CheckForDockingTile(tile); + MarkTileDirtyByTile(current_tile); + MarkCanalsAndRiversAroundDirty(current_tile); + CheckForDockingTile(current_tile); } cost.AddCost(_price[PR_BUILD_CANAL]); @@ -1079,8 +1079,8 @@ static void FloodVehicles(TileIndex tile) if (IsAirportTile(tile)) { const Station *st = Station::GetByTile(tile); - for (TileIndex tile : st->airport) { - if (st->TileBelongsToAirport(tile)) FindFloodVehicle(tile, z); + for (TileIndex airport_tile : st->airport) { + if (st->TileBelongsToAirport(airport_tile)) FindFloodVehicle(airport_tile, z); } /* No vehicle could be flooded on this airport anymore */